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; } 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 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(section_data.GetDataStart()), 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/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/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/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/SymbolFileDWARFDwp.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h @@ -26,13 +26,18 @@ std::unique_ptr 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 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 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/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; +}