Re-land: [lldb] Use vFlash commands when writing to target's flash memory regions

The difference between this and the previous patch is that now we use
ELF physical addresses only for loading objects into the target (and the
rest of the module load address logic still uses virtual addresses).

Summary:
When writing an object file over gdb-remote, use the vFlashErase, vFlashWrite, and vFlashDone commands if the write address is in a flash memory region.  A bare metal target may have this kind of setup.

- Update ObjectFileELF to set load addresses using physical addresses.  A typical case may be a data section with a physical address in ROM and a virtual address in RAM, which should be loaded to the ROM address.
- Add support for querying the target's qXfer:memory-map, which contains information about flash memory regions, leveraging MemoryRegionInfo data structures with minor modifications
- Update ProcessGDBRemote to use vFlash commands in DoWriteMemory when the target address is in a flash region

Original discussion at http://lists.llvm.org/pipermail/lldb-dev/2018-January/013093.html

Reviewers: clayborg, labath

Reviewed By: labath

Subscribers: llvm-commits, arichardson, emaste, mgorny, lldb-commits

Differential Revision: https://reviews.llvm.org/D42145
Patch by Owen Shaw <llvm@owenpshaw.net>.

llvm-svn: 327970
This commit is contained in:
Pavel Labath
2018-03-20 11:56:24 +00:00
parent 3ce2d7f270
commit 16064d354a
18 changed files with 534 additions and 62 deletions

View File

@@ -3442,3 +3442,38 @@ size_t ObjectFileELF::ReadSectionData(Section *section,
section_data.SetData(buffer_sp);
return buffer_sp->GetByteSize();
}
bool ObjectFileELF::AnySegmentHasPhysicalAddress() {
size_t header_count = ParseProgramHeaders();
for (size_t i = 1; i <= header_count; ++i) {
auto header = GetProgramHeaderByIndex(i);
if (header->p_paddr != 0)
return true;
}
return false;
}
std::vector<ObjectFile::LoadableData>
ObjectFileELF::GetLoadableData(Target &target) {
// Create a list of loadable data from loadable segments,
// using physical addresses if they aren't all null
std::vector<LoadableData> loadables;
size_t header_count = ParseProgramHeaders();
bool should_use_paddr = AnySegmentHasPhysicalAddress();
for (size_t i = 1; i <= header_count; ++i) {
LoadableData loadable;
auto header = GetProgramHeaderByIndex(i);
if (header->p_type != llvm::ELF::PT_LOAD)
continue;
loadable.Dest = should_use_paddr ? header->p_paddr : header->p_vaddr;
if (loadable.Dest == LLDB_INVALID_ADDRESS)
continue;
if (header->p_filesz == 0)
continue;
auto segment_data = GetSegmentDataByIndex(i);
loadable.Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(),
segment_data.GetByteSize());
loadables.push_back(loadable);
}
return loadables;
}

View File

@@ -161,6 +161,11 @@ public:
void RelocateSection(lldb_private::Section *section) override;
protected:
std::vector<LoadableData>
GetLoadableData(lldb_private::Target &target) override;
private:
ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
@@ -383,6 +388,8 @@ private:
RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
lldb_private::ArchSpec &arch_spec,
lldb_private::UUID &uuid);
bool AnySegmentHasPhysicalAddress();
};
#endif // liblldb_ObjectFileELF_h_