Index: lldb/trunk/lit/SymbolFile/DWARF/debug-types-basic.test =================================================================== --- lldb/trunk/lit/SymbolFile/DWARF/debug-types-basic.test +++ lldb/trunk/lit/SymbolFile/DWARF/debug-types-basic.test @@ -2,15 +2,27 @@ # Make sure DWARF v4 type units work. # RUN: %clangxx -target x86_64-pc-linux %S/Inputs/debug-types-basic.cpp \ -# RUN: -g -gdwarf-4 -fdebug-types-section -c -o %t.o -# RUN: ld.lld %t.o -o %t -# RUN: %lldb %t -s %s -o exit | FileCheck %s +# RUN: -g -gdwarf-4 -fdebug-types-section -c -o %t4.o +# RUN: ld.lld %t4.o -o %t4 +# RUN: %lldb %t4 -s %s -o exit | FileCheck %s # Now do the same for DWARF v5. # RUN: %clangxx -target x86_64-pc-linux %S/Inputs/debug-types-basic.cpp \ -# RUN: -g -gdwarf-5 -fdebug-types-section -c -o %t.o -# RUN: ld.lld %t.o -o %t -# RUN: %lldb %t -s %s -o exit | FileCheck %s +# RUN: -g -gdwarf-5 -fdebug-types-section -c -o %t5.o +# RUN: ld.lld %t5.o -o %t5 +# RUN: %lldb %t5 -s %s -o exit | FileCheck %s + +# Test type units in dwo files. +# RUN: %clangxx -target x86_64-pc-linux %S/Inputs/debug-types-basic.cpp \ +# RUN: -g -gdwarf-4 -fdebug-types-section -gsplit-dwarf -c -o %t4dwo.o +# RUN: ld.lld %t4dwo.o -o %t4dwo +# RUN: %lldb %t4dwo -s %s -o exit | FileCheck %s + +# And type units+dwo+dwarf5. +# RUN: %clangxx -target x86_64-pc-linux %S/Inputs/debug-types-basic.cpp \ +# RUN: -g -gdwarf-5 -fdebug-types-section -c -o %t5dwo.o +# RUN: ld.lld %t5dwo.o -o %t5dwo +# RUN: %lldb %t5dwo -s %s -o exit | FileCheck %s type lookup A # CHECK-LABEL: type lookup A Index: lldb/trunk/lit/SymbolFile/DWARF/debug-types-expressions.test =================================================================== --- lldb/trunk/lit/SymbolFile/DWARF/debug-types-expressions.test +++ lldb/trunk/lit/SymbolFile/DWARF/debug-types-expressions.test @@ -2,13 +2,23 @@ # Make sure DWARF v4 type units work. # RUN: %clangxx %S/Inputs/debug-types-expressions.cpp \ -# RUN: -g -fdebug-types-section -o %t -# RUN: %lldb %t -s %s -o exit | FileCheck %s +# RUN: -g -gdwarf-4 -fdebug-types-section -o %t4 +# RUN: %lldb %t4 -s %s -o exit | FileCheck %s # Now do the same for DWARF v5. # RUN: %clangxx %S/Inputs/debug-types-expressions.cpp \ -# RUN: -g -gdwarf-5 -fdebug-types-section -o %t -# RUN: %lldb %t -s %s -o exit | FileCheck %s +# RUN: -g -gdwarf-5 -fdebug-types-section -o %t5 +# RUN: %lldb %t5 -s %s -o exit | FileCheck %s + +# Test type units in dwo files. +# RUN: %clangxx %S/Inputs/debug-types-expressions.cpp \ +# RUN: -g -gdwarf-4 -fdebug-types-section -o %t4dwo +# RUN: %lldb %t4dwo -s %s -o exit | FileCheck %s + +# And type units+dwo+dwarf5. +# RUN: %clangxx %S/Inputs/debug-types-expressions.cpp \ +# RUN: -g -gdwarf-5 -fdebug-types-section -o %t5dwo +# RUN: %lldb %t5dwo -s %s -o exit | FileCheck %s breakpoint set -n foo process launch Index: lldb/trunk/lit/SymbolFile/DWARF/split-dwarf-multiple-cu.ll =================================================================== --- lldb/trunk/lit/SymbolFile/DWARF/split-dwarf-multiple-cu.ll +++ lldb/trunk/lit/SymbolFile/DWARF/split-dwarf-multiple-cu.ll @@ -0,0 +1,40 @@ +; Check handling of dwo files with multiple compile units. Right now this is not +; supported, but it should not cause us to crash or misbehave either... + +; RUN: llc %s -filetype=obj -o %t.o --split-dwarf-file=%t.o +; RUN: %lldb %t.o -o "image lookup -s x1 -v" -o "image lookup -s x2 -v" -b | FileCheck %s + +; CHECK: image lookup -s x1 +; CHECK: 1 symbols match 'x1' +; CHECK-NOT: CompileUnit: +; CHECK-NOT: Variable: + +; CHECK: image lookup -s x2 +; CHECK: 1 symbols match 'x2' +; CHECK-NOT: CompileUnit: +; CHECK-NOT: Variable: + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@x1 = dso_local global i32 42, align 4, !dbg !10 +@x2 = dso_local global i32 47, align 4, !dbg !20 + +!llvm.dbg.cu = !{!12, !22} +!llvm.module.flags = !{!8, !9, !1} + +!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression()) +!11 = distinct !DIGlobalVariable(name: "x1", scope: !12, type: !7) +!12 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !15) +!15 = !{!10} + +!20 = !DIGlobalVariableExpression(var: !21, expr: !DIExpression()) +!21 = distinct !DIGlobalVariable(name: "x2", scope: !22, type: !7) +!22 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !25) +!25 = !{!20} + +!3 = !DIFile(filename: "-", directory: "/tmp") +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!1 = !{i32 1, !"wchar_size", i32 4} Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFContext.cpp @@ -97,6 +97,6 @@ } const DWARFDataExtractor &DWARFContext::getOrLoadDebugTypesData() { - return LoadOrGetSection(eSectionTypeDWARFDebugTypes, llvm::None, - m_data_debug_types); + return LoadOrGetSection(eSectionTypeDWARFDebugTypes, + eSectionTypeDWARFDebugTypesDwo, m_data_debug_types); } Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -19,13 +19,14 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/Stream.h" -#include "DWARFUnit.h" +#include "DWARFCompileUnit.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" #include "DWARFDebugRanges.h" #include "DWARFDeclContext.h" #include "DWARFFormValue.h" +#include "DWARFUnit.h" #include "SymbolFileDWARF.h" #include "SymbolFileDWARFDwo.h" @@ -657,7 +658,7 @@ if (!dwo_symbol_file) return 0; - DWARFUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); + DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit(); if (!dwo_cu) return 0; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -363,7 +363,10 @@ else if (gnu_ranges_base) dwo_cu->SetRangesBase(*gnu_ranges_base); - SetDwoStrOffsetsBase(dwo_cu); + for (size_t i = 0; i < m_dwo_symbol_file->DebugInfo()->GetNumUnits(); ++i) { + DWARFUnit *unit = m_dwo_symbol_file->DebugInfo()->GetUnitAtIndex(i); + SetDwoStrOffsetsBase(unit); + } } DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) { Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -104,9 +104,10 @@ IndexUnitImpl(unit, cu_language, set); - SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile(); - if (dwo_symbol_file && dwo_symbol_file->GetCompileUnit()) { - IndexUnitImpl(*dwo_symbol_file->GetCompileUnit(), cu_language, set); + if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) { + DWARFDebugInfo &dwo_info = *dwo_symbol_file->DebugInfo(); + for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) + IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); } } Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -19,7 +19,7 @@ lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu) override; - DWARFUnit *GetCompileUnit(); + DWARFCompileUnit *GetCompileUnit(); DWARFUnit * GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override; @@ -69,8 +69,11 @@ SymbolFileDWARF &GetBaseSymbolFile(); + DWARFCompileUnit *ComputeCompileUnit(); + lldb::ObjectFileSP m_obj_file_sp; DWARFCompileUnit &m_base_dwarf_cu; + DWARFCompileUnit *m_cu = nullptr; }; #endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -12,6 +12,7 @@ #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/LLDBAssert.h" +#include "llvm/Support/Casting.h" #include "DWARFCompileUnit.h" #include "DWARFDebugInfo.h" @@ -54,12 +55,34 @@ return GetBaseSymbolFile().ParseCompileUnit(m_base_dwarf_cu); } -DWARFUnit *SymbolFileDWARFDwo::GetCompileUnit() { - // Only dwo files with 1 compile unit is supported - if (GetNumCompileUnits() == 1) - return DebugInfo()->GetUnitAtIndex(0); - else +DWARFCompileUnit *SymbolFileDWARFDwo::GetCompileUnit() { + if (!m_cu) + m_cu = ComputeCompileUnit(); + return m_cu; +} + +DWARFCompileUnit *SymbolFileDWARFDwo::ComputeCompileUnit() { + 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. + if (!debug_info->ContainsTypeUnits() && debug_info->GetNumUnits() == 1) + return llvm::cast(debug_info->GetUnitAtIndex(0)); + + // Otherwise, we have to run through all units, and find the compile unit that + // way. + DWARFCompileUnit *cu = nullptr; + for (size_t i = 0; i < debug_info->GetNumUnits(); ++i) { + if (auto *candidate = + llvm::dyn_cast(debug_info->GetUnitAtIndex(i))) { + if (cu) + return nullptr; // More that one CU found. + cu = candidate; + } + } + return cu; } DWARFUnit *