[DWARF] Generate DWARF v5 string offsets tables along with strx* index forms.
Summary: This is the producer side for DWARF v5 string offsets tables. The reader/consumer
side was committed with r321295. All compile and type units in a module share a
contribution to the string offsets table. Indirect strings use the strx{1,2,3,4} index forms.
Reviewers: dblaikie, aprantl, JDevliegehere
Differential Revision: https://reviews.llvm.org/D42021
llvm-svn: 323546
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 1e098cc..a417bc7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -323,6 +323,12 @@
// GDB does not fully support the DWARF 4 representation for bitfields.
UseDWARF2Bitfields = (DwarfVersion < 4) || tuneForGDB();
+ // The DWARF v5 string offsets table has - possibly shared - contributions
+ // from each compile and type unit each preceded by a header. The string
+ // offsets table used by the pre-DWARF v5 split-DWARF implementation uses
+ // a monolithic string offsets table without any header.
+ UseSegmentedStringOffsetsTable = DwarfVersion >= 5;
+
Asm->OutStreamer->getContext().setDwarfVersion(DwarfVersion);
}
@@ -488,6 +494,10 @@
DIUnit->getSourceLanguage());
NewCU.addString(Die, dwarf::DW_AT_name, FN);
+ // Add DW_str_offsets_base to the unit DIE, except for split units.
+ if (useSegmentedStringOffsetsTable() && !useSplitDwarf())
+ NewCU.addStringOffsetsStart();
+
if (!useSplitDwarf()) {
NewCU.initStmtList();
@@ -592,6 +602,13 @@
GVMap[GVE->getVariable()].push_back({&Global, GVE->getExpression()});
}
+ // Create the symbol that designates the start of the unit's contribution
+ // to the string offsets table. In a split DWARF scenario, only the skeleton
+ // unit has the DW_AT_str_offsets_base attribute (and hence needs the symbol).
+ if (useSegmentedStringOffsetsTable())
+ (useSplitDwarf() ? SkeletonHolder : InfoHolder)
+ .setStringOffsetsStartSym(Asm->createTempSymbol("str_offsets_base"));
+
for (DICompileUnit *CUNode : M->debug_compile_units()) {
// FIXME: Move local imported entities into a list attached to the
// subprogram, then this search won't be needed and a
@@ -1401,6 +1418,12 @@
Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection());
}
+void DwarfDebug::emitStringOffsetsTableHeader() {
+ DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
+ Holder.emitStringOffsetsTableHeader(
+ Asm->getObjFileLowering().getDwarfStrOffSection());
+}
+
void DwarfDebug::emitAccel(DwarfAccelTable &Accel, MCSection *Section,
StringRef TableName) {
Accel.FinalizeTable(Asm, TableName);
@@ -1575,8 +1598,14 @@
/// Emit null-terminated strings into a debug str section.
void DwarfDebug::emitDebugStr() {
+ MCSection *StringOffsetsSection = nullptr;
+ if (useSegmentedStringOffsetsTable()) {
+ emitStringOffsetsTableHeader();
+ StringOffsetsSection = Asm->getObjFileLowering().getDwarfStrOffSection();
+ }
DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
- Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection());
+ Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection(),
+ StringOffsetsSection, /* UseRelativeOffsets = */ true);
}
void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
@@ -2026,6 +2055,9 @@
NewCU.initStmtList();
+ if (useSegmentedStringOffsetsTable())
+ NewCU.addStringOffsetsStart();
+
initSkeletonUnit(CU, NewCU.getUnitDie(), std::move(OwnedUnit));
return NewCU;
@@ -2053,14 +2085,22 @@
SplitTypeUnitFileTable.Emit(*Asm->OutStreamer, MCDwarfLineTableParams());
}
+void DwarfDebug::emitStringOffsetsTableHeaderDWO() {
+ assert(useSplitDwarf() && "No split dwarf?");
+ InfoHolder.emitStringOffsetsTableHeader(
+ Asm->getObjFileLowering().getDwarfStrOffDWOSection());
+}
+
// Emit the .debug_str.dwo section for separated dwarf. This contains the
// string section and is identical in format to traditional .debug_str
// sections.
void DwarfDebug::emitDebugStrDWO() {
+ if (useSegmentedStringOffsetsTable())
+ emitStringOffsetsTableHeaderDWO();
assert(useSplitDwarf() && "No split dwarf?");
MCSection *OffSec = Asm->getObjFileLowering().getDwarfStrOffDWOSection();
InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),
- OffSec);
+ OffSec, /* UseRelativeOffsets = */ false);
}
MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) {
@@ -2120,6 +2160,11 @@
NewTU.setSection(Asm->getObjFileLowering().getDwarfTypesSection(Signature));
}
+ // Add DW_AT_str_offsets_base to the type unit DIE, but not for split type
+ // units.
+ if (useSegmentedStringOffsetsTable() && !useSplitDwarf())
+ NewTU.addStringOffsetsStart();
+
NewTU.setType(NewTU.createTypeDIE(CTy));
if (TopLevelType) {