[llvm] [MC] Add .loc_label instruction (PR #99710)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 1 12:59:03 PDT 2024


https://github.com/alx32 updated https://github.com/llvm/llvm-project/pull/99710

>From 33d3ac6051dea8334fbc703bf045dd6844d5bbb4 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Fri, 19 Jul 2024 14:24:35 -0700
Subject: [PATCH 1/4] [MC] Add .loc_label instruction

---
 llvm/include/llvm/MC/MCDwarf.h     | 10 +++-
 llvm/include/llvm/MC/MCStreamer.h  |  3 ++
 llvm/lib/MC/MCAsmStreamer.cpp      |  8 ++++
 llvm/lib/MC/MCDwarf.cpp            | 18 +++++++-
 llvm/lib/MC/MCParser/AsmParser.cpp | 20 +++++++-
 llvm/lib/MC/MCStreamer.cpp         | 19 ++++++++
 llvm/test/MC/ELF/debug-loc-label.s | 74 ++++++++++++++++++++++++++++++
 7 files changed, 148 insertions(+), 4 deletions(-)
 create mode 100644 llvm/test/MC/ELF/debug-loc-label.s

diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h
index 7dba67efa22fa..2d54d51b3eb85 100644
--- a/llvm/include/llvm/MC/MCDwarf.h
+++ b/llvm/include/llvm/MC/MCDwarf.h
@@ -194,11 +194,17 @@ class MCDwarfLineEntry : public MCDwarfLoc {
 
 public:
   // Constructor to create an MCDwarfLineEntry given a symbol and the dwarf loc.
-  MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc)
-      : MCDwarfLoc(loc), Label(label) {}
+  MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc,
+                   MCSymbol *lineStreamLabel = nullptr)
+      : MCDwarfLoc(loc), Label(label), LineStreamLabel(lineStreamLabel) {}
 
   MCSymbol *getLabel() const { return Label; }
 
+  // This is the label that is to be emitted into the line stream. If this is
+  // non-null and we need to emit a label, also make sure to restart the current
+  // line sequence.
+  MCSymbol *LineStreamLabel;
+
   // This indicates the line entry is synthesized for an end entry.
   bool IsEndEntry = false;
 
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 78aa12062102c..5fe4534d11d8e 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -912,6 +912,9 @@ class MCStreamer {
                                      unsigned Isa, unsigned Discriminator,
                                      StringRef FileName);
 
+  /// This implements the '.loc_label Name' directive.
+  virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name);
+
   /// Associate a filename with a specified logical file number, and also
   /// specify that file's checksum information.  This implements the '.cv_file 4
   /// "foo.c"' assembler directive. Returns true on success.
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 9309d5987dc94..36d7982d9a25d 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -301,6 +301,8 @@ class MCAsmStreamer final : public MCStreamer {
                              unsigned Flags, unsigned Isa,
                              unsigned Discriminator,
                              StringRef FileName) override;
+  virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) override;
+
   MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
 
   bool emitCVFileDirective(unsigned FileNo, StringRef Filename,
@@ -1767,6 +1769,12 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
                                           Discriminator, FileName);
 }
 
+void MCAsmStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
+  MCStreamer::emitDwarfLocLabelDirective(Loc, Name);
+  OS << "\t.loc_label " << Name;
+  EmitEOL();
+}
+
 MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
   // Always use the zeroth line table, since asm syntax only supports one line
   // table for now.
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 1297dc3828b58..889e5ca6cab76 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -172,6 +172,7 @@ void MCDwarfLineTable::emitOne(
     const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
 
   unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
+  bool IsAtStartSeq;
   MCSymbol *LastLabel;
   auto init = [&]() {
     FileNum = 1;
@@ -181,6 +182,7 @@ void MCDwarfLineTable::emitOne(
     Isa = 0;
     Discriminator = 0;
     LastLabel = nullptr;
+    IsAtStartSeq = true;
   };
   init();
 
@@ -189,11 +191,24 @@ void MCDwarfLineTable::emitOne(
   for (const MCDwarfLineEntry &LineEntry : LineEntries) {
     MCSymbol *Label = LineEntry.getLabel();
     const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
+
+    if (LineEntry.LineStreamLabel) {
+      if (!IsAtStartSeq) {
+        MCOS->emitDwarfLineEndEntry(Section, LastLabel);
+        init();
+      }
+      MCOS->emitLabel(LineEntry.LineStreamLabel);
+
+      IsAtStartSeq = true;
+      continue;
+    }
+
     if (LineEntry.IsEndEntry) {
       MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label,
                                      asmInfo->getCodePointerSize());
       init();
       EndEntryEmitted = true;
+      IsAtStartSeq = true;
       continue;
     }
 
@@ -243,6 +258,7 @@ void MCDwarfLineTable::emitOne(
     Discriminator = 0;
     LastLine = LineEntry.getLine();
     LastLabel = Label;
+    IsAtStartSeq = false;
   }
 
   // Generate DWARF line end entry.
@@ -250,7 +266,7 @@ void MCDwarfLineTable::emitOne(
   // table using ranges whenever CU or section changes. However, the MC path
   // 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)
+  if (!EndEntryEmitted && !IsAtStartSeq)
     MCOS->emitDwarfLineEndEntry(Section, LastLabel);
 }
 
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 1b9c624136e8b..50617a533ae56 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -485,6 +485,7 @@ class AsmParser : public MCAsmParser {
     DK_FILE,
     DK_LINE,
     DK_LOC,
+    DK_LOC_LABEL,
     DK_STABS,
     DK_CV_FILE,
     DK_CV_FUNC_ID,
@@ -580,10 +581,11 @@ class AsmParser : public MCAsmParser {
   // ".align{,32}", ".p2align{,w,l}"
   bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize);
 
-  // ".file", ".line", ".loc", ".stabs"
+  // ".file", ".line", ".loc", ".loc_label", ".stabs"
   bool parseDirectiveFile(SMLoc DirectiveLoc);
   bool parseDirectiveLine();
   bool parseDirectiveLoc();
+  bool parseDirectiveLocLabel(SMLoc DirectiveLoc);
   bool parseDirectiveStabs();
 
   // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable",
@@ -2156,6 +2158,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
       return parseDirectiveLine();
     case DK_LOC:
       return parseDirectiveLoc();
+    case DK_LOC_LABEL:
+      return parseDirectiveLocLabel(IDLoc);
     case DK_STABS:
       return parseDirectiveStabs();
     case DK_CV_FILE:
@@ -3733,6 +3737,19 @@ bool AsmParser::parseDirectiveLoc() {
   return false;
 }
 
+/// parseDirectiveLoc
+/// ::= .loc_label label
+bool AsmParser::parseDirectiveLocLabel(SMLoc DirectiveLoc) {
+  StringRef Name;
+  DirectiveLoc = Lexer.getLoc();
+  if (parseIdentifier(Name))
+    return TokError("expected identifier");
+  if (parseEOL())
+    return true;
+  getStreamer().emitDwarfLocLabelDirective(DirectiveLoc, Name);
+  return false;
+}
+
 /// parseDirectiveStabs
 /// ::= .stabs string, number, number, number
 bool AsmParser::parseDirectiveStabs() {
@@ -5541,6 +5558,7 @@ void AsmParser::initializeDirectiveKindMap() {
   DirectiveKindMap[".file"] = DK_FILE;
   DirectiveKindMap[".line"] = DK_LINE;
   DirectiveKindMap[".loc"] = DK_LOC;
+  DirectiveKindMap[".loc_label"] = DK_LOC_LABEL;
   DirectiveKindMap[".stabs"] = DK_STABS;
   DirectiveKindMap[".cv_file"] = DK_CV_FILE;
   DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID;
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 1594bd3231abe..d5f323129c4dd 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -267,6 +267,25 @@ void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
                                   Discriminator);
 }
 
+void MCStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
+  auto &ctx = getContext();
+
+  auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
+
+  auto *LineSym = ctx.createTempSymbol();
+  const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
+
+  // Create a 'fake' line entry by having LineStreamLabel be non-null. This
+  // won't actually emit any line information, it will reset the line table
+  // sequence and emit a label at the start of the new line table sequence.
+  MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel);
+
+  // Add the line entry to this section's entries.
+  ctx.getMCDwarfLineTable(ctx.getDwarfCompileUnitID())
+      .getMCLineSections()
+      .addLineEntry(LineEntry, getCurrentSectionOnly());
+}
+
 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
   MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
   if (!Table.getLabel()) {
diff --git a/llvm/test/MC/ELF/debug-loc-label.s b/llvm/test/MC/ELF/debug-loc-label.s
new file mode 100644
index 0000000000000..dabf470d417cc
--- /dev/null
+++ b/llvm/test/MC/ELF/debug-loc-label.s
@@ -0,0 +1,74 @@
+// Verify that the .loc_label instruction resets the line sequence and generates
+// the requested label at the correct position in the line stream
+
+// RUN: llvm-mc -filetype obj -triple x86_64-linux-elf %s -o %t.o
+// RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=CHECK-ASM
+// RUN: llvm-dwarfdump -v --debug-line %t.o | FileCheck %s --check-prefix=CHECK-LINE-TABLE
+
+# CHECK-ASM:        <foo>:
+# CHECK-ASM-NEXT:     movq    %rdx, 0x33
+# CHECK-ASM-NEXT:     movq    %rax, 0x3b
+# CHECK-ASM-NEXT:     movq    %rbx, 0x4e
+# CHECK-ASM-NEXT:     movq    %rcx, 0x60
+# CHECK-ASM-NEXT:     retq
+
+# 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: 02 DW_LNS_advance_pc (addr += 33, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x00000038: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000021      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: 0x00000049: 02 DW_LNS_advance_pc (addr += 25, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x0000004b: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000021      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: 0x0000005c: 08 DW_LNS_const_add_pc (addr += 0x0000000000000011, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x0000005d: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000021      1      3      1   0             0       0  is_stmt end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x00000060: 05 DW_LNS_set_column (4)
+# CHECK-LINE-TABLE-NEXT: 0x00000062: 00 DW_LNE_set_address (0x0000000000000018)
+# CHECK-LINE-TABLE-NEXT: 0x0000006d: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      4      1   0             0       0  is_stmt
+# CHECK-LINE-TABLE-NEXT: 0x0000006e: 05 DW_LNS_set_column (5)
+# CHECK-LINE-TABLE-NEXT: 0x00000070: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      5      1   0             0       0  is_stmt
+# CHECK-LINE-TABLE-NEXT: 0x00000071: 02 DW_LNS_advance_pc (addr += 9, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x00000073: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT:             0x0000000000000021      1      5      1   0             0       0  is_stmt end_sequence
+	.text
+	.file	"test.c"
+	.globl	foo
+	.align	16, 0x90
+	.type	foo, at function
+foo:
+.Lfunc_begin0:
+	.file	1 "test.c"
+	.cfi_startproc
+	.loc	1 1 1
+	mov     %rdx, 0x33
+	.loc_label my_label_02
+	.loc	1 1 2
+  movq    %rax, my_label_02-.Lline_table_start0
+	.loc	1 1 3
+	.loc_label my_label_03
+	.loc_label my_label_03.1
+  movq    %rbx, my_label_03-.Lline_table_start0
+	.loc	1 1 4
+	.loc_label my_label_05
+	.loc	1 1 5
+  movq    %rcx, my_label_05-.Lline_table_start0
+	ret
+	.cfi_endproc
+
+	.section	.debug_line,"", at progbits
+.Lline_table_start0:

>From 2977fbc9e7b33eb05ece309ef1f8cb753093cc6e Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Mon, 29 Jul 2024 11:22:38 -0700
Subject: [PATCH 2/4] Address Feedback Nr.1

---
 llvm/include/llvm/MC/MCDwarf.h     | 13 +++++++++--
 llvm/lib/MC/MCDwarf.cpp            | 19 ++++++++++++++-
 llvm/lib/MC/MCStreamer.cpp         | 19 +++------------
 llvm/test/MC/ELF/debug-loc-label.s | 37 ++++++++++++++++++++----------
 4 files changed, 57 insertions(+), 31 deletions(-)

diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h
index 2d54d51b3eb85..bea79545d1ab9 100644
--- a/llvm/include/llvm/MC/MCDwarf.h
+++ b/llvm/include/llvm/MC/MCDwarf.h
@@ -195,8 +195,10 @@ class MCDwarfLineEntry : public MCDwarfLoc {
 public:
   // Constructor to create an MCDwarfLineEntry given a symbol and the dwarf loc.
   MCDwarfLineEntry(MCSymbol *label, const MCDwarfLoc loc,
-                   MCSymbol *lineStreamLabel = nullptr)
-      : MCDwarfLoc(loc), Label(label), LineStreamLabel(lineStreamLabel) {}
+                   MCSymbol *lineStreamLabel = nullptr,
+                   SMLoc streamLabelDefLoc = {})
+      : MCDwarfLoc(loc), Label(label), LineStreamLabel(lineStreamLabel),
+        StreamLabelDefLoc(streamLabelDefLoc) {}
 
   MCSymbol *getLabel() const { return Label; }
 
@@ -205,6 +207,10 @@ class MCDwarfLineEntry : public MCDwarfLoc {
   // line sequence.
   MCSymbol *LineStreamLabel;
 
+  // Location where LineStreamLabel was defined. If there is an error emitting
+  // LineStreamLabel, we can use the SMLoc to report an error.
+  SMLoc StreamLabelDefLoc;
+
   // This indicates the line entry is synthesized for an end entry.
   bool IsEndEntry = false;
 
@@ -371,6 +377,9 @@ class MCDwarfLineTable {
   emitOne(MCStreamer *MCOS, MCSection *Section,
           const MCLineSection::MCDwarfLineEntryCollection &LineEntries);
 
+  void endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, SMLoc DefLoc,
+                                           StringRef Name);
+
   Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
                                 std::optional<MD5::MD5Result> Checksum,
                                 std::optional<StringRef> Source,
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 889e5ca6cab76..380475af8d1da 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -197,7 +197,7 @@ void MCDwarfLineTable::emitOne(
         MCOS->emitDwarfLineEndEntry(Section, LastLabel);
         init();
       }
-      MCOS->emitLabel(LineEntry.LineStreamLabel);
+      MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
 
       IsAtStartSeq = true;
       continue;
@@ -270,6 +270,23 @@ void MCDwarfLineTable::emitOne(
     MCOS->emitDwarfLineEndEntry(Section, LastLabel);
 }
 
+void MCDwarfLineTable::endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS,
+                                                           SMLoc DefLoc,
+                                                           StringRef Name) {
+  auto &ctx = MCOS->getContext();
+  auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
+  auto *LineSym = ctx.createTempSymbol();
+  const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
+
+  // Create a 'fake' line entry by having LineStreamLabel be non-null. This
+  // won't actually emit any line information, it will reset the line table
+  // sequence and emit a label at the start of the new line table sequence.
+  MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel, DefLoc);
+
+  // Add the line entry to this section's entries.
+  getMCLineSections().addLineEntry(LineEntry, MCOS->getCurrentSectionOnly());
+}
+
 //
 // This emits the Dwarf file and the line tables.
 //
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index d5f323129c4dd..13b162768578c 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -268,22 +268,9 @@ void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line,
 }
 
 void MCStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) {
-  auto &ctx = getContext();
-
-  auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
-
-  auto *LineSym = ctx.createTempSymbol();
-  const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
-
-  // Create a 'fake' line entry by having LineStreamLabel be non-null. This
-  // won't actually emit any line information, it will reset the line table
-  // sequence and emit a label at the start of the new line table sequence.
-  MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel);
-
-  // Add the line entry to this section's entries.
-  ctx.getMCDwarfLineTable(ctx.getDwarfCompileUnitID())
-      .getMCLineSections()
-      .addLineEntry(LineEntry, getCurrentSectionOnly());
+  getContext()
+      .getMCDwarfLineTable(getContext().getDwarfCompileUnitID())
+      .endCurrentSeqAndEmitLineStreamLabel(this, Loc, Name);
 }
 
 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
diff --git a/llvm/test/MC/ELF/debug-loc-label.s b/llvm/test/MC/ELF/debug-loc-label.s
index dabf470d417cc..b8a4e2d9463d2 100644
--- a/llvm/test/MC/ELF/debug-loc-label.s
+++ b/llvm/test/MC/ELF/debug-loc-label.s
@@ -2,15 +2,10 @@
 // the requested label at the correct position in the line stream
 
 // RUN: llvm-mc -filetype obj -triple x86_64-linux-elf %s -o %t.o
-// RUN: llvm-objdump -d %t.o | FileCheck %s --check-prefix=CHECK-ASM
 // RUN: llvm-dwarfdump -v --debug-line %t.o | FileCheck %s --check-prefix=CHECK-LINE-TABLE
+// RUN: llvm-objdump -s -j .offset_02 -j .offset_03 -j .offset_05 %t.o | FileCheck %s --check-prefix=CHECK-SECTIONS
+
 
-# CHECK-ASM:        <foo>:
-# CHECK-ASM-NEXT:     movq    %rdx, 0x33
-# CHECK-ASM-NEXT:     movq    %rax, 0x3b
-# CHECK-ASM-NEXT:     movq    %rbx, 0x4e
-# CHECK-ASM-NEXT:     movq    %rcx, 0x60
-# CHECK-ASM-NEXT:     retq
 
 # CHECK-LINE-TABLE:                  Address            Line   Column File   ISA Discriminator OpIndex Flags
 # CHECK-LINE-TABLE-NEXT:             ------------------ ------ ------ ------ --- ------------- ------- -------------
@@ -45,6 +40,15 @@
 # CHECK-LINE-TABLE-NEXT: 0x00000071: 02 DW_LNS_advance_pc (addr += 9, op-index += 0)
 # CHECK-LINE-TABLE-NEXT: 0x00000073: 00 DW_LNE_end_sequence
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000021      1      5      1   0             0       0  is_stmt end_sequence
+
+# CHECK-SECTIONS: Contents of section .offset_02:
+# CHECK-SECTIONS-NEXT: 0000 3b000000
+
+# CHECK-SECTIONS: Contents of section .offset_03:
+# CHECK-SECTIONS-NEXT: 0000 4e000000
+
+# CHECK-SECTIONS: Contents of section .offset_05:
+# CHECK-SECTIONS-NEXT: 0000 60000000
 	.text
 	.file	"test.c"
 	.globl	foo
@@ -55,20 +59,29 @@ foo:
 	.file	1 "test.c"
 	.cfi_startproc
 	.loc	1 1 1
-	mov     %rdx, 0x33
+	mov     %rax, 0x01
 	.loc_label my_label_02
 	.loc	1 1 2
-  movq    %rax, my_label_02-.Lline_table_start0
+	mov     %rax, 0x02
 	.loc	1 1 3
 	.loc_label my_label_03
 	.loc_label my_label_03.1
-  movq    %rbx, my_label_03-.Lline_table_start0
+	mov     %rax, 0x03
 	.loc	1 1 4
-	.loc_label my_label_05
+	.loc_label my_label_04
 	.loc	1 1 5
-  movq    %rcx, my_label_05-.Lline_table_start0
+	mov     %rax, 0x04
 	ret
 	.cfi_endproc
 
 	.section	.debug_line,"", at progbits
 .Lline_table_start0:
+
+	.section	.offset_02,"", at progbits
+	.quad	my_label_02-.Lline_table_start0
+
+	.section	.offset_03,"", at progbits
+	.quad	my_label_03-.Lline_table_start0
+
+	.section	.offset_05,"", at progbits
+	.quad	my_label_04-.Lline_table_start0

>From e1fbb1fad8a3f8ddf6d876af6bc8f0789f685169 Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Mon, 29 Jul 2024 12:57:06 -0700
Subject: [PATCH 3/4] Address Feedback Nr.2

---
 llvm/lib/MC/MCDwarf.cpp | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 380475af8d1da..19410cbeb4ca7 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -198,8 +198,6 @@ void MCDwarfLineTable::emitOne(
         init();
       }
       MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
-
-      IsAtStartSeq = true;
       continue;
     }
 
@@ -208,7 +206,6 @@ void MCDwarfLineTable::emitOne(
                                      asmInfo->getCodePointerSize());
       init();
       EndEntryEmitted = true;
-      IsAtStartSeq = true;
       continue;
     }
 

>From bf20a0c14fd5cdeba4e63028b2e56839f6c7d8be Mon Sep 17 00:00:00 2001
From: Alex B <alexborcan at meta.com>
Date: Thu, 1 Aug 2024 12:58:06 -0700
Subject: [PATCH 4/4] Correctly set end for end_sequence line entry

---
 llvm/include/llvm/MC/MCObjectStreamer.h |  3 +-
 llvm/include/llvm/MC/MCStreamer.h       |  3 +-
 llvm/lib/MC/MCAsmStreamer.cpp           | 11 +++---
 llvm/lib/MC/MCDwarf.cpp                 |  4 ++-
 llvm/lib/MC/MCObjectStreamer.cpp        |  8 +++--
 llvm/test/MC/ELF/debug-loc-label.s      | 47 ++++++++++++-------------
 6 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h
index 4241ec1e1881b..aaa13be6b2986 100644
--- a/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -146,7 +146,8 @@ class MCObjectStreamer : public MCStreamer {
   void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
                                 const MCSymbol *Label,
                                 unsigned PointerSize) override;
-  void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
+  void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel,
+                             MCSymbol *EndLabel = nullptr) override;
   void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
                                  const MCSymbol *Label, SMLoc Loc);
   void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h
index 5fe4534d11d8e..24302822872de 100644
--- a/llvm/include/llvm/MC/MCStreamer.h
+++ b/llvm/include/llvm/MC/MCStreamer.h
@@ -1122,7 +1122,8 @@ class MCStreamer {
   virtual void emitDwarfLineStartLabel(MCSymbol *StartSym);
 
   /// Emit the debug line end entry.
-  virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) {}
+  virtual void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel,
+                                     MCSymbol *EndLabel = nullptr) {}
 
   /// If targets does not support representing debug line section by .loc/.file
   /// directives in assembly output, we need to populate debug line section with
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 36d7982d9a25d..351b759c528f4 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -431,7 +431,8 @@ class MCAsmStreamer final : public MCStreamer {
 
   void emitDwarfLineStartLabel(MCSymbol *StartSym) override;
 
-  void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
+  void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel,
+                             MCSymbol *EndLabel = nullptr) override;
 
   void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
                                 const MCSymbol *Label,
@@ -2587,7 +2588,8 @@ void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) {
 }
 
 void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
-                                          MCSymbol *LastLabel) {
+                                          MCSymbol *LastLabel,
+                                          MCSymbol *EndLabel) {
   // If the targets write the raw debug line data for assembly output (We can
   // not switch to Section and add the end symbol there for assembly output)
   // we currently use the .text end label as any section end. This will not
@@ -2604,9 +2606,10 @@ void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section,
   MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection();
   assert(TextSection->hasEnded() && ".text section is not end!");
 
-  MCSymbol *SectionEnd = TextSection->getEndSymbol(Ctx);
+  if (!EndLabel)
+    EndLabel = TextSection->getEndSymbol(Ctx);
   const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
-  emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
+  emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel,
                            AsmInfo->getCodePointerSize());
 }
 
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 19410cbeb4ca7..20b3c00a38372 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -194,7 +194,8 @@ void MCDwarfLineTable::emitOne(
 
     if (LineEntry.LineStreamLabel) {
       if (!IsAtStartSeq) {
-        MCOS->emitDwarfLineEndEntry(Section, LastLabel);
+        MCOS->emitDwarfLineEndEntry(Section, LastLabel,
+                                    /*EndLabel =*/LastLabel);
         init();
       }
       MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc);
@@ -273,6 +274,7 @@ void MCDwarfLineTable::endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS,
   auto &ctx = MCOS->getContext();
   auto *LineStreamLabel = ctx.getOrCreateSymbol(Name);
   auto *LineSym = ctx.createTempSymbol();
+  MCOS->emitLabel(LineSym);
   const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc();
 
   // Create a 'fake' line entry by having LineStreamLabel be non-null. This
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 9dc3974fd8f0d..5ddb75cc7ce9b 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -467,12 +467,14 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta,
 }
 
 void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
-                                             MCSymbol *LastLabel) {
+                                             MCSymbol *LastLabel,
+                                             MCSymbol *EndLabel) {
   // Emit a DW_LNE_end_sequence for the end of the section.
   // Use the section end label to compute the address delta and use INT64_MAX
   // as the line delta which is the signal that this is actually a
   // DW_LNE_end_sequence.
-  MCSymbol *SectionEnd = endSection(Section);
+  if (!EndLabel)
+    EndLabel = endSection(Section);
 
   // Switch back the dwarf line section, in case endSection had to switch the
   // section.
@@ -480,7 +482,7 @@ void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section,
   switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
 
   const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
-  emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
+  emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel,
                            AsmInfo->getCodePointerSize());
 }
 
diff --git a/llvm/test/MC/ELF/debug-loc-label.s b/llvm/test/MC/ELF/debug-loc-label.s
index b8a4e2d9463d2..14f73b19939c6 100644
--- a/llvm/test/MC/ELF/debug-loc-label.s
+++ b/llvm/test/MC/ELF/debug-loc-label.s
@@ -13,42 +13,39 @@
 # 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: 02 DW_LNS_advance_pc (addr += 33, op-index += 0)
-# CHECK-LINE-TABLE-NEXT: 0x00000038: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000021      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: 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:             0x0000000000000008      1      2      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000049: 02 DW_LNS_advance_pc (addr += 25, op-index += 0)
-# CHECK-LINE-TABLE-NEXT: 0x0000004b: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000021      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: 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:             0x0000000000000010      1      3      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x0000005c: 08 DW_LNS_const_add_pc (addr += 0x0000000000000011, op-index += 0)
-# CHECK-LINE-TABLE-NEXT: 0x0000005d: 00 DW_LNE_end_sequence
-# CHECK-LINE-TABLE-NEXT:             0x0000000000000021      1      3      1   0             0       0  is_stmt end_sequence
-# CHECK-LINE-TABLE-NEXT: 0x00000060: 05 DW_LNS_set_column (4)
-# CHECK-LINE-TABLE-NEXT: 0x00000062: 00 DW_LNE_set_address (0x0000000000000018)
-# CHECK-LINE-TABLE-NEXT: 0x0000006d: 01 DW_LNS_copy
+# 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:             0x0000000000000018      1      4      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x0000006e: 05 DW_LNS_set_column (5)
-# CHECK-LINE-TABLE-NEXT: 0x00000070: 01 DW_LNS_copy
+# CHECK-LINE-TABLE-NEXT: 0x00000069: 05 DW_LNS_set_column (5)
+# CHECK-LINE-TABLE-NEXT: 0x0000006b: 01 DW_LNS_copy
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000018      1      5      1   0             0       0  is_stmt
-# CHECK-LINE-TABLE-NEXT: 0x00000071: 02 DW_LNS_advance_pc (addr += 9, op-index += 0)
-# CHECK-LINE-TABLE-NEXT: 0x00000073: 00 DW_LNE_end_sequence
+# CHECK-LINE-TABLE-NEXT: 0x0000006c: 02 DW_LNS_advance_pc (addr += 9, op-index += 0)
+# CHECK-LINE-TABLE-NEXT: 0x0000006e: 00 DW_LNE_end_sequence
 # CHECK-LINE-TABLE-NEXT:             0x0000000000000021      1      5      1   0             0       0  is_stmt end_sequence
 
 # CHECK-SECTIONS: Contents of section .offset_02:
-# CHECK-SECTIONS-NEXT: 0000 3b000000
+# CHECK-SECTIONS-NEXT: 0000 39000000
 
 # CHECK-SECTIONS: Contents of section .offset_03:
-# CHECK-SECTIONS-NEXT: 0000 4e000000
+# CHECK-SECTIONS-NEXT: 0000 4a000000
 
 # CHECK-SECTIONS: Contents of section .offset_05:
-# CHECK-SECTIONS-NEXT: 0000 60000000
+# CHECK-SECTIONS-NEXT: 0000 5b000000
 	.text
 	.file	"test.c"
 	.globl	foo



More information about the llvm-commits mailing list