[llvm] r325600 - [dsymutil] Correctly handle DW_TAG_label

Jonas Devlieghere via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 20 09:34:29 PST 2018


Author: jdevlieghere
Date: Tue Feb 20 09:34:29 2018
New Revision: 325600

URL: http://llvm.org/viewvc/llvm-project?rev=325600&view=rev
Log:
[dsymutil] Correctly handle DW_TAG_label

This patch contains logic for handling DW_TAG_label that's present in
darwin's dsymutil implementation, but not yet upstream.

Differential revision: https://reviews.llvm.org/D43438

Added:
    llvm/trunk/test/tools/dsymutil/Inputs/label.o   (with props)
    llvm/trunk/test/tools/dsymutil/X86/label.test
Modified:
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp

Added: llvm/trunk/test/tools/dsymutil/Inputs/label.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/label.o?rev=325600&view=auto
==============================================================================
Binary file - no diff available.

Propchange: llvm/trunk/test/tools/dsymutil/Inputs/label.o
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: llvm/trunk/test/tools/dsymutil/X86/label.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/label.test?rev=325600&view=auto
==============================================================================
--- llvm/trunk/test/tools/dsymutil/X86/label.test (added)
+++ llvm/trunk/test/tools/dsymutil/X86/label.test Tue Feb 20 09:34:29 2018
@@ -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 }
+...
+

Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=325600&r1=325599&r2=325600&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Tue Feb 20 09:34:29 2018
@@ -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::shouldKeepSubprogr
     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::shouldKeepSubprogr
     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(Relo
   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:




More information about the llvm-commits mailing list