Merging r257977:
[oota-llvm.git] / lib / CodeGen / AsmPrinter / WinCodeViewLineTables.cpp
1 //===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp --*- C++ -*--===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains support for writing line tables info into COFF files.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "WinCodeViewLineTables.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCSymbol.h"
17 #include "llvm/Support/COFF.h"
18
19 namespace llvm {
20
21 StringRef WinCodeViewLineTables::getFullFilepath(const MDNode *S) {
22   assert(S);
23   assert((isa<DICompileUnit>(S) || isa<DIFile>(S) || isa<DISubprogram>(S) ||
24           isa<DILexicalBlockBase>(S)) &&
25          "Unexpected scope info");
26
27   auto *Scope = cast<DIScope>(S);
28   StringRef Dir = Scope->getDirectory(),
29             Filename = Scope->getFilename();
30   std::string &Filepath =
31       DirAndFilenameToFilepathMap[std::make_pair(Dir, Filename)];
32   if (!Filepath.empty())
33     return Filepath;
34
35   // Clang emits directory and relative filename info into the IR, but CodeView
36   // operates on full paths.  We could change Clang to emit full paths too, but
37   // that would increase the IR size and probably not needed for other users.
38   // For now, just concatenate and canonicalize the path here.
39   if (Filename.find(':') == 1)
40     Filepath = Filename;
41   else
42     Filepath = (Dir + "\\" + Filename).str();
43
44   // Canonicalize the path.  We have to do it textually because we may no longer
45   // have access the file in the filesystem.
46   // First, replace all slashes with backslashes.
47   std::replace(Filepath.begin(), Filepath.end(), '/', '\\');
48
49   // Remove all "\.\" with "\".
50   size_t Cursor = 0;
51   while ((Cursor = Filepath.find("\\.\\", Cursor)) != std::string::npos)
52     Filepath.erase(Cursor, 2);
53
54   // Replace all "\XXX\..\" with "\".  Don't try too hard though as the original
55   // path should be well-formatted, e.g. start with a drive letter, etc.
56   Cursor = 0;
57   while ((Cursor = Filepath.find("\\..\\", Cursor)) != std::string::npos) {
58     // Something's wrong if the path starts with "\..\", abort.
59     if (Cursor == 0)
60       break;
61
62     size_t PrevSlash = Filepath.rfind('\\', Cursor - 1);
63     if (PrevSlash == std::string::npos)
64       // Something's wrong, abort.
65       break;
66
67     Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash);
68     // The next ".." might be following the one we've just erased.
69     Cursor = PrevSlash;
70   }
71
72   // Remove all duplicate backslashes.
73   Cursor = 0;
74   while ((Cursor = Filepath.find("\\\\", Cursor)) != std::string::npos)
75     Filepath.erase(Cursor, 1);
76
77   return Filepath;
78 }
79
80 void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL,
81                                                 const MachineFunction *MF) {
82   const MDNode *Scope = DL.getScope();
83   if (!Scope)
84     return;
85   unsigned LineNumber = DL.getLine();
86   // Skip this line if it is longer than the maximum we can record.
87   if (LineNumber > COFF::CVL_MaxLineNumber)
88     return;
89
90   unsigned ColumnNumber = DL.getCol();
91   // Truncate the column number if it is longer than the maximum we can record.
92   if (ColumnNumber > COFF::CVL_MaxColumnNumber)
93     ColumnNumber = 0;
94
95   StringRef Filename = getFullFilepath(Scope);
96
97   // Skip this instruction if it has the same file:line as the previous one.
98   assert(CurFn);
99   if (!CurFn->Instrs.empty()) {
100     const InstrInfoTy &LastInstr = InstrInfo[CurFn->Instrs.back()];
101     if (LastInstr.Filename == Filename && LastInstr.LineNumber == LineNumber &&
102         LastInstr.ColumnNumber == ColumnNumber)
103       return;
104   }
105   FileNameRegistry.add(Filename);
106
107   MCSymbol *MCL = Asm->MMI->getContext().createTempSymbol();
108   Asm->OutStreamer->EmitLabel(MCL);
109   CurFn->Instrs.push_back(MCL);
110   InstrInfo[MCL] = InstrInfoTy(Filename, LineNumber, ColumnNumber);
111 }
112
113 WinCodeViewLineTables::WinCodeViewLineTables(AsmPrinter *AP)
114     : Asm(nullptr), CurFn(nullptr) {
115   MachineModuleInfo *MMI = AP->MMI;
116
117   // If module doesn't have named metadata anchors or COFF debug section
118   // is not available, skip any debug info related stuff.
119   if (!MMI->getModule()->getNamedMetadata("llvm.dbg.cu") ||
120       !AP->getObjFileLowering().getCOFFDebugSymbolsSection())
121     return;
122
123   // Tell MMI that we have debug info.
124   MMI->setDebugInfoAvailability(true);
125   Asm = AP;
126 }
127
128 void WinCodeViewLineTables::endModule() {
129   if (FnDebugInfo.empty())
130     return;
131
132   assert(Asm != nullptr);
133   Asm->OutStreamer->SwitchSection(
134       Asm->getObjFileLowering().getCOFFDebugSymbolsSection());
135   Asm->EmitInt32(COFF::DEBUG_SECTION_MAGIC);
136
137   // The COFF .debug$S section consists of several subsections, each starting
138   // with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length
139   // of the payload followed by the payload itself.  The subsections are 4-byte
140   // aligned.
141
142   // Emit per-function debug information.  This code is extracted into a
143   // separate function for readability.
144   for (size_t I = 0, E = VisitedFunctions.size(); I != E; ++I)
145     emitDebugInfoForFunction(VisitedFunctions[I]);
146
147   // This subsection holds a file index to offset in string table table.
148   Asm->OutStreamer->AddComment("File index to string table offset subsection");
149   Asm->EmitInt32(COFF::DEBUG_INDEX_SUBSECTION);
150   size_t NumFilenames = FileNameRegistry.Infos.size();
151   Asm->EmitInt32(8 * NumFilenames);
152   for (size_t I = 0, E = FileNameRegistry.Filenames.size(); I != E; ++I) {
153     StringRef Filename = FileNameRegistry.Filenames[I];
154     // For each unique filename, just write its offset in the string table.
155     Asm->EmitInt32(FileNameRegistry.Infos[Filename].StartOffset);
156     // The function name offset is not followed by any additional data.
157     Asm->EmitInt32(0);
158   }
159
160   // This subsection holds the string table.
161   Asm->OutStreamer->AddComment("String table");
162   Asm->EmitInt32(COFF::DEBUG_STRING_TABLE_SUBSECTION);
163   Asm->EmitInt32(FileNameRegistry.LastOffset);
164   // The payload starts with a null character.
165   Asm->EmitInt8(0);
166
167   for (size_t I = 0, E = FileNameRegistry.Filenames.size(); I != E; ++I) {
168     // Just emit unique filenames one by one, separated by a null character.
169     Asm->OutStreamer->EmitBytes(FileNameRegistry.Filenames[I]);
170     Asm->EmitInt8(0);
171   }
172
173   // No more subsections. Fill with zeros to align the end of the section by 4.
174   Asm->OutStreamer->EmitFill((-FileNameRegistry.LastOffset) % 4, 0);
175
176   clear();
177 }
178
179 static void EmitLabelDiff(MCStreamer &Streamer,
180                           const MCSymbol *From, const MCSymbol *To,
181                           unsigned int Size = 4) {
182   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
183   MCContext &Context = Streamer.getContext();
184   const MCExpr *FromRef = MCSymbolRefExpr::create(From, Variant, Context),
185                *ToRef   = MCSymbolRefExpr::create(To, Variant, Context);
186   const MCExpr *AddrDelta =
187       MCBinaryExpr::create(MCBinaryExpr::Sub, ToRef, FromRef, Context);
188   Streamer.EmitValue(AddrDelta, Size);
189 }
190
191 void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
192   // For each function there is a separate subsection
193   // which holds the PC to file:line table.
194   const MCSymbol *Fn = Asm->getSymbol(GV);
195   assert(Fn);
196
197   const FunctionInfo &FI = FnDebugInfo[GV];
198   if (FI.Instrs.empty())
199     return;
200   assert(FI.End && "Don't know where the function ends?");
201
202   StringRef GVName = GV->getName();
203   StringRef FuncName;
204   if (auto *SP = getDISubprogram(GV))
205     FuncName = SP->getDisplayName();
206
207   // FIXME Clang currently sets DisplayName to "bar" for a C++
208   // "namespace_foo::bar" function, see PR21528.  Luckily, dbghelp.dll is trying
209   // to demangle display names anyways, so let's just put a mangled name into
210   // the symbols subsection until Clang gives us what we need.
211   if (GVName.startswith("\01?"))
212     FuncName = GVName.substr(1);
213   // Emit a symbol subsection, required by VS2012+ to find function boundaries.
214   MCSymbol *SymbolsBegin = Asm->MMI->getContext().createTempSymbol(),
215            *SymbolsEnd = Asm->MMI->getContext().createTempSymbol();
216   Asm->OutStreamer->AddComment("Symbol subsection for " + Twine(FuncName));
217   Asm->EmitInt32(COFF::DEBUG_SYMBOL_SUBSECTION);
218   EmitLabelDiff(*Asm->OutStreamer, SymbolsBegin, SymbolsEnd);
219   Asm->OutStreamer->EmitLabel(SymbolsBegin);
220   {
221     MCSymbol *ProcSegmentBegin = Asm->MMI->getContext().createTempSymbol(),
222              *ProcSegmentEnd = Asm->MMI->getContext().createTempSymbol();
223     EmitLabelDiff(*Asm->OutStreamer, ProcSegmentBegin, ProcSegmentEnd, 2);
224     Asm->OutStreamer->EmitLabel(ProcSegmentBegin);
225
226     Asm->EmitInt16(COFF::DEBUG_SYMBOL_TYPE_PROC_START);
227     // Some bytes of this segment don't seem to be required for basic debugging,
228     // so just fill them with zeroes.
229     Asm->OutStreamer->EmitFill(12, 0);
230     // This is the important bit that tells the debugger where the function
231     // code is located and what's its size:
232     EmitLabelDiff(*Asm->OutStreamer, Fn, FI.End);
233     Asm->OutStreamer->EmitFill(12, 0);
234     Asm->OutStreamer->EmitCOFFSecRel32(Fn);
235     Asm->OutStreamer->EmitCOFFSectionIndex(Fn);
236     Asm->EmitInt8(0);
237     // Emit the function display name as a null-terminated string.
238     Asm->OutStreamer->EmitBytes(FuncName);
239     Asm->EmitInt8(0);
240     Asm->OutStreamer->EmitLabel(ProcSegmentEnd);
241
242     // We're done with this function.
243     Asm->EmitInt16(0x0002);
244     Asm->EmitInt16(COFF::DEBUG_SYMBOL_TYPE_PROC_END);
245   }
246   Asm->OutStreamer->EmitLabel(SymbolsEnd);
247   // Every subsection must be aligned to a 4-byte boundary.
248   Asm->OutStreamer->EmitFill((-FuncName.size()) % 4, 0);
249
250   // PCs/Instructions are grouped into segments sharing the same filename.
251   // Pre-calculate the lengths (in instructions) of these segments and store
252   // them in a map for convenience.  Each index in the map is the sequential
253   // number of the respective instruction that starts a new segment.
254   DenseMap<size_t, size_t> FilenameSegmentLengths;
255   size_t LastSegmentEnd = 0;
256   StringRef PrevFilename = InstrInfo[FI.Instrs[0]].Filename;
257   for (size_t J = 1, F = FI.Instrs.size(); J != F; ++J) {
258     if (PrevFilename == InstrInfo[FI.Instrs[J]].Filename)
259       continue;
260     FilenameSegmentLengths[LastSegmentEnd] = J - LastSegmentEnd;
261     LastSegmentEnd = J;
262     PrevFilename = InstrInfo[FI.Instrs[J]].Filename;
263   }
264   FilenameSegmentLengths[LastSegmentEnd] = FI.Instrs.size() - LastSegmentEnd;
265
266   // Emit a line table subsection, required to do PC-to-file:line lookup.
267   Asm->OutStreamer->AddComment("Line table subsection for " + Twine(FuncName));
268   Asm->EmitInt32(COFF::DEBUG_LINE_TABLE_SUBSECTION);
269   MCSymbol *LineTableBegin = Asm->MMI->getContext().createTempSymbol(),
270            *LineTableEnd = Asm->MMI->getContext().createTempSymbol();
271   EmitLabelDiff(*Asm->OutStreamer, LineTableBegin, LineTableEnd);
272   Asm->OutStreamer->EmitLabel(LineTableBegin);
273
274   // Identify the function this subsection is for.
275   Asm->OutStreamer->EmitCOFFSecRel32(Fn);
276   Asm->OutStreamer->EmitCOFFSectionIndex(Fn);
277   // Insert flags after a 16-bit section index.
278   Asm->EmitInt16(COFF::DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS);
279
280   // Length of the function's code, in bytes.
281   EmitLabelDiff(*Asm->OutStreamer, Fn, FI.End);
282
283   // PC-to-linenumber lookup table:
284   MCSymbol *FileSegmentEnd = nullptr;
285
286   // The start of the last segment:
287   size_t LastSegmentStart = 0;
288
289   auto FinishPreviousChunk = [&] {
290     if (!FileSegmentEnd)
291       return;
292     for (size_t ColSegI = LastSegmentStart,
293                 ColSegEnd = ColSegI + FilenameSegmentLengths[LastSegmentStart];
294          ColSegI != ColSegEnd; ++ColSegI) {
295       unsigned ColumnNumber = InstrInfo[FI.Instrs[ColSegI]].ColumnNumber;
296       assert(ColumnNumber <= COFF::CVL_MaxColumnNumber);
297       Asm->EmitInt16(ColumnNumber); // Start column
298       Asm->EmitInt16(0);            // End column
299     }
300     Asm->OutStreamer->EmitLabel(FileSegmentEnd);
301   };
302
303   for (size_t J = 0, F = FI.Instrs.size(); J != F; ++J) {
304     MCSymbol *Instr = FI.Instrs[J];
305     assert(InstrInfo.count(Instr));
306
307     if (FilenameSegmentLengths.count(J)) {
308       // We came to a beginning of a new filename segment.
309       FinishPreviousChunk();
310       StringRef CurFilename = InstrInfo[FI.Instrs[J]].Filename;
311       assert(FileNameRegistry.Infos.count(CurFilename));
312       size_t IndexInStringTable =
313           FileNameRegistry.Infos[CurFilename].FilenameID;
314       // Each segment starts with the offset of the filename
315       // in the string table.
316       Asm->OutStreamer->AddComment(
317           "Segment for file '" + Twine(CurFilename) + "' begins");
318       MCSymbol *FileSegmentBegin = Asm->MMI->getContext().createTempSymbol();
319       Asm->OutStreamer->EmitLabel(FileSegmentBegin);
320       Asm->EmitInt32(8 * IndexInStringTable);
321
322       // Number of PC records in the lookup table.
323       size_t SegmentLength = FilenameSegmentLengths[J];
324       Asm->EmitInt32(SegmentLength);
325
326       // Full size of the segment for this filename, including the prev two
327       // records.
328       FileSegmentEnd = Asm->MMI->getContext().createTempSymbol();
329       EmitLabelDiff(*Asm->OutStreamer, FileSegmentBegin, FileSegmentEnd);
330       LastSegmentStart = J;
331     }
332
333     // The first PC with the given linenumber and the linenumber itself.
334     EmitLabelDiff(*Asm->OutStreamer, Fn, Instr);
335     uint32_t LineNumber = InstrInfo[Instr].LineNumber;
336     assert(LineNumber <= COFF::CVL_MaxLineNumber);
337     uint32_t LineData = LineNumber | COFF::CVL_IsStatement;
338     Asm->EmitInt32(LineData);
339   }
340
341   FinishPreviousChunk();
342   Asm->OutStreamer->EmitLabel(LineTableEnd);
343 }
344
345 void WinCodeViewLineTables::beginFunction(const MachineFunction *MF) {
346   assert(!CurFn && "Can't process two functions at once!");
347
348   if (!Asm || !Asm->MMI->hasDebugInfo())
349     return;
350
351   const Function *GV = MF->getFunction();
352   assert(FnDebugInfo.count(GV) == false);
353   VisitedFunctions.push_back(GV);
354   CurFn = &FnDebugInfo[GV];
355
356   // Find the end of the function prolog.
357   // FIXME: is there a simpler a way to do this? Can we just search
358   // for the first instruction of the function, not the last of the prolog?
359   DebugLoc PrologEndLoc;
360   bool EmptyPrologue = true;
361   for (const auto &MBB : *MF) {
362     if (PrologEndLoc)
363       break;
364     for (const auto &MI : MBB) {
365       if (MI.isDebugValue())
366         continue;
367
368       // First known non-DBG_VALUE and non-frame setup location marks
369       // the beginning of the function body.
370       // FIXME: do we need the first subcondition?
371       if (!MI.getFlag(MachineInstr::FrameSetup) && MI.getDebugLoc()) {
372         PrologEndLoc = MI.getDebugLoc();
373         break;
374       }
375       EmptyPrologue = false;
376     }
377   }
378   // Record beginning of function if we have a non-empty prologue.
379   if (PrologEndLoc && !EmptyPrologue) {
380     DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc();
381     maybeRecordLocation(FnStartDL, MF);
382   }
383 }
384
385 void WinCodeViewLineTables::endFunction(const MachineFunction *MF) {
386   if (!Asm || !CurFn)  // We haven't created any debug info for this function.
387     return;
388
389   const Function *GV = MF->getFunction();
390   assert(FnDebugInfo.count(GV));
391   assert(CurFn == &FnDebugInfo[GV]);
392
393   if (CurFn->Instrs.empty()) {
394     FnDebugInfo.erase(GV);
395     VisitedFunctions.pop_back();
396   } else {
397     CurFn->End = Asm->getFunctionEnd();
398   }
399   CurFn = nullptr;
400 }
401
402 void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) {
403   // Ignore DBG_VALUE locations and function prologue.
404   if (!Asm || MI->isDebugValue() || MI->getFlag(MachineInstr::FrameSetup))
405     return;
406   DebugLoc DL = MI->getDebugLoc();
407   if (DL == PrevInstLoc || !DL)
408     return;
409   maybeRecordLocation(DL, Asm->MF);
410 }
411 }