aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/ObjectFile/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF')
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp69
1 files changed, 46 insertions, 23 deletions
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 097c91b..5d81b11 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -130,6 +130,29 @@ private:
RelocUnion reloc;
};
+
+lldb::SectionSP MergeSections(lldb::SectionSP lhs, lldb::SectionSP rhs) {
+ assert(lhs && rhs);
+
+ lldb::ModuleSP lhs_module_parent = lhs->GetModule();
+ lldb::ModuleSP rhs_module_parent = rhs->GetModule();
+ assert(lhs_module_parent && rhs_module_parent);
+
+ // Do a sanity check, these should be the same.
+ if (lhs->GetFileAddress() != rhs->GetFileAddress())
+ lhs_module_parent->ReportWarning(
+ "Mismatch addresses for section {0} when "
+ "merging with {1}, expected: {2:x}, "
+ "actual: {3:x}",
+ lhs->GetTypeAsCString(),
+ rhs_module_parent->GetFileSpec().GetPathAsConstString().GetCString(),
+ lhs->GetByteSize(), rhs->GetByteSize());
+
+ // We want to take the greater of two sections. If LHS and RHS are both
+ // SHT_NOBITS, we should default to LHS. If RHS has a bigger section,
+ // indicating it has data that wasn't stripped, we should take that instead.
+ return rhs->GetFileSize() > lhs->GetFileSize() ? rhs : lhs;
+}
} // end anonymous namespace
ELFRelocation::ELFRelocation(unsigned type) {
@@ -781,7 +804,7 @@ ByteOrder ObjectFileELF::GetByteOrder() const {
}
uint32_t ObjectFileELF::GetAddressByteSize() const {
- return m_data.GetAddressByteSize();
+ return m_data_nsp->GetAddressByteSize();
}
AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) {
@@ -822,7 +845,7 @@ size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const {
bool ObjectFileELF::ParseHeader() {
lldb::offset_t offset = 0;
- return m_header.Parse(m_data, &offset);
+ return m_header.Parse(*m_data_nsp.get(), &offset);
}
UUID ObjectFileELF::GetUUID() {
@@ -858,7 +881,7 @@ UUID ObjectFileELF::GetUUID() {
return UUID();
core_notes_crc =
- CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
+ CalculateELFNotesSegmentsCRC32(m_program_headers, *m_data_nsp.get());
if (core_notes_crc) {
// Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it
@@ -869,7 +892,7 @@ UUID ObjectFileELF::GetUUID() {
}
} else {
if (!m_gnu_debuglink_crc)
- m_gnu_debuglink_crc = calc_crc32(0, m_data);
+ m_gnu_debuglink_crc = calc_crc32(0, *m_data_nsp.get());
if (m_gnu_debuglink_crc) {
// Use 4 bytes of crc from the .gnu_debuglink section.
u32le data(m_gnu_debuglink_crc);
@@ -1055,7 +1078,8 @@ size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
// ParseProgramHeaders
bool ObjectFileELF::ParseProgramHeaders() {
- return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0;
+ return GetProgramHeaderInfo(m_program_headers, *m_data_nsp.get(), m_header) !=
+ 0;
}
lldb_private::Status
@@ -1645,8 +1669,8 @@ ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
// ParseSectionHeaders
size_t ObjectFileELF::ParseSectionHeaders() {
- return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid,
- m_gnu_debuglink_file, m_gnu_debuglink_crc,
+ return GetSectionHeaderInfo(m_section_headers, *m_data_nsp.get(), m_header,
+ m_uuid, m_gnu_debuglink_file, m_gnu_debuglink_crc,
m_arch_spec);
}
@@ -1678,7 +1702,7 @@ static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
.Case(".ARM.exidx", eSectionTypeARMexidx)
.Case(".ARM.extab", eSectionTypeARMextab)
.Case(".ctf", eSectionTypeDebug)
- .Cases(".data", ".tdata", eSectionTypeData)
+ .Cases({".data", ".tdata"}, eSectionTypeData)
.Case(".eh_frame", eSectionTypeEHFrame)
.Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)
.Case(".gosymtab", eSectionTypeGoSymtab)
@@ -1967,10 +1991,10 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
provider.AddSection(std::move(*InfoOr), std::move(section_sp));
}
- // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
- // unified section list.
- if (GetType() != eTypeDebugInfo)
- unified_section_list = *m_sections_up;
+ // Merge the two adding any new sections, and overwriting any existing
+ // sections that are SHT_NOBITS
+ unified_section_list =
+ SectionList::Merge(unified_section_list, *m_sections_up, MergeSections);
// If there's a .gnu_debugdata section, we'll try to read the .symtab that's
// embedded in there and replace the one in the original object file (if any).
@@ -2735,9 +2759,8 @@ static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel,
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
WritableDataBuffer *data_buffer =
llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
- uint64_t *dst = reinterpret_cast<uint64_t *>(
- data_buffer->GetBytes() + rel_section->GetFileOffset() +
- ELFRelocation::RelocOffset64(rel));
+ void *const dst = data_buffer->GetBytes() + rel_section->GetFileOffset() +
+ ELFRelocation::RelocOffset64(rel);
uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
memcpy(dst, &val_offset, sizeof(uint64_t));
}
@@ -2762,9 +2785,8 @@ static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel,
// ObjectFileELF creates a WritableDataBuffer in CreateInstance.
WritableDataBuffer *data_buffer =
llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
- uint32_t *dst = reinterpret_cast<uint32_t *>(
- data_buffer->GetBytes() + rel_section->GetFileOffset() +
- ELFRelocation::RelocOffset32(rel));
+ void *const dst = data_buffer->GetBytes() + rel_section->GetFileOffset() +
+ ELFRelocation::RelocOffset32(rel);
memcpy(dst, &truncated_addr, sizeof(uint32_t));
}
}
@@ -3657,7 +3679,8 @@ ArchSpec ObjectFileELF::GetArchitecture() {
if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0)
continue;
DataExtractor data;
- if (data.SetData(m_data, H.p_offset, H.p_filesz) == H.p_filesz) {
+ if (data.SetData(*m_data_nsp.get(), H.p_offset, H.p_filesz) ==
+ H.p_filesz) {
UUID uuid;
RefineModuleDetailsFromNote(data, m_arch_spec, uuid);
}
@@ -3812,10 +3835,10 @@ llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() {
}
DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) {
- // Try and read the program header from our cached m_data which can come from
- // the file on disk being mmap'ed or from the initial part of the ELF file we
- // read from memory and cached.
- DataExtractor data = DataExtractor(m_data, H.p_offset, H.p_filesz);
+ // Try and read the program header from our cached m_data_nsp which can come
+ // from the file on disk being mmap'ed or from the initial part of the ELF
+ // file we read from memory and cached.
+ DataExtractor data = DataExtractor(*m_data_nsp.get(), H.p_offset, H.p_filesz);
if (data.GetByteSize() == H.p_filesz)
return data;
if (IsInMemory()) {