]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/MC/MCCodeView.cpp
Merge OpenSSL 1.0.2m.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / MC / MCCodeView.cpp
1 //===- MCCodeView.h - Machine Code CodeView support -------------*- 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 // Holds state from .cv_file and .cv_loc directives for later emission.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/MC/MCCodeView.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/BinaryFormat/COFF.h"
17 #include "llvm/DebugInfo/CodeView/CodeView.h"
18 #include "llvm/DebugInfo/CodeView/Line.h"
19 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
20 #include "llvm/MC/MCAsmLayout.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCObjectStreamer.h"
23 #include "llvm/MC/MCValue.h"
24 #include "llvm/Support/EndianStream.h"
25
26 using namespace llvm;
27 using namespace llvm::codeview;
28
29 CodeViewContext::CodeViewContext() {}
30
31 CodeViewContext::~CodeViewContext() {
32   // If someone inserted strings into the string table but never actually
33   // emitted them somewhere, clean up the fragment.
34   if (!InsertedStrTabFragment)
35     delete StrTabFragment;
36 }
37
38 /// This is a valid number for use with .cv_loc if we've already seen a .cv_file
39 /// for it.
40 bool CodeViewContext::isValidFileNumber(unsigned FileNumber) const {
41   unsigned Idx = FileNumber - 1;
42   if (Idx < Filenames.size())
43     return !Filenames[Idx].empty();
44   return false;
45 }
46
47 bool CodeViewContext::addFile(unsigned FileNumber, StringRef Filename) {
48   assert(FileNumber > 0);
49   Filename = addToStringTable(Filename);
50   unsigned Idx = FileNumber - 1;
51   if (Idx >= Filenames.size())
52     Filenames.resize(Idx + 1);
53
54   if (Filename.empty())
55     Filename = "<stdin>";
56
57   if (!Filenames[Idx].empty())
58     return false;
59
60   // FIXME: We should store the string table offset of the filename, rather than
61   // the filename itself for efficiency.
62   Filename = addToStringTable(Filename);
63
64   Filenames[Idx] = Filename;
65   return true;
66 }
67
68 bool CodeViewContext::recordFunctionId(unsigned FuncId) {
69   if (FuncId >= Functions.size())
70     Functions.resize(FuncId + 1);
71
72   // Return false if this function info was already allocated.
73   if (!Functions[FuncId].isUnallocatedFunctionInfo())
74     return false;
75
76   // Mark this as an allocated normal function, and leave the rest alone.
77   Functions[FuncId].ParentFuncIdPlusOne = MCCVFunctionInfo::FunctionSentinel;
78   return true;
79 }
80
81 bool CodeViewContext::recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc,
82                                               unsigned IAFile, unsigned IALine,
83                                               unsigned IACol) {
84   if (FuncId >= Functions.size())
85     Functions.resize(FuncId + 1);
86
87   // Return false if this function info was already allocated.
88   if (!Functions[FuncId].isUnallocatedFunctionInfo())
89     return false;
90
91   MCCVFunctionInfo::LineInfo InlinedAt;
92   InlinedAt.File = IAFile;
93   InlinedAt.Line = IALine;
94   InlinedAt.Col = IACol;
95
96   // Mark this as an inlined call site and record call site line info.
97   MCCVFunctionInfo *Info = &Functions[FuncId];
98   Info->ParentFuncIdPlusOne = IAFunc + 1;
99   Info->InlinedAt = InlinedAt;
100
101   // Walk up the call chain adding this function id to the InlinedAtMap of all
102   // transitive callers until we hit a real function.
103   while (Info->isInlinedCallSite()) {
104     InlinedAt = Info->InlinedAt;
105     Info = getCVFunctionInfo(Info->getParentFuncId());
106     Info->InlinedAtMap[FuncId] = InlinedAt;
107   }
108
109   return true;
110 }
111
112 MCDataFragment *CodeViewContext::getStringTableFragment() {
113   if (!StrTabFragment) {
114     StrTabFragment = new MCDataFragment();
115     // Start a new string table out with a null byte.
116     StrTabFragment->getContents().push_back('\0');
117   }
118   return StrTabFragment;
119 }
120
121 StringRef CodeViewContext::addToStringTable(StringRef S) {
122   SmallVectorImpl<char> &Contents = getStringTableFragment()->getContents();
123   auto Insertion =
124       StringTable.insert(std::make_pair(S, unsigned(Contents.size())));
125   // Return the string from the table, since it is stable.
126   S = Insertion.first->first();
127   if (Insertion.second) {
128     // The string map key is always null terminated.
129     Contents.append(S.begin(), S.end() + 1);
130   }
131   return S;
132 }
133
134 unsigned CodeViewContext::getStringTableOffset(StringRef S) {
135   // A string table offset of zero is always the empty string.
136   if (S.empty())
137     return 0;
138   auto I = StringTable.find(S);
139   assert(I != StringTable.end());
140   return I->second;
141 }
142
143 void CodeViewContext::emitStringTable(MCObjectStreamer &OS) {
144   MCContext &Ctx = OS.getContext();
145   MCSymbol *StringBegin = Ctx.createTempSymbol("strtab_begin", false),
146            *StringEnd = Ctx.createTempSymbol("strtab_end", false);
147
148   OS.EmitIntValue(unsigned(DebugSubsectionKind::StringTable), 4);
149   OS.emitAbsoluteSymbolDiff(StringEnd, StringBegin, 4);
150   OS.EmitLabel(StringBegin);
151
152   // Put the string table data fragment here, if we haven't already put it
153   // somewhere else. If somebody wants two string tables in their .s file, one
154   // will just be empty.
155   if (!InsertedStrTabFragment) {
156     OS.insert(getStringTableFragment());
157     InsertedStrTabFragment = true;
158   }
159
160   OS.EmitValueToAlignment(4, 0);
161
162   OS.EmitLabel(StringEnd);
163 }
164
165 void CodeViewContext::emitFileChecksums(MCObjectStreamer &OS) {
166   // Do nothing if there are no file checksums. Microsoft's linker rejects empty
167   // CodeView substreams.
168   if (Filenames.empty())
169     return;
170
171   MCContext &Ctx = OS.getContext();
172   MCSymbol *FileBegin = Ctx.createTempSymbol("filechecksums_begin", false),
173            *FileEnd = Ctx.createTempSymbol("filechecksums_end", false);
174
175   OS.EmitIntValue(unsigned(DebugSubsectionKind::FileChecksums), 4);
176   OS.emitAbsoluteSymbolDiff(FileEnd, FileBegin, 4);
177   OS.EmitLabel(FileBegin);
178
179   // Emit an array of FileChecksum entries. We index into this table using the
180   // user-provided file number. Each entry is currently 8 bytes, as we don't
181   // emit checksums.
182   for (StringRef Filename : Filenames) {
183     OS.EmitIntValue(getStringTableOffset(Filename), 4);
184     // Zero the next two fields and align back to 4 bytes. This indicates that
185     // no checksum is present.
186     OS.EmitIntValue(0, 4);
187   }
188
189   OS.EmitLabel(FileEnd);
190 }
191
192 void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS,
193                                                unsigned FuncId,
194                                                const MCSymbol *FuncBegin,
195                                                const MCSymbol *FuncEnd) {
196   MCContext &Ctx = OS.getContext();
197   MCSymbol *LineBegin = Ctx.createTempSymbol("linetable_begin", false),
198            *LineEnd = Ctx.createTempSymbol("linetable_end", false);
199
200   OS.EmitIntValue(unsigned(DebugSubsectionKind::Lines), 4);
201   OS.emitAbsoluteSymbolDiff(LineEnd, LineBegin, 4);
202   OS.EmitLabel(LineBegin);
203   OS.EmitCOFFSecRel32(FuncBegin, /*Offset=*/0);
204   OS.EmitCOFFSectionIndex(FuncBegin);
205
206   // Actual line info.
207   std::vector<MCCVLineEntry> Locs = getFunctionLineEntries(FuncId);
208   bool HaveColumns = any_of(Locs, [](const MCCVLineEntry &LineEntry) {
209     return LineEntry.getColumn() != 0;
210   });
211   OS.EmitIntValue(HaveColumns ? int(LF_HaveColumns) : 0, 2);
212   OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 4);
213
214   for (auto I = Locs.begin(), E = Locs.end(); I != E;) {
215     // Emit a file segment for the run of locations that share a file id.
216     unsigned CurFileNum = I->getFileNum();
217     auto FileSegEnd =
218         std::find_if(I, E, [CurFileNum](const MCCVLineEntry &Loc) {
219           return Loc.getFileNum() != CurFileNum;
220         });
221     unsigned EntryCount = FileSegEnd - I;
222     OS.AddComment("Segment for file '" + Twine(Filenames[CurFileNum - 1]) +
223                   "' begins");
224     OS.EmitIntValue(8 * (CurFileNum - 1), 4);
225     OS.EmitIntValue(EntryCount, 4);
226     uint32_t SegmentSize = 12;
227     SegmentSize += 8 * EntryCount;
228     if (HaveColumns)
229       SegmentSize += 4 * EntryCount;
230     OS.EmitIntValue(SegmentSize, 4);
231
232     for (auto J = I; J != FileSegEnd; ++J) {
233       OS.emitAbsoluteSymbolDiff(J->getLabel(), FuncBegin, 4);
234       unsigned LineData = J->getLine();
235       if (J->isStmt())
236         LineData |= LineInfo::StatementFlag;
237       OS.EmitIntValue(LineData, 4);
238     }
239     if (HaveColumns) {
240       for (auto J = I; J != FileSegEnd; ++J) {
241         OS.EmitIntValue(J->getColumn(), 2);
242         OS.EmitIntValue(0, 2);
243       }
244     }
245     I = FileSegEnd;
246   }
247   OS.EmitLabel(LineEnd);
248 }
249
250 static bool compressAnnotation(uint32_t Data, SmallVectorImpl<char> &Buffer) {
251   if (isUInt<7>(Data)) {
252     Buffer.push_back(Data);
253     return true;
254   }
255
256   if (isUInt<14>(Data)) {
257     Buffer.push_back((Data >> 8) | 0x80);
258     Buffer.push_back(Data & 0xff);
259     return true;
260   }
261
262   if (isUInt<29>(Data)) {
263     Buffer.push_back((Data >> 24) | 0xC0);
264     Buffer.push_back((Data >> 16) & 0xff);
265     Buffer.push_back((Data >> 8) & 0xff);
266     Buffer.push_back(Data & 0xff);
267     return true;
268   }
269
270   return false;
271 }
272
273 static bool compressAnnotation(BinaryAnnotationsOpCode Annotation,
274                                SmallVectorImpl<char> &Buffer) {
275   return compressAnnotation(static_cast<uint32_t>(Annotation), Buffer);
276 }
277
278 static uint32_t encodeSignedNumber(uint32_t Data) {
279   if (Data >> 31)
280     return ((-Data) << 1) | 1;
281   return Data << 1;
282 }
283
284 void CodeViewContext::emitInlineLineTableForFunction(MCObjectStreamer &OS,
285                                                      unsigned PrimaryFunctionId,
286                                                      unsigned SourceFileId,
287                                                      unsigned SourceLineNum,
288                                                      const MCSymbol *FnStartSym,
289                                                      const MCSymbol *FnEndSym) {
290   // Create and insert a fragment into the current section that will be encoded
291   // later.
292   new MCCVInlineLineTableFragment(PrimaryFunctionId, SourceFileId,
293                                   SourceLineNum, FnStartSym, FnEndSym,
294                                   OS.getCurrentSectionOnly());
295 }
296
297 void CodeViewContext::emitDefRange(
298     MCObjectStreamer &OS,
299     ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
300     StringRef FixedSizePortion) {
301   // Create and insert a fragment into the current section that will be encoded
302   // later.
303   new MCCVDefRangeFragment(Ranges, FixedSizePortion,
304                            OS.getCurrentSectionOnly());
305 }
306
307 static unsigned computeLabelDiff(MCAsmLayout &Layout, const MCSymbol *Begin,
308                                  const MCSymbol *End) {
309   MCContext &Ctx = Layout.getAssembler().getContext();
310   MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
311   const MCExpr *BeginRef = MCSymbolRefExpr::create(Begin, Variant, Ctx),
312                *EndRef = MCSymbolRefExpr::create(End, Variant, Ctx);
313   const MCExpr *AddrDelta =
314       MCBinaryExpr::create(MCBinaryExpr::Sub, EndRef, BeginRef, Ctx);
315   int64_t Result;
316   bool Success = AddrDelta->evaluateKnownAbsolute(Result, Layout);
317   assert(Success && "failed to evaluate label difference as absolute");
318   (void)Success;
319   assert(Result >= 0 && "negative label difference requested");
320   assert(Result < UINT_MAX && "label difference greater than 2GB");
321   return unsigned(Result);
322 }
323
324 void CodeViewContext::encodeInlineLineTable(MCAsmLayout &Layout,
325                                             MCCVInlineLineTableFragment &Frag) {
326   size_t LocBegin;
327   size_t LocEnd;
328   std::tie(LocBegin, LocEnd) = getLineExtent(Frag.SiteFuncId);
329
330   // Include all child inline call sites in our .cv_loc extent.
331   MCCVFunctionInfo *SiteInfo = getCVFunctionInfo(Frag.SiteFuncId);
332   for (auto &KV : SiteInfo->InlinedAtMap) {
333     unsigned ChildId = KV.first;
334     auto Extent = getLineExtent(ChildId);
335     LocBegin = std::min(LocBegin, Extent.first);
336     LocEnd = std::max(LocEnd, Extent.second);
337   }
338
339   if (LocBegin >= LocEnd)
340     return;
341   ArrayRef<MCCVLineEntry> Locs = getLinesForExtent(LocBegin, LocEnd);
342   if (Locs.empty())
343     return;
344
345   // Make an artificial start location using the function start and the inlinee
346   // lines start location information. All deltas start relative to this
347   // location.
348   MCCVLineEntry StartLoc(Frag.getFnStartSym(), MCCVLoc(Locs.front()));
349   StartLoc.setFileNum(Frag.StartFileId);
350   StartLoc.setLine(Frag.StartLineNum);
351   bool HaveOpenRange = false;
352
353   const MCSymbol *LastLabel = Frag.getFnStartSym();
354   MCCVFunctionInfo::LineInfo LastSourceLoc, CurSourceLoc;
355   LastSourceLoc.File = Frag.StartFileId;
356   LastSourceLoc.Line = Frag.StartLineNum;
357
358   SmallVectorImpl<char> &Buffer = Frag.getContents();
359   Buffer.clear(); // Clear old contents if we went through relaxation.
360   for (const MCCVLineEntry &Loc : Locs) {
361     // Exit early if our line table would produce an oversized InlineSiteSym
362     // record. Account for the ChangeCodeLength annotation emitted after the
363     // loop ends.
364     constexpr uint32_t InlineSiteSize = 12;
365     constexpr uint32_t AnnotationSize = 8;
366     size_t MaxBufferSize = MaxRecordLength - InlineSiteSize - AnnotationSize;
367     if (Buffer.size() >= MaxBufferSize)
368       break;
369
370     if (Loc.getFunctionId() == Frag.SiteFuncId) {
371       CurSourceLoc.File = Loc.getFileNum();
372       CurSourceLoc.Line = Loc.getLine();
373     } else {
374       auto I = SiteInfo->InlinedAtMap.find(Loc.getFunctionId());
375       if (I != SiteInfo->InlinedAtMap.end()) {
376         // This .cv_loc is from a child inline call site. Use the source
377         // location of the inlined call site instead of the .cv_loc directive
378         // source location.
379         CurSourceLoc = I->second;
380       } else {
381         // We've hit a cv_loc not attributed to this inline call site. Use this
382         // label to end the PC range.
383         if (HaveOpenRange) {
384           unsigned Length = computeLabelDiff(Layout, LastLabel, Loc.getLabel());
385           compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeLength, Buffer);
386           compressAnnotation(Length, Buffer);
387           LastLabel = Loc.getLabel();
388         }
389         HaveOpenRange = false;
390         continue;
391       }
392     }
393
394     // Skip this .cv_loc if we have an open range and this isn't a meaningful
395     // source location update. The current table format does not support column
396     // info, so we can skip updates for those.
397     if (HaveOpenRange && CurSourceLoc.File == LastSourceLoc.File &&
398         CurSourceLoc.Line == LastSourceLoc.Line)
399       continue;
400
401     HaveOpenRange = true;
402
403     if (CurSourceLoc.File != LastSourceLoc.File) {
404       // File ids are 1 based, and each file checksum table entry is 8 bytes
405       // long. See emitFileChecksums above.
406       unsigned FileOffset = 8 * (CurSourceLoc.File - 1);
407       compressAnnotation(BinaryAnnotationsOpCode::ChangeFile, Buffer);
408       compressAnnotation(FileOffset, Buffer);
409     }
410
411     int LineDelta = CurSourceLoc.Line - LastSourceLoc.Line;
412     unsigned EncodedLineDelta = encodeSignedNumber(LineDelta);
413     unsigned CodeDelta = computeLabelDiff(Layout, LastLabel, Loc.getLabel());
414     if (CodeDelta == 0 && LineDelta != 0) {
415       compressAnnotation(BinaryAnnotationsOpCode::ChangeLineOffset, Buffer);
416       compressAnnotation(EncodedLineDelta, Buffer);
417     } else if (EncodedLineDelta < 0x8 && CodeDelta <= 0xf) {
418       // The ChangeCodeOffsetAndLineOffset combination opcode is used when the
419       // encoded line delta uses 3 or fewer set bits and the code offset fits
420       // in one nibble.
421       unsigned Operand = (EncodedLineDelta << 4) | CodeDelta;
422       compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset,
423                          Buffer);
424       compressAnnotation(Operand, Buffer);
425     } else {
426       // Otherwise use the separate line and code deltas.
427       if (LineDelta != 0) {
428         compressAnnotation(BinaryAnnotationsOpCode::ChangeLineOffset, Buffer);
429         compressAnnotation(EncodedLineDelta, Buffer);
430       }
431       compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeOffset, Buffer);
432       compressAnnotation(CodeDelta, Buffer);
433     }
434
435     LastLabel = Loc.getLabel();
436     LastSourceLoc = CurSourceLoc;
437   }
438
439   assert(HaveOpenRange);
440
441   unsigned EndSymLength =
442       computeLabelDiff(Layout, LastLabel, Frag.getFnEndSym());
443   unsigned LocAfterLength = ~0U;
444   ArrayRef<MCCVLineEntry> LocAfter = getLinesForExtent(LocEnd, LocEnd + 1);
445   if (!LocAfter.empty()) {
446     // Only try to compute this difference if we're in the same section.
447     const MCCVLineEntry &Loc = LocAfter[0];
448     if (&Loc.getLabel()->getSection(false) == &LastLabel->getSection(false))
449       LocAfterLength = computeLabelDiff(Layout, LastLabel, Loc.getLabel());
450   }
451
452   compressAnnotation(BinaryAnnotationsOpCode::ChangeCodeLength, Buffer);
453   compressAnnotation(std::min(EndSymLength, LocAfterLength), Buffer);
454 }
455
456 void CodeViewContext::encodeDefRange(MCAsmLayout &Layout,
457                                      MCCVDefRangeFragment &Frag) {
458   MCContext &Ctx = Layout.getAssembler().getContext();
459   SmallVectorImpl<char> &Contents = Frag.getContents();
460   Contents.clear();
461   SmallVectorImpl<MCFixup> &Fixups = Frag.getFixups();
462   Fixups.clear();
463   raw_svector_ostream OS(Contents);
464
465   // Compute all the sizes up front.
466   SmallVector<std::pair<unsigned, unsigned>, 4> GapAndRangeSizes;
467   const MCSymbol *LastLabel = nullptr;
468   for (std::pair<const MCSymbol *, const MCSymbol *> Range : Frag.getRanges()) {
469     unsigned GapSize =
470         LastLabel ? computeLabelDiff(Layout, LastLabel, Range.first) : 0;
471     unsigned RangeSize = computeLabelDiff(Layout, Range.first, Range.second);
472     GapAndRangeSizes.push_back({GapSize, RangeSize});
473     LastLabel = Range.second;
474   }
475
476   // Write down each range where the variable is defined.
477   for (size_t I = 0, E = Frag.getRanges().size(); I != E;) {
478     // If the range size of multiple consecutive ranges is under the max,
479     // combine the ranges and emit some gaps.
480     const MCSymbol *RangeBegin = Frag.getRanges()[I].first;
481     unsigned RangeSize = GapAndRangeSizes[I].second;
482     size_t J = I + 1;
483     for (; J != E; ++J) {
484       unsigned GapAndRangeSize = GapAndRangeSizes[J].first + GapAndRangeSizes[J].second;
485       if (RangeSize + GapAndRangeSize > MaxDefRange)
486         break;
487       RangeSize += GapAndRangeSize;
488     }
489     unsigned NumGaps = J - I - 1;
490
491     support::endian::Writer<support::little> LEWriter(OS);
492
493     unsigned Bias = 0;
494     // We must split the range into chunks of MaxDefRange, this is a fundamental
495     // limitation of the file format.
496     do {
497       uint16_t Chunk = std::min((uint32_t)MaxDefRange, RangeSize);
498
499       const MCSymbolRefExpr *SRE = MCSymbolRefExpr::create(RangeBegin, Ctx);
500       const MCBinaryExpr *BE =
501           MCBinaryExpr::createAdd(SRE, MCConstantExpr::create(Bias, Ctx), Ctx);
502       MCValue Res;
503       BE->evaluateAsRelocatable(Res, &Layout, /*Fixup=*/nullptr);
504
505       // Each record begins with a 2-byte number indicating how large the record
506       // is.
507       StringRef FixedSizePortion = Frag.getFixedSizePortion();
508       // Our record is a fixed sized prefix and a LocalVariableAddrRange that we
509       // are artificially constructing.
510       size_t RecordSize = FixedSizePortion.size() +
511                           sizeof(LocalVariableAddrRange) + 4 * NumGaps;
512       // Write out the record size.
513       LEWriter.write<uint16_t>(RecordSize);
514       // Write out the fixed size prefix.
515       OS << FixedSizePortion;
516       // Make space for a fixup that will eventually have a section relative
517       // relocation pointing at the offset where the variable becomes live.
518       Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_4));
519       LEWriter.write<uint32_t>(0); // Fixup for code start.
520       // Make space for a fixup that will record the section index for the code.
521       Fixups.push_back(MCFixup::create(Contents.size(), BE, FK_SecRel_2));
522       LEWriter.write<uint16_t>(0); // Fixup for section index.
523       // Write down the range's extent.
524       LEWriter.write<uint16_t>(Chunk);
525
526       // Move on to the next range.
527       Bias += Chunk;
528       RangeSize -= Chunk;
529     } while (RangeSize > 0);
530
531     // Emit the gaps afterwards.
532     assert((NumGaps == 0 || Bias <= MaxDefRange) &&
533            "large ranges should not have gaps");
534     unsigned GapStartOffset = GapAndRangeSizes[I].second;
535     for (++I; I != J; ++I) {
536       unsigned GapSize, RangeSize;
537       assert(I < GapAndRangeSizes.size());
538       std::tie(GapSize, RangeSize) = GapAndRangeSizes[I];
539       LEWriter.write<uint16_t>(GapStartOffset);
540       LEWriter.write<uint16_t>(GapSize);
541       GapStartOffset += GapSize + RangeSize;
542     }
543   }
544 }
545
546 //
547 // This is called when an instruction is assembled into the specified section
548 // and if there is information from the last .cv_loc directive that has yet to have
549 // a line entry made for it is made.
550 //
551 void MCCVLineEntry::Make(MCObjectStreamer *MCOS) {
552   CodeViewContext &CVC = MCOS->getContext().getCVContext();
553   if (!CVC.getCVLocSeen())
554     return;
555
556   // Create a symbol at in the current section for use in the line entry.
557   MCSymbol *LineSym = MCOS->getContext().createTempSymbol();
558   // Set the value of the symbol to use for the MCCVLineEntry.
559   MCOS->EmitLabel(LineSym);
560
561   // Get the current .loc info saved in the context.
562   const MCCVLoc &CVLoc = CVC.getCurrentCVLoc();
563
564   // Create a (local) line entry with the symbol and the current .loc info.
565   MCCVLineEntry LineEntry(LineSym, CVLoc);
566
567   // clear CVLocSeen saying the current .loc info is now used.
568   CVC.clearCVLocSeen();
569
570   // Add the line entry to this section's entries.
571   CVC.addLineEntry(LineEntry);
572 }