Index: lldb/include/lldb/Symbol/ObjectFile.h =================================================================== --- lldb/include/lldb/Symbol/ObjectFile.h +++ lldb/include/lldb/Symbol/ObjectFile.h @@ -736,8 +736,8 @@ // This function will transparently decompress section data if the section if // compressed. Note that for compressed section the resulting data size may // be larger than what Section::GetFileSize reports. - virtual size_t ReadSectionData(const SectionPart §ion_part, - DataExtractor §ion_data); + size_t ReadSectionData(const SectionPart §ion_part, + DataExtractor §ion_data); bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; } @@ -765,6 +765,26 @@ //------------------------------------------------------------------ virtual std::vector GetLoadableData(Target &target); + // Similar to ReadSectionData() but you can ask final (decompressed for + // compressed sections) size before really reading the data to an adress. + class SectionReader; + virtual std::unique_ptr SectionReaderFactory( + const SectionPart §ion_part); + class SectionReader { + public: + virtual uint64_t getDecompressedSize(); + virtual size_t read(DataExtractor §ion_data); + virtual size_t read(uint8_t *dst); + virtual ~SectionReader(); + protected: + friend std::unique_ptr ObjectFile::SectionReaderFactory( + const SectionPart §ion_part); + SectionReader(const SectionPart §ion_part_); + const SectionPart §ion_part; + }; + + lldb::ProcessWP &GetProcessWP() { return m_process_wp; } + protected: //------------------------------------------------------------------ // Member variables. Index: lldb/include/lldb/lldb-enumerations.h =================================================================== --- lldb/include/lldb/lldb-enumerations.h +++ lldb/include/lldb/lldb-enumerations.h @@ -718,6 +718,7 @@ eSectionTypeDWARFDebugInfoDwo, eSectionTypeDWARFDebugStrDwo, eSectionTypeDWARFDebugStrOffsetsDwo, + eSectionTypeDWARFDebugTypesDwo, }; FLAGS_ENUM(EmulateInstructionOptions){ Index: lldb/source/Core/Section.cpp =================================================================== --- lldb/source/Core/Section.cpp +++ lldb/source/Core/Section.cpp @@ -104,6 +104,8 @@ return "dwarf-str-offsets-dwo"; case eSectionTypeDWARFDebugTypes: return "dwarf-types"; + case eSectionTypeDWARFDebugTypesDwo: + return "dwarf-types-dwo"; case eSectionTypeDWARFDebugNames: return "dwarf-names"; case eSectionTypeELFSymbolTable: Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h =================================================================== --- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -139,13 +139,11 @@ ObjectFile::Strata CalculateStrata() override; + using lldb_private::ObjectFile::ReadSectionData; size_t ReadSectionData(lldb_private::Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len) override; - size_t ReadSectionData(const lldb_private::SectionPart §ion_part, - lldb_private::DataExtractor §ion_data) override; - llvm::ArrayRef ProgramHeaders(); lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H); @@ -154,6 +152,11 @@ void RelocateSection(lldb_private::Section *section) override; + std::unique_ptr SectionReaderFactory( + const lldb_private::SectionPart §ion_part) override; + + class SectionReaderCompressed; + protected: std::vector Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -34,6 +34,7 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/Decompressor.h" +#include "llvm/Object/ELF.h" #include "llvm/Support/ARMBuildAttributes.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" @@ -1768,6 +1769,7 @@ .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets) .Case(".debug_str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) .Case(".debug_types", eSectionTypeDWARFDebugTypes) + .Case(".debug_types.dwo", eSectionTypeDWARFDebugTypesDwo) .Case(".eh_frame", eSectionTypeEHFrame) .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink) .Case(".gosymtab", eSectionTypeGoSymtab) @@ -3391,58 +3393,113 @@ return data.CopyData(section_offset, dst_len, dst); } -size_t ObjectFileELF::ReadSectionData(const SectionPart §ion_part, - DataExtractor §ion_data) { - Section *section = section_part.GetSection(); - // If some other objectfile owns this data, pass this to them. - if (section->GetObjectFile() != this) - return section->GetObjectFile()->ReadSectionData( - section_part, section_data); +class ObjectFileELF::SectionReaderCompressed + : public ObjectFile::SectionReader { +public: + SectionReaderCompressed(const SectionPart §ion_part_); + uint64_t getDecompressedSize() override; + size_t read(DataExtractor §ion_data) override; + size_t read(uint8_t *dst) override; + ~SectionReaderCompressed(); +private: + static llvm::Expected Initialize( + const SectionPart §ion_part, DataExtractor &compressed_data); + DataExtractor compressed_data; + // 'decompressor' Initialize() requires already initialized 'compressed_data'. + llvm::Expected decompressor; +}; - size_t result = ObjectFile::ReadSectionData(section, section_data); - if (result == 0 || !section->Test(SHF_COMPRESSED)) - return result; +ObjectFileELF::SectionReaderCompressed::SectionReaderCompressed( + const SectionPart §ion_part_) + : ObjectFile::SectionReader(section_part_), + decompressor(Initialize(section_part_, compressed_data)) {} +ObjectFileELF::SectionReaderCompressed::~SectionReaderCompressed() { + if (decompressor.takeError()) {} +} + +llvm::Expected +ObjectFileELF::SectionReaderCompressed::Initialize( + const SectionPart §ion_part, DataExtractor &compressed_data) { + Section *section = section_part.GetSection(); + ObjectFile *obj_file = section->GetObjectFile(); if (section_part.GetOffsetInSection() != 0 || section_part.GetLength() != section->GetFileSize()) { - GetModule()->ReportWarning( + obj_file->GetModule()->ReportWarning( "Unable to read only part %" PRIu64 "+%" PRIu64 " of compressed section '%s'", section_part.GetOffsetInSection(), section_part.GetLength(), section->GetName().GetCString()); - section_data.Clear(); - return 0; + return llvm::object::createError( + "Unable to read only part of compressed section"); } - - auto Decompressor = llvm::object::Decompressor::create( + { + auto reader_up = obj_file->ObjectFile::SectionReaderFactory(section_part); + if (!reader_up + || reader_up->read(compressed_data) != section->GetFileSize()) + return llvm::object::createError("ReadSectionData failed"); + } + auto decompressor = llvm::object::Decompressor::create( section->GetName().GetStringRef(), - {reinterpret_cast(section_data.GetDataStart()), - size_t(section_data.GetByteSize())}, - GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8); - if (!Decompressor) { - GetModule()->ReportWarning( + {reinterpret_cast(compressed_data.GetDataStart()), + size_t(compressed_data.GetByteSize())}, + obj_file->GetByteOrder() == eByteOrderLittle, + obj_file->GetAddressByteSize() == 8); + if (!decompressor) + obj_file->GetModule()->ReportWarning( "Unable to initialize decompressor for section '%s': %s", section->GetName().GetCString(), - llvm::toString(Decompressor.takeError()).c_str()); - section_data.Clear(); + llvm::toString(decompressor.takeError()).c_str()); + return decompressor; +} + +uint64_t ObjectFileELF::SectionReaderCompressed::getDecompressedSize() { + if (!decompressor) return 0; + return decompressor->getDecompressedSize(); +} + +size_t ObjectFileELF::SectionReaderCompressed::read( + DataExtractor §ion_data) { + auto buffer_sp = std::make_shared(getDecompressedSize(), 0); + size_t retval = read(buffer_sp->GetBytes()); + if (retval == 0) + section_data.Clear(); + else { + Section *section = section_part.GetSection(); + ObjectFile *obj_file = section->GetObjectFile(); + + section_data.SetData(buffer_sp); + section_data.SetByteOrder(obj_file->GetByteOrder()); + section_data.SetAddressByteSize(obj_file->GetAddressByteSize()); } + return retval; +} - auto buffer_sp = - std::make_shared(Decompressor->getDecompressedSize(), 0); - if (auto error = Decompressor->decompress( - {reinterpret_cast(buffer_sp->GetBytes()), - size_t(buffer_sp->GetByteSize())})) { - GetModule()->ReportWarning( +size_t ObjectFileELF::SectionReaderCompressed::read(uint8_t *dst) { + if (!decompressor) + return 0; + if (auto error = decompressor->decompress( + {reinterpret_cast(dst), size_t(getDecompressedSize())})) { + Section *section = section_part.GetSection(); + ObjectFile *obj_file = section->GetObjectFile(); + obj_file->GetModule()->ReportWarning( "Decompression of section '%s' failed: %s", section->GetName().GetCString(), llvm::toString(std::move(error)).c_str()); - section_data.Clear(); return 0; } + return getDecompressedSize(); +} - section_data.SetData(buffer_sp); - return buffer_sp->GetByteSize(); +std::unique_ptr +ObjectFileELF::SectionReaderFactory(const SectionPart §ion_part) { + if (!section_part) + return ObjectFile::SectionReaderFactory(section_part); + Section *section = section_part.GetSection(); + if (section->GetFileSize() == 0 || !section->Test(SHF_COMPRESSED)) + return ObjectFile::SectionReaderFactory(section_part); + return llvm::make_unique(section_part); } llvm::ArrayRef ObjectFileELF::ProgramHeaders() { Index: lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h =================================================================== --- lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -82,9 +82,10 @@ lldb::offset_t section_offset, void *dst, size_t dst_len) override; - size_t - ReadSectionData(const lldb_private::SectionPart §ion_part, - lldb_private::DataExtractor §ion_data) override; + std::unique_ptr SectionReaderFactory( + const lldb_private::SectionPart §ion_part) override; + + class SectionReaderJIT; lldb_private::Address GetEntryPointAddress() override; Index: lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp =================================================================== --- lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -242,21 +242,44 @@ return 0; } -size_t ObjectFileJIT::ReadSectionData( - const lldb_private::SectionPart §ion_part, - lldb_private::DataExtractor §ion_data) { - if (section_part.GetLength()) { - const void *src = (void *)(uintptr_t)section_part.GetOffsetInFile(); - - DataBufferSP data_sp( - new lldb_private::DataBufferHeap(src, section_part.GetLength())); - if (data_sp) { - section_data.SetData(data_sp, 0, data_sp->GetByteSize()); - section_data.SetByteOrder(GetByteOrder()); - section_data.SetAddressByteSize(GetAddressByteSize()); - return section_data.GetByteSize(); - } +class ObjectFileJIT::SectionReaderJIT : public ObjectFile::SectionReader { +public: + SectionReaderJIT(const SectionPart §ion_part_); + size_t read(DataExtractor §ion_data) override; + size_t read(uint8_t *dst) override; +}; + +ObjectFileJIT::SectionReaderJIT::SectionReaderJIT( + const SectionPart §ion_part_) + : ObjectFile::SectionReader(section_part_) { + assert(section_part.GetLength()); +} + +size_t ObjectFileJIT::SectionReaderJIT::read(DataExtractor §ion_data) { + const void *src = (void *)(uintptr_t)section_part.GetOffsetInFile(); + + DataBufferSP data_sp(new DataBufferHeap(src, section_part.GetLength())); + if (data_sp) { + Section *section = section_part.GetSection(); + ObjectFile *obj_file = section->GetObjectFile(); + + section_data.SetData(data_sp, 0, data_sp->GetByteSize()); + section_data.SetByteOrder(obj_file->GetByteOrder()); + section_data.SetAddressByteSize(obj_file->GetAddressByteSize()); + return section_data.GetByteSize(); } section_data.Clear(); return 0; } + +size_t ObjectFileJIT::SectionReaderJIT::read(uint8_t *dst) { + Section *section = section_part.GetSection(); + ObjectFile *obj_file = section->GetObjectFile(); + return obj_file->ReadSectionData(section, section_part.GetOffsetInSection(), + dst, section_part.GetLength()); +} + +std::unique_ptr +ObjectFileJIT::SectionReaderFactory(const SectionPart §ion_part) { + return llvm::make_unique(section_part); +} Index: lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp =================================================================== --- lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1212,6 +1212,7 @@ case eSectionTypeDWARFDebugStrOffsets: case eSectionTypeDWARFDebugStrOffsetsDwo: case eSectionTypeDWARFDebugTypes: + case eSectionTypeDWARFDebugTypesDwo: case eSectionTypeDWARFAppleNames: case eSectionTypeDWARFAppleTypes: case eSectionTypeDWARFAppleNamespaces: Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -18,16 +18,6 @@ lldb::offset_t *offset_ptr); void Dump(lldb_private::Stream *s) const override; - //------------------------------------------------------------------ - /// Get the data that contains the DIE information for this unit. - /// - /// @return - /// The correct data (.debug_types for DWARF 4 and earlier, and - /// .debug_info for DWARF 5 and later) for the DIE information in - /// this unit. - //------------------------------------------------------------------ - const lldb_private::DWARFDataExtractor &GetData() const override; - //------------------------------------------------------------------ /// Get the size in bytes of the header. /// Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -89,7 +89,3 @@ } llvm_unreachable("invalid UnitType."); } - -const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const { - return m_dwarf->get_debug_info_data(); -} Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -98,7 +98,8 @@ lldb::offset_t offset = 0; DWARFUnitSP cu_sp; const auto &debug_info_data = m_dwarf2Data->get_debug_info_data(); - while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data, + while (offset < m_dwarf2Data->get_debug_info_size() + && (cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data, &offset))) { m_compile_units.push_back(cu_sp); Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -69,7 +69,7 @@ /// @return /// The correct data for the DIE information in this unit. //------------------------------------------------------------------ - virtual const lldb_private::DWARFDataExtractor &GetData() const = 0; + const lldb_private::DWARFDataExtractor &GetData() const; //------------------------------------------------------------------ /// Get the size in bytes of the compile unit header. /// Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -873,3 +873,6 @@ return *m_func_aranges_up; } +const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const { + return m_dwarf->get_debug_info_data(); +} Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -234,7 +234,8 @@ virtual const lldb_private::DWARFDataExtractor &get_debug_addr_data(); const lldb_private::DWARFDataExtractor &get_debug_aranges_data(); const lldb_private::DWARFDataExtractor &get_debug_frame_data(); - virtual const lldb_private::DWARFDataExtractor &get_debug_info_data(); + const lldb_private::DWARFDataExtractor &get_debug_info_data(); + virtual lldb_private::SectionPart get_debug_info_section_part(); const lldb_private::DWARFDataExtractor &get_debug_line_data(); const lldb_private::DWARFDataExtractor &get_debug_line_str_data(); const lldb_private::DWARFDataExtractor &get_debug_macro_data(); @@ -244,7 +245,7 @@ const lldb_private::DWARFDataExtractor &get_debug_rnglists_data(); virtual const lldb_private::DWARFDataExtractor &get_debug_str_data(); virtual const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data(); - const lldb_private::DWARFDataExtractor &get_debug_types_data(); + virtual lldb_private::SectionPart get_debug_types_section_part(); const lldb_private::DWARFDataExtractor &get_apple_names_data(); const lldb_private::DWARFDataExtractor &get_apple_types_data(); const lldb_private::DWARFDataExtractor &get_apple_namespaces_data(); @@ -324,6 +325,13 @@ void DumpClangAST(lldb_private::Stream &s) override; + uint64_t get_debug_info_size() const { + return m_debug_info_concatenated_info_size; + } + uint64_t get_debug_types_offset() const { + return m_debug_info_concatenated_types_offset; + } + protected: typedef llvm::DenseMap DIEToTypePtr; @@ -474,7 +482,6 @@ DWARFDataSegment m_data_debug_addr; DWARFDataSegment m_data_debug_aranges; DWARFDataSegment m_data_debug_frame; - DWARFDataSegment m_data_debug_info; DWARFDataSegment m_data_debug_line; DWARFDataSegment m_data_debug_line_str; DWARFDataSegment m_data_debug_macro; @@ -484,13 +491,21 @@ DWARFDataSegment m_data_debug_rnglists; DWARFDataSegment m_data_debug_str; DWARFDataSegment m_data_debug_str_offsets; - DWARFDataSegment m_data_debug_types; DWARFDataSegment m_data_apple_names; DWARFDataSegment m_data_apple_types; DWARFDataSegment m_data_apple_namespaces; DWARFDataSegment m_data_apple_objc; DWARFDataSegment m_data_gnu_debugaltlink; + llvm::once_flag m_concatenated_data_once; + // For get_debug_info_data() containing both '.debug_info' and '.debug_types'. + lldb_private::DWARFDataExtractor m_data_debug_info_concatenated; + // First part of m_data_debug_info_concatenated containing '.debug_info'. + uint64_t m_debug_info_concatenated_info_size; + // Start of second part of m_data_debug_info_concatenated containing + // '.debug_types'. There may be a gap between those two sections. + uint64_t m_debug_info_concatenated_types_offset; + // The unique pointer items below are generated on demand if and when someone // accesses // them through a non const version of this class. Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -8,6 +8,7 @@ #include "SymbolFileDWARF.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Threading.h" @@ -356,7 +357,7 @@ // when this class parses .o files to // contain the .o file index/ID m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(), - m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(), + m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(), m_data_debug_ranges(), m_data_debug_rnglists(), m_data_debug_str(), m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(), @@ -550,7 +551,8 @@ const SectionList *section_list = module_sp->GetSectionList(); if (section_list) { Section *section = section_list->FindSectionByType(sect_type, true).get(); - if (section) + // The size check is just a performance optimization. + if (section && (section->GetByteSize() || section->GetFileSize())) return section; } return SectionPart(); @@ -594,8 +596,8 @@ return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame); } -const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info); +SectionPart SymbolFileDWARF::get_debug_info_section_part() { + return GetSectionPart(eSectionTypeDWARFDebugInfo); } const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() { @@ -645,8 +647,8 @@ m_data_debug_str_offsets); } -const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types); +SectionPart SymbolFileDWARF::get_debug_types_section_part() { + return GetSectionPart(eSectionTypeDWARFDebugTypes); } const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() { @@ -671,6 +673,64 @@ m_data_gnu_debugaltlink); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() { + llvm::call_once(m_concatenated_data_once, [&] { + const SectionPart debug_info_part = get_debug_info_section_part(); + const SectionPart debug_types_part = get_debug_types_section_part(); + if (!debug_info_part && !debug_types_part) + return; + // For this optimization of mmapped sections we do not handle .debug_types + // present without .debug_info as that should not happen. + if (!m_obj_file->IsInMemory() && debug_info_part + && !debug_info_part.GetSection()->Test(llvm::ELF::SHF_COMPRESSED) + && (!debug_types_part + || (!debug_types_part.GetSection()->Test(llvm::ELF::SHF_COMPRESSED) + && debug_info_part.GetOffsetInFile() + + debug_info_part.GetLength() + <= debug_types_part.GetOffsetInFile()))) { + m_debug_info_concatenated_info_size = debug_info_part.GetLength(); + uint64_t length; + if (debug_types_part) { + m_debug_info_concatenated_types_offset = + debug_types_part.GetOffsetInFile() + - debug_info_part.GetOffsetInFile(); + length = debug_types_part.GetOffsetInFile() + + debug_types_part.GetLength() - debug_info_part.GetOffsetInFile(); + } else { + m_debug_info_concatenated_types_offset = debug_info_part.GetLength(); + length = debug_info_part.GetLength(); + } + if (m_dwarf_data.GetByteSize()) + m_data_debug_info_concatenated.SetData(m_dwarf_data, + debug_info_part.GetOffsetInParentSection(), length); + else + m_obj_file->GetData(debug_info_part.GetOffsetInFile(), + length, m_data_debug_info_concatenated); + if (m_data_debug_info_concatenated.GetByteSize() != length) + m_data_debug_info_concatenated.Clear(); + return; + } + auto debug_info_reader = m_obj_file->SectionReaderFactory(debug_info_part); + auto debug_types_reader = m_obj_file->SectionReaderFactory( + debug_types_part); + const auto info_len = debug_info_reader->getDecompressedSize(); + const auto types_len = debug_types_reader->getDecompressedSize(); + DataBufferSP databuffer = DataBufferSP( + new DataBufferHeap(info_len + types_len, 0)); + if (debug_info_reader->read(databuffer->GetBytes()) != info_len + || debug_types_reader->read(databuffer->GetBytes() + info_len) + != types_len) + return; + m_debug_info_concatenated_info_size = info_len; + m_debug_info_concatenated_types_offset = info_len; + m_data_debug_info_concatenated.SetData(databuffer); + m_data_debug_info_concatenated.SetByteOrder(m_obj_file->GetByteOrder()); + m_data_debug_info_concatenated.SetAddressByteSize( + m_obj_file->GetAddressByteSize()); + }); + return m_data_debug_info_concatenated; +} + DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { if (m_abbr == NULL) { const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data(); Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -47,9 +47,10 @@ const lldb_private::DWARFDataExtractor &get_debug_abbrev_data() override; const lldb_private::DWARFDataExtractor &get_debug_addr_data() override; - const lldb_private::DWARFDataExtractor &get_debug_info_data() override; + lldb_private::SectionPart get_debug_info_section_part() override; const lldb_private::DWARFDataExtractor &get_debug_str_data() override; const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data() override; + lldb_private::SectionPart get_debug_types_section_part() override; protected: lldb_private::SectionPart GetSectionPart( Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -124,8 +124,8 @@ return m_data_debug_addr.m_data; } -const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_info_data() { - return GetCachedSectionData(eSectionTypeDWARFDebugInfoDwo, m_data_debug_info); +SectionPart SymbolFileDWARFDwo::get_debug_info_section_part() { + return GetSectionPart(eSectionTypeDWARFDebugInfoDwo); } const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_data() { @@ -137,6 +137,10 @@ m_data_debug_str_offsets); } +SectionPart SymbolFileDWARFDwo::get_debug_types_section_part() { + return GetSectionPart(eSectionTypeDWARFDebugTypesDwo); +} + SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() { return m_base_dwarf_cu->GetSymbolFileDWARF(); } Index: lldb/source/Symbol/ObjectFile.cpp =================================================================== --- lldb/source/Symbol/ObjectFile.cpp +++ lldb/source/Symbol/ObjectFile.cpp @@ -365,6 +365,7 @@ case eSectionTypeDWARFDebugStrOffsets: case eSectionTypeDWARFDebugStrOffsetsDwo: case eSectionTypeDWARFDebugTypes: + case eSectionTypeDWARFDebugTypesDwo: case eSectionTypeDWARFAppleNames: case eSectionTypeDWARFAppleTypes: case eSectionTypeDWARFAppleNamespaces: @@ -533,19 +534,54 @@ return 0; } -//---------------------------------------------------------------------- -// Get the section data the file on disk -//---------------------------------------------------------------------- -size_t ObjectFile::ReadSectionData( - const SectionPart §ion_part, DataExtractor §ion_data) { +size_t ObjectFile::ReadSectionData(const SectionPart §ion_part, + DataExtractor §ion_data) { Section *section = section_part.GetSection(); // If some other objectfile owns this data, pass this to them. if (section->GetObjectFile() != this) return section->GetObjectFile()->ReadSectionData( section_part, section_data); - if (IsInMemory()) { - ProcessSP process_sp(m_process_wp.lock()); + auto reader_up = SectionReaderFactory(section_part); + if (!reader_up) + return 0; + return reader_up->read(section_data); +} + +ObjectFile::SectionReader::SectionReader(const SectionPart §ion_part_) + : section_part(section_part_) {} + +std::unique_ptr +ObjectFile::SectionReaderFactory(const SectionPart §ion_part) { + // llvm::make_unique() is not a friend like we are. + return std::unique_ptr(new SectionReader(section_part)); +} + +ObjectFile::SectionReader::~SectionReader() {} + +uint64_t ObjectFile::SectionReader::getDecompressedSize() { + return !section_part ? 0 : section_part.GetSection()->GetFileSize(); +} + +size_t ObjectFile::SectionReader::read(uint8_t *dst) { + if (!section_part) + return 0; + Section *section = section_part.GetSection(); + return section->GetObjectFile()->ObjectFile::ReadSectionData(section, + section_part.GetOffsetInSection(), dst, section_part.GetLength()); +} + +//---------------------------------------------------------------------- +// Get the section data the file on disk +//---------------------------------------------------------------------- +size_t ObjectFile::SectionReader::read(DataExtractor §ion_data) { + if (!section_part) + return 0; + Section *section = section_part.GetSection(); + ObjectFile *obj_file = section->GetObjectFile(); + + if (obj_file->IsInMemory()) { + ProcessSP process_sp(obj_file->GetProcessWP().lock()); if (process_sp) { const addr_t base_load_addr = section->GetLoadBaseAddress(&process_sp->GetTarget()); @@ -566,10 +602,10 @@ // The object file now contains a full mmap'ed copy of the object file // data, so just use this if (!section->IsRelocated()) - RelocateSection(section); + obj_file->RelocateSection(section); } - return GetData(section_part.GetOffsetInFile(), section_part.GetLength(), - section_data); + return obj_file->GetData(section_part.GetOffsetInFile(), + section_part.GetLength(), section_data); } bool ObjectFile::SplitArchivePathWithObject(const char *path_with_object,