[llvm] [DWARFLinker] Preserve DWARF discriminators while linking (PR #96124)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 19 16:52:17 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-debuginfo

Author: David Tellenbach (dtellenbach)

<details>
<summary>Changes</summary>

DWARF-4 introduced DWARF discriminators but both, the classic and the parallel DWARF linkers discarded them so far.

After applying this patch dsymutil, which uses the DWARF linkers, correctly preserves discriminator information.

---
Full diff: https://github.com/llvm/llvm-project/pull/96124.diff


4 Files Affected:

- (modified) llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp (+13-4) 
- (modified) llvm/lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h (+10-4) 
- (added) llvm/test/tools/dsymutil/Inputs/discriminator.arm64 () 
- (added) llvm/test/tools/dsymutil/discriminator.test (+39) 


``````````diff
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
index 8b31b5ead29ad..cc4ee2a1b4aec 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFStreamer.cpp
@@ -1060,6 +1060,7 @@ void DwarfStreamer::emitLineTableRows(
   unsigned FileNum = 1;
   unsigned LastLine = 1;
   unsigned Column = 0;
+  unsigned Discriminator = 0;
   unsigned IsStatement = 1;
   unsigned Isa = 0;
   uint64_t Address = -1ULL;
@@ -1098,9 +1099,17 @@ void DwarfStreamer::emitLineTableRows(
       MS->emitULEB128IntValue(Column);
       LineSectionSize += 1 + getULEB128Size(Column);
     }
-
-    // FIXME: We should handle the discriminator here, but dsymutil doesn't
-    // consider it, thus ignore it for now.
+    if (Discriminator != Row.Discriminator &&
+        MS->getContext().getDwarfVersion() >= 4) {
+      Discriminator = Row.Discriminator;
+      unsigned Size = getULEB128Size(Discriminator);
+      MS->emitIntValue(dwarf::DW_LNS_extended_op, 1);
+      MS->emitULEB128IntValue(Size + 1);
+      MS->emitIntValue(dwarf::DW_LNE_set_discriminator, 1);
+      MS->emitULEB128IntValue(Discriminator);
+      LineSectionSize += /* extended op */ 1 + getULEB128Size(Size + 1) +
+                         /* discriminator */ 1 + Size;
+    }
 
     if (Isa != Row.Isa) {
       Isa = Row.Isa;
@@ -1156,7 +1165,7 @@ void DwarfStreamer::emitLineTableRows(
       EncodingBuffer.resize(0);
       Address = -1ULL;
       LastLine = FileNum = IsStatement = 1;
-      RowsSinceLastSequence = Column = Isa = 0;
+      RowsSinceLastSequence = Column = Discriminator = Isa = 0;
     }
   }
 
diff --git a/llvm/lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h b/llvm/lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h
index 1839164dcec17..0c4395589248a 100644
--- a/llvm/lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h
+++ b/llvm/lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h
@@ -315,6 +315,7 @@ class DebugLineSectionEmitter {
     unsigned FileNum = 1;
     unsigned LastLine = 1;
     unsigned Column = 0;
+    unsigned Discriminator = 0;
     unsigned IsStatement = 1;
     unsigned Isa = 0;
     uint64_t Address = -1ULL;
@@ -350,9 +351,14 @@ class DebugLineSectionEmitter {
         Section.emitIntVal(dwarf::DW_LNS_set_column, 1);
         encodeULEB128(Column, Section.OS);
       }
-
-      // FIXME: We should handle the discriminator here, but dsymutil doesn't
-      // consider it, thus ignore it for now.
+      if (Discriminator != Row.Discriminator && MC->getDwarfVersion() >= 4) {
+        Discriminator = Row.Discriminator;
+        unsigned Size = getULEB128Size(Discriminator);
+        Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
+        encodeULEB128(Size + 1, Section.OS);
+        Section.emitIntVal(dwarf::DW_LNE_set_discriminator, 1);
+        encodeULEB128(Discriminator, Section.OS);
+      }
 
       if (Isa != Row.Isa) {
         Isa = Row.Isa;
@@ -397,7 +403,7 @@ class DebugLineSectionEmitter {
         EncodingBuffer.resize(0);
         Address = -1ULL;
         LastLine = FileNum = IsStatement = 1;
-        RowsSinceLastSequence = Column = Isa = 0;
+        RowsSinceLastSequence = Column = Discriminator = Isa = 0;
       }
     }
 
diff --git a/llvm/test/tools/dsymutil/Inputs/discriminator.arm64 b/llvm/test/tools/dsymutil/Inputs/discriminator.arm64
new file mode 100755
index 0000000000000..c48979fd8e9ff
Binary files /dev/null and b/llvm/test/tools/dsymutil/Inputs/discriminator.arm64 differ
diff --git a/llvm/test/tools/dsymutil/discriminator.test b/llvm/test/tools/dsymutil/discriminator.test
new file mode 100644
index 0000000000000..9bd1de2083567
--- /dev/null
+++ b/llvm/test/tools/dsymutil/discriminator.test
@@ -0,0 +1,39 @@
+; The DWARF at Inputs/discriminator.arm64 this test is based on was produced by
+; compiling
+;
+;   __attribute__((noinline))
+;   int foo(int a, int b, int c) {
+;     int x = a ? b : c;
+;     return x * a * b;
+;   }
+;
+;   int main(int argc, char** argv) {
+;     return foo(argc, 2, 3);
+;   }
+;
+; with -g -fdebug-info-for-profiling.
+
+RUN: dsymutil --flat --linker=classic -o - --verify-dwarf=none %p/Inputs/discriminator.arm64 | llvm-dwarfdump -debug-line - | FileCheck %s
+RUN: dsymutil --flat --linker=parallel -o - --verify-dwarf=none %p/Inputs/discriminator.arm64 | llvm-dwarfdump -debug-line - | FileCheck %s
+
+CHECK:         Address            Line   Column File   ISA Discriminator OpIndex Flags
+CHECK-NEXT:    ------------------ ------ ------ ------ --- ------------- ------- -------------
+CHECK-NEXT:    0x0000000100003f14      2      0      0   0             0       0  is_stmt
+CHECK-NEXT:    0x0000000100003f24      3     11      0   0             0       0  is_stmt prologue_end
+CHECK-NEXT:    0x0000000100003f30      3     15      0   0             2       0
+CHECK-NEXT:    0x0000000100003f38      3     11      0   0             0       0
+CHECK-NEXT:    0x0000000100003f3c      3     19      0   0             4       0
+CHECK-NEXT:    0x0000000100003f44      3     11      0   0             0       0
+CHECK-NEXT:    0x0000000100003f48      0     11      0   0             0       0
+CHECK-NEXT:    0x0000000100003f4c      3      7      0   0             6       0
+CHECK-NEXT:    0x0000000100003f50      4     10      0   0             0       0  is_stmt
+CHECK-NEXT:    0x0000000100003f54      4     14      0   0             0       0
+CHECK-NEXT:    0x0000000100003f58      4     12      0   0             0       0
+CHECK-NEXT:    0x0000000100003f5c      4     18      0   0             0       0
+CHECK-NEXT:    0x0000000100003f60      4     16      0   0             0       0
+CHECK-NEXT:    0x0000000100003f64      4      3      0   0             0       0  epilogue_begin
+CHECK-NEXT:    0x0000000100003f6c      7      0      0   0             0       0  is_stmt
+CHECK-NEXT:    0x0000000100003f84      8     14      0   0             0       0  is_stmt prologue_end
+CHECK-NEXT:    0x0000000100003f88      8     10      0   0             0       0
+CHECK-NEXT:    0x0000000100003f94      8      3      0   0             0       0  epilogue_begin
+CHECK-NEXT:    0x0000000100003fa0      8      3      0   0             0       0  end_sequence
\ No newline at end of file

``````````

</details>


https://github.com/llvm/llvm-project/pull/96124


More information about the llvm-commits mailing list