27 using namespace llvm::codeview;
34 if (!InsertedStrTabFragment)
35 delete StrTabFragment;
41 unsigned Idx = FileNumber - 1;
42 if (Idx < Filenames.size())
43 return !Filenames[Idx].empty();
49 Filename = addToStringTable(Filename);
50 unsigned Idx = FileNumber - 1;
51 if (Idx >= Filenames.size())
52 Filenames.resize(Idx + 1);
57 if (!Filenames[Idx].empty())
62 Filename = addToStringTable(Filename);
64 Filenames[Idx] = Filename;
69 if (FuncId >= Functions.size())
70 Functions.resize(FuncId + 1);
73 if (!Functions[FuncId].isUnallocatedFunctionInfo())
82 unsigned IAFile,
unsigned IALine,
84 if (FuncId >= Functions.size())
85 Functions.resize(FuncId + 1);
88 if (!Functions[FuncId].isUnallocatedFunctionInfo())
92 InlinedAt.
File = IAFile;
93 InlinedAt.
Line = IALine;
94 InlinedAt.
Col = IACol;
113 if (!StrTabFragment) {
116 StrTabFragment->getContents().push_back(
'\0');
118 return StrTabFragment;
126 S = Insertion.first->first();
127 if (Insertion.second) {
134 unsigned CodeViewContext::getStringTableOffset(
StringRef S) {
155 if (!InsertedStrTabFragment) {
156 OS.
insert(getStringTableFragment());
157 InsertedStrTabFragment =
true;
168 if (Filenames.empty())
207 std::vector<MCCVLineEntry> Locs = getFunctionLineEntries(FuncId);
214 for (
auto I = Locs.begin(),
E = Locs.end();
I !=
E;) {
216 unsigned CurFileNum =
I->getFileNum();
221 unsigned EntryCount = FileSegEnd -
I;
222 OS.
AddComment(
"Segment for file '" +
Twine(Filenames[CurFileNum - 1]) +
227 SegmentSize += 8 * EntryCount;
229 SegmentSize += 4 * EntryCount;
232 for (
auto J = I; J != FileSegEnd; ++J) {
234 unsigned LineData = J->getLine();
240 for (
auto J = I; J != FileSegEnd; ++J) {
251 if (isUInt<7>(Data)) {
256 if (isUInt<14>(Data)) {
262 if (isUInt<29>(Data)) {
280 return ((-Data) << 1) | 1;
285 unsigned PrimaryFunctionId,
286 unsigned SourceFileId,
287 unsigned SourceLineNum,
293 SourceLineNum, FnStartSym, FnEndSym,
299 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
317 assert(Success &&
"failed to evaluate label difference as absolute");
319 assert(Result >= 0 &&
"negative label difference requested");
320 assert(Result < UINT_MAX &&
"label difference greater than 2GB");
328 std::tie(LocBegin, LocEnd) = getLineExtent(Frag.SiteFuncId);
333 unsigned ChildId = KV.first;
334 auto Extent = getLineExtent(ChildId);
335 LocBegin =
std::min(LocBegin, Extent.first);
336 LocEnd = std::max(LocEnd, Extent.second);
339 if (LocBegin >= LocEnd)
350 StartLoc.
setLine(Frag.StartLineNum);
351 bool HaveOpenRange =
false;
355 LastSourceLoc.
File = Frag.StartFileId;
356 LastSourceLoc.
Line = Frag.StartLineNum;
364 constexpr
uint32_t InlineSiteSize = 12;
365 constexpr
uint32_t AnnotationSize = 8;
366 size_t MaxBufferSize =
MaxRecordLength - InlineSiteSize - AnnotationSize;
367 if (Buffer.
size() >= MaxBufferSize)
370 if (Loc.getFunctionId() == Frag.SiteFuncId) {
371 CurSourceLoc.
File = Loc.getFileNum();
372 CurSourceLoc.
Line = Loc.getLine();
379 CurSourceLoc =
I->second;
387 LastLabel = Loc.getLabel();
389 HaveOpenRange =
false;
397 if (HaveOpenRange && CurSourceLoc.
File == LastSourceLoc.
File &&
398 CurSourceLoc.
Line == LastSourceLoc.
Line)
401 HaveOpenRange =
true;
403 if (CurSourceLoc.
File != LastSourceLoc.
File) {
406 unsigned FileOffset = 8 * (CurSourceLoc.
File - 1);
411 int LineDelta = CurSourceLoc.
Line - LastSourceLoc.
Line;
414 if (CodeDelta == 0 && LineDelta != 0) {
417 }
else if (EncodedLineDelta < 0x8 && CodeDelta <= 0xf) {
421 unsigned Operand = (EncodedLineDelta << 4) | CodeDelta;
427 if (LineDelta != 0) {
435 LastLabel = Loc.getLabel();
436 LastSourceLoc = CurSourceLoc;
441 unsigned EndSymLength =
443 unsigned LocAfterLength = ~0U;
445 if (!LocAfter.
empty()) {
467 const MCSymbol *LastLabel =
nullptr;
468 for (std::pair<const MCSymbol *, const MCSymbol *> Range : Frag.
getRanges()) {
472 GapAndRangeSizes.
push_back({GapSize, RangeSize});
473 LastLabel = Range.second;
481 unsigned RangeSize = GapAndRangeSizes[
I].second;
483 for (; J !=
E; ++J) {
484 unsigned GapAndRangeSize = GapAndRangeSizes[J].first + GapAndRangeSizes[J].second;
487 RangeSize += GapAndRangeSize;
489 unsigned NumGaps = J -
I - 1;
510 size_t RecordSize = FixedSizePortion.
size() +
513 LEWriter.
write<uint16_t>(RecordSize);
515 OS << FixedSizePortion;
522 LEWriter.
write<uint16_t>(0);
524 LEWriter.
write<uint16_t>(Chunk);
529 }
while (RangeSize > 0);
533 "large ranges should not have gaps");
534 unsigned GapStartOffset = GapAndRangeSizes[
I].second;
535 for (++I; I != J; ++
I) {
536 unsigned GapSize, RangeSize;
538 std::tie(GapSize, RangeSize) = GapAndRangeSizes[
I];
539 LEWriter.
write<uint16_t>(GapStartOffset);
540 LEWriter.
write<uint16_t>(GapSize);
541 GapStartOffset += GapSize + RangeSize;
bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const
void push_back(const T &Elt)
void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F)
Instances of this class represent the information from a .cv_loc directive.
const MCSymbol * getFnStartSym() const
void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId, const MCSymbol *FuncBegin, const MCSymbol *FuncEnd)
Emits a line table substream.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
void EmitLabel(MCSymbol *Symbol) override
Emit a label for Symbol into the current section.
This represents an "assembler immediate".
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
SmallString< 8 > & getContents()
const T & front() const
front - Get the first element.
const MCSymbol * getFnEndSym() const
static void Make(MCObjectStreamer *MCOS)
A raw_ostream that writes to an SmallVector or SmallString.
const MCSymbol * getLabel() const
MCContext & getContext() const
DenseMap< unsigned, LineInfo > InlinedAtMap
Map from inlined call site id to the inlined at location to use for that call site.
static bool compressAnnotation(uint32_t Data, SmallVectorImpl< char > &Buffer)
void emitInlineLineTableForFunction(MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId, unsigned SourceLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym)
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Encapsulates the layout of an assembly file at a particular point in time.
MCSection * getCurrentSectionOnly() const
Base class for the full range of assembler expressions which are needed for parsing.
unsigned getColumn() const
Get the Column of this MCCVLoc.
Represent a reference to a symbol from inside an expression.
static uint32_t encodeSignedNumber(uint32_t Data)
A four-byte section relative fixup.
MCContext & getContext() const
bool isInlinedCallSite() const
Returns true if this represents an inlined call site, meaning ParentFuncIdPlusOne is neither zero nor...
Context object for machine code objects.
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
A two-byte section relative fixup.
Streaming object file generation interface.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
SmallVectorImpl< char > & getContents()
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...
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()
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
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.
bool addFile(unsigned FileNumber, StringRef Filename)
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
void write(ArrayRef< value_type > Vals)
void insert(MCFragment *F)
SmallVectorImpl< MCFixup > & getFixups()
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
static const unsigned End
void setFileNum(unsigned fileNum)
Set the FileNum of this MCCVLoc.
bool empty() const
empty - Check if the array is empty.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
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.
Binary assembler expressions.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Fragment representing the .cv_def_range directive.
void setLine(unsigned line)
Set the Line of this MCCVLoc.
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.
StringRef getFixedSizePortion() const
static unsigned computeLabelDiff(MCAsmLayout &Layout, const MCSymbol *Begin, const MCSymbol *End)
unsigned ParentFuncIdPlusOne
If this represents an inlined call site, then ParentFuncIdPlusOne will be the parent function id plus...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
ArrayRef< std::pair< const MCSymbol *, const MCSymbol * > > getRanges() const
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
MCSection & getSection(bool SetUsed=true) const
Get the section associated with a defined, non-absolute symbol.
Fragment representing the binary annotations produced by the .cv_inline_linetable directive...
bool recordFunctionId(unsigned FuncId)
Records the function id of a normal function.
unsigned getParentFuncId() const
bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol)
Records the function id of an inlined call site.
void emitDefRange(MCObjectStreamer &OS, ArrayRef< std::pair< const MCSymbol *, const MCSymbol * >> Ranges, StringRef FixedSizePortion)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
void emitStringTable(MCObjectStreamer &OS)
Emits the string table substream.
Instances of this class represent the line information for the CodeView line table entries...
CodeViewContext & getCVContext()
Fragment for data and encoded instructions.
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
StringRef - Represent a constant reference to a string, i.e.
Information describing a function or inlined call site introduced by .cv_func_id or ...
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...
void emitFileChecksums(MCObjectStreamer &OS)
Emits the file checksum substream.
unsigned getFileNum() const
Get the FileNum of this MCCVLoc.
virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol)
Emits a COFF section index.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Holds state from .cv_file and .cv_loc directives for later emission.