LLVM  4.0.0
MCCodeView.cpp
Go to the documentation of this file.
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/MC/MCAsmLayout.h"
16 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCValue.h"
23 #include "llvm/Support/COFF.h"
25 
26 using namespace llvm;
27 using namespace llvm::codeview;
28 
30 
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 
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 
144  MCContext &Ctx = OS.getContext();
145  MCSymbol *StringBegin = Ctx.createTempSymbol("strtab_begin", false),
146  *StringEnd = Ctx.createTempSymbol("strtab_end", false);
147 
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 
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 
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 
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(ModuleSubstreamKind::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(LineFlags::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 
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 
274  SmallVectorImpl<char> &Buffer) {
275  return compressAnnotation(static_cast<uint32_t>(Annotation), Buffer);
276 }
277 
279  if (Data >> 31)
280  return ((-Data) << 1) | 1;
281  return Data << 1;
282 }
283 
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 
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();
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 
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());
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);
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) {
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;
423  Buffer);
424  compressAnnotation(Operand, Buffer);
425  } else {
426  // Otherwise use the separate line and code deltas.
427  if (LineDelta != 0) {
429  compressAnnotation(EncodedLineDelta, Buffer);
430  }
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 
453  compressAnnotation(std::min(EndSymLength, LocAfterLength), Buffer);
454 }
455 
457  MCCVDefRangeFragment &Frag) {
458  MCContext &Ctx = Layout.getAssembler().getContext();
459  SmallVectorImpl<char> &Contents = Frag.getContents();
460  Contents.clear();
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 
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 //
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 }
bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const
Definition: MCExpr.cpp:418
void push_back(const T &Elt)
Definition: SmallVector.h:211
void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F)
Definition: MCCodeView.cpp:456
Instances of this class represent the information from a .cv_loc directive.
Definition: MCCodeView.h:32
const MCSymbol * getFnStartSym() const
Definition: MCFragment.h:518
void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId, const MCSymbol *FuncBegin, const MCSymbol *FuncEnd)
Emits a line table substream.
Definition: MCCodeView.cpp:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:298
void EmitLabel(MCSymbol *Symbol) override
Emit a label for Symbol into the current section.
This represents an "assembler immediate".
Definition: MCValue.h:40
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
SmallString< 8 > & getContents()
Definition: MCFragment.h:521
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:144
const MCSymbol * getFnEndSym() const
Definition: MCFragment.h:519
static void Make(MCObjectStreamer *MCOS)
Definition: MCCodeView.cpp:551
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:490
const MCSymbol * getLabel() const
Definition: MCCodeView.h:100
MCContext & getContext() const
Definition: MCAssembler.h:258
DenseMap< unsigned, LineInfo > InlinedAtMap
Map from inlined call site id to the inlined at location to use for that call site.
Definition: MCCodeView.h:138
static bool compressAnnotation(uint32_t Data, SmallVectorImpl< char > &Buffer)
Definition: MCCodeView.cpp:250
void emitInlineLineTableForFunction(MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
Definition: MCCodeView.cpp:284
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.cpp:139
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
MCSection * getCurrentSectionOnly() const
Definition: MCStreamer.h:302
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
unsigned getColumn() const
Get the Column of this MCCVLoc.
Definition: MCCodeView.h:60
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:161
static uint32_t encodeSignedNumber(uint32_t Data)
Definition: MCCodeView.cpp:278
A four-byte section relative fixup.
Definition: MCFixup.h:42
MCContext & getContext() const
Definition: MCStreamer.h:221
bool isInlinedCallSite() const
Returns true if this represents an inlined call site, meaning ParentFuncIdPlusOne is neither zero nor...
Definition: MCCodeView.h:146
Context object for machine code objects.
Definition: MCContext.h:51
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:269
A two-byte section relative fixup.
Definition: MCFixup.h:41
Streaming object file generation interface.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:429
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
SmallVectorImpl< char > & getContents()
Definition: MCFragment.h:175
virtual void EmitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers...
Definition: MCStreamer.cpp:85
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
const MCCVLoc & getCurrentCVLoc()
Definition: MCCodeView.h:205
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
iterator begin() const
Definition: StringRef.h:103
void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) override
Emit the absolute difference between two symbols if possible.
void encodeInlineLineTable(MCAsmLayout &Layout, MCCVInlineLineTableFragment &F)
Encodes the binary annotations once we have a layout.
Definition: MCCodeView.cpp:324
bool addFile(unsigned FileNumber, StringRef Filename)
Definition: MCCodeView.cpp:47
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
Definition: MCContext.cpp:218
void write(ArrayRef< value_type > Vals)
Definition: EndianStream.h:30
void insert(MCFragment *F)
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCFragment.h:200
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:743
static const unsigned End
void setFileNum(unsigned fileNum)
Set the FileNum of this MCCVLoc.
Definition: MCCodeView.h:68
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:136
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
bool isValidFileNumber(unsigned FileNumber) const
This is a valid number for use with .cv_loc if we've already seen a .cv_file for it.
Definition: MCCodeView.cpp:40
Binary assembler expressions.
Definition: MCExpr.h:388
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:82
Fragment representing the .cv_def_range directive.
Definition: MCFragment.h:532
void setLine(unsigned line)
Set the Line of this MCCVLoc.
Definition: MCCodeView.h:71
void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
void addLineEntry(const MCCVLineEntry &LineEntry)
Add a line entry.
Definition: MCCodeView.h:210
StringRef getFixedSizePortion() const
Definition: MCFragment.h:554
static unsigned computeLabelDiff(MCAsmLayout &Layout, const MCSymbol *Begin, const MCSymbol *End)
Definition: MCCodeView.cpp:307
unsigned ParentFuncIdPlusOne
If this represents an inlined call site, then ParentFuncIdPlusOne will be the parent function id plus...
Definition: MCCodeView.h:118
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > getRanges() const
Definition: MCFragment.h:550
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:581
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
MCSection & getSection(bool SetUsed=true) const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:264
Fragment representing the binary annotations produced by the .cv_inline_linetable directive...
Definition: MCFragment.h:494
#define Success
bool recordFunctionId(unsigned FuncId)
Records the function id of a normal function.
Definition: MCCodeView.cpp:68
unsigned getParentFuncId() const
Definition: MCCodeView.h:151
bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol)
Records the function id of an inlined call site.
Definition: MCCodeView.cpp:81
void emitDefRange(MCObjectStreamer &OS, ArrayRef< std::pair< const MCSymbol *, const MCSymbol * >> Ranges, StringRef FixedSizePortion)
Definition: MCCodeView.cpp:297
#define I(x, y, z)
Definition: MD5.cpp:54
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:135
void emitStringTable(MCObjectStreamer &OS)
Emits the string table substream.
Definition: MCCodeView.cpp:143
Instances of this class represent the line information for the CodeView line table entries...
Definition: MCCodeView.h:88
CodeViewContext & getCVContext()
Definition: MCContext.cpp:500
Fragment for data and encoded instructions.
Definition: MCFragment.h:218
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
Definition: MCStreamer.cpp:692
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:51
iterator end() const
Definition: StringRef.h:105
Subtraction.
Definition: MCExpr.h:412
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
Information describing a function or inlined call site introduced by .cv_func_id or ...
Definition: MCCodeView.h:112
auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:764
void emitFileChecksums(MCObjectStreamer &OS)
Emits the file checksum substream.
Definition: MCCodeView.cpp:165
unsigned getFileNum() const
Get the FileNum of this MCCVLoc.
Definition: MCCodeView.h:54
virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol)
Emits a COFF section index.
Definition: MCStreamer.cpp:689
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:149
Holds state from .cv_file and .cv_loc directives for later emission.
Definition: MCCodeView.h:158