From 75759254c399e733bd546dce91653d918d972a5b Mon Sep 17 00:00:00 2001 From: Andrey Guskov Date: Tue, 14 Oct 2014 15:58:23 +0400 Subject: [PATCH 1/2] Added a patch for LLVM 3.5 to enable proper debugging under Windows --- llvm_patches/3_5_win_coff_debug_info.patch | 151 +++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 llvm_patches/3_5_win_coff_debug_info.patch diff --git a/llvm_patches/3_5_win_coff_debug_info.patch b/llvm_patches/3_5_win_coff_debug_info.patch new file mode 100644 index 00000000..d0ed26c1 --- /dev/null +++ b/llvm_patches/3_5_win_coff_debug_info.patch @@ -0,0 +1,151 @@ +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) { From efee86fa2ecd7f10287f935a5e505ffed3cd3cda Mon Sep 17 00:00:00 2001 From: aguskov Date: Tue, 14 Oct 2014 17:17:49 +0400 Subject: [PATCH 2/2] Update 3_5_win_coff_debug_info.patch --- llvm_patches/3_5_win_coff_debug_info.patch | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm_patches/3_5_win_coff_debug_info.patch b/llvm_patches/3_5_win_coff_debug_info.patch index d0ed26c1..b1d26469 100644 --- a/llvm_patches/3_5_win_coff_debug_info.patch +++ b/llvm_patches/3_5_win_coff_debug_info.patch @@ -1,3 +1,5 @@ +# 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)