diff options
-rw-r--r-- | llvm/test/tools/dsymutil/Inputs/label.o | bin | 0 -> 1088 bytes | |||
-rw-r--r-- | llvm/test/tools/dsymutil/X86/label.test | 16 | ||||
-rw-r--r-- | llvm/tools/dsymutil/DwarfLinker.cpp | 29 |
3 files changed, 44 insertions, 1 deletions
diff --git a/llvm/test/tools/dsymutil/Inputs/label.o b/llvm/test/tools/dsymutil/Inputs/label.o Binary files differnew file mode 100644 index 00000000000..cd70eb57e05 --- /dev/null +++ b/llvm/test/tools/dsymutil/Inputs/label.o diff --git a/llvm/test/tools/dsymutil/X86/label.test b/llvm/test/tools/dsymutil/X86/label.test new file mode 100644 index 00000000000..be4bc3c83b4 --- /dev/null +++ b/llvm/test/tools/dsymutil/X86/label.test @@ -0,0 +1,16 @@ +# RUN: llvm-dsymutil -oso-prepend-path %p/../Inputs -y %s -f -o - | llvm-dwarfdump - --debug-info | FileCheck %s + +# Compile with: +# echo -e ".global _foo;\nfoo:\nnop" | clang -x assembler -g - -c -o /tmp/label.o + +# CHECK: DW_TAG_label +# CHECK-NEXT: DW_AT_name ("foo") + +--- +triple: 'x86_64-apple-darwin' +objects: + - filename: label.o + symbols: + - { sym: _foo, objAddr: 0x0, binAddr: 0x1000, size: 0x1 } +... + diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index 4064cd0a6a4..4a34fa6e8e1 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -327,6 +327,7 @@ public: uint64_t getLowPc() const { return LowPc; } uint64_t getHighPc() const { return HighPc; } + bool hasLabelAt(uint64_t Addr) const { return Labels.count(Addr); } Optional<PatchLocation> getUnitRangesAttribute() const { return UnitRangeAttribute; @@ -366,6 +367,10 @@ public: /// Apply all fixups recored by noteForwardReference(). void fixupForwardReferences(); + /// Add the low_pc of a label that is relocatad by applying + /// offset \p PCOffset. + void addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset); + /// Add a function range [\p LowPC, \p HighPC) that is relocatad by applying /// offset \p PCOffset. void addFunctionRange(uint64_t LowPC, uint64_t HighPC, int64_t PCOffset); @@ -471,6 +476,9 @@ private: /// to the addresses to get the linked address. FunctionIntervals Ranges; + /// The DW_AT_low_pc of each DW_TAG_label. + SmallDenseMap<uint64_t, uint64_t, 1> Labels; + /// DW_AT_ranges attributes to patch after we have gathered /// all the unit's function addresses. /// @{ @@ -585,6 +593,10 @@ void CompileUnit::fixupForwardReferences() { } } +void CompileUnit::addLabelLowPc(uint64_t LabelLowPc, int64_t PcOffset) { + Labels.insert({LabelLowPc, PcOffset}); +} + void CompileUnit::addFunctionRange(uint64_t FuncLowPc, uint64_t FuncHighPc, int64_t PcOffset) { Ranges.insert(FuncLowPc, FuncHighPc, PcOffset); @@ -2453,7 +2465,7 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE( return Flags; uint32_t Offset = DIE.getOffset() + getULEB128Size(Abbrev->getCode()); - const DWARFUnit &OrigUnit = Unit.getOrigUnit(); + DWARFUnit &OrigUnit = Unit.getOrigUnit(); uint32_t LowPcOffset, LowPcEndOffset; std::tie(LowPcOffset, LowPcEndOffset) = getAttributeOffsets(Abbrev, *LowPcIdx, Offset, OrigUnit); @@ -2471,6 +2483,20 @@ unsigned DwarfLinker::shouldKeepSubprogramDIE( DIE.dump(outs(), 8 /* Indent */, DumpOpts); } + if (DIE.getTag() == dwarf::DW_TAG_label) { + if (Unit.hasLabelAt(*LowPc)) + return Flags; + // FIXME: dsymutil-classic compat. dsymutil-classic doesn't consider labels + // that don't fall into the CU's aranges. This is wrong IMO. Debug info + // generation bugs aside, this is really wrong in the case of labels, where + // a label marking the end of a function will have a PC == CU's high_pc. + if (dwarf::toAddress(OrigUnit.getUnitDIE().find(dwarf::DW_AT_high_pc)) + .getValueOr(UINT64_MAX) <= LowPc) + return Flags; + Unit.addLabelLowPc(*LowPc, MyInfo.AddrAdjust); + return Flags | TF_Keep; + } + Flags |= TF_Keep; Optional<uint64_t> HighPc = DIE.getHighPC(*LowPc); @@ -2498,6 +2524,7 @@ unsigned DwarfLinker::shouldKeepDIE(RelocationManager &RelocMgr, case dwarf::DW_TAG_variable: return shouldKeepVariableDIE(RelocMgr, DIE, Unit, MyInfo, Flags); case dwarf::DW_TAG_subprogram: + case dwarf::DW_TAG_label: return shouldKeepSubprogramDIE(RelocMgr, DIE, Unit, MyInfo, Flags); case dwarf::DW_TAG_imported_module: case dwarf::DW_TAG_imported_declaration: |