Index: lldb/source/Plugins/SymbolFile/DWARF/DIERef.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -18,7 +18,8 @@ struct DIERef { DIERef() = default; - DIERef(dw_offset_t c, dw_offset_t d) : cu_offset(c), die_offset(d) {} + DIERef(dw_offset_t c, dw_offset_t d, bool t) : cu_offset(c), die_offset(d, t) + {} // In order to properly decode a lldb::user_id_t back into a DIERef we // need the DWARF file since it knows if DWARF in .o files is being used @@ -44,8 +45,35 @@ return cu_offset != DW_INVALID_OFFSET || die_offset != DW_INVALID_OFFSET; } - dw_offset_t cu_offset = DW_INVALID_OFFSET; - dw_offset_t die_offset = DW_INVALID_OFFSET; + dw_offset_t cu_offset; + class DIEOffset { + public: + operator dw_offset_t() const { + if (m_val == (DW_INVALID_OFFSET & 0x7fffffff)) + return DW_INVALID_OFFSET; + return m_val; + } + DIEOffset() : m_val(DW_INVALID_OFFSET & 0x7fffffff), + m_is_types_section(false) {} + DIEOffset(dw_offset_t o, bool t) { + (*this) = o; + m_is_types_section = t; + } + DIEOffset &operator =(dw_offset_t val) { + m_val = val; + assert(val == *this); + return *this; + } + private: + dw_offset_t m_val : 31; + public: + bool m_is_types_section : 1; + } die_offset; + bool IsTypesSection() const { return die_offset.m_is_types_section; } + void IsTypesSection_set(bool val) { die_offset.m_is_types_section = val; } + + // It is 64-bit so that &=~UID_IS_TYPES_SECTION works. + static const uint64_t UID_IS_TYPES_SECTION = (1ULL << 31); }; typedef std::vector DIEArray; Index: lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp @@ -14,7 +14,12 @@ #include "SymbolFileDWARFDebugMap.h" DIERef::DIERef(lldb::user_id_t uid, SymbolFileDWARF *dwarf) - : cu_offset(DW_INVALID_OFFSET), die_offset(uid & 0xffffffff) { + : cu_offset(DW_INVALID_OFFSET), + die_offset( + (uid & 0xffffffff) == DW_INVALID_OFFSET + ? DW_INVALID_OFFSET : uid & 0x7fffffff, + (uid & 0xffffffff) == DW_INVALID_OFFSET + ? false : (uid & UID_IS_TYPES_SECTION) != 0) { SymbolFileDWARFDebugMap *debug_map = dwarf->GetDebugMapSymfile(); if (debug_map) { const uint32_t oso_idx = debug_map->GetOSOIndexFromUserID(uid); @@ -37,7 +42,7 @@ } DIERef::DIERef(const DWARFFormValue &form_value) - : cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET) { + : cu_offset(DW_INVALID_OFFSET), die_offset(DW_INVALID_OFFSET, false) { if (form_value.IsValid()) { DWARFFormValue::CUDIERef cudieref = form_value.Reference(); die_offset = cudieref.DIEOffset(); @@ -46,6 +51,7 @@ cu_offset = cudieref.CU()->GetBaseObjOffset(); else cu_offset = cudieref.CU()->GetOffset(); + IsTypesSection_set(cudieref.CU()->IsTypesSection()); } } } @@ -57,8 +63,16 @@ // ID set to the compile unit index. // // SymbolFileDWARFDwo sets the ID to the compile unit offset. - if (dwarf && die_offset != DW_INVALID_OFFSET) - return dwarf->GetID() | die_offset; - else + if (dwarf && die_offset != DW_INVALID_OFFSET) { + lldb::user_id_t uid = dwarf->GetID(); + lldbassert((uid & 0x7fffffff) == 0); + lldbassert((uid & UID_IS_TYPES_SECTION) == 0); + if (IsTypesSection()) + uid |= UID_IS_TYPES_SECTION; + else + lldbassert((uid & UID_IS_TYPES_SECTION) == 0); + uid |= die_offset & 0x7fffffff; + return uid; + } else return LLDB_INVALID_UID; } Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1767,7 +1767,7 @@ "forward declaration, not a complete definition.\nTry " "compiling the source file with -fstandalone-debug or " "disable -gmodules", - die.GetOffset(), type_die_ref.die_offset); + die.GetOffset(), dw_offset_t(type_die_ref.die_offset)); else module_sp->ReportError( "DWARF DW_TAG_array_type DIE at 0x%8.8x has a " @@ -1775,7 +1775,7 @@ "forward declaration, not a complete definition.\nPlease " "file a bug against the compiler and include the " "preprocessed output for %s", - die.GetOffset(), type_die_ref.die_offset, + die.GetOffset(), dw_offset_t(type_die_ref.die_offset), die.GetLLDBCompileUnit() ? die.GetLLDBCompileUnit()->GetPath().c_str() : "the source file"); @@ -1795,7 +1795,7 @@ "start its definition.\nPlease file a " "bug and attach the file at the start " "of this error message", - type_die_ref.die_offset); + dw_offset_t(type_die_ref.die_offset)); } } Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp @@ -24,7 +24,7 @@ dw_offset_t cu_offset = m_cu->GetOffset(); if (m_cu->GetBaseObjOffset() != DW_INVALID_OFFSET) cu_offset = m_cu->GetBaseObjOffset(); - return DIERef(cu_offset, m_die->GetOffset()); + return DIERef(cu_offset, m_die->GetOffset(), m_cu->IsTypesSection()); } dw_tag_t DWARFBaseDIE::Tag() const { Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -34,6 +34,8 @@ /// Byte size of the compile unit header uint32_t GetHeaderByteSize() const override; + bool IsTypesSection() const override { return false; } + private: DWARFCompileUnit(SymbolFileDWARF *dwarf2Data); DISALLOW_COPY_AND_ASSIGN(DWARFCompileUnit); Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -150,7 +150,8 @@ return DWARFDIE(cu, block_die); else return DWARFDIE(dwarf->DebugInfo()->GetUnit( - DIERef(cu->GetOffset(), block_die->GetOffset())), + DIERef(cu->GetOffset(), block_die->GetOffset(), + cu->IsTypesSection())), block_die); } } Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -38,6 +38,7 @@ public: virtual ~DWARFUnit(); + virtual bool IsTypesSection() const = 0; void ExtractUnitDIEIfNeeded(); void ExtractDIEsIfNeeded(); Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -369,10 +369,12 @@ lldb::user_id_t DWARFUnit::GetID() const { dw_offset_t local_id = m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset; + lldbassert((local_id & DIERef::UID_IS_TYPES_SECTION) == 0); + bool is_types_section = IsTypesSection(); if (m_dwarf) - return DIERef(local_id, local_id).GetUID(m_dwarf); + return DIERef(local_id, local_id, is_types_section).GetUID(m_dwarf); else - return local_id; + return local_id | (is_types_section ? DIERef::UID_IS_TYPES_SECTION : 0); } dw_offset_t DWARFUnit::GetNextUnitOffset() const { Index: lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -66,7 +66,7 @@ uint64_t die_bias = cu->GetDwoSymbolFile() ? 0 : *cu_offset; if (llvm::Optional die_offset = entry.getDIEUnitOffset()) - return DIERef(*cu_offset, die_bias + *die_offset); + return DIERef(*cu_offset, die_bias + *die_offset, cu->IsTypesSection()); return DIERef(); } Index: lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h @@ -49,13 +49,16 @@ struct DIEInfo { dw_offset_t cu_offset; - dw_offset_t offset; // The DIE offset + DIERef::DIEOffset offset; // The DIE offset + bool IsTypesSection() const { return offset.m_is_types_section; } + void IsTypesSection_set(bool val) { offset.m_is_types_section = val; } dw_tag_t tag; uint32_t type_flags; // Any flags for this DIEInfo uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name DIEInfo(); - DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h); + DIEInfo(dw_offset_t c, dw_offset_t o, bool it, dw_tag_t t, uint32_t f, + uint32_t h); }; struct Atom { Index: lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -14,7 +14,8 @@ const size_t count = die_info_array.size(); for (size_t i = 0; i < count; ++i) die_offsets.emplace_back(die_info_array[i].cu_offset, - die_info_array[i].offset); + die_info_array[i].offset, + die_info_array[i].IsTypesSection()); } void DWARFMappedHash::ExtractDIEArray(const DIEInfoArray &die_info_array, @@ -34,7 +35,8 @@ } if (tag_matches) die_offsets.emplace_back(die_info_array[i].cu_offset, - die_info_array[i].offset); + die_info_array[i].offset, + die_info_array[i].IsTypesSection()); } } } @@ -59,7 +61,8 @@ } if (tag_matches) die_offsets.emplace_back(die_info_array[i].cu_offset, - die_info_array[i].offset); + die_info_array[i].offset, + die_info_array[i].IsTypesSection()); } } } @@ -78,16 +81,19 @@ // that die_offsets.clear(); die_offsets.emplace_back(die_info_array[i].cu_offset, - die_info_array[i].offset); + die_info_array[i].offset, + die_info_array[i].IsTypesSection()); return; } else { // Put the one true definition as the first entry so it matches first die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset, - die_info_array[i].offset); + die_info_array[i].offset, + die_info_array[i].IsTypesSection()); } } else { die_offsets.emplace_back(die_info_array[i].cu_offset, - die_info_array[i].offset); + die_info_array[i].offset, + die_info_array[i].IsTypesSection()); } } } @@ -100,7 +106,8 @@ for (size_t i = 0; i < count; ++i) { if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) die_offsets.emplace_back(die_info_array[i].cu_offset, - die_info_array[i].offset); + die_info_array[i].offset, + die_info_array[i].IsTypesSection()); } } @@ -125,12 +132,13 @@ } DWARFMappedHash::DIEInfo::DIEInfo() - : cu_offset(DW_INVALID_OFFSET), offset(DW_INVALID_OFFSET), tag(0), - type_flags(0), qualified_name_hash(0) {} + : cu_offset(DW_INVALID_OFFSET), offset(DW_INVALID_OFFSET, false), tag(0), + type_flags(0), qualified_name_hash(0) {} -DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t c, dw_offset_t o, dw_tag_t t, - uint32_t f, uint32_t h) - : cu_offset(c), offset(o), tag(t), type_flags(f), qualified_name_hash(h) {} +DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t c, dw_offset_t o, bool it, + dw_tag_t t, uint32_t f, uint32_t h) + : cu_offset(c), offset(o, it), tag(t), type_flags(f), qualified_name_hash(h) + {} DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset) : die_base_offset(_die_base_offset), atoms(), atom_mask(0), Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -245,6 +245,7 @@ } } + bool is_types_section = unit.IsTypesSection(); switch (tag) { case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: @@ -259,22 +260,25 @@ objc_method.GetFullNameWithoutCategory(true)); ConstString objc_class_name_no_category(objc_method.GetClassName()); set.function_fullnames.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); if (objc_class_name_with_category) set.objc_class_selectors.Insert( objc_class_name_with_category, - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), is_types_section)); if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category) set.objc_class_selectors.Insert( objc_class_name_no_category, - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), is_types_section)); if (objc_selector_name) set.function_selectors.Insert(objc_selector_name, - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); if (objc_fullname_no_category_name) set.function_fullnames.Insert(objc_fullname_no_category_name, - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); } // If we have a mangled name, then the DW_AT_name attribute is // usually the method name without the class or any parameters @@ -282,14 +286,17 @@ if (is_method) set.function_methods.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); else set.function_basenames.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); if (!is_method && !mangled_cstr && !objc_method.IsValid(true)) set.function_fullnames.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); } if (mangled_cstr) { // Make sure our mangled name isn't the same string table entry as @@ -300,7 +307,8 @@ ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { set.function_fullnames.Insert(ConstString(mangled_cstr), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); } } } @@ -318,22 +326,25 @@ case DW_TAG_union_type: case DW_TAG_unspecified_type: if (name && !is_declaration) - set.types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset())); + set.types.Insert(ConstString(name), DIERef(cu_offset, die.GetOffset(), + is_types_section)); if (mangled_cstr && !is_declaration) set.types.Insert(ConstString(mangled_cstr), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), is_types_section)); break; case DW_TAG_namespace: if (name) set.namespaces.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); break; case DW_TAG_variable: if (name && has_location_or_const_value && is_global_or_static_variable) { set.globals.Insert(ConstString(name), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); // Be sure to include variables by their mangled and demangled names if // they have any since a variable can have a basename "i", a mangled // named "_ZN12_GLOBAL__N_11iE" and a demangled mangled name @@ -346,7 +357,8 @@ if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0))) { set.globals.Insert(ConstString(mangled_cstr), - DIERef(cu_offset, die.GetOffset())); + DIERef(cu_offset, die.GetOffset(), + is_types_section)); } } break; Index: lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -56,7 +56,8 @@ ConstString cstr = m_map.GetCStringAtIndex(i); const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i); s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void *)cstr.GetCString(), - die_ref.cu_offset, die_ref.die_offset, cstr.GetCString()); + die_ref.cu_offset, dw_offset_t(die_ref.die_offset), + cstr.GetCString()); } } Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -692,6 +692,9 @@ // Just a normal DWARF file whose user ID for the compile unit is the DWARF // offset itself + auto offset = comp_unit->GetID(); + bool is_types_section = (offset & DIERef::UID_IS_TYPES_SECTION) != 0; + offset &= ~DIERef::UID_IS_TYPES_SECTION; DWARFUnit *dwarf_cu = info->GetUnit((dw_offset_t)comp_unit->GetID()); if (dwarf_cu && dwarf_cu->GetUserData() == NULL)