File indexing completed on 2026-05-10 08:43:40
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
0010 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
0011
0012 #include "llvm/ADT/APSInt.h"
0013 #include "llvm/ADT/ArrayRef.h"
0014 #include "llvm/ADT/StringRef.h"
0015 #include "llvm/ADT/iterator.h"
0016 #include "llvm/ADT/iterator_range.h"
0017 #include "llvm/DebugInfo/CodeView/CVRecord.h"
0018 #include "llvm/DebugInfo/CodeView/CodeView.h"
0019 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
0020 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
0021 #include "llvm/Support/BinaryStreamArray.h"
0022 #include "llvm/Support/Endian.h"
0023 #include <cstdint>
0024 #include <vector>
0025
0026 namespace llvm {
0027 namespace codeview {
0028
0029 class SymbolRecord {
0030 protected:
0031 explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {}
0032
0033 public:
0034 SymbolRecordKind getKind() const { return Kind; }
0035
0036 SymbolRecordKind Kind;
0037 };
0038
0039
0040
0041 class ProcSym : public SymbolRecord {
0042 static constexpr uint32_t RelocationOffset = 32;
0043
0044 public:
0045 explicit ProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0046 ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset)
0047 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
0048
0049 uint32_t getRelocationOffset() const {
0050 return RecordOffset + RelocationOffset;
0051 }
0052
0053 uint32_t Parent = 0;
0054 uint32_t End = 0;
0055 uint32_t Next = 0;
0056 uint32_t CodeSize = 0;
0057 uint32_t DbgStart = 0;
0058 uint32_t DbgEnd = 0;
0059 TypeIndex FunctionType;
0060 uint32_t CodeOffset = 0;
0061 uint16_t Segment = 0;
0062 ProcSymFlags Flags = ProcSymFlags::None;
0063 StringRef Name;
0064
0065 uint32_t RecordOffset = 0;
0066 };
0067
0068
0069 class Thunk32Sym : public SymbolRecord {
0070 public:
0071 explicit Thunk32Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0072 Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset)
0073 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
0074
0075 uint32_t Parent = 0;
0076 uint32_t End = 0;
0077 uint32_t Next = 0;
0078 uint32_t Offset = 0;
0079 uint16_t Segment = 0;
0080 uint16_t Length = 0;
0081 ThunkOrdinal Thunk = ThunkOrdinal::Standard;
0082 StringRef Name;
0083 ArrayRef<uint8_t> VariantData;
0084
0085 uint32_t RecordOffset = 0;
0086 };
0087
0088
0089 class TrampolineSym : public SymbolRecord {
0090 public:
0091 explicit TrampolineSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0092 TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset)
0093 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
0094
0095 TrampolineType Type;
0096 uint16_t Size = 0;
0097 uint32_t ThunkOffset = 0;
0098 uint32_t TargetOffset = 0;
0099 uint16_t ThunkSection = 0;
0100 uint16_t TargetSection = 0;
0101
0102 uint32_t RecordOffset = 0;
0103 };
0104
0105
0106 class SectionSym : public SymbolRecord {
0107 public:
0108 explicit SectionSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0109 SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset)
0110 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
0111
0112 uint16_t SectionNumber = 0;
0113 uint8_t Alignment = 0;
0114 uint32_t Rva = 0;
0115 uint32_t Length = 0;
0116 uint32_t Characteristics = 0;
0117 StringRef Name;
0118
0119 uint32_t RecordOffset = 0;
0120 };
0121
0122
0123 class CoffGroupSym : public SymbolRecord {
0124 public:
0125 explicit CoffGroupSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0126 CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset)
0127 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
0128
0129 uint32_t Size = 0;
0130 uint32_t Characteristics = 0;
0131 uint32_t Offset = 0;
0132 uint16_t Segment = 0;
0133 StringRef Name;
0134
0135 uint32_t RecordOffset = 0;
0136 };
0137
0138 class ScopeEndSym : public SymbolRecord {
0139 public:
0140 explicit ScopeEndSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0141 ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
0142 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
0143
0144 uint32_t RecordOffset = 0;
0145 };
0146
0147 class JumpTableSym : public SymbolRecord {
0148 public:
0149 explicit JumpTableSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0150 JumpTableSym(uint32_t RecordOffset)
0151 : SymbolRecord(SymbolRecordKind::JumpTableSym),
0152 RecordOffset(RecordOffset) {}
0153
0154 uint32_t BaseOffset = 0;
0155 uint16_t BaseSegment = 0;
0156
0157 JumpTableEntrySize SwitchType;
0158 uint32_t BranchOffset = 0;
0159 uint32_t TableOffset = 0;
0160 uint16_t BranchSegment = 0;
0161 uint16_t TableSegment = 0;
0162
0163 uint32_t EntriesCount = 0;
0164
0165 uint32_t RecordOffset = 0;
0166 };
0167
0168 class CallerSym : public SymbolRecord {
0169 public:
0170 explicit CallerSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0171 CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset)
0172 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
0173
0174 std::vector<TypeIndex> Indices;
0175
0176 uint32_t RecordOffset = 0;
0177 };
0178
0179 struct DecodedAnnotation {
0180 StringRef Name;
0181 ArrayRef<uint8_t> Bytes;
0182 BinaryAnnotationsOpCode OpCode = BinaryAnnotationsOpCode::Invalid;
0183 uint32_t U1 = 0;
0184 uint32_t U2 = 0;
0185 int32_t S1 = 0;
0186 };
0187
0188 struct BinaryAnnotationIterator
0189 : public iterator_facade_base<BinaryAnnotationIterator,
0190 std::forward_iterator_tag,
0191 DecodedAnnotation> {
0192 BinaryAnnotationIterator() = default;
0193 BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
0194 BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
0195 : Data(Other.Data) {}
0196
0197 bool operator==(BinaryAnnotationIterator Other) const {
0198 return Data == Other.Data;
0199 }
0200
0201 BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
0202 Data = Other.Data;
0203 return *this;
0204 }
0205
0206 BinaryAnnotationIterator &operator++() {
0207 if (!ParseCurrentAnnotation()) {
0208 *this = BinaryAnnotationIterator();
0209 return *this;
0210 }
0211 Data = Next;
0212 Next = ArrayRef<uint8_t>();
0213 Current.reset();
0214 return *this;
0215 }
0216
0217 const DecodedAnnotation &operator*() {
0218 ParseCurrentAnnotation();
0219 return *Current;
0220 }
0221
0222 private:
0223 static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) {
0224 if (Annotations.empty())
0225 return -1;
0226
0227 uint8_t FirstByte = Annotations.front();
0228 Annotations = Annotations.drop_front();
0229
0230 if ((FirstByte & 0x80) == 0x00)
0231 return FirstByte;
0232
0233 if (Annotations.empty())
0234 return -1;
0235
0236 uint8_t SecondByte = Annotations.front();
0237 Annotations = Annotations.drop_front();
0238
0239 if ((FirstByte & 0xC0) == 0x80)
0240 return ((FirstByte & 0x3F) << 8) | SecondByte;
0241
0242 if (Annotations.empty())
0243 return -1;
0244
0245 uint8_t ThirdByte = Annotations.front();
0246 Annotations = Annotations.drop_front();
0247
0248 if (Annotations.empty())
0249 return -1;
0250
0251 uint8_t FourthByte = Annotations.front();
0252 Annotations = Annotations.drop_front();
0253
0254 if ((FirstByte & 0xE0) == 0xC0)
0255 return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) |
0256 (ThirdByte << 8) | FourthByte;
0257
0258 return -1;
0259 }
0260
0261 static int32_t DecodeSignedOperand(uint32_t Operand) {
0262 if (Operand & 1)
0263 return -(Operand >> 1);
0264 return Operand >> 1;
0265 }
0266
0267 static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
0268 return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
0269 }
0270
0271 bool ParseCurrentAnnotation() {
0272 if (Current)
0273 return true;
0274
0275 Next = Data;
0276 uint32_t Op = GetCompressedAnnotation(Next);
0277 DecodedAnnotation Result;
0278 Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
0279 switch (Result.OpCode) {
0280 case BinaryAnnotationsOpCode::Invalid:
0281 Result.Name = "Invalid";
0282 Next = ArrayRef<uint8_t>();
0283 break;
0284 case BinaryAnnotationsOpCode::CodeOffset:
0285 Result.Name = "CodeOffset";
0286 Result.U1 = GetCompressedAnnotation(Next);
0287 break;
0288 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
0289 Result.Name = "ChangeCodeOffsetBase";
0290 Result.U1 = GetCompressedAnnotation(Next);
0291 break;
0292 case BinaryAnnotationsOpCode::ChangeCodeOffset:
0293 Result.Name = "ChangeCodeOffset";
0294 Result.U1 = GetCompressedAnnotation(Next);
0295 break;
0296 case BinaryAnnotationsOpCode::ChangeCodeLength:
0297 Result.Name = "ChangeCodeLength";
0298 Result.U1 = GetCompressedAnnotation(Next);
0299 break;
0300 case BinaryAnnotationsOpCode::ChangeFile:
0301 Result.Name = "ChangeFile";
0302 Result.U1 = GetCompressedAnnotation(Next);
0303 break;
0304 case BinaryAnnotationsOpCode::ChangeLineEndDelta:
0305 Result.Name = "ChangeLineEndDelta";
0306 Result.U1 = GetCompressedAnnotation(Next);
0307 break;
0308 case BinaryAnnotationsOpCode::ChangeRangeKind:
0309 Result.Name = "ChangeRangeKind";
0310 Result.U1 = GetCompressedAnnotation(Next);
0311 break;
0312 case BinaryAnnotationsOpCode::ChangeColumnStart:
0313 Result.Name = "ChangeColumnStart";
0314 Result.U1 = GetCompressedAnnotation(Next);
0315 break;
0316 case BinaryAnnotationsOpCode::ChangeColumnEnd:
0317 Result.Name = "ChangeColumnEnd";
0318 Result.U1 = GetCompressedAnnotation(Next);
0319 break;
0320 case BinaryAnnotationsOpCode::ChangeLineOffset:
0321 Result.Name = "ChangeLineOffset";
0322 Result.S1 = DecodeSignedOperand(Next);
0323 break;
0324 case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
0325 Result.Name = "ChangeColumnEndDelta";
0326 Result.S1 = DecodeSignedOperand(Next);
0327 break;
0328 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
0329 Result.Name = "ChangeCodeOffsetAndLineOffset";
0330 uint32_t Annotation = GetCompressedAnnotation(Next);
0331 Result.S1 = DecodeSignedOperand(Annotation >> 4);
0332 Result.U1 = Annotation & 0xf;
0333 break;
0334 }
0335 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
0336 Result.Name = "ChangeCodeLengthAndCodeOffset";
0337 Result.U1 = GetCompressedAnnotation(Next);
0338 Result.U2 = GetCompressedAnnotation(Next);
0339 break;
0340 }
0341 }
0342 Result.Bytes = Data.take_front(Data.size() - Next.size());
0343 Current = Result;
0344 return true;
0345 }
0346
0347 std::optional<DecodedAnnotation> Current;
0348 ArrayRef<uint8_t> Data;
0349 ArrayRef<uint8_t> Next;
0350 };
0351
0352
0353 class InlineSiteSym : public SymbolRecord {
0354 public:
0355 explicit InlineSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0356 explicit InlineSiteSym(uint32_t RecordOffset)
0357 : SymbolRecord(SymbolRecordKind::InlineSiteSym),
0358 RecordOffset(RecordOffset) {}
0359
0360 iterator_range<BinaryAnnotationIterator> annotations() const {
0361 return make_range(BinaryAnnotationIterator(AnnotationData),
0362 BinaryAnnotationIterator());
0363 }
0364
0365 uint32_t Parent = 0;
0366 uint32_t End = 0;
0367 TypeIndex Inlinee;
0368 std::vector<uint8_t> AnnotationData;
0369
0370 uint32_t RecordOffset = 0;
0371 };
0372
0373 struct PublicSym32Header {
0374 ulittle32_t Flags;
0375 ulittle32_t Offset;
0376 ulittle16_t Segment;
0377
0378 };
0379
0380
0381 class PublicSym32 : public SymbolRecord {
0382 public:
0383 PublicSym32() : SymbolRecord(SymbolRecordKind::PublicSym32) {}
0384 explicit PublicSym32(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0385 explicit PublicSym32(uint32_t RecordOffset)
0386 : SymbolRecord(SymbolRecordKind::PublicSym32),
0387 RecordOffset(RecordOffset) {}
0388
0389 PublicSymFlags Flags = PublicSymFlags::None;
0390 uint32_t Offset = 0;
0391 uint16_t Segment = 0;
0392 StringRef Name;
0393
0394 uint32_t RecordOffset = 0;
0395 };
0396
0397
0398 class RegisterSym : public SymbolRecord {
0399 public:
0400 explicit RegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0401 explicit RegisterSym(uint32_t RecordOffset)
0402 : SymbolRecord(SymbolRecordKind::RegisterSym),
0403 RecordOffset(RecordOffset) {}
0404
0405 TypeIndex Index;
0406 RegisterId Register;
0407 StringRef Name;
0408
0409 uint32_t RecordOffset = 0;
0410 };
0411
0412
0413 class ProcRefSym : public SymbolRecord {
0414 public:
0415 explicit ProcRefSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0416 explicit ProcRefSym(uint32_t RecordOffset)
0417 : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset) {
0418 }
0419
0420 uint32_t SumName = 0;
0421 uint32_t SymOffset = 0;
0422 uint16_t Module = 0;
0423 StringRef Name;
0424
0425 uint16_t modi() const { return Module - 1; }
0426 uint32_t RecordOffset = 0;
0427 };
0428
0429
0430 class LocalSym : public SymbolRecord {
0431 public:
0432 explicit LocalSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0433 explicit LocalSym(uint32_t RecordOffset)
0434 : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset) {}
0435
0436 TypeIndex Type;
0437 LocalSymFlags Flags = LocalSymFlags::None;
0438 StringRef Name;
0439
0440 uint32_t RecordOffset = 0;
0441 };
0442
0443 struct LocalVariableAddrRange {
0444 uint32_t OffsetStart = 0;
0445 uint16_t ISectStart = 0;
0446 uint16_t Range = 0;
0447 };
0448
0449 struct LocalVariableAddrGap {
0450 uint16_t GapStartOffset = 0;
0451 uint16_t Range = 0;
0452 };
0453
0454 enum : uint16_t { MaxDefRange = 0xf000 };
0455
0456
0457 class DefRangeSym : public SymbolRecord {
0458 static constexpr uint32_t RelocationOffset = 8;
0459
0460 public:
0461 explicit DefRangeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0462 explicit DefRangeSym(uint32_t RecordOffset)
0463 : SymbolRecord(SymbolRecordKind::DefRangeSym),
0464 RecordOffset(RecordOffset) {}
0465
0466 uint32_t getRelocationOffset() const {
0467 return RecordOffset + RelocationOffset;
0468 }
0469
0470 uint32_t Program = 0;
0471 LocalVariableAddrRange Range;
0472 std::vector<LocalVariableAddrGap> Gaps;
0473
0474 uint32_t RecordOffset = 0;
0475 };
0476
0477
0478 class DefRangeSubfieldSym : public SymbolRecord {
0479 static constexpr uint32_t RelocationOffset = 12;
0480
0481 public:
0482 explicit DefRangeSubfieldSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0483 explicit DefRangeSubfieldSym(uint32_t RecordOffset)
0484 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
0485 RecordOffset(RecordOffset) {}
0486
0487 uint32_t getRelocationOffset() const {
0488 return RecordOffset + RelocationOffset;
0489 }
0490
0491 uint32_t Program = 0;
0492 uint16_t OffsetInParent = 0;
0493 LocalVariableAddrRange Range;
0494 std::vector<LocalVariableAddrGap> Gaps;
0495
0496 uint32_t RecordOffset = 0;
0497 };
0498
0499 struct DefRangeRegisterHeader {
0500 ulittle16_t Register;
0501 ulittle16_t MayHaveNoName;
0502 };
0503
0504
0505 class DefRangeRegisterSym : public SymbolRecord {
0506 public:
0507 explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0508 explicit DefRangeRegisterSym(uint32_t RecordOffset)
0509 : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
0510 RecordOffset(RecordOffset) {}
0511
0512 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(DefRangeRegisterHeader); }
0513
0514 DefRangeRegisterHeader Hdr;
0515 LocalVariableAddrRange Range;
0516 std::vector<LocalVariableAddrGap> Gaps;
0517
0518 uint32_t RecordOffset = 0;
0519 };
0520
0521 struct DefRangeSubfieldRegisterHeader {
0522 ulittle16_t Register;
0523 ulittle16_t MayHaveNoName;
0524 ulittle32_t OffsetInParent;
0525 };
0526
0527
0528 class DefRangeSubfieldRegisterSym : public SymbolRecord {
0529 public:
0530 explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
0531 : SymbolRecord(Kind) {}
0532 explicit DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
0533 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
0534 RecordOffset(RecordOffset) {}
0535
0536 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(DefRangeSubfieldRegisterHeader); }
0537
0538 DefRangeSubfieldRegisterHeader Hdr;
0539 LocalVariableAddrRange Range;
0540 std::vector<LocalVariableAddrGap> Gaps;
0541
0542 uint32_t RecordOffset = 0;
0543 };
0544
0545 struct DefRangeFramePointerRelHeader {
0546 little32_t Offset;
0547 };
0548
0549
0550 class DefRangeFramePointerRelSym : public SymbolRecord {
0551 static constexpr uint32_t RelocationOffset = 8;
0552
0553 public:
0554 explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind)
0555 : SymbolRecord(Kind) {}
0556 explicit DefRangeFramePointerRelSym(uint32_t RecordOffset)
0557 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
0558 RecordOffset(RecordOffset) {}
0559
0560 uint32_t getRelocationOffset() const {
0561 return RecordOffset + RelocationOffset;
0562 }
0563
0564 DefRangeFramePointerRelHeader Hdr;
0565 LocalVariableAddrRange Range;
0566 std::vector<LocalVariableAddrGap> Gaps;
0567
0568 uint32_t RecordOffset = 0;
0569 };
0570
0571 struct DefRangeRegisterRelHeader {
0572 ulittle16_t Register;
0573 ulittle16_t Flags;
0574 little32_t BasePointerOffset;
0575 };
0576
0577
0578 class DefRangeRegisterRelSym : public SymbolRecord {
0579 public:
0580 explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0581 explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
0582 : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
0583 RecordOffset(RecordOffset) {}
0584
0585
0586
0587
0588
0589 enum : uint16_t {
0590 IsSubfieldFlag = 1,
0591 OffsetInParentShift = 4,
0592 };
0593
0594 bool hasSpilledUDTMember() const { return Hdr.Flags & IsSubfieldFlag; }
0595 uint16_t offsetInParent() const { return Hdr.Flags >> OffsetInParentShift; }
0596
0597 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(DefRangeRegisterRelHeader); }
0598
0599 DefRangeRegisterRelHeader Hdr;
0600 LocalVariableAddrRange Range;
0601 std::vector<LocalVariableAddrGap> Gaps;
0602
0603 uint32_t RecordOffset = 0;
0604 };
0605
0606
0607 class DefRangeFramePointerRelFullScopeSym : public SymbolRecord {
0608 public:
0609 explicit DefRangeFramePointerRelFullScopeSym(SymbolRecordKind Kind)
0610 : SymbolRecord(Kind) {}
0611 explicit DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset)
0612 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
0613 RecordOffset(RecordOffset) {}
0614
0615 int32_t Offset = 0;
0616
0617 uint32_t RecordOffset = 0;
0618 };
0619
0620
0621 class BlockSym : public SymbolRecord {
0622 static constexpr uint32_t RelocationOffset = 16;
0623
0624 public:
0625 explicit BlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0626 explicit BlockSym(uint32_t RecordOffset)
0627 : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset) {}
0628
0629 uint32_t getRelocationOffset() const {
0630 return RecordOffset + RelocationOffset;
0631 }
0632
0633 uint32_t Parent = 0;
0634 uint32_t End = 0;
0635 uint32_t CodeSize = 0;
0636 uint32_t CodeOffset = 0;
0637 uint16_t Segment = 0;
0638 StringRef Name;
0639
0640 uint32_t RecordOffset = 0;
0641 };
0642
0643
0644 class LabelSym : public SymbolRecord {
0645 static constexpr uint32_t RelocationOffset = 4;
0646
0647 public:
0648 explicit LabelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0649 explicit LabelSym(uint32_t RecordOffset)
0650 : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset) {}
0651
0652 uint32_t getRelocationOffset() const {
0653 return RecordOffset + RelocationOffset;
0654 }
0655
0656 uint32_t CodeOffset = 0;
0657 uint16_t Segment = 0;
0658 ProcSymFlags Flags = ProcSymFlags::None;
0659 StringRef Name;
0660
0661 uint32_t RecordOffset = 0;
0662 };
0663
0664
0665 class ObjNameSym : public SymbolRecord {
0666 public:
0667 explicit ObjNameSym() : SymbolRecord(SymbolRecordKind::ObjNameSym) {}
0668 explicit ObjNameSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0669 explicit ObjNameSym(uint32_t RecordOffset)
0670 : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset) {
0671 }
0672
0673 uint32_t Signature = 0;
0674 StringRef Name;
0675
0676 uint32_t RecordOffset = 0;
0677 };
0678
0679
0680 class EnvBlockSym : public SymbolRecord {
0681 public:
0682 explicit EnvBlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0683 explicit EnvBlockSym(uint32_t RecordOffset)
0684 : SymbolRecord(SymbolRecordKind::EnvBlockSym),
0685 RecordOffset(RecordOffset) {}
0686
0687 std::vector<StringRef> Fields;
0688
0689 uint32_t RecordOffset = 0;
0690 };
0691
0692
0693 class ExportSym : public SymbolRecord {
0694 public:
0695 explicit ExportSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0696 explicit ExportSym(uint32_t RecordOffset)
0697 : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset) {}
0698
0699 uint16_t Ordinal = 0;
0700 ExportFlags Flags = ExportFlags::None;
0701 StringRef Name;
0702
0703 uint32_t RecordOffset = 0;
0704 };
0705
0706
0707 class FileStaticSym : public SymbolRecord {
0708 public:
0709 explicit FileStaticSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0710 explicit FileStaticSym(uint32_t RecordOffset)
0711 : SymbolRecord(SymbolRecordKind::FileStaticSym),
0712 RecordOffset(RecordOffset) {}
0713
0714 TypeIndex Index;
0715 uint32_t ModFilenameOffset = 0;
0716 LocalSymFlags Flags = LocalSymFlags::None;
0717 StringRef Name;
0718
0719 uint32_t RecordOffset = 0;
0720 };
0721
0722
0723 class Compile2Sym : public SymbolRecord {
0724 public:
0725 explicit Compile2Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0726 explicit Compile2Sym(uint32_t RecordOffset)
0727 : SymbolRecord(SymbolRecordKind::Compile2Sym),
0728 RecordOffset(RecordOffset) {}
0729
0730 CompileSym2Flags Flags = CompileSym2Flags::None;
0731 CPUType Machine;
0732 uint16_t VersionFrontendMajor = 0;
0733 uint16_t VersionFrontendMinor = 0;
0734 uint16_t VersionFrontendBuild = 0;
0735 uint16_t VersionBackendMajor = 0;
0736 uint16_t VersionBackendMinor = 0;
0737 uint16_t VersionBackendBuild = 0;
0738 StringRef Version;
0739 std::vector<StringRef> ExtraStrings;
0740
0741 uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
0742 uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
0743
0744 uint32_t RecordOffset = 0;
0745 };
0746
0747
0748 class Compile3Sym : public SymbolRecord {
0749 public:
0750 Compile3Sym() : SymbolRecord(SymbolRecordKind::Compile3Sym) {}
0751 explicit Compile3Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0752 explicit Compile3Sym(uint32_t RecordOffset)
0753 : SymbolRecord(SymbolRecordKind::Compile3Sym),
0754 RecordOffset(RecordOffset) {}
0755
0756 CompileSym3Flags Flags = CompileSym3Flags::None;
0757 CPUType Machine;
0758 uint16_t VersionFrontendMajor = 0;
0759 uint16_t VersionFrontendMinor = 0;
0760 uint16_t VersionFrontendBuild = 0;
0761 uint16_t VersionFrontendQFE = 0;
0762 uint16_t VersionBackendMajor = 0;
0763 uint16_t VersionBackendMinor = 0;
0764 uint16_t VersionBackendBuild = 0;
0765 uint16_t VersionBackendQFE = 0;
0766 StringRef Version;
0767
0768 void setLanguage(SourceLanguage Lang) {
0769 Flags = CompileSym3Flags((uint32_t(Flags) & 0xFFFFFF00) | uint32_t(Lang));
0770 }
0771
0772 SourceLanguage getLanguage() const {
0773 return static_cast<SourceLanguage>(static_cast<uint32_t>(Flags) & 0xFF);
0774 }
0775 CompileSym3Flags getFlags() const {
0776 return static_cast<CompileSym3Flags>(static_cast<uint32_t>(Flags) & ~0xFF);
0777 }
0778
0779 bool hasOptimizations() const {
0780 return CompileSym3Flags::None !=
0781 (getFlags() & (CompileSym3Flags::PGO | CompileSym3Flags::LTCG));
0782 }
0783
0784 uint32_t RecordOffset = 0;
0785 };
0786
0787
0788 class FrameProcSym : public SymbolRecord {
0789 public:
0790 explicit FrameProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0791 explicit FrameProcSym(uint32_t RecordOffset)
0792 : SymbolRecord(SymbolRecordKind::FrameProcSym),
0793 RecordOffset(RecordOffset) {}
0794
0795 uint32_t TotalFrameBytes = 0;
0796 uint32_t PaddingFrameBytes = 0;
0797 uint32_t OffsetToPadding = 0;
0798 uint32_t BytesOfCalleeSavedRegisters = 0;
0799 uint32_t OffsetOfExceptionHandler = 0;
0800 uint16_t SectionIdOfExceptionHandler = 0;
0801 FrameProcedureOptions Flags = FrameProcedureOptions::None;
0802
0803
0804 RegisterId getLocalFramePtrReg(CPUType CPU) const {
0805 return decodeFramePtrReg(
0806 EncodedFramePtrReg((uint32_t(Flags) >> 14U) & 0x3U), CPU);
0807 }
0808
0809
0810 RegisterId getParamFramePtrReg(CPUType CPU) const {
0811 return decodeFramePtrReg(
0812 EncodedFramePtrReg((uint32_t(Flags) >> 16U) & 0x3U), CPU);
0813 }
0814
0815 uint32_t RecordOffset = 0;
0816
0817 private:
0818 };
0819
0820
0821 class CallSiteInfoSym : public SymbolRecord {
0822 static constexpr uint32_t RelocationOffset = 4;
0823
0824 public:
0825 explicit CallSiteInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0826 explicit CallSiteInfoSym(uint32_t RecordOffset)
0827 : SymbolRecord(SymbolRecordKind::CallSiteInfoSym) {}
0828
0829 uint32_t getRelocationOffset() const {
0830 return RecordOffset + RelocationOffset;
0831 }
0832
0833 uint32_t CodeOffset = 0;
0834 uint16_t Segment = 0;
0835 TypeIndex Type;
0836
0837 uint32_t RecordOffset = 0;
0838 };
0839
0840
0841 class HeapAllocationSiteSym : public SymbolRecord {
0842 static constexpr uint32_t RelocationOffset = 4;
0843
0844 public:
0845 explicit HeapAllocationSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0846 explicit HeapAllocationSiteSym(uint32_t RecordOffset)
0847 : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
0848 RecordOffset(RecordOffset) {}
0849
0850 uint32_t getRelocationOffset() const {
0851 return RecordOffset + RelocationOffset;
0852 }
0853
0854 uint32_t CodeOffset = 0;
0855 uint16_t Segment = 0;
0856 uint16_t CallInstructionSize = 0;
0857 TypeIndex Type;
0858
0859 uint32_t RecordOffset = 0;
0860 };
0861
0862
0863 class FrameCookieSym : public SymbolRecord {
0864 static constexpr uint32_t RelocationOffset = 4;
0865
0866 public:
0867 explicit FrameCookieSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0868 explicit FrameCookieSym(uint32_t RecordOffset)
0869 : SymbolRecord(SymbolRecordKind::FrameCookieSym) {}
0870
0871 uint32_t getRelocationOffset() const {
0872 return RecordOffset + RelocationOffset;
0873 }
0874
0875 uint32_t CodeOffset = 0;
0876 uint16_t Register = 0;
0877 FrameCookieKind CookieKind;
0878 uint8_t Flags = 0;
0879
0880 uint32_t RecordOffset = 0;
0881 };
0882
0883
0884 class UDTSym : public SymbolRecord {
0885 public:
0886 explicit UDTSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0887 explicit UDTSym(uint32_t RecordOffset)
0888 : SymbolRecord(SymbolRecordKind::UDTSym) {}
0889
0890 TypeIndex Type;
0891 StringRef Name;
0892
0893 uint32_t RecordOffset = 0;
0894 };
0895
0896
0897 class BuildInfoSym : public SymbolRecord {
0898 public:
0899 explicit BuildInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0900 explicit BuildInfoSym(uint32_t RecordOffset)
0901 : SymbolRecord(SymbolRecordKind::BuildInfoSym),
0902 RecordOffset(RecordOffset) {}
0903
0904 TypeIndex BuildId;
0905
0906 uint32_t RecordOffset = 0;
0907 };
0908
0909
0910 class BPRelativeSym : public SymbolRecord {
0911 public:
0912 explicit BPRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0913 explicit BPRelativeSym(uint32_t RecordOffset)
0914 : SymbolRecord(SymbolRecordKind::BPRelativeSym),
0915 RecordOffset(RecordOffset) {}
0916
0917 int32_t Offset = 0;
0918 TypeIndex Type;
0919 StringRef Name;
0920
0921 uint32_t RecordOffset = 0;
0922 };
0923
0924
0925 class RegRelativeSym : public SymbolRecord {
0926 public:
0927 explicit RegRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0928 explicit RegRelativeSym(uint32_t RecordOffset)
0929 : SymbolRecord(SymbolRecordKind::RegRelativeSym),
0930 RecordOffset(RecordOffset) {}
0931
0932 uint32_t Offset = 0;
0933 TypeIndex Type;
0934 RegisterId Register;
0935 StringRef Name;
0936
0937 uint32_t RecordOffset = 0;
0938 };
0939
0940
0941 class ConstantSym : public SymbolRecord {
0942 public:
0943 explicit ConstantSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0944 explicit ConstantSym(uint32_t RecordOffset)
0945 : SymbolRecord(SymbolRecordKind::ConstantSym),
0946 RecordOffset(RecordOffset) {}
0947
0948 TypeIndex Type;
0949 APSInt Value;
0950 StringRef Name;
0951
0952 uint32_t RecordOffset = 0;
0953 };
0954
0955
0956 class DataSym : public SymbolRecord {
0957 static constexpr uint32_t RelocationOffset = 8;
0958
0959 public:
0960 explicit DataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0961 explicit DataSym(uint32_t RecordOffset)
0962 : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset) {}
0963
0964 uint32_t getRelocationOffset() const {
0965 return RecordOffset + RelocationOffset;
0966 }
0967
0968 TypeIndex Type;
0969 uint32_t DataOffset = 0;
0970 uint16_t Segment = 0;
0971 StringRef Name;
0972
0973 uint32_t RecordOffset = 0;
0974 };
0975
0976
0977 class ThreadLocalDataSym : public SymbolRecord {
0978 static constexpr uint32_t RelocationOffset = 8;
0979
0980 public:
0981 explicit ThreadLocalDataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
0982 explicit ThreadLocalDataSym(uint32_t RecordOffset)
0983 : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
0984 RecordOffset(RecordOffset) {}
0985
0986 uint32_t getRelocationOffset() const {
0987 return RecordOffset + RelocationOffset;
0988 }
0989
0990 TypeIndex Type;
0991 uint32_t DataOffset = 0;
0992 uint16_t Segment = 0;
0993 StringRef Name;
0994
0995 uint32_t RecordOffset = 0;
0996 };
0997
0998
0999 class UsingNamespaceSym : public SymbolRecord {
1000 public:
1001 explicit UsingNamespaceSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
1002 explicit UsingNamespaceSym(uint32_t RecordOffset)
1003 : SymbolRecord(SymbolRecordKind::UsingNamespaceSym),
1004 RecordOffset(RecordOffset) {}
1005
1006 StringRef Name;
1007
1008 uint32_t RecordOffset = 0;
1009 };
1010
1011
1012 class AnnotationSym : public SymbolRecord {
1013 public:
1014 explicit AnnotationSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
1015 explicit AnnotationSym(uint32_t RecordOffset)
1016 : SymbolRecord(SymbolRecordKind::AnnotationSym),
1017 RecordOffset(RecordOffset) {}
1018
1019 uint32_t CodeOffset = 0;
1020 uint16_t Segment = 0;
1021 std::vector<StringRef> Strings;
1022
1023 uint32_t RecordOffset = 0;
1024 };
1025
1026 Expected<CVSymbol> readSymbolFromStream(BinaryStreamRef Stream,
1027 uint32_t Offset);
1028
1029 }
1030 }
1031
1032 #endif