diff options
| -rw-r--r-- | llvm/test/tools/dsymutil/X86/generate-empty-CU.test | 33 | ||||
| -rw-r--r-- | llvm/tools/dsymutil/DwarfLinker.cpp | 34 |
2 files changed, 53 insertions, 14 deletions
diff --git a/llvm/test/tools/dsymutil/X86/generate-empty-CU.test b/llvm/test/tools/dsymutil/X86/generate-empty-CU.test new file mode 100644 index 00000000000..233611460b6 --- /dev/null +++ b/llvm/test/tools/dsymutil/X86/generate-empty-CU.test @@ -0,0 +1,33 @@ +# RUN: llvm-dsymutil -f -o - -oso-prepend-path=%p/.. -y %s | llvm-dwarfdump - | FileCheck %s + +# This test on links the Dwarf for an LTO binary and on purpose doesn't retain +# any symbol in the second CU out of 3. This is the only case where dsymutil +# will generate an empty CU and it requires special handling. + +--- +triple: 'x86_64-apple-darwin' +objects: + - filename: /Inputs/basic-lto.macho.x86_64.o + timestamp: 1417654896 + symbols: + - { sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000F40, size: 0x00000010 } + - { sym: _bar, objAddr: 0x0000000000000050, binAddr: 0x0000000100000F90, size: 0x00000024 } +... + +.debug_info contents: +CHECK: Compile Unit: length = 0x0000007d version = 0x0002 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000081) + +CHECK: DW_TAG_compile_unit +CHECK: DW_AT_name {{.*}} "basic1.c" +CHECK: DW_TAG_subprogram + DW_AT_name {{.*}} "main" + +CHECK: Compile Unit: length = 0x00000007 version = 0x0002 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x0000008c) + +CHECK: Compile Unit: length = 0x00000089 version = 0x0002 abbr_offset = 0x0000 addr_size = 0x08 (next unit at 0x00000119) + +CHECK: DW_TAG_compile_unit +CHECK: DW_AT_name {{.*}} "basic3.c" + +CHECK: DW_TAG_subprogram [7] * +CHECK: DW_AT_name {{.*}} = "bar" diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index 2fe4f29d408..35cefaa69e8 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -197,11 +197,8 @@ public: CompileUnit(DWARFUnit &OrigUnit, unsigned ID, bool CanUseODR, StringRef ClangModuleName) - : OrigUnit(OrigUnit), ID(ID), NewUnit(OrigUnit.getVersion(), - OrigUnit.getAddressByteSize(), - OrigUnit.getUnitDIE().getTag()), - LowPc(UINT64_MAX), HighPc(0), RangeAlloc(), Ranges(RangeAlloc), - ClangModuleName(ClangModuleName) { + : OrigUnit(OrigUnit), ID(ID), LowPc(UINT64_MAX), HighPc(0), RangeAlloc(), + Ranges(RangeAlloc), ClangModuleName(ClangModuleName) { Info.resize(OrigUnit.getNumDIEs()); auto CUDie = OrigUnit.getUnitDIE(false); @@ -219,8 +216,15 @@ public: unsigned getUniqueID() const { return ID; } + void createOutputDIE() { + NewUnit.emplace(OrigUnit.getVersion(), OrigUnit.getAddressByteSize(), + OrigUnit.getUnitDIE().getTag()); + } + DIE *getOutputUnitDIE() const { - return &const_cast<DIEUnit &>(NewUnit).getUnitDie(); + if (NewUnit) + return &const_cast<DIEUnit &>(*NewUnit).getUnitDie(); + return nullptr; } bool hasODR() const { return HasODR; } @@ -329,7 +333,7 @@ private: DWARFUnit &OrigUnit; unsigned ID; std::vector<DIEInfo> Info; ///< DIE info indexed by DIE index. - DIEUnit NewUnit; + Optional<DIEUnit> NewUnit; uint64_t StartOffset; uint64_t NextUnitOffset; @@ -397,7 +401,8 @@ uint64_t CompileUnit::computeNextUnitOffset() { // The root DIE might be null, meaning that the Unit had nothing to // contribute to the linked output. In that case, we will emit the // unit header without any actual DIE. - NextUnitOffset += NewUnit.getUnitDie().getSize(); + if (NewUnit) + NextUnitOffset += NewUnit->getUnitDie().getSize(); return NextUnitOffset; } @@ -3357,12 +3362,13 @@ void DwarfLinker::DIECloner::cloneAllCompileUnits( for (auto &CurrentUnit : CompileUnits) { auto InputDIE = CurrentUnit->getOrigUnit().getUnitDIE(); CurrentUnit->setStartOffset(Linker.OutputDebugInfoSize); - // Clonse the InputDIE into your Unit DIE in our compile unit since it - // already has a DIE inside of it. - if (!cloneDIE(InputDIE, *CurrentUnit, 0 /* PC offset */, - 11 /* Unit Header size */, 0, - CurrentUnit->getOutputUnitDIE())) - continue; + if (CurrentUnit->getInfo(0).Keep) { + // Clone the InputDIE into your Unit DIE in our compile unit since it + // already has a DIE inside of it. + CurrentUnit->createOutputDIE(); + cloneDIE(InputDIE, *CurrentUnit, 0 /* PC offset */, + 11 /* Unit Header size */, 0, CurrentUnit->getOutputUnitDIE()); + } Linker.OutputDebugInfoSize = CurrentUnit->computeNextUnitOffset(); if (Linker.Options.NoOutput) continue; |

