Index: include/lldb/lldb-enumerations.h =================================================================== --- include/lldb/lldb-enumerations.h +++ include/lldb/lldb-enumerations.h @@ -626,6 +626,7 @@ eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, eSectionTypeDWARFDebugAranges, + eSectionTypeDWARFDebugCuIndex, eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, eSectionTypeDWARFDebugLine, Index: source/Core/Section.cpp =================================================================== --- source/Core/Section.cpp +++ source/Core/Section.cpp @@ -65,6 +65,8 @@ return "dwarf-addr"; case eSectionTypeDWARFDebugAranges: return "dwarf-aranges"; + case eSectionTypeDWARFDebugCuIndex: + return "dwarf-cu-index"; case eSectionTypeDWARFDebugFrame: return "dwarf-frame"; case eSectionTypeDWARFDebugInfo: Index: source/Expression/IRExecutionUnit.cpp =================================================================== --- source/Expression/IRExecutionUnit.cpp +++ source/Expression/IRExecutionUnit.cpp @@ -1115,6 +1115,7 @@ case lldb::eSectionTypeDWARFDebugAbbrev: case lldb::eSectionTypeDWARFDebugAddr: case lldb::eSectionTypeDWARFDebugAranges: + case lldb::eSectionTypeDWARFDebugCuIndex: case lldb::eSectionTypeDWARFDebugFrame: case lldb::eSectionTypeDWARFDebugInfo: case lldb::eSectionTypeDWARFDebugLine: Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp =================================================================== --- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1835,6 +1835,7 @@ static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev"); static ConstString g_sect_name_dwarf_debug_addr(".debug_addr"); static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges"); + static ConstString g_sect_name_dwarf_debug_cu_index(".debug_cu_index"); static ConstString g_sect_name_dwarf_debug_frame(".debug_frame"); static ConstString g_sect_name_dwarf_debug_info(".debug_info"); static ConstString g_sect_name_dwarf_debug_line(".debug_line"); @@ -1904,6 +1905,8 @@ sect_type = eSectionTypeDWARFDebugAddr; else if (name == g_sect_name_dwarf_debug_aranges) sect_type = eSectionTypeDWARFDebugAranges; + else if (name == g_sect_name_dwarf_debug_cu_index) + sect_type = eSectionTypeDWARFDebugCuIndex; else if (name == g_sect_name_dwarf_debug_frame) sect_type = eSectionTypeDWARFDebugFrame; else if (name == g_sect_name_dwarf_debug_info) @@ -2015,13 +2018,14 @@ if (m_sections_ap.get()) { if (GetType() == eTypeDebugInfo) { static const SectionType g_sections[] = { - eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, - eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugFrame, - eSectionTypeDWARFDebugInfo, eSectionTypeDWARFDebugLine, - eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugMacInfo, - eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes, - eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugStr, - eSectionTypeDWARFDebugStrOffsets, eSectionTypeELFSymbolTable, + eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, + eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, + eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, + eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc, + eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames, + eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges, + eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets, + eSectionTypeELFSymbolTable, }; SectionList *elf_section_list = m_sections_ap.get(); for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp =================================================================== --- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -1200,6 +1200,7 @@ case eSectionTypeDWARFDebugAbbrev: case eSectionTypeDWARFDebugAddr: case eSectionTypeDWARFDebugAranges: + case eSectionTypeDWARFDebugCuIndex: case eSectionTypeDWARFDebugFrame: case eSectionTypeDWARFDebugInfo: case eSectionTypeDWARFDebugLine: Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt =================================================================== --- source/Plugins/SymbolFile/DWARF/CMakeLists.txt +++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt @@ -30,6 +30,8 @@ NameToDIE.cpp SymbolFileDWARF.cpp SymbolFileDWARFDwo.cpp + SymbolFileDWARFDwoDwp.cpp + SymbolFileDWARFDwp.cpp SymbolFileDWARFDebugMap.cpp UniqueDWARFASTType.cpp @@ -47,5 +49,6 @@ lldbPluginCPlusPlusLanguage lldbPluginExpressionParserClang LINK_COMPONENTS + DebugInfoDWARF Support ) Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -61,6 +61,7 @@ class DWARFFormValue; class SymbolFileDWARFDebugMap; class SymbolFileDWARFDwo; +class SymbolFileDWARFDwp; #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) @@ -464,8 +465,14 @@ return m_forward_decl_clang_type_to_die; } + SymbolFileDWARFDwp *GetDwpSymbolFile(); + lldb::ModuleWP m_debug_map_module_wp; SymbolFileDWARFDebugMap *m_debug_map_symfile; + + llvm::once_flag m_dwp_symfile_once_flag; + std::unique_ptr m_dwp_symfile; + lldb_private::DWARFDataExtractor m_dwarf_data; DWARFDataSegment m_data_debug_abbrev; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -71,6 +71,7 @@ #include "LogChannelDWARF.h" #include "SymbolFileDWARFDebugMap.h" #include "SymbolFileDWARFDwo.h" +#include "SymbolFileDWARFDwp.h" #include "llvm/Support/FileSystem.h" @@ -1554,6 +1555,16 @@ if (!dwo_name) return nullptr; + SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile(); + if (dwp_symfile) { + uint64_t dwo_id = cu_die.GetAttributeValueAsUnsigned(this, &dwarf_cu, + DW_AT_GNU_dwo_id, 0); + std::unique_ptr dwo_symfile = + dwp_symfile->GetSymbolFileForDwoId(&dwarf_cu, dwo_id); + if (dwo_symfile) + return dwo_symfile; + } + FileSpec dwo_file(dwo_name, true); if (dwo_file.IsRelative()) { const char *comp_dir = cu_die.GetAttributeValueAsString( @@ -4303,3 +4314,14 @@ SymbolFileDWARF::GetLocationListFormat() const { return DWARFExpression::RegularLocationList; } + +SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() { + llvm::call_once(m_dwp_symfile_once_flag, [this]() { + FileSpec dwp_filespec(m_obj_file->GetFileSpec().GetPath() + ".dwp", false); + if (dwp_filespec.Exists()) { + m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(), + dwp_filespec); + } + }); + return m_dwp_symfile.get(); +} Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h @@ -0,0 +1,34 @@ +//===-- SymbolFileDWARFDwoDwp.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ +#define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "SymbolFileDWARFDwo.h" +#include "SymbolFileDWARFDwp.h" + +class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo { +public: + 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_ Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp @@ -0,0 +1,36 @@ +//===-- SymbolFileDWARFDwoDwp.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#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; + +SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile, + ObjectFileSP objfile, + DWARFCompileUnit *dwarf_cu, + uint64_t dwo_id) + : 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; + + SymbolFileDWARF::LoadSectionData(sect_type, data); +} Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h @@ -0,0 +1,53 @@ +//===-- SymbolFileDWARFDwp.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ +#define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ + +// C Includes +// C++ Includes +#include + +// Other libraries and framework includes +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" + +// Project includes +#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); + + 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_ Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp =================================================================== --- /dev/null +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp @@ -0,0 +1,138 @@ +//===-- SymbolFileDWARFDwp.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SymbolFileDWARFDwp.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#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, file_spec.GetByteSize(), 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; + return dwp_symfile; +} + +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) { + for (const auto &entry : m_debug_cu_index.getRows()) { + m_debug_cu_index_map.emplace(entry.getSignature(), &entry); + } +} + +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; +} Index: source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp =================================================================== --- source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -127,13 +127,14 @@ SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList(); static const SectionType g_sections[] = { - eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, - eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugFrame, - eSectionTypeDWARFDebugInfo, eSectionTypeDWARFDebugLine, - eSectionTypeDWARFDebugLoc, eSectionTypeDWARFDebugMacInfo, - eSectionTypeDWARFDebugPubNames, eSectionTypeDWARFDebugPubTypes, - eSectionTypeDWARFDebugRanges, eSectionTypeDWARFDebugStr, - eSectionTypeDWARFDebugStrOffsets, eSectionTypeELFSymbolTable, + eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, + eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, + eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, + eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc, + eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames, + eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges, + eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets, + eSectionTypeELFSymbolTable, }; for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); ++idx) { Index: source/Symbol/ObjectFile.cpp =================================================================== --- source/Symbol/ObjectFile.cpp +++ source/Symbol/ObjectFile.cpp @@ -348,6 +348,7 @@ case eSectionTypeDWARFDebugAbbrev: case eSectionTypeDWARFDebugAddr: case eSectionTypeDWARFDebugAranges: + case eSectionTypeDWARFDebugCuIndex: case eSectionTypeDWARFDebugFrame: case eSectionTypeDWARFDebugInfo: case eSectionTypeDWARFDebugLine: