1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[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
This commit is contained in:
Sourabh Singh Tomar 2020-04-03 12:44:09 +05:30
parent ae3c34854e
commit 8ba532e8e1
5 changed files with 178 additions and 25 deletions

View File

@ -89,6 +89,7 @@ protected:
MCSection *DwarfARangesSection = nullptr;
MCSection *DwarfRangesSection = nullptr;
MCSection *DwarfMacinfoSection = nullptr;
MCSection *DwarfMacroSection = nullptr;
// The pubnames section is no longer generated by default. The generation
// can be enabled by a compiler flag.
MCSection *DwarfPubNamesSection = nullptr;
@ -275,6 +276,7 @@ public:
MCSection *getDwarfRnglistsSection() const { return DwarfRnglistsSection; }
MCSection *getDwarfLoclistsSection() const { return DwarfLoclistsSection; }
MCSection *getDwarfMacinfoSection() const { return DwarfMacinfoSection; }
MCSection *getDwarfMacroSection() const { return DwarfMacroSection; }
MCSection *getDwarfDebugNamesSection() const {
return DwarfDebugNamesSection;

View File

@ -1288,18 +1288,29 @@ void DwarfDebug::finalizeModuleInfo() {
}
auto *CUNode = cast<DICompileUnit>(P.first);
// If compile Unit has macros, emit "DW_AT_macro_info" attribute.
// If compile Unit has macros, emit "DW_AT_macro_info/DW_AT_macros"
// attribute.
if (CUNode->getMacros()) {
if (useSplitDwarf())
TheCU.addSectionDelta(TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
if (getDwarfVersion() >= 5) {
// FIXME: Add support for DWARFv5 DW_AT_macros attribute for split
// case.
if (!useSplitDwarf())
U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macros,
U.getMacroLabelBegin(),
TLOF.getDwarfMacinfoDWOSection()->getBeginSymbol());
else
U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
U.getMacroLabelBegin(),
TLOF.getDwarfMacinfoSection()->getBeginSymbol());
TLOF.getDwarfMacroSection()->getBeginSymbol());
} else {
if (useSplitDwarf())
TheCU.addSectionDelta(
TheCU.getUnitDie(), dwarf::DW_AT_macro_info,
U.getMacroLabelBegin(),
TLOF.getDwarfMacinfoDWOSection()->getBeginSymbol());
else
U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
U.getMacroLabelBegin(),
TLOF.getDwarfMacinfoSection()->getBeginSymbol());
}
}
}
}
// Emit all frontend-produced Skeleton CUs, i.e., Clang modules.
for (auto *CUNode : MMI->getModule()->debug_compile_units())
@ -1355,7 +1366,7 @@ void DwarfDebug::endModule() {
// Emit info into a debug macinfo.dwo section.
emitDebugMacinfoDWO();
else
// Emit info into a debug macinfo section.
// Emit info into a debug macinfo/macro section.
emitDebugMacinfo();
emitDebugStr();
@ -2854,6 +2865,27 @@ void DwarfDebug::emitDebugRangesDWO() {
Asm->getObjFileLowering().getDwarfRnglistsDWOSection());
}
/// Emit the header of a DWARF 5 macro section.
static void emitMacroHeader(AsmPrinter *Asm, const DwarfDebug &DD,
const DwarfCompileUnit &CU) {
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);
// We are setting Offset and line offset flags unconditionally here,
// since we're only supporting DWARF32 and line offset should be mostly
// present.
// FIXME: Add support for DWARF64.
Flags |= MACRO_FLAG_DEBUG_LINE_OFFSET;
Asm->OutStreamer->AddComment("Flags: 32 bit, debug_line_offset present");
Asm->emitInt8(Flags);
Asm->OutStreamer->AddComment("debug_line_offset");
Asm->OutStreamer->emitSymbolValue(CU.getLineTableStartSym(), /*Size=*/4);
}
void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
for (auto *MN : Nodes) {
if (auto *M = dyn_cast<DIMacro>(MN))
@ -2866,26 +2898,75 @@ void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
}
void DwarfDebug::emitMacro(DIMacro &M) {
Asm->emitULEB128(M.getMacinfoType());
Asm->emitULEB128(M.getLine());
StringRef Name = M.getName();
StringRef Value = M.getValue();
Asm->OutStreamer->emitBytes(Name);
if (!Value.empty()) {
// There should be one space between macro name and macro value.
Asm->emitInt8(' ');
Asm->OutStreamer->emitBytes(Value);
bool UseMacro = getDwarfVersion() >= 5;
if (UseMacro) {
unsigned Type = M.getMacinfoType() == dwarf::DW_MACINFO_define
? dwarf::DW_MACRO_define_strp
: dwarf::DW_MACRO_undef_strp;
Asm->OutStreamer->AddComment(dwarf::MacroString(Type));
Asm->emitULEB128(Type);
Asm->OutStreamer->AddComment("Line Number");
Asm->emitULEB128(M.getLine());
Asm->OutStreamer->AddComment("Macro String");
if (!Value.empty())
Asm->OutStreamer->emitSymbolValue(
this->InfoHolder.getStringPool()
.getEntry(*Asm, (Name + " " + Value).str())
.getSymbol(),
4);
else
// DW_MACRO_undef_strp doesn't have a value, so just emit the macro
// string.
Asm->OutStreamer->emitSymbolValue(this->InfoHolder.getStringPool()
.getEntry(*Asm, (Name).str())
.getSymbol(),
4);
} else {
Asm->OutStreamer->AddComment(dwarf::MacinfoString(M.getMacinfoType()));
Asm->emitULEB128(M.getMacinfoType());
Asm->OutStreamer->AddComment("Line Number");
Asm->emitULEB128(M.getLine());
Asm->OutStreamer->AddComment("Macro String");
Asm->OutStreamer->emitBytes(Name);
if (!Value.empty()) {
// There should be one space between macro name and macro value.
Asm->emitInt8(' ');
Asm->OutStreamer->AddComment("Macro Value=");
Asm->OutStreamer->emitBytes(Value);
}
Asm->emitInt8('\0');
}
Asm->emitInt8('\0');
}
void DwarfDebug::emitMacroFileImpl(
DIMacroFile &F, DwarfCompileUnit &U, unsigned StartFile, unsigned EndFile,
StringRef (*MacroFormToString)(unsigned Form)) {
Asm->OutStreamer->AddComment(MacroFormToString(StartFile));
Asm->emitULEB128(StartFile);
Asm->OutStreamer->AddComment("Line Number");
Asm->emitULEB128(F.getLine());
Asm->OutStreamer->AddComment("File Number");
Asm->emitULEB128(U.getOrCreateSourceID(F.getFile()));
handleMacroNodes(F.getElements(), U);
Asm->OutStreamer->AddComment(MacroFormToString(EndFile));
Asm->emitULEB128(EndFile);
}
void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) {
// DWARFv5 macro and DWARFv4 macinfo share some common encodings,
// so for readibility/uniformity, We are explicitly emitting those.
assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file);
Asm->emitULEB128(dwarf::DW_MACINFO_start_file);
Asm->emitULEB128(F.getLine());
Asm->emitULEB128(U.getOrCreateSourceID(F.getFile()));
handleMacroNodes(F.getElements(), U);
Asm->emitULEB128(dwarf::DW_MACINFO_end_file);
bool UseMacro = getDwarfVersion() >= 5;
if (UseMacro)
emitMacroFileImpl(F, U, dwarf::DW_MACRO_start_file,
dwarf::DW_MACRO_end_file, dwarf::MacroString);
else
emitMacroFileImpl(F, U, dwarf::DW_MACINFO_start_file,
dwarf::DW_MACINFO_end_file, dwarf::MacinfoString);
}
void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
@ -2899,18 +2980,26 @@ void DwarfDebug::emitDebugMacinfoImpl(MCSection *Section) {
continue;
Asm->OutStreamer->SwitchSection(Section);
Asm->OutStreamer->emitLabel(U.getMacroLabelBegin());
if (getDwarfVersion() >= 5)
emitMacroHeader(Asm, *this, U);
handleMacroNodes(Macros, U);
Asm->OutStreamer->AddComment("End Of Macro List Mark");
Asm->emitInt8(0);
}
}
/// Emit macros into a debug macinfo section.
/// Emit macros into a debug macinfo/macro section.
void DwarfDebug::emitDebugMacinfo() {
emitDebugMacinfoImpl(Asm->getObjFileLowering().getDwarfMacinfoSection());
auto &ObjLower = Asm->getObjFileLowering();
emitDebugMacinfoImpl(getDwarfVersion() >= 5
? ObjLower.getDwarfMacroSection()
: ObjLower.getDwarfMacinfoSection());
}
void DwarfDebug::emitDebugMacinfoDWO() {
// FIXME: Add support for macro.dwo section.
if (getDwarfVersion() >= 5)
return;
emitDebugMacinfoImpl(Asm->getObjFileLowering().getDwarfMacinfoDWOSection());
}

View File

@ -528,6 +528,9 @@ class DwarfDebug : public DebugHandlerBase {
void emitDebugMacinfoImpl(MCSection *Section);
void emitMacro(DIMacro &M);
void emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U);
void emitMacroFileImpl(DIMacroFile &F, DwarfCompileUnit &U,
unsigned StartFile, unsigned EndFile,
StringRef (*MacroFormToString)(unsigned Form));
void handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U);
/// DWARF 5 Experimental Split Dwarf Emitters

View File

@ -276,6 +276,9 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
DwarfMacinfoSection =
Ctx->getMachOSection("__DWARF", "__debug_macinfo", MachO::S_ATTR_DEBUG,
SectionKind::getMetadata(), "debug_macinfo");
DwarfMacroSection =
Ctx->getMachOSection("__DWARF", "__debug_macro", MachO::S_ATTR_DEBUG,
SectionKind::getMetadata(), "debug_macro");
DwarfDebugInlineSection =
Ctx->getMachOSection("__DWARF", "__debug_inlined", MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
@ -427,6 +430,7 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
Ctx->getELFSection(".debug_ranges", DebugSecType, 0);
DwarfMacinfoSection =
Ctx->getELFSection(".debug_macinfo", DebugSecType, 0);
DwarfMacroSection = Ctx->getELFSection(".debug_macro", DebugSecType, 0);
// DWARF5 Experimental Debug Info
@ -635,6 +639,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata(), "debug_macinfo");
DwarfMacroSection = Ctx->getCOFFSection(
".debug_macro",
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata(), "debug_macro");
DwarfMacinfoDWOSection = Ctx->getCOFFSection(
".debug_macinfo.dwo",
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@ -771,6 +780,8 @@ void MCObjectFileInfo::initWasmMCObjectFileInfo(const Triple &T) {
Ctx->getWasmSection(".debug_ranges", SectionKind::getMetadata());
DwarfMacinfoSection =
Ctx->getWasmSection(".debug_macinfo", SectionKind::getMetadata());
DwarfMacroSection =
Ctx->getWasmSection(".debug_macro", SectionKind::getMetadata());
DwarfCUIndexSection = Ctx->getWasmSection(".debug_cu_index", SectionKind::getMetadata());
DwarfTUIndexSection = Ctx->getWasmSection(".debug_tu_index", SectionKind::getMetadata());
DwarfInfoSection =

View File

@ -0,0 +1,48 @@
; This test checks emission of .debug_macro section when
; -gdwarf-5 -fdebug-macro is specified.
; RUN: %llc_dwarf -dwarf-version=5 -O0 -filetype=obj < %s | llvm-dwarfdump -v - | FileCheck %s
; CHECK-LABEL: .debug_info contents:
; CHECK: DW_AT_macros [DW_FORM_sec_offset] (0x00000000)
; CHECK-LABEL: .debug_macro contents:
; CHECK-NEXT: 0x00000000:
; CHECK-NEXT: macro header: version = 0x0005, flags = 0x02, debug_line_offset = 0x0000
; CHECK-NEXT: DW_MACRO_start_file - lineno: 0 filenum: 0
; CHECK-NEXT: DW_MACRO_start_file - lineno: 1 filenum: 1
; CHECK-NEXT: DW_MACRO_define_strp - lineno: 1 macro: FOO 5
; CHECK-NEXT: DW_MACRO_end_file
; CHECK-NEXT: DW_MACRO_start_file - lineno: 2 filenum: 2
; CHECK-NEXT: DW_MACRO_undef_strp - lineno: 14 macro: YEA
; CHECK-NEXT: DW_MACRO_end_file
; CHECK-NEXT: DW_MACRO_undef_strp - lineno: 14 macro: YEA
; CHECK-NEXT: DW_MACRO_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/", checksumkind: CSK_MD5, checksum: "ef6a7032e0c7ceeef614583f2c00dc80")
!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/", checksumkind: CSK_MD5, checksum: "0f0cd0e15b44f49d3944992c8dc28661")
!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/", checksumkind: CSK_MD5, checksum: "bf4b34c263eaaa1d7085c18243b8d100")
!12 = !{!13}
!13 = !DIMacro(type: DW_MACINFO_undef, line: 14, name: "YEA")
!14 = !{i32 7, !"Dwarf Version", i32 5}
!15 = !{i32 2, !"Debug Info Version", i32 3}
!16 = !{i32 1, !"wchar_size", i32 4}
!17 = !{!"clang version 10.0.0"}