Index: llvm/include/llvm/BinaryFormat/Dwarf.h =================================================================== --- llvm/include/llvm/BinaryFormat/Dwarf.h +++ llvm/include/llvm/BinaryFormat/Dwarf.h @@ -480,6 +480,7 @@ StringRef LNExtendedString(unsigned Encoding); StringRef MacinfoString(unsigned Encoding); StringRef MacroString(unsigned Encoding); +StringRef GnuMacroString(unsigned Encoding); StringRef RangeListEncodingString(unsigned Encoding); StringRef LocListEncodingString(unsigned Encoding); StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch); Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h @@ -96,6 +96,9 @@ MacroHeader Header; SmallVector Macros; uint64_t Offset; + + /// Whether or not this is a .debug_macro section. + bool IsDebugMacro; }; /// A list of all the macro entries in the debug_macinfo section. Index: llvm/lib/BinaryFormat/Dwarf.cpp =================================================================== --- llvm/lib/BinaryFormat/Dwarf.cpp +++ llvm/lib/BinaryFormat/Dwarf.cpp @@ -488,6 +488,17 @@ } } +StringRef llvm::dwarf::GnuMacroString(unsigned Encoding) { + switch (Encoding) { + default: + return StringRef(); +#define HANDLE_DW_MACRO_GNU(ID, NAME) \ + case DW_MACRO_GNU_##NAME: \ + return "DW_MACRO_GNU_" #NAME; +#include "llvm/BinaryFormat/Dwarf.def" + } +} + unsigned llvm::dwarf::getMacro(StringRef MacroString) { return StringSwitch(MacroString) #define HANDLE_DW_MACRO(ID, NAME) .Case("DW_MACRO_" #NAME, ID) Index: llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp @@ -40,7 +40,7 @@ unsigned IndLevel = 0; for (const auto &Macros : MacroLists) { OS << format("0x%08" PRIx64 ":\n", Macros.Offset); - if (Macros.Header.Version >= 5) + if (Macros.IsDebugMacro) Macros.Header.dumpMacroHeader(OS); for (const Entry &E : Macros.Macros) { // There should not be DW_MACINFO_end_file when IndLevel is Zero. However, @@ -52,8 +52,10 @@ OS << " "; IndLevel += (E.Type == DW_MACINFO_start_file); // Based on which version we are handling choose appropriate macro forms. - if (Macros.Header.Version >= 5) - WithColor(OS, HighlightColor::Macro).get() << MacroString(E.Type); + if (Macros.IsDebugMacro) + WithColor(OS, HighlightColor::Macro).get() + << (Macros.Header.Version < 5 ? GnuMacroString(E.Type) + : MacroString(E.Type)); else WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type); switch (E.Type) { @@ -67,6 +69,9 @@ // DW_MACRO_start_file == DW_MACINFO_start_file // DW_MACRO_end_file == DW_MACINFO_end_file // For readability/uniformity we are using DW_MACRO_*. + // + // The GNU .debug_macro extension's entries have the same encoding + // as DWARF 5's DW_MACRO_* entries, so we only use the latter here. case DW_MACRO_define: case DW_MACRO_undef: case DW_MACRO_define_strp: @@ -118,6 +123,7 @@ MacroLists.emplace_back(); M = &MacroLists.back(); M->Offset = Offset; + M->IsDebugMacro = IsMacro; if (IsMacro) { auto Err = M->Header.parseMacroHeader(Data, &Offset); if (Err) Index: llvm/test/DebugInfo/X86/debug-macro-gnu.s =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/debug-macro-gnu.s @@ -0,0 +1,59 @@ +## This test checks that llvm-dwarfdump can dump a .debug_macro section +## with the GNU extension format. + +# RUN: llvm-mc -triple x86_64-unknown-linux -filetype=obj %s -o -| \ +# RUN: llvm-dwarfdump -debug-macro - | FileCheck -strict-whitespace -match-full-lines %s + +# CHECK:.debug_macro contents: +# CHECK-NEXT:0x00000000: +# CHECK-NEXT:macro header: version = 0x0004, flags = 0x02, format = DWARF32, debug_line_offset = 0x00000000 +# CHECK-NEXT:DW_MACRO_GNU_start_file - lineno: 0 filenum: 0 +# CHECK-NEXT: DW_MACRO_GNU_start_file - lineno: 1 filenum: 6 +# CHECK-NEXT: DW_MACRO_GNU_define_indirect - lineno: 1 macro: FOO 5 +# CHECK-NEXT: DW_MACRO_GNU_end_file +# CHECK-NEXT: DW_MACRO_GNU_undef_indirect - lineno: 8 macro: WORLD1 +# CHECK-NEXT: DW_MACRO_GNU_transparent_include - import offset: 0x[[OFFSET:[0-9]+]] +# CHECK-NEXT:DW_MACRO_GNU_end_file + +# CHECK:0x[[OFFSET]]: +# CHECK-NEXT:macro header: version = 0x0004, flags = 0x00, format = DWARF32 +# CHECK-NEXT:DW_MACRO_GNU_define_indirect - lineno: 0 macro: WORLD 2 + + .section .debug_macro,"",@progbits +.Lcu_macro_begin0: + .short 4 # Macro information version + .byte 2 # Flags: 32 bit, debug_line_offset present + .long 0 # debug_line_offset + .byte 3 # DW_MACRO_GNU_start_file + .byte 0 # Line Number + .byte 0 # File Number + .byte 3 # DW_MACRO_GNU_start_file + .byte 1 # Line Number + .byte 6 # File Number + .byte 5 # DW_MACRO_GNU_define_indirect + .byte 1 # Line Number + .long .Linfo_string0 # Macro String + .byte 4 # DW_MACRO_GNU_end_file + .byte 6 # DW_MACRO_GNU_undef_indirect + .byte 8 # Line Number + .long .Linfo_string1 # Macro String + .byte 7 # DW_MACRO_GNU_transparent_include + .long .Lmacro1 # Macro Unit Offset + .byte 4 # DW_MACRO_GNU_end_file + .byte 0 # End Of Macro List Mark + +.Lmacro1: + .short 4 # Macro information version + .byte 0 # Flags: 32 bit + .byte 5 # DW_MACRO_GNU_define_indirect + .byte 0 # Line Number + .long .Linfo_string2 # Macro String + .byte 0 # End Of Macro List Mark + + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "FOO 5" +.Linfo_string1: + .asciz "WORLD1" +.Linfo_string2: + .asciz "WORLD 2"