[llvm] [dsymutil] Add support for inline DWARF source files. (PR #77016)

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 4 14:32:47 PST 2024


https://github.com/adrian-prantl created https://github.com/llvm/llvm-project/pull/77016

There was a strange and seemingly unncessary empty string optimization in NonRelocatableStringPool that I had to remove in order to support empty strings in the line_str string table, without unconditionally forcing an empty string to be added to every debug_line_str table.

>From 6fca3aafa3699b2551e60c2b958d5a271f69b000 Mon Sep 17 00:00:00 2001
From: Adrian Prantl <aprantl at apple.com>
Date: Thu, 4 Jan 2024 14:29:48 -0800
Subject: [PATCH] [dsymutil] Add support for inline DWARF source files.

There was a strange and seemingly unncessary empty string optimization
in NonRelocatableStringPool that I had to remove in order to support
empty strings in the line_str string table, without unconditionally
forcing an empty string to be added to every debug_line_str table.
---
 .../llvm/CodeGen/NonRelocatableStringpool.h   |  3 +-
 llvm/lib/CodeGen/NonRelocatableStringpool.cpp |  3 --
 llvm/lib/DWARFLinker/DWARFStreamer.cpp        | 14 +++++++-
 .../tools/dsymutil/ARM/inline-source.test     | 20 +++++++++++
 llvm/test/tools/dsymutil/Inputs/inline.ll     | 34 +++++++++++++++++++
 5 files changed, 68 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/tools/dsymutil/ARM/inline-source.test
 create mode 100644 llvm/test/tools/dsymutil/Inputs/inline.ll

diff --git a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h
index fe07c70d85c597..3dc0731f5a04ee 100644
--- a/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h
+++ b/llvm/include/llvm/CodeGen/NonRelocatableStringpool.h
@@ -32,7 +32,7 @@ class NonRelocatableStringpool {
       bool PutEmptyString = false)
       : Translator(Translator) {
     if (PutEmptyString)
-      EmptyString = getEntry("");
+      getEntry("");
   }
 
   DwarfStringPoolEntryRef getEntry(StringRef S);
@@ -59,7 +59,6 @@ class NonRelocatableStringpool {
   MapTy Strings;
   uint64_t CurrentEndOffset = 0;
   unsigned NumEntries = 0;
-  DwarfStringPoolEntryRef EmptyString;
   std::function<StringRef(StringRef Input)> Translator;
 };
 
diff --git a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp
index 7304bfef55cb7a..e8391afb8e3f8d 100644
--- a/llvm/lib/CodeGen/NonRelocatableStringpool.cpp
+++ b/llvm/lib/CodeGen/NonRelocatableStringpool.cpp
@@ -12,9 +12,6 @@
 namespace llvm {
 
 DwarfStringPoolEntryRef NonRelocatableStringpool::getEntry(StringRef S) {
-  if (S.empty() && !Strings.empty())
-    return EmptyString;
-
   if (Translator)
     S = Translator(S);
   auto I = Strings.insert({S, DwarfStringPoolEntry()});
diff --git a/llvm/lib/DWARFLinker/DWARFStreamer.cpp b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
index cd649c328ed930..a7270ece11659b 100644
--- a/llvm/lib/DWARFLinker/DWARFStreamer.cpp
+++ b/llvm/lib/DWARFLinker/DWARFStreamer.cpp
@@ -859,13 +859,19 @@ void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
   for (auto Include : P.IncludeDirectories)
     emitLineTableString(P, Include, DebugStrPool, DebugLineStrPool);
 
+  bool InlineSources =
+      std::any_of(P.FileNames.begin(), P.FileNames.end(), [](auto File) {
+        auto s = dwarf::toString(File.Source);
+        return s && **s;
+      });
+
   if (P.FileNames.empty()) {
     // file_name_entry_format_count (ubyte).
     MS->emitInt8(0);
     LineSectionSize += 1;
   } else {
     // file_name_entry_format_count (ubyte).
-    MS->emitInt8(2);
+    MS->emitInt8(2 + (InlineSources ? 1 : 0));
     LineSectionSize += 1;
 
     // file_name_entry_format (sequence of ULEB128 pairs).
@@ -874,6 +880,10 @@ void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
 
     LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_directory_index);
     LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_FORM_data1);
+    if (InlineSources) {
+      LineSectionSize += MS->emitULEB128IntValue(dwarf::DW_LNCT_LLVM_source);
+      LineSectionSize += MS->emitULEB128IntValue(P.FileNames[0].Name.getForm());
+    }
   }
 
   // file_names_count (ULEB128).
@@ -884,6 +894,8 @@ void DwarfStreamer::emitLineTablePrologueV5IncludeAndFileTable(
     emitLineTableString(P, File.Name, DebugStrPool, DebugLineStrPool);
     MS->emitInt8(File.DirIdx);
     LineSectionSize += 1;
+    if (InlineSources)
+      emitLineTableString(P, File.Source, DebugStrPool, DebugLineStrPool);
   }
 }
 
diff --git a/llvm/test/tools/dsymutil/ARM/inline-source.test b/llvm/test/tools/dsymutil/ARM/inline-source.test
new file mode 100644
index 00000000000000..ec437e3de9008c
--- /dev/null
+++ b/llvm/test/tools/dsymutil/ARM/inline-source.test
@@ -0,0 +1,20 @@
+# RUN: rm -rf %t
+# RUN: mkdir -p %t
+# RUN: llc -filetype=obj -mtriple arm64-apple-darwin %p/../Inputs/inline.ll -o %t/inline.o
+# RUN: dsymutil -f -oso-prepend-path=%t -y %s -o - | llvm-dwarfdump -debug-line - | FileCheck %s
+
+# Test inline source files.
+
+---
+triple:          'arm64-apple-darwin'
+objects:
+  - filename: inline.o
+    symbols:
+      - { sym: _f, objAddr: 0x0, binAddr: 0x1000, size: 0x12 }
+...
+
+# CHECK: .debug_line contents:
+# CHECK: file_names[  1]:
+# CHECK-NEXT: name: "inlined.c"
+# CHECK-NEXT: dir_index: 1
+# CHECK-NEXT: source: "{{.*}}This is inline source code.
\ No newline at end of file
diff --git a/llvm/test/tools/dsymutil/Inputs/inline.ll b/llvm/test/tools/dsymutil/Inputs/inline.ll
new file mode 100644
index 00000000000000..e7c9b7096ee5bf
--- /dev/null
+++ b/llvm/test/tools/dsymutil/Inputs/inline.ll
@@ -0,0 +1,34 @@
+; ModuleID = '/tmp/t.c'
+source_filename = "/tmp/t.c"
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
+define void @f() #0 !dbg !9 {
+entry:
+  ret void, !dbg !14
+}
+
+attributes #0 = { noinline nounwind optnone ssp uwtable(sync) }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}
+!llvm.ident = !{!8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 18.0.0git (git at github.com:llvm/llvm-project.git 29ee66f4a0967e43a035f147c960743c7b640f2f)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
+!1 = !DIFile(filename: "/INLINE/inlined.c", directory: "/Volumes/Data/llvm-project", checksumkind: CSK_MD5, checksum: "3183154a5cb31debe9a8e27ca500bc3c")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 8, !"PIC Level", i32 2}
+!6 = !{i32 7, !"uwtable", i32 1}
+!7 = !{i32 7, !"frame-pointer", i32 1}
+!8 = !{!"clang version 18.0.0git (git at github.com:llvm/llvm-project.git 29ee66f4a0967e43a035f147c960743c7b640f2f)"}
+!9 = distinct !DISubprogram(name: "f", scope: !10, file: !10, line: 2, type: !11, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !0)
+!10 = !DIFile(filename: "/INLINE/inlined.c", directory: "", source: "void stop();
+void f() {
+  // This is inline source code.
+}
+")
+!11 = !DISubroutineType(types: !12)
+!12 = !{null}
+!14 = !DILocation(line: 4, column: 1, scope: !9)



More information about the llvm-commits mailing list