Skip to content

[DWARFLinker] Preserve DWARF discriminators while linking #96124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 21, 2024

Conversation

dtellenbach
Copy link
Member

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.

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.
@llvmbot
Copy link
Member

llvmbot commented Jun 19, 2024

@llvm/pr-subscribers-debuginfo

Author: David Tellenbach (dtellenbach)

Changes

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 --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

@dtellenbach dtellenbach requested review from avillega and avl-llvm June 19, 2024 23:53
Copy link
Member

@JDevlieghere JDevlieghere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks David!

Copy link
Collaborator

@avl-llvm avl-llvm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@dtellenbach
Copy link
Member Author

Had to change the test because it contained an absolute N_OSO.

@dtellenbach dtellenbach merged commit 9f71a6b into llvm:main Jun 21, 2024
5 of 6 checks passed
@dtellenbach dtellenbach deleted the dsymutil_discriminator branch June 21, 2024 05:41
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants