Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.h =================================================================== --- source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -218,6 +218,8 @@ /// The address class for each symbol in the elf file FileAddressToAddressClassMap m_address_class_map; + bool m_did_relocations; + /// Returns a 1 based index of the given section header. size_t SectionIndex(const SectionHeaderCollIter &I); @@ -294,9 +296,12 @@ void ParseUnwindSymbols(lldb_private::Symtab *symbol_table, lldb_private::DWARFCallFrameInfo *eh_frame); + void PerformRelocations(lldb_private::Symtab *thetab); + /// Relocates debug sections unsigned RelocateDebugSections(const elf::ELFSectionHeader *rel_hdr, - lldb::user_id_t rel_id); + lldb::user_id_t rel_id, + lldb_private::Symtab *thetab); unsigned RelocateSection(lldb_private::Symtab *symtab, const elf::ELFHeader *hdr, Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -405,7 +405,7 @@ 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 @@ // 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; @@ -815,7 +815,8 @@ : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0), m_program_headers(), m_section_headers(), m_dynamic_symbols(), - m_filespec_ap(), m_entry_point_address(), m_arch_spec() { + m_filespec_ap(), m_entry_point_address(), m_arch_spec(), + m_did_relocations(false) { if (file) m_file = *file; ::memset(&m_header, 0, sizeof(m_header)); @@ -1814,10 +1815,38 @@ return 0; } +static bool IsDebugSection(SectionType Type) { + switch (Type) { + case eSectionTypeDWARFDebugAbbrev: + case eSectionTypeDWARFDebugAddr: + case eSectionTypeDWARFDebugAranges: + case eSectionTypeDWARFDebugFrame: + case eSectionTypeDWARFDebugInfo: + case eSectionTypeDWARFDebugLine: + case eSectionTypeDWARFDebugLoc: + case eSectionTypeDWARFDebugMacInfo: + case eSectionTypeDWARFDebugMacro: + case eSectionTypeDWARFDebugPubNames: + case eSectionTypeDWARFDebugPubTypes: + case eSectionTypeDWARFDebugRanges: + case eSectionTypeDWARFDebugStr: + case eSectionTypeDWARFDebugStrOffsets: + return true; + default: + return false; + } +} + 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; @@ -1995,6 +2024,23 @@ : LLDB_INVALID_ADDRESS; elf::elf_xword log2align = (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign); + + uint64_t addr = header.sh_addr; + + bool is_loaded = + (header.sh_type == SHT_NOBITS || header.sh_type == SHT_PROGBITS || + header.sh_type == SHT_X86_64_UNWIND) && + !IsDebugSection(sect_type); + + // Sections expected to be loaded at runtime from a relocatable + // object might need synthetic file addresses + if (synthaddrs && is_loaded && addr == 0) { + 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 +2048,7 @@ 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. @@ -2797,7 +2843,8 @@ } 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. @@ -2835,7 +2882,7 @@ if (ReadSectionData(rel, rel_data) && ReadSectionData(symtab, symtab_data) && ReadSectionData(debug, debug_data)) { - RelocateSection(m_symtab_ap.get(), &m_header, rel_hdr, symtab_hdr, + RelocateSection(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr, rel_data, symtab_data, debug_data, debug); } @@ -2851,8 +2898,11 @@ // cached copy // of our symtab, dynamic sections, etc. ObjectFile *module_obj_file = module_sp->GetObjectFile(); - if (module_obj_file && module_obj_file != this) - return module_obj_file->GetSymtab(); + if (module_obj_file && module_obj_file != this) { + Symtab *thetab = module_obj_file->GetSymtab(); + PerformRelocations(thetab); + return thetab; + } if (m_symtab_ap.get() == NULL) { SectionList *section_list = module_sp->GetSectionList(); @@ -2930,6 +2980,14 @@ m_symtab_ap->CalculateSymbolSizes(); } + PerformRelocations(m_symtab_ap.get()); + return m_symtab_ap.get(); +} + +void ObjectFileELF::PerformRelocations(lldb_private::Symtab *thetab) +{ + if (m_did_relocations) + return; for (SectionHeaderCollIter I = m_section_headers.begin(); I != m_section_headers.end(); ++I) { if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) { @@ -2939,12 +2997,12 @@ strstr(section_name, ".rel.debug")) { const ELFSectionHeader &reloc_header = *I; user_id_t reloc_id = SectionIndex(I); - RelocateDebugSections(&reloc_header, reloc_id); + RelocateDebugSections(&reloc_header, reloc_id, thetab); } } } } - return m_symtab_ap.get(); + m_did_relocations = true; } void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -632,6 +632,8 @@ } const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() { + // Force application of relocations + (void) m_obj_file->GetSymtab(); return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info); }