diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 6 |
5 files changed, 81 insertions, 12 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 295531f..31b519a 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -301,6 +301,8 @@ public: unsigned Flags, unsigned Isa, unsigned Discriminator, StringRef FileName) override; + virtual void emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) override; + MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override; bool emitCVFileDirective(unsigned FileNo, StringRef Filename, @@ -429,7 +431,8 @@ public: void emitDwarfLineStartLabel(MCSymbol *StartSym) override; - void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override; + void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel, + MCSymbol *EndLabel = nullptr) override; void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, @@ -1767,6 +1770,12 @@ void MCAsmStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line, Discriminator, FileName); } +void MCAsmStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) { + MCStreamer::emitDwarfLocLabelDirective(Loc, Name); + OS << ".loc_label\t" << Name; + EmitEOL(); +} + MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) { // Always use the zeroth line table, since asm syntax only supports one line // table for now. @@ -2579,7 +2588,8 @@ void MCAsmStreamer::emitDwarfLineStartLabel(MCSymbol *StartSym) { } void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section, - MCSymbol *LastLabel) { + MCSymbol *LastLabel, + MCSymbol *EndLabel) { // If the targets write the raw debug line data for assembly output (We can // not switch to Section and add the end symbol there for assembly output) // we currently use the .text end label as any section end. This will not @@ -2596,9 +2606,10 @@ void MCAsmStreamer::emitDwarfLineEndEntry(MCSection *Section, MCSection *TextSection = Ctx.getObjectFileInfo()->getTextSection(); assert(TextSection->hasEnded() && ".text section is not end!"); - MCSymbol *SectionEnd = TextSection->getEndSymbol(Ctx); + if (!EndLabel) + EndLabel = TextSection->getEndSymbol(Ctx); const MCAsmInfo *AsmInfo = Ctx.getAsmInfo(); - emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd, + emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel, AsmInfo->getCodePointerSize()); } diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 0dd1137..8ff097f 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -172,6 +172,7 @@ void MCDwarfLineTable::emitOne( const MCLineSection::MCDwarfLineEntryCollection &LineEntries) { unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator; + bool IsAtStartSeq; MCSymbol *LastLabel; auto init = [&]() { FileNum = 1; @@ -181,6 +182,7 @@ void MCDwarfLineTable::emitOne( Isa = 0; Discriminator = 0; LastLabel = nullptr; + IsAtStartSeq = true; }; init(); @@ -189,6 +191,17 @@ void MCDwarfLineTable::emitOne( for (const MCDwarfLineEntry &LineEntry : LineEntries) { MCSymbol *Label = LineEntry.getLabel(); const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); + + if (LineEntry.LineStreamLabel) { + if (!IsAtStartSeq) { + MCOS->emitDwarfLineEndEntry(Section, LastLabel, + /*EndLabel =*/LastLabel); + init(); + } + MCOS->emitLabel(LineEntry.LineStreamLabel, LineEntry.StreamLabelDefLoc); + continue; + } + if (LineEntry.IsEndEntry) { MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label, asmInfo->getCodePointerSize()); @@ -243,6 +256,7 @@ void MCDwarfLineTable::emitOne( Discriminator = 0; LastLine = LineEntry.getLine(); LastLabel = Label; + IsAtStartSeq = false; } // Generate DWARF line end entry. @@ -250,10 +264,26 @@ void MCDwarfLineTable::emitOne( // table using ranges whenever CU or section changes. However, the MC path // does not track ranges nor terminate the line table. In that case, // conservatively use the section end symbol to end the line table. - if (!EndEntryEmitted) + if (!EndEntryEmitted && !IsAtStartSeq) MCOS->emitDwarfLineEndEntry(Section, LastLabel); } +void MCDwarfLineTable::endCurrentSeqAndEmitLineStreamLabel(MCStreamer *MCOS, + SMLoc DefLoc, + StringRef Name) { + auto &ctx = MCOS->getContext(); + auto *LineStreamLabel = ctx.getOrCreateSymbol(Name); + auto *LineSym = ctx.createTempSymbol(); + MCOS->emitLabel(LineSym); + const MCDwarfLoc &DwarfLoc = ctx.getCurrentDwarfLoc(); + + // Create a 'fake' line entry by having LineStreamLabel be non-null. This + // won't actually emit any line information, it will reset the line table + // sequence and emit a label at the start of the new line table sequence. + MCDwarfLineEntry LineEntry(LineSym, DwarfLoc, LineStreamLabel, DefLoc); + getMCLineSections().addLineEntry(LineEntry, MCOS->getCurrentSectionOnly()); +} + // // This emits the Dwarf file and the line tables. // diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 9dc3974..b2b2143 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -467,12 +467,16 @@ void MCObjectStreamer::emitDwarfAdvanceLineAddr(int64_t LineDelta, } void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section, - MCSymbol *LastLabel) { - // Emit a DW_LNE_end_sequence for the end of the section. - // Use the section end label to compute the address delta and use INT64_MAX - // as the line delta which is the signal that this is actually a + MCSymbol *LastLabel, + MCSymbol *EndLabel) { + // Emit a DW_LNE_end_sequence into the line table. When EndLabel is null, it + // means we should emit the entry for the end of the section and therefore we + // use the section end label for the reference label. After having the + // appropriate reference label, we emit the address delta and use INT64_MAX as + // the line delta which is the signal that this is actually a // DW_LNE_end_sequence. - MCSymbol *SectionEnd = endSection(Section); + if (!EndLabel) + EndLabel = endSection(Section); // Switch back the dwarf line section, in case endSection had to switch the // section. @@ -480,7 +484,7 @@ void MCObjectStreamer::emitDwarfLineEndEntry(MCSection *Section, switchSection(Ctx.getObjectFileInfo()->getDwarfLineSection()); const MCAsmInfo *AsmInfo = Ctx.getAsmInfo(); - emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd, + emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, EndLabel, AsmInfo->getCodePointerSize()); } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 14f98db..a86c092 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -485,6 +485,7 @@ private: DK_FILE, DK_LINE, DK_LOC, + DK_LOC_LABEL, DK_STABS, DK_CV_FILE, DK_CV_FUNC_ID, @@ -580,10 +581,11 @@ private: // ".align{,32}", ".p2align{,w,l}" bool parseDirectiveAlign(bool IsPow2, unsigned ValueSize); - // ".file", ".line", ".loc", ".stabs" + // ".file", ".line", ".loc", ".loc_label", ".stabs" bool parseDirectiveFile(SMLoc DirectiveLoc); bool parseDirectiveLine(); bool parseDirectiveLoc(); + bool parseDirectiveLocLabel(SMLoc DirectiveLoc); bool parseDirectiveStabs(); // ".cv_file", ".cv_func_id", ".cv_inline_site_id", ".cv_loc", ".cv_linetable", @@ -2156,6 +2158,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, return parseDirectiveLine(); case DK_LOC: return parseDirectiveLoc(); + case DK_LOC_LABEL: + return parseDirectiveLocLabel(IDLoc); case DK_STABS: return parseDirectiveStabs(); case DK_CV_FILE: @@ -3733,6 +3737,19 @@ bool AsmParser::parseDirectiveLoc() { return false; } +/// parseDirectiveLoc +/// ::= .loc_label label +bool AsmParser::parseDirectiveLocLabel(SMLoc DirectiveLoc) { + StringRef Name; + DirectiveLoc = Lexer.getLoc(); + if (parseIdentifier(Name)) + return TokError("expected identifier"); + if (parseEOL()) + return true; + getStreamer().emitDwarfLocLabelDirective(DirectiveLoc, Name); + return false; +} + /// parseDirectiveStabs /// ::= .stabs string, number, number, number bool AsmParser::parseDirectiveStabs() { @@ -5541,6 +5558,7 @@ void AsmParser::initializeDirectiveKindMap() { DirectiveKindMap[".file"] = DK_FILE; DirectiveKindMap[".line"] = DK_LINE; DirectiveKindMap[".loc"] = DK_LOC; + DirectiveKindMap[".loc_label"] = DK_LOC_LABEL; DirectiveKindMap[".stabs"] = DK_STABS; DirectiveKindMap[".cv_file"] = DK_CV_FILE; DirectiveKindMap[".cv_func_id"] = DK_CV_FUNC_ID; diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 1594bd3..13b1627 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -267,6 +267,12 @@ void MCStreamer::emitDwarfLocDirective(unsigned FileNo, unsigned Line, Discriminator); } +void MCStreamer::emitDwarfLocLabelDirective(SMLoc Loc, StringRef Name) { + getContext() + .getMCDwarfLineTable(getContext().getDwarfCompileUnitID()) + .endCurrentSeqAndEmitLineStreamLabel(this, Loc, Name); +} + MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) { MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID); if (!Table.getLabel()) { |