Merge pull request #870 from aguskov/master
Added a patch for LLVM 3.5 to enable proper debugging under Windows
This commit is contained in:
153
llvm_patches/3_5_win_coff_debug_info.patch
Normal file
153
llvm_patches/3_5_win_coff_debug_info.patch
Normal file
@@ -0,0 +1,153 @@
|
||||
# This patch allows ISPC code to be debugged in Visual Studio 2012 and above
|
||||
# Requires LLVM 3.5
|
||||
Index: include/llvm/Support/COFF.h
|
||||
===================================================================
|
||||
--- include/llvm/Support/COFF.h (revision 215535)
|
||||
+++ include/llvm/Support/COFF.h (working copy)
|
||||
@@ -642,9 +642,14 @@
|
||||
|
||||
enum CodeViewLineTableIdentifiers {
|
||||
DEBUG_SECTION_MAGIC = 0x4,
|
||||
+ DEBUG_SYMBOL_SUBSECTION = 0xF1,
|
||||
DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
|
||||
DEBUG_STRING_TABLE_SUBSECTION = 0xF3,
|
||||
- DEBUG_INDEX_SUBSECTION = 0xF4
|
||||
+ DEBUG_INDEX_SUBSECTION = 0xF4,
|
||||
+
|
||||
+ // Symbol subsections are split into subsubsections.
|
||||
+ DEBUG_SYMBOL_PROC_START_SUBSUBSECTION = 0x1147,
|
||||
+ DEBUG_SYMBOL_PROC_END_SUBSUBSECTION = 0x114F
|
||||
};
|
||||
|
||||
inline bool isReservedSectionNumber(int N) {
|
||||
Index: lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
|
||||
===================================================================
|
||||
--- lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp (revision 215535)
|
||||
+++ lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp (working copy)
|
||||
@@ -117,14 +117,15 @@
|
||||
}
|
||||
|
||||
static void EmitLabelDiff(MCStreamer &Streamer,
|
||||
- const MCSymbol *From, const MCSymbol *To) {
|
||||
+ const MCSymbol *From, const MCSymbol *To,
|
||||
+ unsigned int Size = 4) {
|
||||
MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
|
||||
MCContext &Context = Streamer.getContext();
|
||||
const MCExpr *FromRef = MCSymbolRefExpr::Create(From, Variant, Context),
|
||||
*ToRef = MCSymbolRefExpr::Create(To, Variant, Context);
|
||||
const MCExpr *AddrDelta =
|
||||
MCBinaryExpr::Create(MCBinaryExpr::Sub, ToRef, FromRef, Context);
|
||||
- Streamer.EmitValue(AddrDelta, 4);
|
||||
+ Streamer.EmitValue(AddrDelta, Size);
|
||||
}
|
||||
|
||||
void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
|
||||
@@ -132,12 +133,50 @@
|
||||
// which holds the PC to file:line table.
|
||||
const MCSymbol *Fn = Asm->getSymbol(GV);
|
||||
assert(Fn);
|
||||
+ const StringRef FuncName = Fn->getName();
|
||||
|
||||
const FunctionInfo &FI = FnDebugInfo[GV];
|
||||
if (FI.Instrs.empty())
|
||||
return;
|
||||
assert(FI.End && "Don't know where the function ends?");
|
||||
|
||||
+ // Emit a symbol subsection, required by VS2012+ to find function boundaries.
|
||||
+ MCSymbol *SymbolsBegin = Asm->MMI->getContext().CreateTempSymbol(),
|
||||
+ *SymbolsEnd = Asm->MMI->getContext().CreateTempSymbol();
|
||||
+ Asm->OutStreamer.AddComment("Symbol subsection for " + Twine(FuncName));
|
||||
+ Asm->EmitInt32(COFF::DEBUG_SYMBOL_SUBSECTION);
|
||||
+ EmitLabelDiff(Asm->OutStreamer, SymbolsBegin, SymbolsEnd);
|
||||
+ Asm->OutStreamer.EmitLabel(SymbolsBegin);
|
||||
+ {
|
||||
+ MCSymbol *ProcSegmentBegin = Asm->MMI->getContext().CreateTempSymbol(),
|
||||
+ *ProcSegmentEnd = Asm->MMI->getContext().CreateTempSymbol();
|
||||
+ EmitLabelDiff(Asm->OutStreamer, ProcSegmentBegin, ProcSegmentEnd, 2);
|
||||
+ Asm->OutStreamer.EmitLabel(ProcSegmentBegin);
|
||||
+
|
||||
+ Asm->EmitInt16(COFF::DEBUG_SYMBOL_PROC_START_SUBSUBSECTION);
|
||||
+ // Some bytes of this segment don't seem to be required for basic debugging,
|
||||
+ // so just fill them with zeroes.
|
||||
+ Asm->OutStreamer.EmitFill(12, 0);
|
||||
+ // This is the important bit that tells the debugger where the function
|
||||
+ // code is located:
|
||||
+ EmitLabelDiff(Asm->OutStreamer, Fn, FI.End);
|
||||
+ Asm->OutStreamer.EmitFill(12, 0);
|
||||
+ Asm->OutStreamer.EmitCOFFSecRel32(Fn);
|
||||
+ Asm->OutStreamer.EmitCOFFSectionIndex(Fn);
|
||||
+ Asm->EmitInt8(0);
|
||||
+ // Emit the function name as a null-terminated string.
|
||||
+ Asm->OutStreamer.EmitBytes(FuncName);
|
||||
+ Asm->EmitInt8(0);
|
||||
+ Asm->OutStreamer.EmitLabel(ProcSegmentEnd);
|
||||
+
|
||||
+ // We're done with this function.
|
||||
+ Asm->EmitInt16(0x0002);
|
||||
+ Asm->EmitInt16(COFF::DEBUG_SYMBOL_PROC_END_SUBSUBSECTION);
|
||||
+ }
|
||||
+ Asm->OutStreamer.EmitLabel(SymbolsEnd);
|
||||
+ // Every subsection must be aligned to a 4-byte boundary.
|
||||
+ Asm->OutStreamer.EmitFill((-FuncName.size()) % 4, 0);
|
||||
+
|
||||
// PCs/Instructions are grouped into segments sharing the same filename.
|
||||
// Pre-calculate the lengths (in instructions) of these segments and store
|
||||
// them in a map for convenience. Each index in the map is the sequential
|
||||
@@ -154,18 +193,18 @@
|
||||
}
|
||||
FilenameSegmentLengths[LastSegmentEnd] = FI.Instrs.size() - LastSegmentEnd;
|
||||
|
||||
- // Emit the control code of the subsection followed by the payload size.
|
||||
- Asm->OutStreamer.AddComment(
|
||||
- "Linetable subsection for " + Twine(Fn->getName()));
|
||||
+ // Emit a linetable subsection, requred to do PC-to-file:line lookup.
|
||||
+ Asm->OutStreamer.AddComment("Linetable subsection for " + Twine(FuncName));
|
||||
Asm->EmitInt32(COFF::DEBUG_LINE_TABLE_SUBSECTION);
|
||||
- MCSymbol *SubsectionBegin = Asm->MMI->getContext().CreateTempSymbol(),
|
||||
- *SubsectionEnd = Asm->MMI->getContext().CreateTempSymbol();
|
||||
- EmitLabelDiff(Asm->OutStreamer, SubsectionBegin, SubsectionEnd);
|
||||
- Asm->OutStreamer.EmitLabel(SubsectionBegin);
|
||||
+ MCSymbol *LineTableBegin = Asm->MMI->getContext().CreateTempSymbol(),
|
||||
+ *LineTableEnd = Asm->MMI->getContext().CreateTempSymbol();
|
||||
+ EmitLabelDiff(Asm->OutStreamer, LineTableBegin, LineTableEnd);
|
||||
+ Asm->OutStreamer.EmitLabel(LineTableBegin);
|
||||
|
||||
// Identify the function this subsection is for.
|
||||
Asm->OutStreamer.EmitCOFFSecRel32(Fn);
|
||||
Asm->OutStreamer.EmitCOFFSectionIndex(Fn);
|
||||
+ Asm->EmitInt16(0);
|
||||
|
||||
// Length of the function's code, in bytes.
|
||||
EmitLabelDiff(Asm->OutStreamer, Fn, FI.End);
|
||||
@@ -209,7 +248,7 @@
|
||||
|
||||
if (FileSegmentEnd)
|
||||
Asm->OutStreamer.EmitLabel(FileSegmentEnd);
|
||||
- Asm->OutStreamer.EmitLabel(SubsectionEnd);
|
||||
+ Asm->OutStreamer.EmitLabel(LineTableEnd);
|
||||
}
|
||||
|
||||
void WinCodeViewLineTables::endModule() {
|
||||
@@ -254,8 +293,7 @@
|
||||
Asm->OutStreamer.EmitBytes(FileNameRegistry.Filenames[I]);
|
||||
Asm->EmitInt8(0);
|
||||
}
|
||||
-
|
||||
- // No more subsections. Fill with zeros to align the end of the section by 4.
|
||||
+ // Every subsection must be aligned to a 4-byte boundary.
|
||||
Asm->OutStreamer.EmitFill((-FileNameRegistry.LastOffset) % 4, 0);
|
||||
|
||||
clear();
|
||||
Index: lib/MC/WinCOFFStreamer.cpp
|
||||
===================================================================
|
||||
--- lib/MC/WinCOFFStreamer.cpp (revision 215535)
|
||||
+++ lib/MC/WinCOFFStreamer.cpp (working copy)
|
||||
@@ -163,7 +163,7 @@
|
||||
const MCSymbolRefExpr *SRE = MCSymbolRefExpr::Create(Symbol, getContext());
|
||||
MCFixup Fixup = MCFixup::Create(DF->getContents().size(), SRE, FK_SecRel_2);
|
||||
DF->getFixups().push_back(Fixup);
|
||||
- DF->getContents().resize(DF->getContents().size() + 4, 0);
|
||||
+ DF->getContents().resize(DF->getContents().size() + 2, 0);
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) {
|
||||
Reference in New Issue
Block a user