Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

DataCorrupted
Copy link
Member

This reverts commit aabf18d.
#157529 included a test that used clang, which doesn't exists in some CI. #158343 reverts it.

This PR reapplies the original patch with the incorrect test removed.

Context

#99710 introduced .loc_label so we can terminate a line sequence. However, it did not advance PC properly. This is problematic for 1-instruction functions as it will have zero-length sequence. The test checked in that PR shows the problem:

# CHECK-LINE-TABLE:                  Address            Line   Column File   ISA Discriminator OpIndex Flags
# CHECK-LINE-TABLE-NEXT:             ------------------ ------ ------ ------ --- ------------- ------- -------------
# CHECK-LINE-TABLE-NEXT: 0x00000028: 05 DW_LNS_set_column (1)
# CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
# CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt
# CHECK-LINE-TABLE-NEXT: 0x00000036: 00 DW_LNE_end_sequence
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt end_sequence

Both rows having PC 0x0 is incorrect, and parsers won't be able to parse them. See more explanation why this is wrong in #154851.

Design

This PR attempts to fix this by advancing the PC to the next available Label, and advance to the end of the section if no Label is available.

Implementation

  • emitDwarfLineEndEntry will advance PC to the CurrLabel
  • If CurrLabel is null, its probably a fake LineEntry we introduced in [DebugInfo][DWARF] Emit Per-Function Line Table Offsets and End Sequences #110192. In that case look for the next Label
  • If still not label can be found, use null and emitDwarfLineEndEntry is smart enough to advance PC to the end of the section
  • Rename LastLabel to PrevLabel, "last" can mean "previous" or "final", this is ambigous.
  • Updated the tests to emit a correct label.

Note

This fix should render #154986 and #154851 obsolete, they were temporary fixes and don't resolve the root cause.

@DataCorrupted DataCorrupted marked this pull request as ready for review September 12, 2025 23:11
@llvmbot llvmbot added debuginfo llvm:mc Machine (object) code labels Sep 12, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 12, 2025

@llvm/pr-subscribers-llvm-mc

@llvm/pr-subscribers-debuginfo

Author: Peter Rong (DataCorrupted)

Changes

This reverts commit aabf18d.
#157529 included a test that used clang, which doesn't exists in some CI. #158343 reverts it.

This PR reapplies the original patch with the incorrect test removed.

Context

#99710 introduced .loc_label so we can terminate a line sequence. However, it did not advance PC properly. This is problematic for 1-instruction functions as it will have zero-length sequence. The test checked in that PR shows the problem:

# CHECK-LINE-TABLE:                  Address            Line   Column File   ISA Discriminator OpIndex Flags
# CHECK-LINE-TABLE-NEXT:             ------------------ ------ ------ ------ --- ------------- ------- -------------
# CHECK-LINE-TABLE-NEXT: 0x00000028: 05 DW_LNS_set_column (1)
# CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
# CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt
# CHECK-LINE-TABLE-NEXT: 0x00000036: 00 DW_LNE_end_sequence
# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt end_sequence

Both rows having PC 0x0 is incorrect, and parsers won't be able to parse them. See more explanation why this is wrong in #154851.

Design

This PR attempts to fix this by advancing the PC to the next available Label, and advance to the end of the section if no Label is available.

Implementation

  • emitDwarfLineEndEntry will advance PC to the CurrLabel
  • If CurrLabel is null, its probably a fake LineEntry we introduced in #110192. In that case look for the next Label
  • If still not label can be found, use null and emitDwarfLineEndEntry is smart enough to advance PC to the end of the section
  • Rename LastLabel to PrevLabel, "last" can mean "previous" or "final", this is ambigous.
  • Updated the tests to emit a correct label.

Note

This fix should render #154986 and #154851 obsolete, they were temporary fixes and don't resolve the root cause.


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

3 Files Affected:

  • (modified) llvm/lib/MC/MCDwarf.cpp (+20-10)
  • (modified) llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll (+15-14)
  • (modified) llvm/test/MC/ELF/debug-loc-label.s (+29-25)
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index e7c0d37e8f99b..e8f000a584839 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -181,7 +181,7 @@ void MCDwarfLineTable::emitOne(
 
   unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
   bool IsAtStartSeq;
-  MCSymbol *LastLabel;
+  MCSymbol *PrevLabel;
   auto init = [&]() {
     FileNum = 1;
     LastLine = 1;
@@ -189,21 +189,31 @@ void MCDwarfLineTable::emitOne(
     Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
     Isa = 0;
     Discriminator = 0;
-    LastLabel = nullptr;
+    PrevLabel = nullptr;
     IsAtStartSeq = true;
   };
   init();
 
   // Loop through each MCDwarfLineEntry and encode the dwarf line number table.
   bool EndEntryEmitted = false;
-  for (const MCDwarfLineEntry &LineEntry : LineEntries) {
-    MCSymbol *Label = LineEntry.getLabel();
+  for (auto It = LineEntries.begin(); It != LineEntries.end(); ++It) {
+    auto LineEntry = *It;
+    MCSymbol *CurrLabel = LineEntry.getLabel();
     const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
 
     if (LineEntry.LineStreamLabel) {
       if (!IsAtStartSeq) {
-        MCOS->emitDwarfLineEndEntry(Section, LastLabel,
-                                    /*EndLabel =*/LastLabel);
+        auto *Label = CurrLabel;
+        auto NextIt = It + 1;
+        // LineEntry with a null Label is probably a fake LineEntry we added
+        // when `-emit-func-debug-line-table-offsets` in order to terminate the
+        // sequence. Look for the next Label if possible, otherwise we will set
+        // the PC to the end of the section.
+        if (!Label && NextIt != LineEntries.end()) {
+          Label = NextIt->getLabel();
+        }
+        MCOS->emitDwarfLineEndEntry(Section, PrevLabel,
+                                    /*EndLabel =*/Label);
         init();
       }
       MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
@@ -211,7 +221,7 @@ void MCDwarfLineTable::emitOne(
     }
 
     if (LineEntry.IsEndEntry) {
-      MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label,
+      MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, PrevLabel, CurrLabel,
                                      asmInfo->getCodePointerSize());
       init();
       EndEntryEmitted = true;
@@ -258,12 +268,12 @@ void MCDwarfLineTable::emitOne(
     // At this point we want to emit/create the sequence to encode the delta in
     // line numbers and the increment of the address from the previous Label
     // and the current Label.
-    MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
+    MCOS->emitDwarfAdvanceLineAddr(LineDelta, PrevLabel, CurrLabel,
                                    asmInfo->getCodePointerSize());
 
     Discriminator = 0;
     LastLine = LineEntry.getLine();
-    LastLabel = Label;
+    PrevLabel = CurrLabel;
     IsAtStartSeq = false;
   }
 
@@ -273,7 +283,7 @@ void MCDwarfLineTable::emitOne(
   // does not track ranges nor terminate the line table. In that case,
   // conservatively use the section end symbol to end the line table.
   if (!EndEntryEmitted && !IsAtStartSeq)
-    MCOS->emitDwarfLineEndEntry(Section, LastLabel);
+    MCOS->emitDwarfLineEndEntry(Section, PrevLabel);
 }
 
 void MCDwarfLineTable::endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS,
diff --git a/llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll b/llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll
index 58f6495924b90..f17c6e5429b6b 100644
--- a/llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll
+++ b/llvm/test/DebugInfo/X86/DW_AT_LLVM_stmt_seq_sec_offset.ll
@@ -14,7 +14,7 @@
 ; STMT_SEQ:       DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset]	(0x00000043)
 ; STMT_SEQ:   DW_AT_name {{.*}}func01
 ; STMT_SEQ:   DW_TAG_subprogram [[[ABBREV_CODE2]]]
-; STMT_SEQ:       DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset]	(0x00000056)
+; STMT_SEQ:       DW_AT_LLVM_stmt_sequence [DW_FORM_sec_offset]	(0x00000058)
 ; STMT_SEQ:   DW_AT_name {{.*}}main
 
 ;; Check the entire line sequence to see that it's correct
@@ -29,22 +29,23 @@
 ; STMT_SEQ-NEXT:  0x00000050: 05 DW_LNS_set_column (3)
 ; STMT_SEQ-NEXT:  0x00000052: 67 address += 6,  line += 1,  op-index += 0
 ; STMT_SEQ-NEXT:              0x0000000000000006      6      3      0   0             0       0  is_stmt
-; STMT_SEQ-NEXT:  0x00000053: 00 DW_LNE_end_sequence
-; STMT_SEQ-NEXT:              0x0000000000000006      6      3      0   0             0       0  is_stmt end_sequence
-; STMT_SEQ-NEXT:  0x00000056: 04 DW_LNS_set_file (0)
-; STMT_SEQ-NEXT:  0x00000058: 00 DW_LNE_set_address (0x00000008)
-; STMT_SEQ-NEXT:  0x0000005f: 03 DW_LNS_advance_line (10)
-; STMT_SEQ-NEXT:  0x00000061: 01 DW_LNS_copy
+; STMT_SEQ-NEXT:  0x00000053: 02 DW_LNS_advance_pc (addr += 2, op-index += 0)
+; STMT_SEQ-NEXT:  0x00000055: 00 DW_LNE_end_sequence
+; STMT_SEQ-NEXT:              0x0000000000000008      6      3      0   0             0       0  is_stmt end_sequence
+; STMT_SEQ-NEXT:  0x00000058: 04 DW_LNS_set_file (0)
+; STMT_SEQ-NEXT:  0x0000005a: 00 DW_LNE_set_address (0x00000008)
+; STMT_SEQ-NEXT:  0x00000061: 03 DW_LNS_advance_line (10)
+; STMT_SEQ-NEXT:  0x00000063: 01 DW_LNS_copy
 ; STMT_SEQ-NEXT:              0x0000000000000008     10      0      0   0             0       0  is_stmt
-; STMT_SEQ-NEXT:  0x00000062: 05 DW_LNS_set_column (10)
-; STMT_SEQ-NEXT:  0x00000064: 0a DW_LNS_set_prologue_end
-; STMT_SEQ-NEXT:  0x00000065: 83 address += 8,  line += 1,  op-index += 0
+; STMT_SEQ-NEXT:  0x00000064: 05 DW_LNS_set_column (10)
+; STMT_SEQ-NEXT:  0x00000066: 0a DW_LNS_set_prologue_end
+; STMT_SEQ-NEXT:  0x00000067: 83 address += 8,  line += 1,  op-index += 0
 ; STMT_SEQ-NEXT:              0x0000000000000010     11     10      0   0             0       0  is_stmt prologue_end
-; STMT_SEQ-NEXT:  0x00000066: 05 DW_LNS_set_column (3)
-; STMT_SEQ-NEXT:  0x00000068: 9f address += 10,  line += 1,  op-index += 0
+; STMT_SEQ-NEXT:  0x00000068: 05 DW_LNS_set_column (3)
+; STMT_SEQ-NEXT:  0x0000006a: 9f address += 10,  line += 1,  op-index += 0
 ; STMT_SEQ-NEXT:              0x000000000000001a     12      3      0   0             0       0  is_stmt
-; STMT_SEQ-NEXT:  0x00000069: 02 DW_LNS_advance_pc (addr += 5, op-index += 0)
-; STMT_SEQ-NEXT:  0x0000006b: 00 DW_LNE_end_sequence
+; STMT_SEQ-NEXT:  0x0000006b: 02 DW_LNS_advance_pc (addr += 5, op-index += 0)
+; STMT_SEQ-NEXT:  0x0000006d: 00 DW_LNE_end_sequence
 ; STMT_SEQ-NEXT:              0x000000000000001f     12      3      0   0             0       0  is_stmt end_sequence
 
 ; generated from:
diff --git a/llvm/test/MC/ELF/debug-loc-label.s b/llvm/test/MC/ELF/debug-loc-label.s
index 6b5d04777bef4..4200b1192107b 100644
--- a/llvm/test/MC/ELF/debug-loc-label.s
+++ b/llvm/test/MC/ELF/debug-loc-label.s
@@ -17,43 +17,47 @@
 # CHECK-LINE-TABLE-NEXT: 0x0000002a: 00 DW_LNE_set_address (0x0000000000000000)
 # CHECK-LINE-TABLE-NEXT: 0x00000035: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000036: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000000      1      1      1   0             0       0  is_stmt end_sequence
-# CHECK-LINE-TABLE-NEXT: 0x00000039: 05 DW_LNS_set_column (2)
-# CHECK-LINE-TABLE-NEXT: 0x0000003b: 00 DW_LNE_set_address (0x0000000000000008)
-# CHECK-LINE-TABLE-NEXT: 0x00000046: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x00000036: 02 DW_LNS_advance_pc (addr += 8, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x00000038: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000008      1      1      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x0000003b: 05 DW_LNS_set_column (2)
+# CHECK-LINE-TABLE-NEXT: 0x0000003d: 00 DW_LNE_set_address (0x0000000000000008)
+# CHECK-LINE-TABLE-NEXT: 0x00000048: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000008      1      2      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000047: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000008      1      2      1   0             0       0  is_stmt end_sequence
-# CHECK-LINE-TABLE-NEXT: 0x0000004a: 05 DW_LNS_set_column (3)
-# CHECK-LINE-TABLE-NEXT: 0x0000004c: 00 DW_LNE_set_address (0x0000000000000010)
-# CHECK-LINE-TABLE-NEXT: 0x00000057: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x00000049: 02 DW_LNS_advance_pc (addr += 8, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x0000004b: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000010      1      2      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x0000004e: 05 DW_LNS_set_column (3)
+# CHECK-LINE-TABLE-NEXT: 0x00000050: 00 DW_LNE_set_address (0x0000000000000010)
+# CHECK-LINE-TABLE-NEXT: 0x0000005b: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000010      1      3      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000058: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000010      1      3      1   0             0       0  is_stmt end_sequence
-# CHECK-LINE-TABLE-NEXT: 0x0000005b: 05 DW_LNS_set_column (4)
-# CHECK-LINE-TABLE-NEXT: 0x0000005d: 00 DW_LNE_set_address (0x0000000000000018)
-# CHECK-LINE-TABLE-NEXT: 0x00000068: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x0000005c: 02 DW_LNS_advance_pc (addr += 8, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x0000005e: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      3      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x00000061: 05 DW_LNS_set_column (4)
+# CHECK-LINE-TABLE-NEXT: 0x00000063: 00 DW_LNE_set_address (0x0000000000000018)
+# CHECK-LINE-TABLE-NEXT: 0x0000006e: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      4      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000069: 05 DW_LNS_set_column (5)
-# CHECK-LINE-TABLE-NEXT: 0x0000006b: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x0000006f: 05 DW_LNS_set_column (5)
+# CHECK-LINE-TABLE-NEXT: 0x00000071: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      5      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x0000006c: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      5      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x00000072: 02 DW_LNS_advance_pc (addr += 8, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x00000074: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000020      1      5      1   0             0       0  is_stmt end_sequence
 
 # CHECK-SYM:      Symbol table '.symtab' contains 9 entries:
 # CHECK-SYM-NEXT:    Num:    Value          Size Type    Bind   Vis       Ndx Name
 # CHECK-SYM-NEXT:      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND
 # CHECK-SYM-NEXT:      1: 0000000000000000     0 FILE    LOCAL  DEFAULT   ABS test.c
 # CHECK-SYM-NEXT:      2: 0000000000000000     0 SECTION LOCAL  DEFAULT     2 .text
-# CHECK-SYM-NEXT:      3: 0000000000000039     0 NOTYPE  LOCAL  DEFAULT     3 my_label_02
-# CHECK-SYM-NEXT:      4: 000000000000004a     0 NOTYPE  LOCAL  DEFAULT     3 my_label_03
-# CHECK-SYM-NEXT:      5: 000000000000005b     0 NOTYPE  LOCAL  DEFAULT     3 my_label_04
-# CHECK-SYM-NEXT:      6: 000000000000004a     0 NOTYPE  LOCAL  DEFAULT     3 my_label_03.1
-# CHECK-SYM-NEXT:      7: 000000000000006f     0 NOTYPE  LOCAL  DEFAULT     3 my_label_05
+# CHECK-SYM-NEXT:      3: 000000000000003b     0 NOTYPE  LOCAL  DEFAULT     3 my_label_02
+# CHECK-SYM-NEXT:      4: 000000000000004e     0 NOTYPE  LOCAL  DEFAULT     3 my_label_03
+# CHECK-SYM-NEXT:      5: 0000000000000061     0 NOTYPE  LOCAL  DEFAULT     3 my_label_04
+# CHECK-SYM-NEXT:      6: 000000000000004e     0 NOTYPE  LOCAL  DEFAULT     3 my_label_03.1
+# CHECK-SYM-NEXT:      7: 0000000000000077     0 NOTYPE  LOCAL  DEFAULT     3 my_label_05
 # CHECK-SYM-NEXT:      8: 0000000000000000     0 FUNC    GLOBAL DEFAULT     2 foo
 
-# CHECK-OFFSETS: 0000 39000000 4a000000 5b000000
+# CHECK-OFFSETS: 0000 3b000000 4e000000 61000000
 
 	.text
 	.file	"test.c"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debuginfo llvm:mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants