File indexing completed on 2026-05-10 08:44:12
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_MC_MCCODEVIEW_H
0014 #define LLVM_MC_MCCODEVIEW_H
0015
0016 #include "llvm/ADT/ArrayRef.h"
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/ADT/StringMap.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include <map>
0022 #include <vector>
0023
0024 namespace llvm {
0025 class MCAssembler;
0026 class MCCVDefRangeFragment;
0027 class MCCVInlineLineTableFragment;
0028 class MCDataFragment;
0029 class MCFragment;
0030 class MCSection;
0031 class MCSymbol;
0032 class MCContext;
0033 class MCObjectStreamer;
0034 class MCStreamer;
0035
0036
0037
0038 class MCCVLoc {
0039 const MCSymbol *Label = nullptr;
0040 uint32_t FunctionId;
0041 uint32_t FileNum;
0042 uint32_t Line;
0043 uint16_t Column;
0044 uint16_t PrologueEnd : 1;
0045 uint16_t IsStmt : 1;
0046
0047 private:
0048 friend class CodeViewContext;
0049 MCCVLoc(const MCSymbol *Label, unsigned functionid, unsigned fileNum,
0050 unsigned line, unsigned column, bool prologueend, bool isstmt)
0051 : Label(Label), FunctionId(functionid), FileNum(fileNum), Line(line),
0052 Column(column), PrologueEnd(prologueend), IsStmt(isstmt) {}
0053
0054
0055
0056
0057 public:
0058 const MCSymbol *getLabel() const { return Label; }
0059
0060 unsigned getFunctionId() const { return FunctionId; }
0061
0062
0063 unsigned getFileNum() const { return FileNum; }
0064
0065
0066 unsigned getLine() const { return Line; }
0067
0068
0069 unsigned getColumn() const { return Column; }
0070
0071 bool isPrologueEnd() const { return PrologueEnd; }
0072 bool isStmt() const { return IsStmt; }
0073
0074 void setLabel(const MCSymbol *L) { Label = L; }
0075
0076 void setFunctionId(unsigned FID) { FunctionId = FID; }
0077
0078
0079 void setFileNum(unsigned fileNum) { FileNum = fileNum; }
0080
0081
0082 void setLine(unsigned line) { Line = line; }
0083
0084
0085 void setColumn(unsigned column) {
0086 assert(column <= UINT16_MAX);
0087 Column = column;
0088 }
0089
0090 void setPrologueEnd(bool PE) { PrologueEnd = PE; }
0091 void setIsStmt(bool IS) { IsStmt = IS; }
0092 };
0093
0094
0095
0096
0097
0098 struct MCCVFunctionInfo {
0099
0100
0101
0102
0103
0104 unsigned ParentFuncIdPlusOne = 0;
0105
0106 enum : unsigned { FunctionSentinel = ~0U };
0107
0108 struct LineInfo {
0109 unsigned File;
0110 unsigned Line;
0111 unsigned Col;
0112 };
0113
0114 LineInfo InlinedAt;
0115
0116
0117
0118 MCSection *Section = nullptr;
0119
0120
0121
0122
0123
0124 DenseMap<unsigned, LineInfo> InlinedAtMap;
0125
0126
0127
0128 bool isUnallocatedFunctionInfo() const { return ParentFuncIdPlusOne == 0; }
0129
0130
0131
0132 bool isInlinedCallSite() const {
0133 return !isUnallocatedFunctionInfo() &&
0134 ParentFuncIdPlusOne != FunctionSentinel;
0135 }
0136
0137 unsigned getParentFuncId() const {
0138 assert(isInlinedCallSite());
0139 return ParentFuncIdPlusOne - 1;
0140 }
0141 };
0142
0143
0144 class CodeViewContext {
0145 public:
0146 CodeViewContext(MCContext *MCCtx) : MCCtx(MCCtx) {}
0147
0148 CodeViewContext &operator=(const CodeViewContext &other) = delete;
0149 CodeViewContext(const CodeViewContext &other) = delete;
0150
0151 void finish();
0152
0153 bool isValidFileNumber(unsigned FileNumber) const;
0154 bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
0155 ArrayRef<uint8_t> ChecksumBytes, uint8_t ChecksumKind);
0156
0157
0158
0159 bool recordFunctionId(unsigned FuncId);
0160
0161
0162
0163
0164
0165 bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc,
0166 unsigned IAFile, unsigned IALine,
0167 unsigned IACol);
0168
0169
0170 MCCVFunctionInfo *getCVFunctionInfo(unsigned FuncId);
0171
0172
0173
0174
0175
0176 void recordCVLoc(MCContext &Ctx, const MCSymbol *Label, unsigned FunctionId,
0177 unsigned FileNo, unsigned Line, unsigned Column,
0178 bool PrologueEnd, bool IsStmt);
0179
0180
0181 void addLineEntry(const MCCVLoc &LineEntry);
0182
0183 std::vector<MCCVLoc> getFunctionLineEntries(unsigned FuncId);
0184
0185 std::pair<size_t, size_t> getLineExtent(unsigned FuncId);
0186 std::pair<size_t, size_t> getLineExtentIncludingInlinees(unsigned FuncId);
0187
0188 ArrayRef<MCCVLoc> getLinesForExtent(size_t L, size_t R);
0189
0190
0191 void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
0192 const MCSymbol *FuncBegin,
0193 const MCSymbol *FuncEnd);
0194
0195 void emitInlineLineTableForFunction(MCObjectStreamer &OS,
0196 unsigned PrimaryFunctionId,
0197 unsigned SourceFileId,
0198 unsigned SourceLineNum,
0199 const MCSymbol *FnStartSym,
0200 const MCSymbol *FnEndSym);
0201
0202
0203 void encodeInlineLineTable(const MCAssembler &Asm,
0204 MCCVInlineLineTableFragment &F);
0205
0206 MCFragment *
0207 emitDefRange(MCObjectStreamer &OS,
0208 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
0209 StringRef FixedSizePortion);
0210
0211 void encodeDefRange(const MCAssembler &Asm, MCCVDefRangeFragment &F);
0212
0213
0214 void emitStringTable(MCObjectStreamer &OS);
0215
0216
0217 void emitFileChecksums(MCObjectStreamer &OS);
0218
0219
0220 void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
0221
0222
0223
0224 std::pair<StringRef, unsigned> addToStringTable(StringRef S);
0225
0226 private:
0227 MCContext *MCCtx;
0228
0229
0230 StringMap<unsigned> StringTable;
0231
0232
0233 MCDataFragment *StrTabFragment = nullptr;
0234 SmallVector<char, 0> StrTab = {'\0'};
0235
0236
0237 unsigned getStringTableOffset(StringRef S);
0238
0239 struct FileInfo {
0240 unsigned StringTableOffset;
0241
0242
0243
0244 bool Assigned = false;
0245
0246 uint8_t ChecksumKind;
0247
0248 ArrayRef<uint8_t> Checksum;
0249
0250
0251
0252 MCSymbol *ChecksumTableOffset;
0253 };
0254
0255
0256 SmallVector<FileInfo, 4> Files;
0257
0258
0259
0260 std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
0261
0262
0263 std::vector<MCCVLoc> MCCVLines;
0264
0265
0266 std::vector<MCCVFunctionInfo> Functions;
0267
0268
0269
0270 bool ChecksumOffsetsAssigned = false;
0271 };
0272
0273 }
0274 #endif