aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCDwarf.cpp
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2020-02-27 21:57:40 -0800
committerFangrui Song <maskray@google.com>2020-03-03 09:03:34 -0800
commit55a56041d1da59dacb8f9abb1f3bfa841798e6cc (patch)
tree5ecab463cfad764feabb1f5a44bb44cf993f64a9 /llvm/lib/MC/MCDwarf.cpp
parentc5ec8890c95bf9f56beff285efbcc7b797ffb15a (diff)
downloadllvm-55a56041d1da59dacb8f9abb1f3bfa841798e6cc.zip
llvm-55a56041d1da59dacb8f9abb1f3bfa841798e6cc.tar.gz
llvm-55a56041d1da59dacb8f9abb1f3bfa841798e6cc.tar.bz2
[MCDwarf] Generate DWARF v5 .debug_rnglists for assembly files
``` // clang -c -gdwarf-5 a.s -o a.o .section .init; ret .text; ret ``` .debug_info contains DW_AT_ranges and llvm-dwarfdump will report a verification error because .debug_rnglists does not exist (not implemented). This patch generates .debug_rnglists for assembly files. emitListsTableHeaderStart() in DwarfDebug.cpp can be shared with MCDwarf.cpp. Because CodeGen depends on MC, I move the function to MCDwarf.cpp Reviewed By: probinson Differential Revision: https://reviews.llvm.org/D75375
Diffstat (limited to 'llvm/lib/MC/MCDwarf.cpp')
-rw-r--r--llvm/lib/MC/MCDwarf.cpp119
1 files changed, 75 insertions, 44 deletions
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index ecf7581..a0d4756 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -45,6 +45,19 @@
using namespace llvm;
+void mcdwarf::emitListsTableHeaderStart(MCStreamer *S, MCSymbol *TableStart,
+ MCSymbol *TableEnd) {
+ S->AddComment("Length");
+ S->emitAbsoluteSymbolDiff(TableEnd, TableStart, 4);
+ S->emitLabel(TableStart);
+ S->AddComment("Version");
+ S->emitInt16(S->getContext().getDwarfVersion());
+ S->AddComment("Address size");
+ S->emitInt8(S->getContext().getAsmInfo()->getCodePointerSize());
+ S->AddComment("Segment selector size");
+ S->emitInt8(0);
+}
+
/// Manage the .debug_line_str section contents, if we use it.
class llvm::MCDwarfLineStr {
MCSymbol *LineStrLabel = nullptr;
@@ -925,7 +938,7 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS,
static void EmitGenDwarfInfo(MCStreamer *MCOS,
const MCSymbol *AbbrevSectionSymbol,
const MCSymbol *LineSectionSymbol,
- const MCSymbol *RangesSectionSymbol) {
+ const MCSymbol *RangesSymbol) {
MCContext &context = MCOS->getContext();
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
@@ -977,13 +990,11 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
else
MCOS->emitInt32(0);
- if (RangesSectionSymbol) {
- // There are multiple sections containing code, so we must use the
- // .debug_ranges sections.
-
- // AT_ranges, the 4 byte offset from the start of the .debug_ranges section
- // to the address range list for this compilation unit.
- MCOS->emitSymbolValue(RangesSectionSymbol, 4);
+ if (RangesSymbol) {
+ // There are multiple sections containing code, so we must use
+ // .debug_ranges/.debug_rnglists. AT_ranges, the 4 byte offset from the
+ // start of the .debug_ranges/.debug_rnglists.
+ MCOS->emitSymbolValue(RangesSymbol, 4);
} else {
// If we only have one non-empty code section, we can use the simpler
// AT_low_pc and AT_high_pc attributes.
@@ -1096,37 +1107,65 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
// When generating dwarf for assembly source files this emits the data for
// .debug_ranges section. We only emit one range list, which spans all of the
// executable sections of this file.
-static void EmitGenDwarfRanges(MCStreamer *MCOS) {
+static MCSymbol *emitGenDwarfRanges(MCStreamer *MCOS) {
MCContext &context = MCOS->getContext();
auto &Sections = context.getGenDwarfSectionSyms();
const MCAsmInfo *AsmInfo = context.getAsmInfo();
int AddrSize = AsmInfo->getCodePointerSize();
+ MCSymbol *RangesSymbol;
+
+ if (MCOS->getContext().getDwarfVersion() >= 5) {
+ MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRnglistsSection());
+ MCSymbol *StartSymbol =
+ context.createTempSymbol("debug_rnglists_start", true, true);
+ MCSymbol *EndSymbol =
+ context.createTempSymbol("debug_rnglists_end", true, true);
+ mcdwarf::emitListsTableHeaderStart(MCOS, StartSymbol, EndSymbol);
+ MCOS->AddComment("Offset entry count");
+ MCOS->emitInt32(0);
+ RangesSymbol = context.createTempSymbol("debug_rnglist0_start", true, true);
+ MCOS->emitLabel(RangesSymbol);
+ for (MCSection *Sec : Sections) {
+ const MCSymbol *StartSymbol = Sec->getBeginSymbol();
+ const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
+ const MCExpr *SectionStartAddr = MCSymbolRefExpr::create(
+ StartSymbol, MCSymbolRefExpr::VK_None, context);
+ const MCExpr *SectionSize =
+ MakeStartMinusEndExpr(*MCOS, *StartSymbol, *EndSymbol, 0);
+ MCOS->emitInt8(dwarf::DW_RLE_start_length);
+ MCOS->emitValue(SectionStartAddr, AddrSize);
+ MCOS->emitULEB128Value(SectionSize);
+ }
+ MCOS->emitInt8(dwarf::DW_RLE_end_of_list);
+ MCOS->emitLabel(EndSymbol);
+ } else {
+ MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
+ RangesSymbol = context.createTempSymbol("debug_ranges_start", true, true);
+ MCOS->emitLabel(RangesSymbol);
+ for (MCSection *Sec : Sections) {
+ const MCSymbol *StartSymbol = Sec->getBeginSymbol();
+ const MCSymbol *EndSymbol = Sec->getEndSymbol(context);
+
+ // Emit a base address selection entry for the section start.
+ const MCExpr *SectionStartAddr = MCSymbolRefExpr::create(
+ StartSymbol, MCSymbolRefExpr::VK_None, context);
+ MCOS->emitFill(AddrSize, 0xFF);
+ MCOS->emitValue(SectionStartAddr, AddrSize);
+
+ // Emit a range list entry spanning this section.
+ const MCExpr *SectionSize =
+ MakeStartMinusEndExpr(*MCOS, *StartSymbol, *EndSymbol, 0);
+ MCOS->emitIntValue(0, AddrSize);
+ emitAbsValue(*MCOS, SectionSize, AddrSize);
+ }
- MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
-
- for (MCSection *Sec : Sections) {
- const MCSymbol *StartSymbol = Sec->getBeginSymbol();
- MCSymbol *EndSymbol = Sec->getEndSymbol(context);
- assert(StartSymbol && "StartSymbol must not be NULL");
- assert(EndSymbol && "EndSymbol must not be NULL");
-
- // Emit a base address selection entry for the start of this section
- const MCExpr *SectionStartAddr = MCSymbolRefExpr::create(
- StartSymbol, MCSymbolRefExpr::VK_None, context);
- MCOS->emitFill(AddrSize, 0xFF);
- MCOS->emitValue(SectionStartAddr, AddrSize);
-
- // Emit a range list entry spanning this section
- const MCExpr *SectionSize = MakeStartMinusEndExpr(*MCOS,
- *StartSymbol, *EndSymbol, 0);
+ // Emit end of list entry
+ MCOS->emitIntValue(0, AddrSize);
MCOS->emitIntValue(0, AddrSize);
- emitAbsValue(*MCOS, SectionSize, AddrSize);
}
- // Emit end of list entry
- MCOS->emitIntValue(0, AddrSize);
- MCOS->emitIntValue(0, AddrSize);
+ return RangesSymbol;
}
//
@@ -1145,7 +1184,7 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
LineSectionSymbol = MCOS->getDwarfLineTableSymbol(0);
MCSymbol *AbbrevSectionSymbol = nullptr;
MCSymbol *InfoSectionSymbol = nullptr;
- MCSymbol *RangesSectionSymbol = nullptr;
+ MCSymbol *RangesSymbol = nullptr;
// Create end symbols for each section, and remove empty sections
MCOS->getContext().finalizeDwarfSections(*MCOS);
@@ -1172,30 +1211,22 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
AbbrevSectionSymbol = context.createTempSymbol();
MCOS->emitLabel(AbbrevSectionSymbol);
}
- if (UseRangesSection) {
- MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
- if (CreateDwarfSectionSymbols) {
- RangesSectionSymbol = context.createTempSymbol();
- MCOS->emitLabel(RangesSectionSymbol);
- }
- }
-
- assert((RangesSectionSymbol != nullptr) || !UseRangesSection);
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
// Output the data for .debug_aranges section.
EmitGenDwarfAranges(MCOS, InfoSectionSymbol);
- if (UseRangesSection)
- EmitGenDwarfRanges(MCOS);
+ if (UseRangesSection) {
+ RangesSymbol = emitGenDwarfRanges(MCOS);
+ assert(RangesSymbol);
+ }
// Output the data for .debug_abbrev section.
EmitGenDwarfAbbrev(MCOS);
// Output the data for .debug_info section.
- EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol,
- RangesSectionSymbol);
+ EmitGenDwarfInfo(MCOS, AbbrevSectionSymbol, LineSectionSymbol, RangesSymbol);
}
//