diff options
Diffstat (limited to 'lldb/source/Plugins/ObjectFile/ELF')
| -rw-r--r-- | lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 69 |
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()) { |
