summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp51
1 files changed, 40 insertions, 11 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 0eb3e44fba1..3f3408eb368 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -18,6 +18,7 @@
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/COFF.h"
#include "llvm/Target/TargetSubtargetInfo.h"
@@ -217,19 +218,19 @@ void CodeViewDebug::maybeRecordLocation(DebugLoc DL,
/*IsStmt=*/false, DL->getFilename());
}
+void CodeViewDebug::emitCodeViewMagicVersion() {
+ OS.EmitValueToAlignment(4);
+ OS.AddComment("Debug section magic");
+ OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
+}
+
void CodeViewDebug::endModule() {
if (FnDebugInfo.empty())
return;
emitTypeInformation();
- // FIXME: For functions that are comdat, we should emit separate .debug$S
- // sections that are comdat associative with the main function instead of
- // having one big .debug$S section.
assert(Asm != nullptr);
- OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugSymbolsSection());
- OS.AddComment("Debug section magic");
- OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
// The COFF .debug$S section consists of several subsections, each starting
// with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length
@@ -237,12 +238,16 @@ void CodeViewDebug::endModule() {
// aligned.
// Make a subsection for all the inlined subprograms.
- emitInlineeFuncIdsAndLines();
+ emitInlineeLinesSubsection();
// Emit per-function debug information.
for (auto &P : FnDebugInfo)
emitDebugInfoForFunction(P.first, P.second);
+ // Switch back to the generic .debug$S section after potentially processing
+ // comdat symbol sections.
+ switchToDebugSectionForSymbol(nullptr);
+
// This subsection holds a file index to offset in string table table.
OS.AddComment("File index to string table offset subsection");
OS.EmitCVFileChecksumsDirective();
@@ -275,9 +280,7 @@ void CodeViewDebug::emitTypeInformation() {
// Start the .debug$T section with 0x4.
OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
- OS.AddComment("Debug section magic");
- OS.EmitValueToAlignment(4);
- OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
+ emitCodeViewMagicVersion();
TypeTable.ForEachRecord(
[&](TypeIndex Index, const MemoryTypeTableBuilder::Record *R) {
@@ -298,10 +301,13 @@ void CodeViewDebug::emitTypeInformation() {
});
}
-void CodeViewDebug::emitInlineeFuncIdsAndLines() {
+void CodeViewDebug::emitInlineeLinesSubsection() {
if (InlinedSubprograms.empty())
return;
+ // Use the generic .debug$S section.
+ switchToDebugSectionForSymbol(nullptr);
+
MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(),
*InlineEnd = MMI->getContext().createTempSymbol();
@@ -401,6 +407,26 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI,
OS.EmitIntValue(SymbolKind::S_INLINESITE_END, 2); // RecordKind
}
+void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) {
+ // If we have a symbol, it may be in a section that is COMDAT. If so, find the
+ // comdat key. A section may be comdat because of -ffunction-sections or
+ // because it is comdat in the IR.
+ MCSectionCOFF *GVSec =
+ GVSym ? dyn_cast<MCSectionCOFF>(&GVSym->getSection()) : nullptr;
+ const MCSymbol *KeySym = GVSec ? GVSec->getCOMDATSymbol() : nullptr;
+
+ MCSectionCOFF *DebugSec = cast<MCSectionCOFF>(
+ Asm->getObjFileLowering().getCOFFDebugSymbolsSection());
+ DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym);
+
+ OS.SwitchSection(DebugSec);
+
+ // Emit the magic version number if this is the first time we've switched to
+ // this section.
+ if (ComdatDebugSections.insert(DebugSec).second)
+ emitCodeViewMagicVersion();
+}
+
void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
FunctionInfo &FI) {
// For each function there is a separate subsection
@@ -408,6 +434,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
const MCSymbol *Fn = Asm->getSymbol(GV);
assert(Fn);
+ // Switch to the to a comdat section, if appropriate.
+ switchToDebugSectionForSymbol(Fn);
+
StringRef FuncName;
if (auto *SP = GV->getSubprogram())
FuncName = SP->getDisplayName();
OpenPOWER on IntegriCloud