[llvm] e2f3240 - [DebugInfo] Allow GNU macro extension to be emitted

David Stenberg via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 08:00:54 PDT 2020


Author: David Stenberg
Date: 2020-08-11T17:00:25+02:00
New Revision: e2f32404727f891fea309f8457d87b1c306e3fcc

URL: https://github.com/llvm/llvm-project/commit/e2f32404727f891fea309f8457d87b1c306e3fcc
DIFF: https://github.com/llvm/llvm-project/commit/e2f32404727f891fea309f8457d87b1c306e3fcc.diff

LOG: [DebugInfo] Allow GNU macro extension to be emitted

Allow the GNU .debug_macro extension to be emitted for DWARF versions
earlier than 5. The extension is basically what became DWARF 5's format,
except that a DW_AT_GNU_macros attribute is emitted, and some entries
like the strx entries are missing. In this patch I emit GNU's indirect
entries, which are the same as DWARF 5's strp entries.

This patch adds the extension behind a hidden LLVM flag,
-use-gnu-debug-macro. I would later want to enable it by default when
tuning for GDB and targeting DWARF versions earlier than 5.

The size of a Clang 8.0 binary built with RelWithDebInfo and the flags
"-gdwarf-4 -fdebug-macro" reduces from 1533 MB to 1349 MB with
.debug_macro (compared to 1296 MB without -fdebug-macro).

Reviewed By: SouraVX, dblaikie

Differential Revision: https://reviews.llvm.org/D82975

Added: 
    llvm/test/DebugInfo/X86/debug-macro-gnu-dwo.ll
    llvm/test/DebugInfo/X86/debug-macro-gnu.ll

Modified: 
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 3fb47948b4dc..f438dff27083 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -147,6 +147,11 @@ static cl::opt<DefaultOnOff> DwarfSectionsAsReferences(
                clEnumVal(Enable, "Enabled"), clEnumVal(Disable, "Disabled")),
     cl::init(Default));
 
+static cl::opt<bool>
+    UseGNUDebugMacro("use-gnu-debug-macro", cl::Hidden,
+                     cl::desc("Emit the GNU .debug_macro format with DWARF <5"),
+                     cl::init(false));
+
 enum LinkageNameOption {
   DefaultLinkageNames,
   AllLinkageNames,
@@ -428,7 +433,10 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
   // the debug entry values feature. It can also be enabled explicitly.
   EmitDebugEntryValues = Asm->TM.Options.ShouldEmitDebugEntryValues();
 
-  UseDebugMacroSection = DwarfVersion >= 5;
+  // It is unclear if the GCC .debug_macro extension is well-specified
+  // for split DWARF. For now, do not allow LLVM to emit it.
+  UseDebugMacroSection =
+      DwarfVersion >= 5 || (UseGNUDebugMacro && !useSplitDwarf());
 
   Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
 }
@@ -1353,10 +1361,13 @@ void DwarfDebug::finalizeModuleInfo() {
           TheCU.addSectionDelta(
               TheCU.getUnitDie(), dwarf::DW_AT_macros, U.getMacroLabelBegin(),
               TLOF.getDwarfMacroDWOSection()->getBeginSymbol());
-        else
-          U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macros,
-                            U.getMacroLabelBegin(),
+        else {
+          dwarf::Attribute MacrosAttr = getDwarfVersion() >= 5
+                                            ? dwarf::DW_AT_macros
+                                            : dwarf::DW_AT_GNU_macros;
+          U.addSectionLabel(U.getUnitDie(), MacrosAttr, U.getMacroLabelBegin(),
                             TLOF.getDwarfMacroSection()->getBeginSymbol());
+        }
       } else {
         if (useSplitDwarf())
           TheCU.addSectionDelta(
@@ -2980,16 +2991,17 @@ void DwarfDebug::emitDebugRangesDWO() {
                       Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
 }
 
-/// Emit the header of a DWARF 5 macro section.
+/// Emit the header of a DWARF 5 macro section, or the GNU extension for
+/// DWARF 4.
 static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD,
-                            const DwarfCompileUnit &CU) {
+                            const DwarfCompileUnit &CU, uint16_t DwarfVersion) {
   enum HeaderFlagMask {
 #define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
 #include "llvm/BinaryFormat/Dwarf.def"
   };
   uint8_t Flags = 0;
   Asm->OutStreamer->AddComment("Macro information version");
-  Asm->emitInt16(5);
+  Asm->emitInt16(DwarfVersion >= 5 ? DwarfVersion : 4);
   // We are setting Offset and line offset flags unconditionally here,
   // since we're only supporting DWARF32 and line offset should be mostly
   // present.
@@ -3024,16 +3036,31 @@ void DwarfDebug::emitMacro(DIMacro &M) {
   std::string Str = Value.empty() ? Name.str() : (Name + " " + Value).str();
 
   if (UseDebugMacroSection) {
-    unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
-                        ? dwarf::DW_MACRO_define_strx
-                        : dwarf::DW_MACRO_undef_strx;
-    Asm->OutStreamer->AddComment(dwarf::MacroString(Type));
-    Asm->emitULEB128(Type);
-    Asm->OutStreamer->AddComment("Line Number");
-    Asm->emitULEB128(M.getLine());
-    Asm->OutStreamer->AddComment("Macro String");
-    Asm->emitULEB128(
-        InfoHolder.getStringPool().getIndexedEntry(*Asm, Str).getIndex());
+    if (getDwarfVersion() >= 5) {
+      unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
+                          ? dwarf::DW_MACRO_define_strx
+                          : dwarf::DW_MACRO_undef_strx;
+      Asm->OutStreamer->AddComment(dwarf::MacroString(Type));
+      Asm->emitULEB128(Type);
+      Asm->OutStreamer->AddComment("Line Number");
+      Asm->emitULEB128(M.getLine());
+      Asm->OutStreamer->AddComment("Macro String");
+      Asm->emitULEB128(
+          InfoHolder.getStringPool().getIndexedEntry(*Asm, Str).getIndex());
+    } else {
+      unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
+                          ? dwarf::DW_MACRO_GNU_define_indirect
+                          : dwarf::DW_MACRO_GNU_undef_indirect;
+      Asm->OutStreamer->AddComment(dwarf::GnuMacroString(Type));
+      Asm->emitULEB128(Type);
+      Asm->OutStreamer->AddComment("Line Number");
+      Asm->emitULEB128(M.getLine());
+      Asm->OutStreamer->AddComment("Macro String");
+      // FIXME: Add support for DWARF64.
+      Asm->OutStreamer->emitSymbolValue(
+          InfoHolder.getStringPool().getEntry(*Asm, Str).getSymbol(),
+          /*Size=*/4);
+    }
   } else {
     Asm->OutStreamer->AddComment(dwarf::MacinfoString(M.getMacinfoType()));
     Asm->emitULEB128(M.getMacinfoType());
@@ -3071,8 +3098,9 @@ void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) {
   // so for readibility/uniformity, We are explicitly emitting those.
   assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file);
   if (UseDebugMacroSection)
-    emitMacroFileImpl(F, U, dwarf::DW_MACRO_start_file,
-                      dwarf::DW_MACRO_end_file, dwarf::MacroString);
+    emitMacroFileImpl(
+        F, U, dwarf::DW_MACRO_start_file, dwarf::DW_MACRO_end_file,
+        (getDwarfVersion() >= 5) ? dwarf::MacroString : dwarf::GnuMacroString);
   else
     emitMacroFileImpl(F, U, dwarf::DW_MACINFO_start_file,
                       dwarf::DW_MACINFO_end_file, dwarf::MacinfoString);
@@ -3090,7 +3118,7 @@ void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
     Asm->OutStreamer->SwitchSection(Section);
     Asm->OutStreamer->emitLabel(U.getMacroLabelBegin());
     if (UseDebugMacroSection)
-      emitMacroHeader(Asm, *this, U);
+      emitMacroHeader(Asm, *this, U, getDwarfVersion());
     handleMacroNodes(Macros, U);
     Asm->OutStreamer->AddComment("End Of Macro List Mark");
     Asm->emitInt8(0);

diff  --git a/llvm/test/DebugInfo/X86/debug-macro-gnu-dwo.ll b/llvm/test/DebugInfo/X86/debug-macro-gnu-dwo.ll
new file mode 100644
index 000000000000..b9050a681f7c
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/debug-macro-gnu-dwo.ll
@@ -0,0 +1,50 @@
+; It is unclear if the GNU .debug_macro extension is well-specified for split
+; DWARF. For now, verify that a .debug_macinfo.dwo section is emitted when
+; -gdwarf-4 -gsplit-dwarf -fdebug-macro is specified, regardless of the GNU
+; extension being requested.
+
+; RUN: %llc_dwarf -dwarf-version=4 -O0 -filetype=obj -use-gnu-debug-macro \
+; RUN: -split-dwarf-file=foo.dwo < %s | llvm-dwarfdump -v - | FileCheck %s
+
+; CHECK: .debug_info.dwo contents:
+; CHECK:       DW_AT_macro_info [DW_FORM_sec_offset] (0x00000000)
+
+; CHECK-LABEL: .debug_macinfo.dwo contents:
+; CHECK-NEXT: 0x00000000:
+; CHECK-NEXT: DW_MACINFO_start_file - lineno: 0 filenum: 1
+; CHECK-NEXT:   DW_MACINFO_start_file - lineno: 1 filenum: 2
+; CHECK-NEXT:     DW_MACINFO_define - lineno: 1 macro: FOO 5
+; CHECK-NEXT:   DW_MACINFO_end_file
+; CHECK-NEXT:   DW_MACINFO_start_file - lineno: 2 filenum: 3
+; CHECK-NEXT:     DW_MACINFO_undef - lineno: 14 macro: YEA
+; CHECK-NEXT:   DW_MACINFO_end_file
+; CHECK-NEXT:   DW_MACINFO_undef - lineno: 14 macro: YEA
+; CHECK-NEXT: DW_MACINFO_end_file
+
+; ModuleID = 'test.c'
+source_filename = "test.c"
+target datalayout = "e-m:e-p200:32:32-p201:32:32-p202:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!14, !15, !16}
+!llvm.ident = !{!17}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, macros: !3, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.c", directory: "/home/")
+!2 = !{}
+!3 = !{!4}
+!4 = !DIMacroFile(file: !1, nodes: !5)
+!5 = !{!6, !10, !13}
+!6 = !DIMacroFile(line: 1, file: !7, nodes: !8)
+!7 = !DIFile(filename: "./foo.h", directory: "/home/")
+!8 = !{!9}
+!9 = !DIMacro(type: DW_MACINFO_define, line: 1, name: "FOO", value: "5")
+!10 = !DIMacroFile(line: 2, file: !11, nodes: !12)
+!11 = !DIFile(filename: "./bar.h", directory: "/home/")
+!12 = !{!13}
+!13 = !DIMacro(type: DW_MACINFO_undef, line: 14, name: "YEA")
+!14 = !{i32 7, !"Dwarf Version", i32 4}
+!15 = !{i32 2, !"Debug Info Version", i32 3}
+!16 = !{i32 1, !"wchar_size", i32 4}
+!17 = !{!"clang version 10.0.0"}

diff  --git a/llvm/test/DebugInfo/X86/debug-macro-gnu.ll b/llvm/test/DebugInfo/X86/debug-macro-gnu.ll
new file mode 100644
index 000000000000..24b90192c99c
--- /dev/null
+++ b/llvm/test/DebugInfo/X86/debug-macro-gnu.ll
@@ -0,0 +1,47 @@
+; This test checks emission of the GNU extension for the .debug_macro section.
+
+; RUN: %llc_dwarf -dwarf-version=4 -O0 -use-gnu-debug-macro -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s
+
+; CHECK-LABEL:  .debug_info contents:
+; CHECK: DW_AT_GNU_macros [DW_FORM_sec_offset] (0x00000000)
+
+; CHECK-LABEL:  .debug_macro contents:
+; CHECK-NEXT: 0x00000000:
+; CHECK-NEXT: macro header: version = 0x0004, flags = 0x02, format = DWARF32, debug_line_offset = 0x0000
+; CHECK-NEXT: DW_MACRO_GNU_start_file - lineno: 0 filenum: 1
+; CHECK-NEXT:   DW_MACRO_GNU_start_file - lineno: 1 filenum: 2
+; CHECK-NEXT:     DW_MACRO_GNU_define_indirect - lineno: 1 macro: FOO 5
+; CHECK-NEXT:   DW_MACRO_GNU_end_file
+; CHECK-NEXT:   DW_MACRO_GNU_start_file - lineno: 2 filenum: 3
+; CHECK-NEXT:     DW_MACRO_GNU_undef_indirect - lineno: 14 macro: YEA
+; CHECK-NEXT:   DW_MACRO_GNU_end_file
+; CHECK-NEXT:   DW_MACRO_GNU_undef_indirect - lineno: 14 macro: YEA
+; CHECK-NEXT: DW_MACRO_GNU_end_file
+
+; ModuleID = 'test.c'
+source_filename = "test.c"
+target datalayout = "e-m:e-p200:32:32-p201:32:32-p202:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!14, !15, !16}
+!llvm.ident = !{!17}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, macros: !3, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.c", directory: "/home/")
+!2 = !{}
+!3 = !{!4}
+!4 = !DIMacroFile(file: !1, nodes: !5)
+!5 = !{!6, !10, !13}
+!6 = !DIMacroFile(line: 1, file: !7, nodes: !8)
+!7 = !DIFile(filename: "./foo.h", directory: "/home/")
+!8 = !{!9}
+!9 = !DIMacro(type: DW_MACINFO_define, line: 1, name: "FOO", value: "5")
+!10 = !DIMacroFile(line: 2, file: !11, nodes: !12)
+!11 = !DIFile(filename: "./bar.h", directory: "/home/")
+!12 = !{!13}
+!13 = !DIMacro(type: DW_MACINFO_undef, line: 14, name: "YEA")
+!14 = !{i32 7, !"Dwarf Version", i32 4}
+!15 = !{i32 2, !"Debug Info Version", i32 3}
+!16 = !{i32 1, !"wchar_size", i32 4}
+!17 = !{!"clang version 10.0.0"}


        


More information about the llvm-commits mailing list