jankratochvil created this revision. jankratochvil added a reviewer: clayborg. jankratochvil added a project: LLDB. Herald added subscribers: jdoerfert, arichardson, emaste. Herald added a reviewer: espindola.
@clayborg requested <https://reviews.llvm.org/D51578#1383458> more effective loading of concatenated sections. For compressed sections it means one has to measure decompressed size of both to be able to effectively allocate memory for both of them. But current `LoadSectionData()` can only load the data without knowing first how big it will be. Therefore D51578 <https://reviews.llvm.org/D51578> introduces `SectionReader` but it needs to also handle subranges of DWP `Section`. Despite DWP `Section` is not supported to be compressed and compressed sections do not need to support subranges to unify the API I had to replace `Section *` by `SectionPart` for all the cases. Repository: rLLDB LLDB https://reviews.llvm.org/D58330 Files: lldb/include/lldb/Symbol/ObjectFile.h lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h lldb/source/Symbol/ObjectFile.cpp
Index: lldb/source/Symbol/ObjectFile.cpp =================================================================== --- lldb/source/Symbol/ObjectFile.cpp +++ lldb/source/Symbol/ObjectFile.cpp @@ -536,11 +536,13 @@ //---------------------------------------------------------------------- // Get the section data the file on disk //---------------------------------------------------------------------- -size_t ObjectFile::ReadSectionData(Section *section, - 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, section_data); + return section->GetObjectFile()->ReadSectionData( + section_part, section_data); if (IsInMemory()) { ProcessSP process_sp(m_process_wp.lock()); @@ -549,7 +551,9 @@ section->GetLoadBaseAddress(&process_sp->GetTarget()); if (base_load_addr != LLDB_INVALID_ADDRESS) { DataBufferSP data_sp( - ReadMemory(process_sp, base_load_addr, section->GetByteSize())); + ReadMemory(process_sp, + base_load_addr + section_part.GetOffsetInSection(), + section_part.GetLength())); if (data_sp) { section_data.SetData(data_sp, 0, data_sp->GetByteSize()); section_data.SetByteOrder(process_sp->GetByteOrder()); @@ -558,17 +562,14 @@ } } } - return GetData(section->GetFileOffset(), section->GetFileSize(), - section_data); } else { // The object file now contains a full mmap'ed copy of the object file // data, so just use this if (!section->IsRelocated()) RelocateSection(section); - - return GetData(section->GetFileOffset(), section->GetFileSize(), - section_data); } + return GetData(section_part.GetOffsetInFile(), section_part.GetLength(), + section_data); } bool ObjectFile::SplitArchivePathWithObject(const char *path_with_object, @@ -743,3 +744,46 @@ break; } } + +SectionPart::SectionPart() : m_section(nullptr), + m_offset(LLDB_INVALID_ADDRESS), m_length(LLDB_INVALID_ADDRESS) {} + +SectionPart::SectionPart(Section *section) + : m_section(section), m_offset(0), m_length(section->GetFileSize()) { + assert(m_section); +} + +SectionPart::SectionPart(Section *section, lldb::addr_t offset, lldb::addr_t length) + : m_section(section), m_offset(offset), m_length(length) { + assert(m_section); + lldbassert(m_offset + m_length <= m_section->GetFileSize()); +} + +Section *SectionPart::GetSection() const { + assert(m_section); + return m_section; +} + +lldb::addr_t SectionPart::GetOffsetInSection() const { + assert(m_section); + return m_offset; +} + +lldb::addr_t SectionPart::GetOffsetInFile() const { + assert(m_section); + return m_section->GetFileOffset() + GetOffsetInSection(); +} + +lldb::addr_t SectionPart::GetOffsetInParentSection() const { + assert(m_section); + return m_section->GetOffset() + GetOffsetInSection(); +} + +lldb::addr_t SectionPart::GetLength() const { + assert(m_section); + return m_length; +} + +SectionPart::operator bool() const { + return m_section != nullptr; +} Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h @@ -26,13 +26,18 @@ std::unique_ptr<SymbolFileDWARFDwo> GetSymbolFileForDwoId(DWARFUnit *dwarf_cu, uint64_t dwo_id); - bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data); + lldb_private::SectionPart GetSectionPart( + uint64_t dwo_id, lldb::SectionType sect_type) const; private: explicit SymbolFileDWARFDwp(lldb::ModuleSP module_sp, lldb::ObjectFileSP obj_file); + lldb_private::Section *GetRawSection(lldb::SectionType sect_type) const; + + lldb_private::Section *GetRawSectionHaveLock( + lldb::SectionType sect_type) const; + bool LoadRawSectionData(lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data); @@ -40,7 +45,7 @@ lldb::ObjectFileSP m_obj_file; - std::mutex m_sections_mutex; + mutable std::mutex m_sections_mutex; std::map<lldb::SectionType, lldb_private::DWARFDataExtractor> m_sections; llvm::DWARFUnitIndex m_debug_cu_index; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp @@ -87,25 +87,37 @@ new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id)); } -bool SymbolFileDWARFDwp::LoadSectionData( - uint64_t dwo_id, lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) { - lldb_private::DWARFDataExtractor section_data; - if (!LoadRawSectionData(sect_type, section_data)) - return false; +lldb_private::SectionPart SymbolFileDWARFDwp::GetSectionPart( + uint64_t dwo_id, lldb::SectionType sect_type) const { + lldb_private::Section *section = GetRawSection(sect_type); + if (!section) + return lldb_private::SectionPart(); auto it = m_debug_cu_index_map.find(dwo_id); if (it == m_debug_cu_index_map.end()) - return false; + return lldb_private::SectionPart(); auto *offsets = it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type)); - if (offsets) { - data.SetData(section_data, offsets->Offset, offsets->Length); - } else { - data.SetData(section_data, 0, section_data.GetByteSize()); - } - return true; + if (offsets) + return lldb_private::SectionPart(section, + offsets->Offset, offsets->Length); + return lldb_private::SectionPart(section); +} + +lldb_private::Section *SymbolFileDWARFDwp::GetRawSection( + lldb::SectionType sect_type) const { + std::lock_guard<std::mutex> lock(m_sections_mutex); + return GetRawSectionHaveLock(sect_type); +} + +lldb_private::Section * +SymbolFileDWARFDwp::GetRawSectionHaveLock(lldb::SectionType sect_type) const { + const lldb_private::SectionList *section_list = + m_obj_file->GetSectionList(false /* update_module_section_list */); + if (!section_list) + return nullptr; + return section_list->FindSectionByType(sect_type, true).get(); } bool SymbolFileDWARFDwp::LoadRawSectionData( @@ -121,17 +133,10 @@ return true; } - const lldb_private::SectionList *section_list = - m_obj_file->GetSectionList(false /* update_module_section_list */); - if (section_list) { - lldb::SectionSP section_sp( - section_list->FindSectionByType(sect_type, true)); - if (section_sp) { - if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) { - m_sections[sect_type] = data; - return true; - } - } + lldb_private::Section *section = GetRawSectionHaveLock(sect_type); + if (section && m_obj_file->ReadSectionData(section, data) != 0) { + m_sections[sect_type] = data; + return true; } m_sections[sect_type].Clear(); return false; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h @@ -19,8 +19,8 @@ uint64_t dwo_id); protected: - void LoadSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) override; + lldb_private::SectionPart GetSectionPart( + lldb::SectionType sect_type) const override; SymbolFileDWARFDwp *m_dwp_symfile; uint64_t m_dwo_id; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp @@ -26,10 +26,11 @@ : SymbolFileDWARFDwo(objfile, dwarf_cu), m_dwp_symfile(dwp_symfile), m_dwo_id(dwo_id) {} -void SymbolFileDWARFDwoDwp::LoadSectionData(lldb::SectionType sect_type, - DWARFDataExtractor &data) { - if (m_dwp_symfile->LoadSectionData(m_dwo_id, sect_type, data)) - return; +SectionPart +SymbolFileDWARFDwoDwp::GetSectionPart(lldb::SectionType sect_type) const { + SectionPart section_part = m_dwp_symfile->GetSectionPart(m_dwo_id, sect_type); + if (section_part) + return section_part; - SymbolFileDWARF::LoadSectionData(sect_type, data); + return SymbolFileDWARF::GetSectionPart(sect_type); } Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -52,8 +52,8 @@ const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data() override; protected: - void LoadSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) override; + lldb_private::SectionPart GetSectionPart( + lldb::SectionType sect_type) const override; DIEToTypePtr &GetDIEToType() override; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -26,28 +26,17 @@ SetID(((lldb::user_id_t)dwarf_cu->GetOffset()) << 32); } -void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type, - DWARFDataExtractor &data) { +SectionPart +SymbolFileDWARFDwo::GetSectionPart(lldb::SectionType sect_type) const { const SectionList *section_list = m_obj_file->GetSectionList(false /* update_module_section_list */); if (section_list) { - SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); - if (section_sp) { - // See if we memory mapped the DWARF segment? - if (m_dwarf_data.GetByteSize()) { - data.SetData(m_dwarf_data, section_sp->GetOffset(), - section_sp->GetFileSize()); - return; - } - - if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) - return; - - data.Clear(); - } + Section *section = section_list->FindSectionByType(sect_type, true).get(); + if (section) + return section; } - SymbolFileDWARF::LoadSectionData(sect_type, data); + return SymbolFileDWARF::GetSectionPart(sect_type); } lldb::CompUnitSP @@ -129,8 +118,8 @@ // For regular split debug case, .dwo file does not contain the // .debug_addr, so we would always fall back to such lookup anyways. llvm::call_once(m_data_debug_addr.m_flag, [this] { - SymbolFileDWARF::LoadSectionData(eSectionTypeDWARFDebugAddr, - std::ref(m_data_debug_addr.m_data)); + LoadSectionData(SymbolFileDWARF::GetSectionPart(eSectionTypeDWARFDebugAddr), + std::ref(m_data_debug_addr.m_data)); }); return m_data_debug_addr.m_data; } Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -55,6 +55,9 @@ class SymbolFileDWARFDebugMap; class SymbolFileDWARFDwo; class SymbolFileDWARFDwp; +namespace lldb_private { + class SectionPart; +} #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) @@ -342,8 +345,13 @@ GetCachedSectionData(lldb::SectionType sect_type, DWARFDataSegment &data_segment); - virtual void LoadSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data); + virtual lldb_private::SectionPart GetSectionPart( + lldb::SectionType sect_type) const; + + void LoadSectionData(lldb::SectionType sect_type, + lldb_private::DWARFDataExtractor &data); + void LoadSectionData(const lldb_private::SectionPart §ion_part, + lldb_private::DWARFDataExtractor &data); bool DeclContextMatchesThisSymbolFile( const lldb_private::CompilerDeclContext *decl_ctx); Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -540,27 +540,39 @@ SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type, DWARFDataSegment &data_segment) { llvm::call_once(data_segment.m_flag, [this, sect_type, &data_segment] { - this->LoadSectionData(sect_type, std::ref(data_segment.m_data)); + LoadSectionData(GetSectionPart(sect_type), data_segment.m_data); }); return data_segment.m_data; } -void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type, - DWARFDataExtractor &data) { +SectionPart SymbolFileDWARF::GetSectionPart(lldb::SectionType sect_type) const { ModuleSP module_sp(m_obj_file->GetModule()); const SectionList *section_list = module_sp->GetSectionList(); if (section_list) { - SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); - if (section_sp) { - // See if we memory mapped the DWARF segment? - if (m_dwarf_data.GetByteSize()) { - data.SetData(m_dwarf_data, section_sp->GetOffset(), - section_sp->GetFileSize()); - } else { - if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0) - data.Clear(); - } - } + Section *section = section_list->FindSectionByType(sect_type, true).get(); + if (section) + return section; + } + return SectionPart(); +} + +void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type, + DWARFDataExtractor &data) { + LoadSectionData(GetSectionPart(sect_type), data); +} + +void SymbolFileDWARF::LoadSectionData(const SectionPart §ion_part, + DWARFDataExtractor &data) { + if (!section_part) + return; + + // See if we memory mapped the DWARF segment? + if (m_dwarf_data.GetByteSize()) { + data.SetData(m_dwarf_data, + section_part.GetOffsetInParentSection(), section_part.GetLength()); + } else { + if (m_obj_file->ReadSectionData(section_part, data) == 0) + data.Clear(); } } Index: lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h =================================================================== --- lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -83,7 +83,7 @@ size_t dst_len) override; size_t - ReadSectionData(lldb_private::Section *section, + ReadSectionData(const lldb_private::SectionPart §ion_part, lldb_private::DataExtractor §ion_data) override; 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 @@ -243,13 +243,13 @@ } size_t ObjectFileJIT::ReadSectionData( - lldb_private::Section *section, + const lldb_private::SectionPart §ion_part, lldb_private::DataExtractor §ion_data) { - if (section->GetFileSize()) { - const void *src = (void *)(uintptr_t)section->GetFileOffset(); + if (section_part.GetLength()) { + const void *src = (void *)(uintptr_t)section_part.GetOffsetInFile(); DataBufferSP data_sp( - new lldb_private::DataBufferHeap(src, section->GetFileSize())); + new lldb_private::DataBufferHeap(src, section_part.GetLength())); if (data_sp) { section_data.SetData(data_sp, 0, data_sp->GetByteSize()); section_data.SetByteOrder(GetByteOrder()); Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h =================================================================== --- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -143,7 +143,7 @@ lldb::offset_t section_offset, void *dst, size_t dst_len) override; - size_t ReadSectionData(lldb_private::Section *section, + size_t ReadSectionData(const lldb_private::SectionPart §ion_part, lldb_private::DataExtractor §ion_data) override; llvm::ArrayRef<elf::ELFProgramHeader> ProgramHeaders(); Index: lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -3391,16 +3391,29 @@ return data.CopyData(section_offset, dst_len, dst); } -size_t ObjectFileELF::ReadSectionData(Section *section, +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, section_data); + return section->GetObjectFile()->ReadSectionData( + section_part, section_data); size_t result = ObjectFile::ReadSectionData(section, section_data); if (result == 0 || !section->Test(SHF_COMPRESSED)) return result; + if (section_part.GetOffsetInSection() != 0 + || section_part.GetLength() != section->GetFileSize()) { + 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; + } + auto Decompressor = llvm::object::Decompressor::create( section->GetName().GetStringRef(), {reinterpret_cast<const char *>(section_data.GetDataStart()), Index: lldb/include/lldb/Symbol/ObjectFile.h =================================================================== --- lldb/include/lldb/Symbol/ObjectFile.h +++ lldb/include/lldb/Symbol/ObjectFile.h @@ -42,6 +42,25 @@ virtual ArchSpec GetArchitecture() = 0; }; +// Specify section optionally with its subrange. +class SectionPart { +public: + SectionPart(); + SectionPart(Section *section); + SectionPart(Section *section, lldb::addr_t offset, lldb::addr_t length); + Section *GetSection() const; + lldb::addr_t GetOffsetInSection() const; + lldb::addr_t GetOffsetInFile() const; + lldb::addr_t GetOffsetInParentSection() const; + lldb::addr_t GetLength() const; + explicit operator bool() const; +private: + Section *const m_section; + // It should match: llvm::DWARFUnitIndex::Entry::SectionContribution + // But we need wider lldb::addr_t for: ObjectFileJIT::ReadSectionData + const lldb::addr_t m_offset, m_length; +}; + //---------------------------------------------------------------------- /// @class ObjectFile ObjectFile.h "lldb/Symbol/ObjectFile.h" /// A plug-in interface definition class for object file parsers. @@ -717,7 +736,7 @@ // 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(Section *section, + virtual size_t ReadSectionData(const SectionPart §ion_part, DataExtractor §ion_data); bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits