[llvm] [MC] Fix DWARF file table for files with empty DWARF (PR #119572)

Aleksei Vetrov via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 12 06:10:37 PST 2024


https://github.com/noxwell updated https://github.com/llvm/llvm-project/pull/119572

>From c370f9789708800a3e8671900899fa71d28f163e Mon Sep 17 00:00:00 2001
From: Aleksei Vetrov <vetaleha at gmail.com>
Date: Mon, 9 Dec 2024 15:04:07 +0000
Subject: [PATCH] [MC] Fix DWARF file table for files with empty DWARF
 (#119020)

Update root file in DWARF file/line table as soon as we see the first
"#line" directive.

This was moved from "enabledGenDwarfForAssembly", which is called right
before we emit DWARF information. But if the file is empty or contains
expressions that doesn't need DWARF, it is never called, leaving an
original root file and not the file in the "#line" directive.

Add a test checking for this case.

This is reapply of #119229 with the following fix:

"MCContext::setMCLineTableRootFile" has the effect of adding
".debug_line" section to the output, even if DWARF generation is
disabled. Add a check and a test for this case.

Fixes: #119020
Fixes: #119229
---
 llvm/lib/MC/MCParser/AsmParser.cpp            | 26 ++++++++++++-------
 .../test/MC/ELF/debug-hash-file-empty-dwarf.s | 26 +++++++++++++++++++
 llvm/test/MC/ELF/debug-hash-file.s            |  6 +++++
 3 files changed, 48 insertions(+), 10 deletions(-)
 create mode 100644 llvm/test/MC/ELF/debug-hash-file-empty-dwarf.s

diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index d15a9a8a36c5a3..153c1070a68c82 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -162,8 +162,8 @@ class AsmParser : public MCAsmParser {
   };
   CppHashInfoTy CppHashInfo;
 
-  /// The filename from the first cpp hash file line comment, if any.
-  StringRef FirstCppHashFilename;
+  /// Have we seen any file line comment.
+  bool HadCppHashFilename = false;
 
   /// List of forward directional labels for diagnosis at the end.
   SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels;
@@ -952,12 +952,6 @@ bool AsmParser::enabledGenDwarfForAssembly() {
   // the assembler source was produced with debug info already) then emit one
   // describing the assembler source file itself.
   if (getContext().getGenDwarfFileNumber() == 0) {
-    // Use the first #line directive for this, if any. It's preprocessed, so
-    // there is no checksum, and of course no source directive.
-    if (!FirstCppHashFilename.empty())
-      getContext().setMCLineTableRootFile(
-          /*CUID=*/0, getContext().getCompilationDir(), FirstCppHashFilename,
-          /*Cksum=*/std::nullopt, /*Source=*/std::nullopt);
     const MCDwarfFile &RootFile =
         getContext().getMCDwarfLineTable(/*CUID=*/0).getRootFile();
     getContext().setGenDwarfFileNumber(getStreamer().emitDwarfFileDirective(
@@ -2440,8 +2434,20 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L, bool SaveLocInfo) {
   CppHashInfo.Filename = Filename;
   CppHashInfo.LineNumber = LineNumber;
   CppHashInfo.Buf = CurBuffer;
-  if (FirstCppHashFilename.empty())
-    FirstCppHashFilename = Filename;
+  if (!HadCppHashFilename) {
+    HadCppHashFilename = true;
+    // If we haven't encountered any .file directives, then the first #line
+    // directive describes the "root" file and directory of the compilation
+    // unit.
+    if (getContext().getGenDwarfForAssembly() &&
+        getContext().getGenDwarfFileNumber() == 0) {
+      // It's preprocessed, so there is no checksum, and of course no source
+      // directive.
+      getContext().setMCLineTableRootFile(
+          /*CUID=*/0, getContext().getCompilationDir(), Filename,
+          /*Cksum=*/std::nullopt, /*Source=*/std::nullopt);
+    }
+  }
   return false;
 }
 
diff --git a/llvm/test/MC/ELF/debug-hash-file-empty-dwarf.s b/llvm/test/MC/ELF/debug-hash-file-empty-dwarf.s
new file mode 100644
index 00000000000000..cc1c3d1796b6e2
--- /dev/null
+++ b/llvm/test/MC/ELF/debug-hash-file-empty-dwarf.s
@@ -0,0 +1,26 @@
+// RUN: llvm-mc -triple x86_64-unknown-linux-gnu -filetype obj -g -dwarf-version 5 -o %t %s
+// RUN: llvm-dwarfdump -debug-info -debug-line %t | FileCheck %s
+
+// CHECK-NOT: DW_TAG_
+
+// CHECK:      include_directories[ 0] =
+// CHECK-NOT:  include_directories[ 1] =
+// CHECK:      file_names[ 0]:
+// CHECK-NEXT:           name: "/MyTest/Inputs/other.S"
+// CHECK-NEXT:      dir_index: 0
+// CHECK-NOT:  file_names[ 1]:
+
+// RUN: llvm-mc -triple=x86_64 -filetype=obj -g -dwarf-version=5 -fdebug-prefix-map=/MyTest=/src_root %s -o %t.5.o
+// RUN: llvm-dwarfdump -debug-info -debug-line %t.5.o | FileCheck %s --check-prefixes=MAP
+
+// MAP-NOT: DW_TAG_
+
+// MAP:      include_directories[  0] = "{{.*}}"
+// MAP-NEXT: file_names[  0]:
+// MAP-NEXT:            name: "/src_root/Inputs/other.S"
+// MAP-NEXT:       dir_index: 0
+
+# 1 "/MyTest/Inputs/other.S"
+
+.section .data
+.asciz "data"
diff --git a/llvm/test/MC/ELF/debug-hash-file.s b/llvm/test/MC/ELF/debug-hash-file.s
index 99e3d6dca9bbae..508813abcacd50 100644
--- a/llvm/test/MC/ELF/debug-hash-file.s
+++ b/llvm/test/MC/ELF/debug-hash-file.s
@@ -43,6 +43,12 @@
 // MAP_V5-NEXT:            name: "/src_root/Inputs/other.S"
 // MAP_V5-NEXT:       dir_index: 0
 
+// RUN: llvm-mc -triple x86_64-unknown-linux-gnu -filetype obj -o %t %s
+// RUN: llvm-readelf --sections %t | FileCheck %s --check-prefix=CHECK-NO-DEBUG
+
+// CHECK-NO-DEBUG: Section Headers:
+// CHECK-NO-DEBUG-NOT: .debug_
+
 # 1 "/MyTest/Inputs/other.S"
 
 foo:



More information about the llvm-commits mailing list