diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -27,18 +27,33 @@ class DIERef { public: enum Section : uint8_t { DebugInfo, DebugTypes }; + enum IndexType : uint8_t { DWONum, OSONum }; - DIERef(llvm::Optional dwo_num, Section section, + DIERef(llvm::Optional dwo_oso_num, Section section, dw_offset_t die_offset) - : m_die_offset(die_offset), m_dwo_num(dwo_num.value_or(0)), - m_dwo_num_valid(dwo_num ? true : false), m_section(section) { - assert(this->dwo_num() == dwo_num && "Dwo number out of range?"); + : m_die_offset(die_offset), m_dwo_oso_num(dwo_oso_num.value_or(0)), + m_dwo_num_valid(dwo_oso_num ? true : false), m_oso_num_valid(0), + m_section(section) { + assert(this->dwo_num() == dwo_oso_num && "Dwo number out of range?"); + } + + DIERef(IndexType Type, llvm::Optional dwo_oso_num, Section section, + dw_offset_t die_offset) + : m_die_offset(die_offset), + m_dwo_oso_num(Type == IndexType::DWONum ? dwo_oso_num.value_or(0) : 0), + m_dwo_num_valid(Type == IndexType::DWONum ? bool(dwo_oso_num) : false), + m_oso_num_valid(Type == IndexType::OSONum ? bool(dwo_oso_num) : false), + m_section(section) { + assert(((this->dwo_num() == dwo_oso_num && Type == IndexType::DWONum) || + (this->oso_num() == dwo_oso_num && Type == IndexType::OSONum)) && + "DWO/OSO number out of range?"); } explicit DIERef(lldb::user_id_t uid) { m_die_offset = uid & k_die_offset_mask; m_dwo_num_valid = (uid & k_dwo_num_valid_bit) != 0; - m_dwo_num = + m_oso_num_valid = (uid & k_oso_num_valid_bit) != 0; + m_dwo_oso_num = m_dwo_num_valid ? (uid >> k_die_offset_bit_size) & k_dwo_num_mask : 0; m_section = (uid & k_section_bit) != 0 ? Section::DebugTypes : Section::DebugInfo; @@ -47,6 +62,7 @@ lldb::user_id_t get_id() const { return lldb::user_id_t(dwo_num().value_or(0)) << k_die_offset_bit_size | die_offset() | (m_dwo_num_valid ? k_dwo_num_valid_bit : 0) | + (m_oso_num_valid ? k_oso_num_valid_bit : 0) | (section() == Section::DebugTypes ? k_section_bit : 0); } @@ -57,7 +73,13 @@ llvm::Optional dwo_num() const { if (m_dwo_num_valid) - return m_dwo_num; + return m_dwo_oso_num; + return std::nullopt; + } + + llvm::Optional oso_num() const { + if (m_oso_num_valid) + return m_dwo_oso_num; return std::nullopt; } @@ -68,8 +90,10 @@ bool operator<(DIERef other) const { if (m_dwo_num_valid != other.m_dwo_num_valid) return m_dwo_num_valid < other.m_dwo_num_valid; - if (m_dwo_num_valid && (m_dwo_num != other.m_dwo_num)) - return m_dwo_num < other.m_dwo_num; + if (m_oso_num_valid != other.m_oso_num_valid) + return m_oso_num_valid < other.m_oso_num_valid; + if (m_dwo_num_valid && (m_dwo_oso_num != other.m_dwo_oso_num)) + return m_dwo_oso_num < other.m_dwo_oso_num; if (m_section != other.m_section) return m_section < other.m_section; return m_die_offset < other.m_die_offset; @@ -108,12 +132,14 @@ static constexpr uint64_t k_die_offset_bit_size = DW_DIE_OFFSET_MAX_BITSIZE; static constexpr uint64_t k_dwo_num_bit_size = - 64 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 2; + 64 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 3; static constexpr uint64_t k_dwo_num_valid_bit = (1ull << (k_dwo_num_bit_size + k_die_offset_bit_size)); - static constexpr uint64_t k_section_bit = + static constexpr uint64_t k_oso_num_valid_bit = (1ull << (k_dwo_num_bit_size + k_die_offset_bit_size + 1)); + static constexpr uint64_t k_section_bit = + (1ull << (k_dwo_num_bit_size + k_die_offset_bit_size + 2)); static constexpr uint64_t k_dwo_num_mask = (~0ull) >> (64 - k_dwo_num_bit_size); // 0x1fffff; @@ -124,9 +150,12 @@ // Allow 2TB of .debug_info/.debug_types offset dw_offset_t m_die_offset : k_die_offset_bit_size; // Used for DWO index or for .o file index on mac - dw_offset_t m_dwo_num : k_dwo_num_bit_size; + dw_offset_t m_dwo_oso_num : k_dwo_num_bit_size; // Set to 1 if m_file_index is a DWO number dw_offset_t m_dwo_num_valid : 1; + // Set to 1 if m_file_index is a N_OSO index for mac debugging without a dSYM + // file + dw_offset_t m_oso_num_valid : 1; // Set to 0 for .debug_info 1 for .debug_types, dw_offset_t m_section : 1; }; 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 @@ -1395,8 +1395,11 @@ } user_id_t SymbolFileDWARF::GetUID(DIERef ref) { - if (GetDebugMapSymfile()) - return GetID() | ref.die_offset(); + if (GetDebugMapSymfile()) { + DIERef die_ref(GetID()); + die_ref.set_die_offset(ref.die_offset()); + return die_ref.get_id(); + } return DIERef(GetDwoNum(), ref.section(), ref.die_offset()).get_id(); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -9,6 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H +#include "DIERef.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Utility/RangeMap.h" #include "llvm/Support/Chrono.h" @@ -208,7 +209,9 @@ lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) { - return (uint32_t)((uid >> 32ull) - 1ull); + llvm::Optional OsoNum = DIERef(uid).oso_num(); + lldbassert(OsoNum && "Invalid OSO Index"); + return *OsoNum; } static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "SymbolFileDWARFDebugMap.h" +#include "DIERef.h" #include "DWARFCompileUnit.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" @@ -210,7 +211,9 @@ // Set the ID of the symbol file DWARF to the index of the OSO // shifted left by 32 bits to provide a unique prefix for any // UserID's that get created in the symbol file. - oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull); + oso_symfile->SetID(DIERef(DIERef::IndexType::OSONum, m_cu_idx, + DIERef::Section(0), 0) + .get_id()); } return symfile; } diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s --- a/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/debug_rnglists-dwo.s @@ -4,9 +4,9 @@ # RUN: -o exit | FileCheck %s # CHECK-LABEL: image lookup -v -s lookup_rnglists -# CHECK: Function: id = {0x4000000000000028}, name = "rnglists", range = [0x0000000000000000-0x0000000000000003) -# CHECK: Blocks: id = {0x4000000000000028}, range = [0x00000000-0x00000003) -# CHECK-NEXT: id = {0x4000000000000037}, range = [0x00000001-0x00000002) +# CHECK: Function: id = {0x2000000000000028}, name = "rnglists", range = [0x0000000000000000-0x0000000000000003) +# CHECK: Blocks: id = {0x2000000000000028}, range = [0x00000000-0x00000003) +# CHECK-NEXT: id = {0x2000000000000037}, range = [0x00000001-0x00000002) .text rnglists: