aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp19
-rw-r--r--llvm/lib/MC/MCDwarf.cpp32
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp16
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp20
-rw-r--r--llvm/lib/MC/MCStreamer.cpp6
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()) {