Skip to content

Commit 5d7e9ad

Browse files
committed
[DWARF5] Added support for emission of debug_macro section.
Summary: This patch adds support for emission of following DWARFv5 macro forms in .debug_macro section. 1. DW_MACRO_start_file 2. DW_MACRO_end_file 3. DW_MACRO_define_strp 4. DW_MACRO_undef_strp. Reviewed By: dblaikie, ikudrin Differential Revision: https://reviews.llvm.org/D72828
1 parent 8f12336 commit 5d7e9ad

File tree

5 files changed

+177
-24
lines changed

5 files changed

+177
-24
lines changed

llvm/include/llvm/MC/MCObjectFileInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class MCObjectFileInfo {
8989
MCSection *DwarfARangesSection = nullptr;
9090
MCSection *DwarfRangesSection = nullptr;
9191
MCSection *DwarfMacinfoSection = nullptr;
92+
MCSection *DwarfMacroSection = nullptr;
9293
// The pubnames section is no longer generated by default. The generation
9394
// can be enabled by a compiler flag.
9495
MCSection *DwarfPubNamesSection = nullptr;
@@ -275,6 +276,7 @@ class MCObjectFileInfo {
275276
MCSection *getDwarfRnglistsSection() const { return DwarfRnglistsSection; }
276277
MCSection *getDwarfLoclistsSection() const { return DwarfLoclistsSection; }
277278
MCSection *getDwarfMacinfoSection() const { return DwarfMacinfoSection; }
279+
MCSection *getDwarfMacroSection() const { return DwarfMacroSection; }
278280

279281
MCSection *getDwarfDebugNamesSection() const {
280282
return DwarfDebugNamesSection;

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 113 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,18 +1288,29 @@ void DwarfDebug::finalizeModuleInfo() {
12881288
}
12891289

12901290
auto *CUNode = cast<DICompileUnit>(P.first);
1291-
// If compile Unit has macros, emit "DW_AT_macro_info" attribute.
1291+
// If compile Unit has macros, emit "DW_AT_macro_info/DW_AT_macros"
1292+
// attribute.
12921293
if (CUNode->getMacros()) {
1293-
if (useSplitDwarf())
1294-
TheCU.addSectionDelta(TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1294+
if (getDwarfVersion() >= 5) {
1295+
// FIXME: Add support for DWARFv5 DW_AT_macros attribute for split
1296+
// case.
1297+
if (!useSplitDwarf())
1298+
U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macros,
12951299
U.getMacroLabelBegin(),
1296-
TLOF.getDwarfMacinfoDWOSection()->getBeginSymbol());
1297-
else
1298-
U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
1299-
U.getMacroLabelBegin(),
1300-
TLOF.getDwarfMacinfoSection()->getBeginSymbol());
1300+
TLOF.getDwarfMacroSection()->getBeginSymbol());
1301+
} else {
1302+
if (useSplitDwarf())
1303+
TheCU.addSectionDelta(
1304+
TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
1305+
U.getMacroLabelBegin(),
1306+
TLOF.getDwarfMacinfoDWOSection()->getBeginSymbol());
1307+
else
1308+
U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
1309+
U.getMacroLabelBegin(),
1310+
TLOF.getDwarfMacinfoSection()->getBeginSymbol());
1311+
}
1312+
}
13011313
}
1302-
}
13031314

13041315
// Emit all frontend-produced Skeleton CUs, i.e., Clang modules.
13051316
for (auto *CUNode : MMI->getModule()->debug_compile_units())
@@ -1355,7 +1366,7 @@ void DwarfDebug::endModule() {
13551366
// Emit info into a debug macinfo.dwo section.
13561367
emitDebugMacinfoDWO();
13571368
else
1358-
// Emit info into a debug macinfo section.
1369+
// Emit info into a debug macinfo/macro section.
13591370
emitDebugMacinfo();
13601371

13611372
emitDebugStr();
@@ -2854,6 +2865,27 @@ void DwarfDebug::emitDebugRangesDWO() {
28542865
Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
28552866
}
28562867

2868+
/// Emit the header of a DWARF 5 macro section.
2869+
static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD,
2870+
const DwarfCompileUnit &CU) {
2871+
enum HeaderFlagMask {
2872+
#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_FLAG_##NAME = ID,
2873+
#include "llvm/BinaryFormat/Dwarf.def"
2874+
};
2875+
uint8_t Flags = 0;
2876+
Asm->OutStreamer->AddComment("Macro information version");
2877+
Asm->emitInt16(5);
2878+
// We are setting Offset and line offset flags unconditionally here,
2879+
// since we're only supporting DWARF32 and line offset should be mostly
2880+
// present.
2881+
// FIXME: Add support for DWARF64.
2882+
Flags |= MACRO_FLAG_DEBUG_LINE_OFFSET;
2883+
Asm->OutStreamer->AddComment("Flags: 32 bit, debug_line_offset present");
2884+
Asm->emitInt8(Flags);
2885+
Asm->OutStreamer->AddComment("debug_line_offset");
2886+
Asm->OutStreamer->emitSymbolValue(CU.getLineTableStartSym(), /*Size=*/4);
2887+
}
2888+
28572889
void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
28582890
for (auto *MN : Nodes) {
28592891
if (auto *M = dyn_cast<DIMacro>(MN))
@@ -2866,26 +2898,75 @@ void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
28662898
}
28672899

28682900
void DwarfDebug::emitMacro(DIMacro &M) {
2869-
Asm->emitULEB128(M.getMacinfoType());
2870-
Asm->emitULEB128(M.getLine());
28712901
StringRef Name = M.getName();
28722902
StringRef Value = M.getValue();
2873-
Asm->OutStreamer->emitBytes(Name);
2874-
if (!Value.empty()) {
2875-
// There should be one space between macro name and macro value.
2876-
Asm->emitInt8(' ');
2877-
Asm->OutStreamer->emitBytes(Value);
2903+
bool UseMacro = getDwarfVersion() >= 5;
2904+
2905+
if (UseMacro) {
2906+
unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
2907+
? dwarf::DW_MACRO_define_strp
2908+
: dwarf::DW_MACRO_undef_strp;
2909+
Asm->OutStreamer->AddComment(dwarf::MacroString(Type));
2910+
Asm->emitULEB128(Type);
2911+
Asm->OutStreamer->AddComment("Line Number");
2912+
Asm->emitULEB128(M.getLine());
2913+
Asm->OutStreamer->AddComment("Macro String");
2914+
if (!Value.empty())
2915+
Asm->OutStreamer->emitSymbolValue(
2916+
this->InfoHolder.getStringPool()
2917+
.getEntry(*Asm, (Name + " " + Value).str())
2918+
.getSymbol(),
2919+
4);
2920+
else
2921+
// DW_MACRO_undef_strp doesn't have a value, so just emit the macro
2922+
// string.
2923+
Asm->OutStreamer->emitSymbolValue(this->InfoHolder.getStringPool()
2924+
.getEntry(*Asm, (Name).str())
2925+
.getSymbol(),
2926+
4);
2927+
} else {
2928+
Asm->OutStreamer->AddComment(dwarf::MacinfoString(M.getMacinfoType()));
2929+
Asm->emitULEB128(M.getMacinfoType());
2930+
Asm->OutStreamer->AddComment("Line Number");
2931+
Asm->emitULEB128(M.getLine());
2932+
Asm->OutStreamer->AddComment("Macro String");
2933+
Asm->OutStreamer->emitBytes(Name);
2934+
if (!Value.empty()) {
2935+
// There should be one space between macro name and macro value.
2936+
Asm->emitInt8(' ');
2937+
Asm->OutStreamer->AddComment("Macro Value=");
2938+
Asm->OutStreamer->emitBytes(Value);
2939+
}
2940+
Asm->emitInt8('\0');
28782941
}
2879-
Asm->emitInt8('\0');
28802942
}
28812943

2882-
void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) {
2883-
assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file);
2884-
Asm->emitULEB128(dwarf::DW_MACINFO_start_file);
2944+
void DwarfDebug::emitMacroFileImpl(
2945+
DIMacroFile &F, DwarfCompileUnit &U, unsigned StartFile, unsigned EndFile,
2946+
StringRef (*MacroFormToString)(unsigned Form)) {
2947+
2948+
Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
2949+
Asm->emitULEB128(StartFile);
2950+
Asm->OutStreamer->AddComment("Line Number");
28852951
Asm->emitULEB128(F.getLine());
2952+
Asm->OutStreamer->AddComment("File Number");
28862953
Asm->emitULEB128(U.getOrCreateSourceID(F.getFile()));
28872954
handleMacroNodes(F.getElements(), U);
2888-
Asm->emitULEB128(dwarf::DW_MACINFO_end_file);
2955+
Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
2956+
Asm->emitULEB128(EndFile);
2957+
}
2958+
2959+
void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) {
2960+
// DWARFv5 macro and DWARFv4 macinfo share some common encodings,
2961+
// so for readibility/uniformity, We are explicitly emitting those.
2962+
assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file);
2963+
bool UseMacro = getDwarfVersion() >= 5;
2964+
if (UseMacro)
2965+
emitMacroFileImpl(F, U, dwarf::DW_MACRO_start_file,
2966+
dwarf::DW_MACRO_end_file, dwarf::MacroString);
2967+
else
2968+
emitMacroFileImpl(F, U, dwarf::DW_MACINFO_start_file,
2969+
dwarf::DW_MACINFO_end_file, dwarf::MacinfoString);
28892970
}
28902971

28912972
void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
@@ -2899,18 +2980,26 @@ void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
28992980
continue;
29002981
Asm->OutStreamer->SwitchSection(Section);
29012982
Asm->OutStreamer->emitLabel(U.getMacroLabelBegin());
2983+
if (getDwarfVersion() >= 5)
2984+
emitMacroHeader(Asm, *this, U);
29022985
handleMacroNodes(Macros, U);
29032986
Asm->OutStreamer->AddComment("End Of Macro List Mark");
29042987
Asm->emitInt8(0);
29052988
}
29062989
}
29072990

2908-
/// Emit macros into a debug macinfo section.
2991+
/// Emit macros into a debug macinfo/macro section.
29092992
void DwarfDebug::emitDebugMacinfo() {
2910-
emitDebugMacinfoImpl(Asm->getObjFileLowering().getDwarfMacinfoSection());
2993+
auto &ObjLower = Asm->getObjFileLowering();
2994+
emitDebugMacinfoImpl(getDwarfVersion() >= 5
2995+
? ObjLower.getDwarfMacroSection()
2996+
: ObjLower.getDwarfMacinfoSection());
29112997
}
29122998

29132999
void DwarfDebug::emitDebugMacinfoDWO() {
3000+
// FIXME: Add support for macro.dwo section.
3001+
if (getDwarfVersion() >= 5)
3002+
return;
29143003
emitDebugMacinfoImpl(Asm->getObjFileLowering().getDwarfMacinfoDWOSection());
29153004
}
29163005

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,9 @@ class DwarfDebug : public DebugHandlerBase {
528528
void emitDebugMacinfoImpl(MCSection *Section);
529529
void emitMacro(DIMacro &M);
530530
void emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U);
531+
void emitMacroFileImpl(DIMacroFile &F, DwarfCompileUnit &U,
532+
unsigned StartFile, unsigned EndFile,
533+
StringRef (*MacroFormToString)(unsigned Form));
531534
void handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U);
532535

533536
/// DWARF 5 Experimental Split Dwarf Emitters

llvm/lib/MC/MCObjectFileInfo.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
276276
DwarfMacinfoSection =
277277
Ctx->getMachOSection("__DWARF", "__debug_macinfo", MachO::S_ATTR_DEBUG,
278278
SectionKind::getMetadata(), "debug_macinfo");
279+
DwarfMacroSection =
280+
Ctx->getMachOSection("__DWARF", "__debug_macro", MachO::S_ATTR_DEBUG,
281+
SectionKind::getMetadata(), "debug_macro");
279282
DwarfDebugInlineSection =
280283
Ctx->getMachOSection("__DWARF", "__debug_inlined", MachO::S_ATTR_DEBUG,
281284
SectionKind::getMetadata());
@@ -427,6 +430,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
427430
Ctx->getELFSection(".debug_ranges", DebugSecType, 0);
428431
DwarfMacinfoSection =
429432
Ctx->getELFSection(".debug_macinfo", DebugSecType, 0);
433+
DwarfMacroSection = Ctx->getELFSection(".debug_macro", DebugSecType, 0);
430434

431435
// DWARF5 Experimental Debug Info
432436

@@ -635,6 +639,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
635639
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
636640
COFF::IMAGE_SCN_MEM_READ,
637641
SectionKind::getMetadata(), "debug_macinfo");
642+
DwarfMacroSection = Ctx->getCOFFSection(
643+
".debug_macro",
644+
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
645+
COFF::IMAGE_SCN_MEM_READ,
646+
SectionKind::getMetadata(), "debug_macro");
638647
DwarfMacinfoDWOSection = Ctx->getCOFFSection(
639648
".debug_macinfo.dwo",
640649
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -771,6 +780,8 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
771780
Ctx->getWasmSection(".debug_ranges", SectionKind::getMetadata());
772781
DwarfMacinfoSection =
773782
Ctx->getWasmSection(".debug_macinfo", SectionKind::getMetadata());
783+
DwarfMacroSection =
784+
Ctx->getWasmSection(".debug_macro", SectionKind::getMetadata());
774785
DwarfCUIndexSection = Ctx->getWasmSection(".debug_cu_index", SectionKind::getMetadata());
775786
DwarfTUIndexSection = Ctx->getWasmSection(".debug_tu_index", SectionKind::getMetadata());
776787
DwarfInfoSection =
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
; This test checks emission of .debug_macro section when
2+
; -gdwarf-5 -fdebug-macro is specified.
3+
4+
; RUN: %llc_dwarf -dwarf-version=5 -O0 -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s
5+
6+
; CHECK-LABEL: .debug_info contents:
7+
; CHECK: DW_AT_macros [DW_FORM_sec_offset] (0x00000000)
8+
9+
; CHECK-LABEL: .debug_macro contents:
10+
; CHECK-NEXT: 0x00000000:
11+
; CHECK-NEXT: macro header: version = 0x0005, flags = 0x02, debug_line_offset = 0x0000
12+
; CHECK-NEXT: DW_MACRO_start_file - lineno: 0 filenum: 0
13+
; CHECK-NEXT: DW_MACRO_start_file - lineno: 1 filenum: 1
14+
; CHECK-NEXT: DW_MACRO_define_strp - lineno: 1 macro: FOO 5
15+
; CHECK-NEXT: DW_MACRO_end_file
16+
; CHECK-NEXT: DW_MACRO_start_file - lineno: 2 filenum: 2
17+
; CHECK-NEXT: DW_MACRO_undef_strp - lineno: 14 macro: YEA
18+
; CHECK-NEXT: DW_MACRO_end_file
19+
; CHECK-NEXT: DW_MACRO_undef_strp - lineno: 14 macro: YEA
20+
; CHECK-NEXT: DW_MACRO_end_file
21+
22+
; ModuleID = 'test.c'
23+
source_filename = "test.c"
24+
target datalayout = "e-m:e-p200:32:32-p201:32:32-p202:64:64-i64:64-f80:128-n8:16:32:64-S128"
25+
target triple = "x86_64-unknown-linux-gnu"
26+
27+
!llvm.dbg.cu = !{!0}
28+
!llvm.module.flags = !{!14, !15, !16}
29+
!llvm.ident = !{!17}
30+
31+
!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)
32+
!1 = !DIFile(filename: "test.c", directory: "/home/", checksumkind: CSK_MD5, checksum: "ef6a7032e0c7ceeef614583f2c00dc80")
33+
!2 = !{}
34+
!3 = !{!4}
35+
!4 = !DIMacroFile(file: !1, nodes: !5)
36+
!5 = !{!6, !10, !13}
37+
!6 = !DIMacroFile(line: 1, file: !7, nodes: !8)
38+
!7 = !DIFile(filename: "./foo.h", directory: "/home/", checksumkind: CSK_MD5, checksum: "0f0cd0e15b44f49d3944992c8dc28661")
39+
!8 = !{!9}
40+
!9 = !DIMacro(type: DW_MACINFO_define, line: 1, name: "FOO", value: "5")
41+
!10 = !DIMacroFile(line: 2, file: !11, nodes: !12)
42+
!11 = !DIFile(filename: "./bar.h", directory: "/home/", checksumkind: CSK_MD5, checksum: "bf4b34c263eaaa1d7085c18243b8d100")
43+
!12 = !{!13}
44+
!13 = !DIMacro(type: DW_MACINFO_undef, line: 14, name: "YEA")
45+
!14 = !{i32 7, !"Dwarf Version", i32 5}
46+
!15 = !{i32 2, !"Debug Info Version", i32 3}
47+
!16 = !{i32 1, !"wchar_size", i32 4}
48+
!17 = !{!"clang version 10.0.0"}

0 commit comments

Comments
 (0)