Index: lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp @@ -27,8 +27,8 @@ if (actual_dwarf) { DWARFDebugInfo *debug_info = actual_dwarf->DebugInfo(); if (debug_info) { - DWARFUnit *dwarf_cu = - debug_info->GetUnitContainingDIEOffset(die_offset); + DWARFUnit *dwarf_cu = debug_info->GetUnitContainingDIEOffset( + die_offset, IsTypesSection()); if (dwarf_cu) { cu_offset = dwarf_cu->GetOffset(); return; Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -23,9 +23,7 @@ /// Get the data that contains the DIE information for this unit. /// /// \return - /// The correct data (.debug_types for DWARF 4 and earlier, and - /// .debug_info for DWARF 5 and later) for the DIE information in - /// this unit. + /// .debug_info data for the DIE information in this unit. const lldb_private::DWARFDataExtractor &GetData() const override; /// Get the size in bytes of the header. Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h @@ -19,6 +19,8 @@ #include "lldb/lldb-private.h" #include "llvm/Support/Error.h" +class DWARFTypeUnit; + namespace lldb_private { class DWARFContext; } @@ -40,11 +42,31 @@ void SetDwarfData(SymbolFileDWARF *dwarf2Data); size_t GetNumUnits(); + // GetNumUnits was called GetNumCompileUnits before, do not clash the rename: + size_t GetNumOnlyCompileUnits(); DWARFUnit *GetUnitAtIndex(uint32_t idx); - DWARFUnit *GetUnit(dw_offset_t cu_offset, uint32_t *idx_ptr = NULL); - DWARFUnit *GetUnitContainingDIEOffset(dw_offset_t die_offset); + DWARFTypeUnit *GetTypeUnitForSignature(uint64_t type_sig); + DWARFUnit *GetCompileUnit(dw_offset_t cu_offset, + uint32_t *idx_ptr = nullptr) { + return GetUnitImpl(m_compile_units, cu_offset, idx_ptr); + } + DWARFUnit *GetTypesSectionUnit(dw_offset_t cu_offset, + uint32_t *idx_ptr = nullptr) { + return GetUnitImpl(m_type_units, cu_offset, idx_ptr); + } + DWARFUnit *GetUnitContainingDIEOffset(dw_offset_t die_offset, + bool is_types_section) { + return is_types_section + ? GetTypeUnitContainingDIEOffset(die_offset) + : GetCompileUnitContainingDIEOffset(die_offset); + } + DWARFUnit *GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) { + return GetUnitContainingDIEOffsetImpl(m_compile_units, die_offset); + } + DWARFUnit *GetTypeUnitContainingDIEOffset(dw_offset_t die_offset) { + return GetUnitContainingDIEOffsetImpl(m_type_units, die_offset); + } DWARFUnit *GetUnit(const DIERef &die_ref); - DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset); DWARFDIE GetDIE(const DIERef &die_ref); enum { @@ -65,7 +87,7 @@ // Member variables SymbolFileDWARF *m_dwarf2Data; lldb_private::DWARFContext &m_context; - UnitColl m_units; + UnitColl m_compile_units, m_type_units; std::unique_ptr m_cu_aranges_up; // A quick address to compile unit table @@ -75,30 +97,34 @@ void ParseUnitHeadersIfNeeded(); template - DWARFUnit *GetUnitTmpl( - Contains contains, dw_offset_t offset, uint32_t *idx_ptr = NULL); + DWARFUnit *GetUnitTmpl(Contains contains, const UnitColl &units, + dw_offset_t offset, uint32_t *idx_ptr = nullptr); + DWARFUnit *GetUnitImpl(const UnitColl &units, dw_offset_t cu_offset, + uint32_t *idx_ptr); + DWARFUnit *GetUnitContainingDIEOffsetImpl(const UnitColl &units, + dw_offset_t die_offset); DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo); }; template -DWARFUnit *DWARFDebugInfo::GetUnitTmpl( - Contains contains, dw_offset_t offset, uint32_t *idx_ptr) { +DWARFUnit *DWARFDebugInfo::GetUnitTmpl(Contains contains, const UnitColl &units, + dw_offset_t offset, uint32_t *idx_ptr) { ParseUnitHeadersIfNeeded(); DWARFUnitSP cu_sp; // Watch out for single unit executable as they are pretty common - const size_t num_cus = m_units.size(); + const size_t num_cus = units.size(); if (num_cus == 1) { - if (contains(*m_units[0], offset)) { + if (contains(*units[0], offset)) { if (idx_ptr) *idx_ptr = 0; - return m_units[0].get(); + return units[0].get(); } } else if (num_cus) { - UnitColl::const_iterator end_pos = m_units.end(); - UnitColl::const_iterator begin_pos = m_units.begin(); + UnitColl::const_iterator end_pos = units.end(); + UnitColl::const_iterator begin_pos = units.begin(); UnitColl::const_iterator pos = std::upper_bound( begin_pos, end_pos, offset, OffsetLessThanUnitOffset); if (pos != begin_pos) { Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -29,12 +29,14 @@ // Constructor DWARFDebugInfo::DWARFDebugInfo(lldb_private::DWARFContext &context) - : m_dwarf2Data(NULL), m_context(context), m_units(), m_cu_aranges_up() {} + : m_dwarf2Data(NULL), m_context(context), m_compile_units(), m_type_units(), + m_cu_aranges_up() {} // SetDwarfData void DWARFDebugInfo::SetDwarfData(SymbolFileDWARF *dwarf2Data) { m_dwarf2Data = dwarf2Data; - m_units.clear(); + m_compile_units.clear(); + m_type_units.clear(); } llvm::Expected DWARFDebugInfo::GetCompileUnitAranges() { @@ -77,43 +79,53 @@ } void DWARFDebugInfo::ParseUnitHeadersIfNeeded() { - if (!m_units.empty()) + if (!m_compile_units.empty() || !m_type_units.empty()) return; if (!m_dwarf2Data) return; - lldb::offset_t offset = 0; - const auto &debug_info_data = m_dwarf2Data->get_debug_info_data(); + { + lldb::offset_t offset = 0; + const auto &debug_info_data = m_dwarf2Data->get_debug_info_data(); + while (debug_info_data.ValidOffset(offset)) { + llvm::Expected cu_sp = + DWARFCompileUnit::extract(m_dwarf2Data, debug_info_data, &offset); - while (debug_info_data.ValidOffset(offset)) { - llvm::Expected cu_sp = - DWARFCompileUnit::extract(m_dwarf2Data, debug_info_data, &offset); + if (!cu_sp) { + // FIXME: Propagate this error up. + llvm::consumeError(cu_sp.takeError()); + return; + } - if (!cu_sp) { - // FIXME: Propagate this error up. - llvm::consumeError(cu_sp.takeError()); - return; - } - - // If it didn't return an error, then it should be returning a valid Unit. - assert(*cu_sp); + // If it didn't return an error, then it should be returning a valid + // DWARFCompileUnit. + assert(*cu_sp); - m_units.push_back(*cu_sp); + m_compile_units.push_back(*cu_sp); - offset = (*cu_sp)->GetNextUnitOffset(); + offset = (*cu_sp)->GetNextUnitOffset(); + } } } size_t DWARFDebugInfo::GetNumUnits() { ParseUnitHeadersIfNeeded(); - return m_units.size(); + return m_compile_units.size() + m_type_units.size(); +} + +size_t DWARFDebugInfo::GetNumOnlyCompileUnits() { + ParseUnitHeadersIfNeeded(); + return m_compile_units.size(); } DWARFUnit *DWARFDebugInfo::GetUnitAtIndex(uint32_t idx) { - DWARFUnit *cu = NULL; - if (idx < GetNumUnits()) - cu = m_units[idx].get(); - return cu; + ParseUnitHeadersIfNeeded(); + if (idx < m_compile_units.size()) + return m_compile_units[idx].get(); + else if (idx < m_compile_units.size() + m_type_units.size()) + return m_type_units[idx - m_compile_units.size()].get(); + else + return NULL; } bool DWARFDebugInfo::OffsetLessThanUnitOffset( @@ -121,34 +133,32 @@ return offset < cu_sp->GetOffset(); } -DWARFUnit *DWARFDebugInfo::GetUnit(dw_offset_t cu_offset, uint32_t *idx_ptr) { +DWARFUnit *DWARFDebugInfo::GetUnitImpl(const UnitColl &units, + dw_offset_t cu_offset, uint32_t *idx_ptr) { return GetUnitTmpl( [](const DWARFUnit &unit, dw_offset_t cu_offset) { return unit.GetOffset() == cu_offset; - }, cu_offset, idx_ptr); + }, units, cu_offset, idx_ptr); } DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef &die_ref) { - if (die_ref.cu_offset == DW_INVALID_OFFSET) - return GetUnitContainingDIEOffset(die_ref.die_offset); - else - return GetUnit(die_ref.cu_offset); + if (die_ref.cu_offset == DW_INVALID_OFFSET) { + return GetUnitContainingDIEOffset(die_ref.die_offset, die_ref.IsTypesSection()); + } else { + if (die_ref.IsTypesSection()) + return GetTypesSectionUnit(die_ref.cu_offset); + else + return GetCompileUnit(die_ref.cu_offset); + } } DWARFUnit * -DWARFDebugInfo::GetUnitContainingDIEOffset(dw_offset_t die_offset) { +DWARFDebugInfo::GetUnitContainingDIEOffsetImpl(const UnitColl &units, + dw_offset_t die_offset) { return GetUnitTmpl( [](const DWARFUnit &unit, dw_offset_t die_offset) { return unit.ContainsDIEOffset(die_offset); - }, die_offset); -} - -DWARFDIE -DWARFDebugInfo::GetDIEForDIEOffset(dw_offset_t die_offset) { - DWARFUnit *cu = GetUnitContainingDIEOffset(die_offset); - if (cu) - return cu->GetDIE(die_offset); - return DWARFDIE(); + }, units, die_offset); } // GetDIE() Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -575,8 +575,10 @@ return CUDIERef(m_cu, value); case DW_FORM_ref_addr: { + // GetTypeUnitContainingDIEOffset is never possible as DWARFTypeUnit cannot + // reference anything outside. DWARFUnit *ref_cu = m_cu->GetSymbolFileDWARF()->DebugInfo() - ->GetUnitContainingDIEOffset(value); + ->GetCompileUnitContainingDIEOffset(value); if (!ref_cu) { m_cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( "DW_FORM_ref_addr DIE reference 0x%" PRIx64 " has no matching CU", Index: lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -55,7 +55,8 @@ if (!cu_offset) return DIERef(); - DWARFUnit *cu = m_debug_info.GetUnit(*cu_offset); + // FIXME: May DW_ATOM_cu_offset somehow contain a TypeUnit? + DWARFUnit *cu = m_debug_info.GetCompileUnit(*cu_offset); if (!cu) return DIERef(); @@ -164,7 +165,7 @@ if (!ref) continue; - DWARFUnit *cu = m_debug_info.GetUnit(ref.cu_offset); + DWARFUnit *cu = m_debug_info.GetUnit(ref); if (!cu || !cu->Supports_DW_AT_APPLE_objc_complete_type()) { incomplete_types.push_back(ref); continue; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -695,8 +695,8 @@ 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()); + DWARFUnit *dwarf_cu = is_types_section + ? info->GetTypesSectionUnit(offset) : info->GetCompileUnit(offset); if (dwarf_cu && dwarf_cu->GetUserData() == NULL) dwarf_cu->SetUserData(comp_unit); return dwarf_cu; @@ -779,16 +779,22 @@ cu_sp->GetSupportFiles().Replace(0, cu_file_spec); } } + } - dwarf_cu->SetUserData(cu_sp.get()); - - // Figure out the compile unit index if we weren't given one - if (cu_idx == UINT32_MAX) - DebugInfo()->GetUnit(dwarf_cu->GetOffset(), &cu_idx); + dwarf_cu->SetUserData(cu_sp.get()); - m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( - cu_idx, cu_sp); + // Figure out the compile unit index if we weren't given one + if (cu_idx == UINT32_MAX) { + if (dwarf_cu->IsTypesSection()) { + DebugInfo()->GetTypesSectionUnit(dwarf_cu->GetOffset(), + &cu_idx); + cu_idx += DebugInfo()->GetNumOnlyCompileUnits(); + } else + DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx); } + + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( + cu_idx, cu_sp); } } } @@ -1766,8 +1772,7 @@ } } else { uint32_t cu_idx = DW_INVALID_INDEX; - DWARFUnit *dwarf_cu = - debug_info->GetUnit(cu_offset, &cu_idx); + DWARFUnit *dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx); if (dwarf_cu) { sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx); if (sc.comp_unit) { @@ -3124,7 +3129,7 @@ return num_variables; } } else if (sc.comp_unit) { - DWARFUnit *dwarf_cu = info->GetUnit(sc.comp_unit->GetID()); + DWARFUnit *dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()); if (dwarf_cu == NULL) return 0; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -159,5 +159,10 @@ DWARFDIE SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { lldbassert(m_base_dwarf_cu->GetOffset() == die_ref.cu_offset); - return DebugInfo()->GetDIEForDIEOffset(die_ref.die_offset); + lldbassert(DebugInfo()->GetNumUnits() == 1); + DWARFUnit *cu = DebugInfo()->GetUnitContainingDIEOffset( + die_ref.die_offset, die_ref.IsTypesSection()); + if (cu) + return cu->GetDIE(die_ref.die_offset); + return DWARFDIE(); }