summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/Section.h9
-rw-r--r--lldb/include/lldb/Symbol/ArmUnwindInfo.h2
-rw-r--r--lldb/include/lldb/Symbol/ObjectFile.h18
-rw-r--r--lldb/source/Core/Section.cpp6
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp84
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h25
-rw-r--r--lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp8
-rw-r--r--lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h8
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp2
-rw-r--r--lldb/source/Symbol/ArmUnwindInfo.cpp2
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp22
11 files changed, 126 insertions, 60 deletions
diff --git a/lldb/include/lldb/Core/Section.h b/lldb/include/lldb/Core/Section.h
index 0466693edbc..2d5d6443ba7 100644
--- a/lldb/include/lldb/Core/Section.h
+++ b/lldb/include/lldb/Core/Section.h
@@ -238,7 +238,7 @@ public:
/// section has no data or \a offset is not a valid offset
/// in this section.
//------------------------------------------------------------------
- lldb::offset_t GetSectionData(DataExtractor &data) const;
+ lldb::offset_t GetSectionData(DataExtractor &data);
uint32_t GetLog2Align() { return m_log2align; }
@@ -247,6 +247,10 @@ public:
// Get the number of host bytes required to hold a target byte
uint32_t GetTargetByteSize() const { return m_target_byte_size; }
+ bool IsRelocated() const { return m_relocated; }
+
+ void SetIsRelocated(bool b) { m_relocated = b; }
+
protected:
ObjectFile *m_obj_file; // The object file that data for this section should
// be read from
@@ -274,7 +278,8 @@ protected:
m_thread_specific : 1, // This section is thread specific
m_readable : 1, // If this section has read permissions
m_writable : 1, // If this section has write permissions
- m_executable : 1; // If this section has executable permissions
+ m_executable : 1, // If this section has executable permissions
+ m_relocated : 1; // If this section has had relocations applied
uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size.
// This is specified as
// as a multiple number of a host bytes
diff --git a/lldb/include/lldb/Symbol/ArmUnwindInfo.h b/lldb/include/lldb/Symbol/ArmUnwindInfo.h
index ef67a31e7d0..422408b034c 100644
--- a/lldb/include/lldb/Symbol/ArmUnwindInfo.h
+++ b/lldb/include/lldb/Symbol/ArmUnwindInfo.h
@@ -31,7 +31,7 @@ namespace lldb_private {
class ArmUnwindInfo {
public:
- ArmUnwindInfo(const ObjectFile &objfile, lldb::SectionSP &arm_exidx,
+ ArmUnwindInfo(ObjectFile &objfile, lldb::SectionSP &arm_exidx,
lldb::SectionSP &arm_extab);
~ArmUnwindInfo();
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index a4c7b01ece1..60a748bb39d 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -352,6 +352,12 @@ public:
virtual Symtab *GetSymtab() = 0;
//------------------------------------------------------------------
+ /// Perform relocations on the section if necessary.
+ ///
+ //------------------------------------------------------------------
+ virtual void RelocateSection(lldb_private::Section *section);
+
+ //------------------------------------------------------------------
/// Appends a Symbol for the specified so_addr to the symbol table.
///
/// If verify_unique is false, the symbol table is not searched
@@ -792,15 +798,15 @@ public:
size_t CopyData(lldb::offset_t offset, size_t length, void *dst) const;
- virtual size_t ReadSectionData(const Section *section,
+ virtual size_t ReadSectionData(Section *section,
lldb::offset_t section_offset, void *dst,
- size_t dst_len) const;
+ size_t dst_len);
- virtual size_t ReadSectionData(const Section *section,
- DataExtractor &section_data) const;
+ virtual size_t ReadSectionData(Section *section,
+ DataExtractor &section_data);
- size_t MemoryMapSectionData(const Section *section,
- DataExtractor &section_data) const;
+ size_t MemoryMapSectionData(Section *section,
+ DataExtractor &section_data);
bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index 2ea497eba56..c9faf9f8915 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/source/Core/Section.cpp
@@ -135,7 +135,7 @@ Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file,
m_file_offset(file_offset), m_file_size(file_size),
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
m_thread_specific(false), m_readable(false), m_writable(false),
- m_executable(false), m_target_byte_size(target_byte_size) {
+ m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ",
// addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 "
// - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
@@ -157,7 +157,7 @@ Section::Section(const lldb::SectionSP &parent_section_sp,
m_file_offset(file_offset), m_file_size(file_size),
m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
m_thread_specific(false), m_readable(false), m_writable(false),
- m_executable(false), m_target_byte_size(target_byte_size) {
+ m_executable(false), m_relocated(false), m_target_byte_size(target_byte_size) {
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ",
// addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 "
// - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
@@ -392,7 +392,7 @@ lldb::offset_t Section::GetSectionData(void *dst, lldb::offset_t dst_len,
return 0;
}
-lldb::offset_t Section::GetSectionData(DataExtractor &section_data) const {
+lldb::offset_t Section::GetSectionData(DataExtractor &section_data) {
if (m_obj_file)
return m_obj_file->ReadSectionData(this, section_data);
return 0;
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 0f67ab5f33c..e431d4a08f9 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -405,7 +405,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
lldb::offset_t length) {
if (!data_sp) {
data_sp =
- DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset);
+ DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset, true);
if (!data_sp)
return nullptr;
data_offset = 0;
@@ -423,7 +423,7 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
// Update the data to contain the entire file if it doesn't already
if (data_sp->GetByteSize() < length) {
data_sp =
- DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset);
+ DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset, true);
if (!data_sp)
return nullptr;
data_offset = 0;
@@ -1818,6 +1818,12 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
if (!m_sections_ap.get() && ParseSectionHeaders()) {
m_sections_ap.reset(new SectionList());
+ // Object files frequently have 0 for every section address, meaning we
+ // need to compute synthetic addresses in order for "file addresses" from
+ // different sections to not overlap
+ bool synthaddrs = (CalculateType() == ObjectFile::Type::eTypeObjectFile);
+ uint64_t nextaddr = 0;
+
for (SectionHeaderCollIter I = m_section_headers.begin();
I != m_section_headers.end(); ++I) {
const ELFSectionHeaderInfo &header = *I;
@@ -1990,11 +1996,18 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
? m_arch_spec.GetDataByteSize()
: eSectionTypeCode == sect_type ? m_arch_spec.GetCodeByteSize()
: 1;
- const addr_t sect_file_addr = header.sh_flags & SHF_ALLOC
- ? header.sh_addr
- : LLDB_INVALID_ADDRESS;
elf::elf_xword log2align =
(header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign);
+
+ uint64_t addr = header.sh_addr;
+
+ if ((header.sh_flags & SHF_ALLOC) && synthaddrs) {
+ nextaddr =
+ (nextaddr + header.sh_addralign - 1) & ~(header.sh_addralign - 1);
+ addr = nextaddr;
+ nextaddr += vm_size;
+ }
+
SectionSP section_sp(new Section(
GetModule(), // Module to which this section belongs.
this, // ObjectFile to which this section belongs and should read
@@ -2002,7 +2015,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
SectionIndex(I), // Section ID.
name, // Section name.
sect_type, // Section type.
- sect_file_addr, // VM address.
+ addr, // VM address.
vm_size, // VM size in bytes of this section.
header.sh_offset, // Offset of this section in the file.
file_size, // Size of the section as found in the file.
@@ -2720,7 +2733,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
rel_data, symtab_data, strtab_data);
}
-unsigned ObjectFileELF::RelocateSection(
+unsigned ObjectFileELF::ApplyRelocations(
Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
DataExtractor &rel_data, DataExtractor &symtab_data,
@@ -2797,7 +2810,8 @@ unsigned ObjectFileELF::RelocateSection(
}
unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
- user_id_t rel_id) {
+ user_id_t rel_id,
+ lldb_private::Symtab *thetab) {
assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
// Parse in the section list if needed.
@@ -2833,10 +2847,11 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
DataExtractor symtab_data;
DataExtractor debug_data;
- if (ReadSectionData(rel, rel_data) && ReadSectionData(symtab, symtab_data) &&
- ReadSectionData(debug, debug_data)) {
- RelocateSection(m_symtab_ap.get(), &m_header, rel_hdr, symtab_hdr,
- debug_hdr, rel_data, symtab_data, debug_data, debug);
+ if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) &&
+ GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) &&
+ GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) {
+ ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr,
+ rel_data, symtab_data, debug_data, debug);
}
return 0;
@@ -2930,21 +2945,48 @@ Symtab *ObjectFileELF::GetSymtab() {
m_symtab_ap->CalculateSymbolSizes();
}
+ return m_symtab_ap.get();
+}
+
+void ObjectFileELF::RelocateSection(lldb_private::Section *section)
+{
+ static const char *debug_prefix = ".debug";
+
+ // Set relocated bit so we stop getting called, regardless of
+ // whether we actually relocate.
+ section->SetIsRelocated(true);
+
+ // We only relocate in ELF relocatable files
+ if (CalculateType() != eTypeObjectFile)
+ return;
+
+ const char *section_name = section->GetName().GetCString();
+ // Can't relocate that which can't be named
+ if (section_name == nullptr)
+ return;
+
+ // We don't relocate non-debug sections at the moment
+ if (strncmp(section_name, debug_prefix, strlen(debug_prefix)))
+ return;
+
+ // Relocation section names to look for
+ std::string needle = std::string(".rel") + section_name;
+ std::string needlea = std::string(".rela") + section_name;
+
for (SectionHeaderCollIter I = m_section_headers.begin();
I != m_section_headers.end(); ++I) {
if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
- if (CalculateType() == eTypeObjectFile) {
- const char *section_name = I->section_name.AsCString("");
- if (strstr(section_name, ".rela.debug") ||
- strstr(section_name, ".rel.debug")) {
- const ELFSectionHeader &reloc_header = *I;
- user_id_t reloc_id = SectionIndex(I);
- RelocateDebugSections(&reloc_header, reloc_id);
- }
+ const char *hay_name = I->section_name.GetCString();
+ if (hay_name == nullptr)
+ continue;
+ if (needle == hay_name || needlea == hay_name) {
+ const ELFSectionHeader &reloc_header = *I;
+ user_id_t reloc_id = SectionIndex(I);
+ RelocateDebugSections(&reloc_header, reloc_id, GetSymtab());
+ break;
}
}
}
- return m_symtab_ap.get();
}
void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 6d8717b0ef2..e0478cc0697 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -154,6 +154,8 @@ public:
llvm::StringRef
StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;
+ void RelocateSection(lldb_private::Section *section) override;
+
private:
ObjectFileELF(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp,
lldb::offset_t data_offset, const lldb_private::FileSpec *file,
@@ -296,17 +298,18 @@ private:
/// Relocates debug sections
unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr,
- lldb::user_id_t rel_id);
-
- unsigned RelocateSection(lldb_private::Symtab *symtab,
- const elf::ELFHeader *hdr,
- const elf::ELFSectionHeader *rel_hdr,
- const elf::ELFSectionHeader *symtab_hdr,
- const elf::ELFSectionHeader *debug_hdr,
- lldb_private::DataExtractor &rel_data,
- lldb_private::DataExtractor &symtab_data,
- lldb_private::DataExtractor &debug_data,
- lldb_private::Section *rel_section);
+ lldb::user_id_t rel_id,
+ lldb_private::Symtab *thetab);
+
+ unsigned ApplyRelocations(lldb_private::Symtab *symtab,
+ const elf::ELFHeader *hdr,
+ const elf::ELFSectionHeader *rel_hdr,
+ const elf::ELFSectionHeader *symtab_hdr,
+ const elf::ELFSectionHeader *debug_hdr,
+ lldb_private::DataExtractor &rel_data,
+ lldb_private::DataExtractor &symtab_data,
+ lldb_private::DataExtractor &debug_data,
+ lldb_private::Section *rel_section);
/// Loads the section name string table into m_shstr_data. Returns the
/// number of bytes constituting the table.
diff --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
index 06406c6f165..90982e8db9e 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
@@ -230,9 +230,9 @@ bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value,
return num_loaded_sections > 0;
}
-size_t ObjectFileJIT::ReadSectionData(const lldb_private::Section *section,
+size_t ObjectFileJIT::ReadSectionData(lldb_private::Section *section,
lldb::offset_t section_offset, void *dst,
- size_t dst_len) const {
+ size_t dst_len) {
lldb::offset_t file_size = section->GetFileSize();
if (section_offset < file_size) {
size_t src_len = file_size - section_offset;
@@ -248,8 +248,8 @@ size_t ObjectFileJIT::ReadSectionData(const lldb_private::Section *section,
}
size_t ObjectFileJIT::ReadSectionData(
- const lldb_private::Section *section,
- lldb_private::DataExtractor &section_data) const {
+ lldb_private::Section *section,
+ lldb_private::DataExtractor &section_data) {
if (section->GetFileSize()) {
const void *src = (void *)(uintptr_t)section->GetFileOffset();
diff --git a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
index a211645d5d8..c964906a5e8 100644
--- a/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
+++ b/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h
@@ -83,13 +83,13 @@ public:
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override;
- size_t ReadSectionData(const lldb_private::Section *section,
+ size_t ReadSectionData(lldb_private::Section *section,
lldb::offset_t section_offset, void *dst,
- size_t dst_len) const override;
+ size_t dst_len) override;
size_t
- ReadSectionData(const lldb_private::Section *section,
- lldb_private::DataExtractor &section_data) const override;
+ ReadSectionData(lldb_private::Section *section,
+ lldb_private::DataExtractor &section_data) override;
lldb_private::Address GetEntryPointAddress() override;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 4642c2e14dd..27752da86eb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -436,7 +436,7 @@ void SymbolFileDWARF::InitializeObject() {
ModuleSP module_sp(m_obj_file->GetModule());
if (module_sp) {
const SectionList *section_list = module_sp->GetSectionList();
- const Section *section =
+ Section *section =
section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
// Memory map the DWARF mach-o segment so we have everything mmap'ed
diff --git a/lldb/source/Symbol/ArmUnwindInfo.cpp b/lldb/source/Symbol/ArmUnwindInfo.cpp
index 742c057e10e..4da307bf0c3 100644
--- a/lldb/source/Symbol/ArmUnwindInfo.cpp
+++ b/lldb/source/Symbol/ArmUnwindInfo.cpp
@@ -46,7 +46,7 @@ bool ArmUnwindInfo::ArmExidxEntry::operator<(const ArmExidxEntry &other) const {
return address < other.address;
}
-ArmUnwindInfo::ArmUnwindInfo(const ObjectFile &objfile, SectionSP &arm_exidx,
+ArmUnwindInfo::ArmUnwindInfo(ObjectFile &objfile, SectionSP &arm_exidx,
SectionSP &arm_extab)
: m_byte_order(objfile.GetByteOrder()), m_arm_exidx_sp(arm_exidx),
m_arm_extab_sp(arm_extab) {
diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index c2e2be9cfb7..39593bc6e2b 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -483,9 +483,9 @@ size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,
return m_data.CopyData(offset, length, dst);
}
-size_t ObjectFile::ReadSectionData(const Section *section,
+size_t ObjectFile::ReadSectionData(Section *section,
lldb::offset_t section_offset, void *dst,
- size_t dst_len) const {
+ size_t dst_len) {
assert(section);
section_offset *= section->GetTargetByteSize();
@@ -505,6 +505,9 @@ size_t ObjectFile::ReadSectionData(const Section *section,
dst_len, error);
}
} else {
+ if (!section->IsRelocated())
+ RelocateSection(section);
+
const lldb::offset_t section_file_size = section->GetFileSize();
if (section_offset < section_file_size) {
const size_t section_bytes_left = section_file_size - section_offset;
@@ -531,8 +534,8 @@ size_t ObjectFile::ReadSectionData(const Section *section,
//----------------------------------------------------------------------
// Get the section data the file on disk
//----------------------------------------------------------------------
-size_t ObjectFile::ReadSectionData(const Section *section,
- DataExtractor &section_data) const {
+size_t ObjectFile::ReadSectionData(Section *section,
+ DataExtractor &section_data) {
// If some other objectfile owns this data, pass this to them.
if (section->GetObjectFile() != this)
return section->GetObjectFile()->ReadSectionData(section, section_data);
@@ -562,8 +565,8 @@ size_t ObjectFile::ReadSectionData(const Section *section,
}
}
-size_t ObjectFile::MemoryMapSectionData(const Section *section,
- DataExtractor &section_data) const {
+size_t ObjectFile::MemoryMapSectionData(Section *section,
+ DataExtractor &section_data) {
// If some other objectfile owns this data, pass this to them.
if (section->GetObjectFile() != this)
return section->GetObjectFile()->MemoryMapSectionData(section,
@@ -572,6 +575,9 @@ size_t ObjectFile::MemoryMapSectionData(const Section *section,
if (IsInMemory()) {
return ReadSectionData(section, section_data);
} else {
+ if (!section->IsRelocated())
+ RelocateSection(section);
+
// The object file now contains a full mmap'ed copy of the object file data,
// so just use this
return GetData(section->GetFileOffset(), section->GetFileSize(),
@@ -694,3 +700,7 @@ Status ObjectFile::LoadInMemory(Target &target, bool set_pc) {
}
return error;
}
+
+void ObjectFile::RelocateSection(lldb_private::Section *section)
+{
+}
OpenPOWER on IntegriCloud