aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCDwarf.cpp
diff options
context:
space:
mode:
authorKyungwoo Lee <kyulee@fb.com>2021-11-14 20:18:36 -0800
committerKyungwoo Lee <kyulee@fb.com>2021-11-14 20:19:47 -0800
commit6747d44bda8c460c90c2276ac6e2402d434e0780 (patch)
treeeda99b5316d527599fcc4f3b98f0bc0808942dbe /llvm/lib/MC/MCDwarf.cpp
parentcda72e92971bc8b4e88f89fd01e18ee55376b84f (diff)
downloadllvm-6747d44bda8c460c90c2276ac6e2402d434e0780.zip
llvm-6747d44bda8c460c90c2276ac6e2402d434e0780.tar.gz
llvm-6747d44bda8c460c90c2276ac6e2402d434e0780.tar.bz2
[DebugInfo] Fix end_sequence of debug_line in LTO Object
In a LTO build, the `end_sequence` in debug_line table for each compile unit (CU) points the end of text section which merged all CUs. The `end_sequence` needs to point to the end of each CU's range. This bug often causes invalid `debug_line` table in the final `.dSYM` binary for MachO after running `dsymutil` which tries to compensate an out-of-range address of `end_sequence`. The fix is to sync the line table termination with the range operations that are already maintained in DwarfDebug. When CU or section changes, or nodebug functions appear or module is finished, the prior pending line table is terminated using the last range label. In the MC path where no range is tracked, the old logic is conservatively used to end the line table using the section end symbol. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D108261
Diffstat (limited to 'llvm/lib/MC/MCDwarf.cpp')
-rw-r--r--llvm/lib/MC/MCDwarf.cpp59
1 files changed, 48 insertions, 11 deletions
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index ef0cc81..1c9cfb9 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -141,6 +141,24 @@ makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal) {
return Res;
}
+void MCLineSection::addEndEntry(MCSymbol *EndLabel) {
+ auto *Sec = &EndLabel->getSection();
+ // The line table may be empty, which we should skip adding an end entry.
+ // There are two cases:
+ // (1) MCAsmStreamer - emitDwarfLocDirective emits a location directive in
+ // place instead of adding a line entry if the target has
+ // usesDwarfFileAndLocDirectives.
+ // (2) MCObjectStreamer - if a function has incomplete debug info where
+ // instructions don't have DILocations, the line entries are missing.
+ auto I = MCLineDivisions.find(Sec);
+ if (I != MCLineDivisions.end()) {
+ auto &Entries = I->second;
+ auto EndEntry = Entries.back();
+ EndEntry.setEndLabel(EndLabel);
+ Entries.push_back(EndEntry);
+ }
+}
+
//
// This emits the Dwarf line table for the specified section from the entries
// in the LineSection.
@@ -148,16 +166,33 @@ makeStartPlusIntExpr(MCContext &Ctx, const MCSymbol &Start, int IntVal) {
void MCDwarfLineTable::emitOne(
MCStreamer *MCOS, MCSection *Section,
const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
- unsigned FileNum = 1;
- unsigned LastLine = 1;
- unsigned Column = 0;
- unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
- unsigned Isa = 0;
- unsigned Discriminator = 0;
- MCSymbol *LastLabel = nullptr;
+
+ unsigned FileNum, LastLine, Column, Flags, Isa, Discriminator;
+ MCSymbol *LastLabel;
+ auto init = [&]() {
+ FileNum = 1;
+ LastLine = 1;
+ Column = 0;
+ Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
+ Isa = 0;
+ Discriminator = 0;
+ LastLabel = nullptr;
+ };
+ init();
// Loop through each MCDwarfLineEntry and encode the dwarf line number table.
+ bool EndEntryEmitted = false;
for (const MCDwarfLineEntry &LineEntry : LineEntries) {
+ MCSymbol *Label = LineEntry.getLabel();
+ const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
+ if (LineEntry.IsEndEntry) {
+ MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label,
+ asmInfo->getCodePointerSize());
+ init();
+ EndEntryEmitted = true;
+ continue;
+ }
+
int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
if (FileNum != LineEntry.getFileNum()) {
@@ -195,12 +230,9 @@ void MCDwarfLineTable::emitOne(
if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
- MCSymbol *Label = LineEntry.getLabel();
-
// At this point we want to emit/create the sequence to encode the delta in
// line numbers and the increment of the address from the previous Label
// and the current Label.
- const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
asmInfo->getCodePointerSize());
@@ -210,7 +242,12 @@ void MCDwarfLineTable::emitOne(
}
// Generate DWARF line end entry.
- MCOS->emitDwarfLineEndEntry(Section, LastLabel);
+ // We do not need this for DwarfDebug that explicitly terminates the line
+ // 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)
+ MCOS->emitDwarfLineEndEntry(Section, LastLabel);
}
//