diff --git a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt --- a/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ b/lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -37,8 +37,6 @@ NameToDIE.cpp SymbolFileDWARF.cpp SymbolFileDWARFDwo.cpp - SymbolFileDWARFDwoDwp.cpp - SymbolFileDWARFDwp.cpp SymbolFileDWARFDebugMap.cpp UniqueDWARFASTType.cpp diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.h @@ -31,6 +31,7 @@ SectionData m_data_debug_abbrev; SectionData m_data_debug_addr; SectionData m_data_debug_aranges; + SectionData m_data_debug_cu_index; SectionData m_data_debug_info; SectionData m_data_debug_line; SectionData m_data_debug_line_str; @@ -44,10 +45,12 @@ SectionData m_data_debug_types; const DWARFDataExtractor & - LoadOrGetSection(lldb::SectionType main_section_type, + LoadOrGetSection(llvm::Optional main_section_type, llvm::Optional dwo_section_type, SectionData &data); + const DWARFDataExtractor &getOrLoadCuIndexData(); + public: explicit DWARFContext(SectionList *main_section_list, SectionList *dwo_section_list) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp @@ -28,18 +28,23 @@ } const DWARFDataExtractor & -DWARFContext::LoadOrGetSection(SectionType main_section_type, +DWARFContext::LoadOrGetSection(llvm::Optional main_section_type, llvm::Optional dwo_section_type, SectionData &data) { llvm::call_once(data.flag, [&] { if (dwo_section_type && isDwo()) data.data = LoadSection(m_dwo_section_list, *dwo_section_type); - else - data.data = LoadSection(m_main_section_list, main_section_type); + else if (main_section_type) + data.data = LoadSection(m_main_section_list, *main_section_type); }); return data.data; } +const DWARFDataExtractor &DWARFContext::getOrLoadCuIndexData() { + return LoadOrGetSection(llvm::None, eSectionTypeDWARFDebugCuIndex, + m_data_debug_cu_index); +} + const DWARFDataExtractor &DWARFContext::getOrLoadAbbrevData() { return LoadOrGetSection(eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAbbrevDwo, m_data_debug_abbrev); @@ -128,6 +133,7 @@ }; AddSection("debug_line_str", getOrLoadLineStrData()); + AddSection("debug_cu_index", getOrLoadCuIndexData()); m_llvm_context = llvm::DWARFContext::create(section_map, addr_size); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -61,7 +61,10 @@ SymbolFileDWARF &m_dwarf; lldb_private::DWARFContext &m_context; + + llvm::once_flag m_units_once_flag; UnitColl m_units; + std::unique_ptr m_cu_aranges_up; // A quick address to compile unit table diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -72,10 +72,16 @@ DWARFDataExtractor data = section == DIERef::Section::DebugTypes ? m_context.getOrLoadDebugTypesData() : m_context.getOrLoadDebugInfoData(); + const llvm::DWARFUnitIndex *index = nullptr; + if (m_context.isDwo()) + index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(), + section == DIERef::Section::DebugTypes + ? llvm::DW_SECT_TYPES + : llvm::DW_SECT_INFO); lldb::offset_t offset = 0; while (data.ValidOffset(offset)) { - llvm::Expected unit_sp = - DWARFUnit::extract(m_dwarf, m_units.size(), data, section, &offset); + llvm::Expected unit_sp = DWARFUnit::extract( + m_dwarf, m_units.size(), data, section, &offset, index); if (!unit_sp) { // FIXME: Propagate this error up. @@ -96,12 +102,11 @@ } void DWARFDebugInfo::ParseUnitHeadersIfNeeded() { - if (!m_units.empty()) - return; - - ParseUnitsFor(DIERef::Section::DebugInfo); - ParseUnitsFor(DIERef::Section::DebugTypes); - llvm::sort(m_type_hash_to_unit_index, llvm::less_first()); + llvm::call_once(m_units_once_flag, [&] { + ParseUnitsFor(DIERef::Section::DebugInfo); + ParseUnitsFor(DIERef::Section::DebugTypes); + llvm::sort(m_type_hash_to_unit_index, llvm::less_first()); + }); } size_t DWARFDebugInfo::GetNumUnits() { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -39,6 +39,9 @@ dw_offset_t m_length = 0; uint16_t m_version = 0; dw_offset_t m_abbr_offset = 0; + + const llvm::DWARFUnitIndex::Entry *m_index_entry = nullptr; + uint8_t m_unit_type = 0; uint8_t m_addr_size = 0; @@ -65,7 +68,7 @@ static llvm::Expected extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section, - lldb::offset_t *offset_ptr); + lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index); }; class DWARFUnit : public lldb_private::UserID { @@ -76,7 +79,8 @@ static llvm::Expected extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid, const lldb_private::DWARFDataExtractor &debug_info, - DIERef::Section section, lldb::offset_t *offset_ptr); + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index); virtual ~DWARFUnit(); bool IsDWOUnit() { return m_is_dwo; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -773,10 +773,13 @@ } llvm::Expected -DWARFUnitHeader::extract(const DWARFDataExtractor &data, DIERef::Section section, - lldb::offset_t *offset_ptr) { +DWARFUnitHeader::extract(const DWARFDataExtractor &data, + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index) { DWARFUnitHeader header; header.m_offset = *offset_ptr; + if (index) + header.m_index_entry = index->getFromOffset(*offset_ptr); header.m_length = data.GetDWARFInitialLength(offset_ptr); header.m_version = data.GetU16(offset_ptr); if (header.m_version == 5) { @@ -792,6 +795,25 @@ section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile; } + if (header.m_index_entry) { + if (header.m_abbr_offset) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Package unit with a non-zero abbreviation offset"); + } + auto *unit_contrib = header.m_index_entry->getOffset(); + if (!unit_contrib || unit_contrib->Length != header.m_length + 4) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Inconsistent DWARF package unit index"); + } + auto *abbr_entry = header.m_index_entry->getOffset(llvm::DW_SECT_ABBREV); + if (!abbr_entry) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "DWARF package index missing abbreviation column"); + } + header.m_abbr_offset = abbr_entry->Offset; + } if (header.IsTypeUnit()) { header.m_type_hash = data.GetU64(offset_ptr); header.m_type_offset = data.GetDWARFOffset(offset_ptr); @@ -822,11 +844,12 @@ llvm::Expected DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid, const DWARFDataExtractor &debug_info, - DIERef::Section section, lldb::offset_t *offset_ptr) { + DIERef::Section section, lldb::offset_t *offset_ptr, + const llvm::DWARFUnitIndex *index) { assert(debug_info.ValidOffset(*offset_ptr)); auto expected_header = - DWARFUnitHeader::extract(debug_info, section, offset_ptr); + DWARFUnitHeader::extract(debug_info, section, offset_ptr, index); if (!expected_header) return expected_header.takeError(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -473,7 +473,7 @@ }; llvm::Optional DecodeUID(lldb::user_id_t uid); - SymbolFileDWARFDwp *GetDwpSymbolFile(); + void FindDwpSymbolFile(); const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu); @@ -481,12 +481,14 @@ SymbolFileDWARFDebugMap *m_debug_map_symfile; llvm::once_flag m_dwp_symfile_once_flag; - std::unique_ptr m_dwp_symfile; + std::shared_ptr m_dwp_symfile; lldb_private::DWARFContext m_context; - std::unique_ptr m_abbr; + llvm::once_flag m_info_once_flag; std::unique_ptr m_info; + + std::unique_ptr m_abbr; std::unique_ptr m_global_aranges_up; typedef std::unordered_map diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -70,7 +70,6 @@ #include "ManualDWARFIndex.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" -#include "SymbolFileDWARFDwp.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/Support/FileSystem.h" @@ -601,13 +600,13 @@ } DWARFDebugInfo *SymbolFileDWARF::DebugInfo() { - if (m_info == nullptr) { + llvm::call_once(m_info_once_flag, [&] { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast(this)); if (m_context.getOrLoadDebugInfoData().GetByteSize() > 0) m_info = std::make_unique(*this, m_context); - } + }); return m_info.get(); } @@ -1509,10 +1508,12 @@ DWARFDIE SymbolFileDWARF::GetDIE(const DIERef &die_ref) { if (die_ref.dwo_num()) { - return DebugInfo() - ->GetUnitAtIndex(*die_ref.dwo_num()) - ->GetDwoSymbolFile() - ->GetDIE(die_ref); + SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x3fffffff + ? m_dwp_symfile.get() + : this->DebugInfo() + ->GetUnitAtIndex(*die_ref.dwo_num()) + ->GetDwoSymbolFile(); + return dwarf->DebugInfo()->GetDIE(die_ref); } DWARFDebugInfo *debug_info = DebugInfo(); @@ -1576,14 +1577,9 @@ if (!dwo_name) return nullptr; - SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile(); - if (dwp_symfile) { - uint64_t dwo_id = ::GetDWOId(*dwarf_cu, cu_die); - std::unique_ptr dwo_symfile = - dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id); - if (dwo_symfile) - return dwo_symfile; - } + FindDwpSymbolFile(); + if (m_dwp_symfile) + return m_dwp_symfile; FileSpec dwo_file(dwo_name); FileSystem::Instance().Resolve(dwo_file); @@ -3935,7 +3931,7 @@ return m_debug_map_symfile; } -SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() { +void SymbolFileDWARF::FindDwpSymbolFile() { llvm::call_once(m_dwp_symfile_once_flag, [this]() { ModuleSpec module_spec; module_spec.GetFileSpec() = m_objfile_sp->GetFileSpec(); @@ -3946,11 +3942,18 @@ FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec, search_paths); if (FileSystem::Instance().Exists(dwp_filespec)) { - m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(), - dwp_filespec); + DataBufferSP dwp_file_data_sp; + lldb::offset_t dwp_file_data_offset = 0; + ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin( + GetObjectFile()->GetModule(), &dwp_filespec, 0, + FileSystem::Instance().GetByteSize(dwp_filespec), dwp_file_data_sp, + dwp_file_data_offset); + if (!dwp_obj_file) + return; + m_dwp_symfile = + std::make_shared(*this, dwp_obj_file, 0x3fffffff); } }); - return m_dwp_symfile.get(); } llvm::Expected SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -43,9 +43,6 @@ llvm::Optional GetDwoNum() override { return GetID() >> 32; } protected: - void LoadSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) override; - DIEToTypePtr &GetDIEToType() override; DIEToVariableSP &GetDIEToVariable() override; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -29,27 +29,27 @@ /*update_module_section_list*/ false)), m_base_symbol_file(base_symbol_file) { SetID(user_id_t(id) << 32); -} -void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type, - DWARFDataExtractor &data) { - const SectionList *section_list = - m_objfile_sp->GetSectionList(false /* update_module_section_list */); - if (section_list) { - SectionSP section_sp(section_list->FindSectionByType(sect_type, true)); - if (section_sp) { + // Parsing of the dwarf unit index is not thread-safe, so we need to prime it + // to enable subsequent concurrent lookups. + m_context.GetAsLLVM().getCUIndex(); +} - if (m_objfile_sp->ReadSectionData(section_sp.get(), data) != 0) - return; +DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) { + DWARFDebugInfo *debug_info = DebugInfo(); + if (!debug_info) + return nullptr; - data.Clear(); + if (const llvm::DWARFUnitIndex &index = m_context.GetAsLLVM().getCUIndex()) { + if (const llvm::DWARFUnitIndex::Entry *entry = index.getFromHash(hash)) { + if (auto *unit_contrib = entry->getOffset()) + return llvm::dyn_cast_or_null( + debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo, + unit_contrib->Offset)); } + return nullptr; } - SymbolFileDWARF::LoadSectionData(sect_type, data); -} - -DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) { DWARFCompileUnit *cu = FindSingleCompileUnit(); if (!cu) return nullptr; @@ -61,8 +61,6 @@ DWARFCompileUnit *SymbolFileDWARFDwo::FindSingleCompileUnit() { DWARFDebugInfo *debug_info = DebugInfo(); - if (!debug_info) - return nullptr; // Right now we only support dwo files with one compile unit. If we don't have // type units, we can just check for the unit count. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h deleted file mode 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h +++ /dev/null @@ -1,39 +0,0 @@ -//===-- SymbolFileDWARFDwoDwp.h ---------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ -#define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ - -#include "SymbolFileDWARFDwo.h" -#include "SymbolFileDWARFDwp.h" - -class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo { - /// LLVM RTTI support. - static char ID; - -public: - /// LLVM RTTI support. - /// \{ - bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFileDWARFDwo::isA(ClassID); - } - static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } - /// \} - SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile, - lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu, - uint64_t dwo_id); - -protected: - void LoadSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data) override; - - SymbolFileDWARFDwp *m_dwp_symfile; - uint64_t m_dwo_id; -}; - -#endif // SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp deleted file mode 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp +++ /dev/null @@ -1,38 +0,0 @@ -//===-- SymbolFileDWARFDwoDwp.cpp -----------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "SymbolFileDWARFDwoDwp.h" - -#include "lldb/Core/Section.h" -#include "lldb/Expression/DWARFExpression.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Utility/LLDBAssert.h" - -#include "DWARFCompileUnit.h" -#include "DWARFDebugInfo.h" - -using namespace lldb; -using namespace lldb_private; - -char SymbolFileDWARFDwoDwp::ID; - -SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile, - ObjectFileSP objfile, - DWARFCompileUnit &dwarf_cu, - uint64_t dwo_id) - : SymbolFileDWARFDwo(dwarf_cu.GetSymbolFileDWARF(), objfile, - dwarf_cu.GetID()), - 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; - - SymbolFileDWARF::LoadSectionData(sect_type, data); -} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h deleted file mode 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h +++ /dev/null @@ -1,50 +0,0 @@ -//===-- SymbolFileDWARFDwp.h ------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ -#define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ - -#include - -#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" - -#include "lldb/Core/Module.h" - -#include "DWARFDataExtractor.h" -#include "SymbolFileDWARFDwo.h" - -class SymbolFileDWARFDwp { -public: - static std::unique_ptr - Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec); - - std::unique_ptr - GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, uint64_t dwo_id); - - bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data); - -private: - explicit SymbolFileDWARFDwp(lldb::ModuleSP module_sp, - lldb::ObjectFileSP obj_file); - - bool LoadRawSectionData(lldb::SectionType sect_type, - lldb_private::DWARFDataExtractor &data); - - void InitDebugCUIndexMap(); - - lldb::ObjectFileSP m_obj_file; - - std::mutex m_sections_mutex; - std::map m_sections; - - llvm::DWARFUnitIndex m_debug_cu_index; - std::map m_debug_cu_index_map; -}; - -#endif // SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp deleted file mode 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//===-- SymbolFileDWARFDwp.cpp --------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "SymbolFileDWARFDwp.h" - -#include "lldb/Core/Section.h" -#include "lldb/Symbol/ObjectFile.h" - -#include "SymbolFileDWARFDwoDwp.h" - -static llvm::DWARFSectionKind -lldbSectTypeToLlvmSectionKind(lldb::SectionType type) { - switch (type) { - case lldb::eSectionTypeDWARFDebugInfo: - return llvm::DW_SECT_INFO; - // case lldb::eSectionTypeDWARFDebugTypes: - // return llvm::DW_SECT_TYPES; - case lldb::eSectionTypeDWARFDebugAbbrev: - return llvm::DW_SECT_ABBREV; - case lldb::eSectionTypeDWARFDebugLine: - return llvm::DW_SECT_LINE; - case lldb::eSectionTypeDWARFDebugLoc: - return llvm::DW_SECT_LOC; - case lldb::eSectionTypeDWARFDebugStrOffsets: - return llvm::DW_SECT_STR_OFFSETS; - // case lldb::eSectionTypeDWARFDebugMacinfo: - // return llvm::DW_SECT_MACINFO; - case lldb::eSectionTypeDWARFDebugMacro: - return llvm::DW_SECT_MACRO; - default: - // Note: 0 is an invalid dwarf section kind. - return llvm::DWARFSectionKind(0); - } -} - -std::unique_ptr -SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp, - const lldb_private::FileSpec &file_spec) { - const lldb::offset_t file_offset = 0; - lldb::DataBufferSP file_data_sp; - lldb::offset_t file_data_offset = 0; - lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin( - module_sp, &file_spec, file_offset, - lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp, - file_data_offset); - if (obj_file == nullptr) - return nullptr; - - std::unique_ptr dwp_symfile( - new SymbolFileDWARFDwp(module_sp, obj_file)); - - lldb_private::DWARFDataExtractor debug_cu_index; - if (!dwp_symfile->LoadRawSectionData(lldb::eSectionTypeDWARFDebugCuIndex, - debug_cu_index)) - return nullptr; - - llvm::DataExtractor llvm_debug_cu_index( - llvm::StringRef(debug_cu_index.PeekCStr(0), debug_cu_index.GetByteSize()), - debug_cu_index.GetByteOrder() == lldb::eByteOrderLittle, - debug_cu_index.GetAddressByteSize()); - if (!dwp_symfile->m_debug_cu_index.parse(llvm_debug_cu_index)) - return nullptr; - dwp_symfile->InitDebugCUIndexMap(); - return dwp_symfile; -} - -void SymbolFileDWARFDwp::InitDebugCUIndexMap() { - m_debug_cu_index_map.clear(); - for (const auto &entry : m_debug_cu_index.getRows()) - m_debug_cu_index_map.emplace(entry.getSignature(), &entry); -} - -SymbolFileDWARFDwp::SymbolFileDWARFDwp(lldb::ModuleSP module_sp, - lldb::ObjectFileSP obj_file) - : m_obj_file(std::move(obj_file)), m_debug_cu_index(llvm::DW_SECT_INFO) -{} - -std::unique_ptr -SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, - uint64_t dwo_id) { - return std::unique_ptr( - 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; - - auto it = m_debug_cu_index_map.find(dwo_id); - if (it == m_debug_cu_index_map.end()) - return false; - - 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; -} - -bool SymbolFileDWARFDwp::LoadRawSectionData( - lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) { - std::lock_guard lock(m_sections_mutex); - - auto it = m_sections.find(sect_type); - if (it != m_sections.end()) { - if (it->second.GetByteSize() == 0) - return false; - - data = it->second; - 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; - } - } - } - m_sections[sect_type].Clear(); - return false; -} diff --git a/lldb/test/Shell/SymbolFile/DWARF/dwp.s b/lldb/test/Shell/SymbolFile/DWARF/dwp.s new file mode 100644 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/DWARF/dwp.s @@ -0,0 +1,149 @@ +# REQUIRES: x86 + +# RUN: llvm-mc --filetype=obj --triple x86_64-pc-linux %s -o %t --defsym MAIN=0 +# RUN: llvm-mc --filetype=obj --triple x86_64-pc-linux %s -o %t.dwp --defsym DWP=0 +# RUN: %lldb %t -o "target variable A" -b | FileCheck %s +# RUN: lldb-test symbols %t | FileCheck %s --check-prefix=SYMBOLS + +# CHECK: (int) A = 0 +# CHECK: (int) A = 1 +# CHECK: (int) A = 2 +# CHECK: (int) A = 3 + +# SYMBOLS: Compile units: +# SYMBOLS-NEXT: CompileUnit{0x00000000}, language = "unknown", file = '0.c' +# SYMBOLS-NEXT: Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x0 +# SYMBOLS-NEXT: CompileUnit{0x00000001}, language = "unknown", file = '1.c' +# SYMBOLS-NEXT: Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x1 +# SYMBOLS-NEXT: CompileUnit{0x00000002}, language = "unknown", file = '2.c' +# SYMBOLS-NEXT: Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x2 +# SYMBOLS-NEXT: CompileUnit{0x00000003}, language = "unknown", file = '3.c' +# SYMBOLS-NEXT: Variable{{.*}}, name = "A", {{.*}}, location = DW_OP_GNU_addr_index 0x3 +# SYMBOLS-NEXT: CompileUnit{0x00000004}, language = "unknown", file = '' +# SYMBOLS-EMPTY: + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 0 # DW_CHILDREN_no + .ascii "\260B" # DW_AT_GNU_dwo_name + .byte 8 # DW_FORM_string + .ascii "\261B" # DW_AT_GNU_dwo_id + .byte 7 # DW_FORM_data8 + .ascii "\263B" # DW_AT_GNU_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + +.ifdef MAIN +.irpc I,01234 + .data +A\I: + .long \I + + .section .debug_info,"",@progbits +.Lcu_begin\I: + .long .Ldebug_info_end\I-.Ldebug_info_start\I # Length of Unit +.Ldebug_info_start\I: + .short 4 # DWARF version number + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte 1 # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit + .asciz "A.dwo" # DW_AT_GNU_dwo_name + .quad \I # DW_AT_GNU_dwo_id + .long .debug_addr # DW_AT_GNU_addr_base +.Ldebug_info_end\I: + + .section .debug_addr,"",@progbits + .quad A\I +.endr +.endif + +.ifdef DWP +# This deliberately excludes compile unit 4 to check test the case of a missing +# split unit. +.irpc I,0123 + .section .debug_abbrev.dwo,"e",@progbits +.Labbrev\I: + .byte \I*10+1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 8 # DW_FORM_string + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte \I*10+2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 8 # DW_FORM_string + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte \I*10+3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 14 # DW_FORM_string + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) +.Labbrev_end\I: + + .section .debug_info.dwo,"e",@progbits +.Lcu_begin\I: + .long .Ldebug_info_end\I-.Ldebug_info_start\I # Length of Unit +.Ldebug_info_start\I: + .short 4 # DWARF version number + .long 0 # Offset Into Abbrev. Section + .byte 8 # Address Size (in bytes) + .byte \I*10+1 # Abbrev DW_TAG_compile_unit + .asciz "Hand-written DWARF" # DW_AT_producer + .byte '0'+\I, '.', 'c', 0 # DW_AT_name + .byte \I*10+2 # Abbrev DW_TAG_variable + .asciz "A" # DW_AT_name + .long .Ltype\I-.Lcu_begin\I # DW_AT_type + .byte 2 # DW_AT_location + .byte 0xfb # DW_OP_GNU_addr_index + .byte \I +.Ltype\I: + .byte \I*10+3 # Abbrev DW_TAG_base_type + .asciz "int" # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end\I: +.endr + + .section .debug_cu_index,"e",@progbits + .short 2 # DWARF version number + .short 0 # Reserved + .long 2 # Section count + .long 4 # Unit count + .long 8 # Slot count + + .quad 0, 1, 2, 3, 0, 0, 0, 0 # Hash table + .long 1, 2, 3, 4, 0, 0, 0, 0 # Index table + + .long 1, 3 # DW_SECT_INFO, DW_SECT_ABBREV + +.irpc I,0123 + .long .Lcu_begin\I-.debug_info.dwo + .long .Labbrev\I-.debug_abbrev.dwo +.endr +.irpc I,0123 + .long .Ldebug_info_end\I-.Lcu_begin\I + .long .Labbrev_end\I-.Labbrev\I +.endr + +.endif diff --git a/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp b/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp --- a/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp +++ b/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp @@ -111,7 +111,7 @@ llvm::Expected dwarf_unit = DWARFUnit::extract( *m_symfile_dwarf, uid, *static_cast(&debug_info), - DIERef::DebugInfo, &offset_ptr); + DIERef::DebugInfo, &offset_ptr, nullptr); if (dwarf_unit) m_dwarf_unit = dwarf_unit.get(); }