forked from OSchip/llvm-project
DebugInfo: Emit relocation to debug_line section when emitting asm for asm
I don't think this is reachable by any frontend (why would you transform asm to asm+debug info?) but it helps tidy up some of this code, avoid the weird special case of "emit the first CU, store the label, then emit the rest" in MCDwarfLineTable::Emit by instead having the DWARF-for-assembly case use the same codepath as DwarfDebug.cpp, by registering the label of the debug_line section, thus causing it to be emitted. (with a special case in asm output to just emit the label since asm output uses the .loc directives, etc, rather than the debug_loc directly) llvm-svn: 205286
This commit is contained in:
parent
8d265c2633
commit
8bf66c4f3f
|
@ -210,10 +210,10 @@ class MCDwarfLineTable {
|
|||
|
||||
public:
|
||||
// This emits the Dwarf file and the line tables for all Compile Units.
|
||||
static const MCSymbol *Emit(MCStreamer *MCOS);
|
||||
static void Emit(MCStreamer *MCOS);
|
||||
|
||||
// This emits the Dwarf file and the line tables for a given Compile Unit.
|
||||
const MCSymbol *EmitCU(MCStreamer *MCOS) const;
|
||||
void EmitCU(MCStreamer *MCOS) const;
|
||||
|
||||
unsigned getFile(StringRef &Directory, StringRef &FileName,
|
||||
unsigned FileNumber = 0);
|
||||
|
@ -270,7 +270,7 @@ public:
|
|||
// When generating dwarf for assembly source files this emits the Dwarf
|
||||
// sections.
|
||||
//
|
||||
static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol);
|
||||
static void Emit(MCStreamer *MCOS);
|
||||
};
|
||||
|
||||
// When generating dwarf for assembly source files this is the info that is
|
||||
|
|
|
@ -1435,7 +1435,20 @@ void MCAsmStreamer::EmitRawTextImpl(StringRef String) {
|
|||
void MCAsmStreamer::FinishImpl() {
|
||||
// If we are generating dwarf for assembly source files dump out the sections.
|
||||
if (getContext().getGenDwarfForAssembly())
|
||||
MCGenDwarfInfo::Emit(this, NULL);
|
||||
MCGenDwarfInfo::Emit(this);
|
||||
|
||||
// Emit the label for the line table, if requested - since the rest of the
|
||||
// line table will be defined by .loc/.file directives, and not emitted
|
||||
// directly, the label is the only work required here.
|
||||
auto &Tables = getContext().getMCDwarfLineTables();
|
||||
if (!Tables.empty()) {
|
||||
// FIXME: assert Tables.size() == 1 here, except that's not currently true
|
||||
// due to DwarfUnit.cpp:2074.
|
||||
if (auto *Label = Tables.begin()->second.getLabel()) {
|
||||
SwitchSection(getContext().getObjectFileInfo()->getDwarfLineSection());
|
||||
EmitLabel(Label);
|
||||
}
|
||||
}
|
||||
|
||||
if (!UseCFI)
|
||||
EmitFrames(AsmBackend.get(), false);
|
||||
|
|
|
@ -204,24 +204,22 @@ EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section,
|
|||
//
|
||||
// This emits the Dwarf file and the line tables.
|
||||
//
|
||||
const MCSymbol *MCDwarfLineTable::Emit(MCStreamer *MCOS) {
|
||||
void MCDwarfLineTable::Emit(MCStreamer *MCOS) {
|
||||
MCContext &context = MCOS->getContext();
|
||||
|
||||
// CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
|
||||
// not exist, CUID will be 0 and MCLineTableSymbols will be empty.
|
||||
// Handle Compile Unit 0, the line table start symbol is the section symbol.
|
||||
auto I = MCOS->getContext().getMCDwarfLineTables().begin(),
|
||||
E = MCOS->getContext().getMCDwarfLineTables().end();
|
||||
auto &LineTables = context.getMCDwarfLineTables();
|
||||
|
||||
// Bail out early so we don't switch to the debug_line section needlessly and
|
||||
// in doing so create an unnecessary (if empty) section.
|
||||
if (LineTables.empty())
|
||||
return;
|
||||
|
||||
// Switch to the section where the table will be emitted into.
|
||||
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
|
||||
|
||||
const MCSymbol *LineStartSym = I->second.EmitCU(MCOS);
|
||||
// Handle the rest of the Compile Units.
|
||||
for (++I; I != E; ++I)
|
||||
I->second.EmitCU(MCOS);
|
||||
|
||||
return LineStartSym;
|
||||
for (const auto &CUIDTablePair : LineTables)
|
||||
CUIDTablePair.second.EmitCU(MCOS);
|
||||
}
|
||||
|
||||
void MCDwarfDwoLineTable::Emit(MCStreamer &MCOS) const {
|
||||
|
@ -320,10 +318,8 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS,
|
|||
return std::make_pair(LineStartSym, LineEndSym);
|
||||
}
|
||||
|
||||
const MCSymbol *MCDwarfLineTable::EmitCU(MCStreamer *MCOS) const {
|
||||
MCSymbol *LineStartSym;
|
||||
MCSymbol *LineEndSym;
|
||||
std::tie(LineStartSym, LineEndSym) = Header.Emit(MCOS);
|
||||
void MCDwarfLineTable::EmitCU(MCStreamer *MCOS) const {
|
||||
MCSymbol *LineEndSym = Header.Emit(MCOS).second;
|
||||
|
||||
// Put out the line tables.
|
||||
for (const auto &LineSec : MCLineSections.getMCLineEntries())
|
||||
|
@ -344,8 +340,6 @@ const MCSymbol *MCDwarfLineTable::EmitCU(MCStreamer *MCOS) const {
|
|||
// This is the end of the section, so set the value of the symbol at the end
|
||||
// of this section (that was used in a previous expression).
|
||||
MCOS->EmitLabel(LineEndSym);
|
||||
|
||||
return LineStartSym;
|
||||
}
|
||||
|
||||
unsigned MCDwarfLineTable::getFile(StringRef &Directory, StringRef &FileName,
|
||||
|
@ -787,14 +781,17 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
|
|||
// When generating dwarf for assembly source files this emits the Dwarf
|
||||
// sections.
|
||||
//
|
||||
void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
|
||||
void MCGenDwarfInfo::Emit(MCStreamer *MCOS) {
|
||||
// Create the dwarf sections in this order (.debug_line already created).
|
||||
MCContext &context = MCOS->getContext();
|
||||
const MCAsmInfo *AsmInfo = context.getAsmInfo();
|
||||
bool CreateDwarfSectionSymbols =
|
||||
AsmInfo->doesDwarfUseRelocationsAcrossSections();
|
||||
if (!CreateDwarfSectionSymbols)
|
||||
LineSectionSymbol = NULL;
|
||||
MCSymbol *LineSectionSymbol = nullptr;
|
||||
if (CreateDwarfSectionSymbols) {
|
||||
LineSectionSymbol = context.CreateTempSymbol();
|
||||
context.setMCLineTableSymbol(LineSectionSymbol, 0);
|
||||
}
|
||||
MCSymbol *AbbrevSectionSymbol = NULL;
|
||||
MCSymbol *InfoSectionSymbol = NULL;
|
||||
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
|
||||
|
|
|
@ -383,14 +383,12 @@ void MCObjectStreamer::EmitZeros(uint64_t NumBytes) {
|
|||
}
|
||||
|
||||
void MCObjectStreamer::FinishImpl() {
|
||||
// Dump out the dwarf file & directory tables and line tables.
|
||||
const MCSymbol *LineSectionSymbol = NULL;
|
||||
if (getContext().hasMCLineSections())
|
||||
LineSectionSymbol = MCDwarfLineTable::Emit(this);
|
||||
|
||||
// If we are generating dwarf for assembly source files dump out the sections.
|
||||
if (getContext().getGenDwarfForAssembly())
|
||||
MCGenDwarfInfo::Emit(this, LineSectionSymbol);
|
||||
MCGenDwarfInfo::Emit(this);
|
||||
|
||||
// Dump out the dwarf file & directory tables and line tables.
|
||||
MCDwarfLineTable::Emit(this);
|
||||
|
||||
getAssembler().Finish();
|
||||
}
|
||||
|
|
|
@ -661,11 +661,15 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
|
|||
return TokError("unmatched .ifs or .elses");
|
||||
|
||||
// Check to see there are no empty DwarfFile slots.
|
||||
const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles =
|
||||
getContext().getMCDwarfFiles();
|
||||
for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
|
||||
if (MCDwarfFiles[i].Name.empty())
|
||||
TokError("unassigned file number: " + Twine(i) + " for .file directives");
|
||||
const auto &LineTables = getContext().getMCDwarfLineTables();
|
||||
if (!LineTables.empty()) {
|
||||
unsigned Index = 0;
|
||||
for (const auto &File : LineTables.begin()->second.getMCDwarfFiles()) {
|
||||
if (File.Name.empty() && Index != 0)
|
||||
TokError("unassigned file number: " + Twine(Index) +
|
||||
" for .file directives");
|
||||
++Index;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see that all assembler local symbols were actually defined.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// RUN: llvm-mc -g -triple i686-pc-linux-gnu %s -filetype=obj -o - | llvm-readobj -r | FileCheck %s
|
||||
// RUN: llvm-mc -g -triple i686-pc-linux-gnu %s -filetype=asm -o - | FileCheck --check-prefix=ASM %s
|
||||
|
||||
|
||||
// Test that on ELF:
|
||||
|
@ -23,4 +24,23 @@ foo:
|
|||
// CHECK-NEXT: 0x6 R_386_32 .debug_info 0x0
|
||||
// CHECK-NEXT: 0x10 R_386_32 .text 0x0
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK: ]
|
||||
|
||||
// First instance of the section is just to give it a label for debug_aranges to refer to
|
||||
// ASM: .section .debug_info
|
||||
|
||||
// ASM: .section .debug_abbrev
|
||||
// ASM-NEXT: [[ABBREV_LABEL:.Ltmp[0-9]+]]
|
||||
|
||||
// Second instance of the section has the CU
|
||||
// ASM: .section .debug_info
|
||||
// Dwarf version
|
||||
// ASM: .short 2
|
||||
// ASM-NEXT: .long [[ABBREV_LABEL]]
|
||||
// First .byte 1 is the abbreviation number for the compile_unit abbrev
|
||||
// ASM: .byte 1
|
||||
// ASM-NEXT: .long [[LINE_LABEL:.Ltmp[0-9]+]]
|
||||
|
||||
// ASM: .section .debug_line
|
||||
// ASM-NEXT: [[LINE_LABEL]]
|
||||
|
||||
|
|
Loading…
Reference in New Issue