1 //===- SymbolRecord.h -------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
11 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
13 #include "llvm/ADT/APSInt.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/Optional.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/ADT/iterator_range.h"
18 #include "llvm/DebugInfo/CodeView/CVRecord.h"
19 #include "llvm/DebugInfo/CodeView/CodeView.h"
20 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
21 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
22 #include "llvm/Support/BinaryStreamArray.h"
23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/Error.h"
34 explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {}
37 SymbolRecordKind getKind() const { return Kind; }
40 SymbolRecordKind Kind;
43 // S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or
45 class ProcSym : public SymbolRecord {
46 static constexpr uint32_t RelocationOffset = 32;
49 explicit ProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
50 ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset)
51 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
53 uint32_t getRelocationOffset() const {
54 return RecordOffset + RelocationOffset;
60 uint32_t CodeSize = 0;
61 uint32_t DbgStart = 0;
63 TypeIndex FunctionType;
64 uint32_t CodeOffset = 0;
66 ProcSymFlags Flags = ProcSymFlags::None;
69 uint32_t RecordOffset = 0;
73 class Thunk32Sym : public SymbolRecord {
75 explicit Thunk32Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
76 Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset)
77 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
87 ArrayRef<uint8_t> VariantData;
89 uint32_t RecordOffset;
93 class TrampolineSym : public SymbolRecord {
95 explicit TrampolineSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
96 TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset)
97 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
101 uint32_t ThunkOffset;
102 uint32_t TargetOffset;
103 uint16_t ThunkSection;
104 uint16_t TargetSection;
106 uint32_t RecordOffset;
110 class SectionSym : public SymbolRecord {
112 explicit SectionSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
113 SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset)
114 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
116 uint16_t SectionNumber;
120 uint32_t Characteristics;
123 uint32_t RecordOffset;
127 class CoffGroupSym : public SymbolRecord {
129 explicit CoffGroupSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
130 CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset)
131 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
134 uint32_t Characteristics;
139 uint32_t RecordOffset;
142 class ScopeEndSym : public SymbolRecord {
144 explicit ScopeEndSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
145 ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
146 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
148 uint32_t RecordOffset;
151 class CallerSym : public SymbolRecord {
153 explicit CallerSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
154 CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset)
155 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
157 std::vector<TypeIndex> Indices;
158 uint32_t RecordOffset;
161 struct BinaryAnnotationIterator {
162 struct AnnotationData {
163 BinaryAnnotationsOpCode OpCode;
170 BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
171 BinaryAnnotationIterator() = default;
172 BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
173 : Data(Other.Data) {}
175 bool operator==(BinaryAnnotationIterator Other) const {
176 return Data == Other.Data;
179 bool operator!=(const BinaryAnnotationIterator &Other) const {
180 return !(*this == Other);
183 BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
188 BinaryAnnotationIterator &operator++() {
189 if (!ParseCurrentAnnotation()) {
190 *this = BinaryAnnotationIterator();
194 Next = ArrayRef<uint8_t>();
199 BinaryAnnotationIterator operator++(int) {
200 BinaryAnnotationIterator Orig(*this);
205 const AnnotationData &operator*() {
206 ParseCurrentAnnotation();
207 return Current.getValue();
211 static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) {
212 if (Annotations.empty())
215 uint8_t FirstByte = Annotations.front();
216 Annotations = Annotations.drop_front();
218 if ((FirstByte & 0x80) == 0x00)
221 if (Annotations.empty())
224 uint8_t SecondByte = Annotations.front();
225 Annotations = Annotations.drop_front();
227 if ((FirstByte & 0xC0) == 0x80)
228 return ((FirstByte & 0x3F) << 8) | SecondByte;
230 if (Annotations.empty())
233 uint8_t ThirdByte = Annotations.front();
234 Annotations = Annotations.drop_front();
236 if (Annotations.empty())
239 uint8_t FourthByte = Annotations.front();
240 Annotations = Annotations.drop_front();
242 if ((FirstByte & 0xE0) == 0xC0)
243 return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) |
244 (ThirdByte << 8) | FourthByte;
249 static int32_t DecodeSignedOperand(uint32_t Operand) {
251 return -(Operand >> 1);
255 static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
256 return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
259 bool ParseCurrentAnnotation() {
260 if (Current.hasValue())
264 uint32_t Op = GetCompressedAnnotation(Next);
265 AnnotationData Result;
266 Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
267 switch (Result.OpCode) {
268 case BinaryAnnotationsOpCode::Invalid:
269 Result.Name = "Invalid";
270 Next = ArrayRef<uint8_t>();
272 case BinaryAnnotationsOpCode::CodeOffset:
273 Result.Name = "CodeOffset";
274 Result.U1 = GetCompressedAnnotation(Next);
276 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
277 Result.Name = "ChangeCodeOffsetBase";
278 Result.U1 = GetCompressedAnnotation(Next);
280 case BinaryAnnotationsOpCode::ChangeCodeOffset:
281 Result.Name = "ChangeCodeOffset";
282 Result.U1 = GetCompressedAnnotation(Next);
284 case BinaryAnnotationsOpCode::ChangeCodeLength:
285 Result.Name = "ChangeCodeLength";
286 Result.U1 = GetCompressedAnnotation(Next);
288 case BinaryAnnotationsOpCode::ChangeFile:
289 Result.Name = "ChangeFile";
290 Result.U1 = GetCompressedAnnotation(Next);
292 case BinaryAnnotationsOpCode::ChangeLineEndDelta:
293 Result.Name = "ChangeLineEndDelta";
294 Result.U1 = GetCompressedAnnotation(Next);
296 case BinaryAnnotationsOpCode::ChangeRangeKind:
297 Result.Name = "ChangeRangeKind";
298 Result.U1 = GetCompressedAnnotation(Next);
300 case BinaryAnnotationsOpCode::ChangeColumnStart:
301 Result.Name = "ChangeColumnStart";
302 Result.U1 = GetCompressedAnnotation(Next);
304 case BinaryAnnotationsOpCode::ChangeColumnEnd:
305 Result.Name = "ChangeColumnEnd";
306 Result.U1 = GetCompressedAnnotation(Next);
308 case BinaryAnnotationsOpCode::ChangeLineOffset:
309 Result.Name = "ChangeLineOffset";
310 Result.S1 = DecodeSignedOperand(Next);
312 case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
313 Result.Name = "ChangeColumnEndDelta";
314 Result.S1 = DecodeSignedOperand(Next);
316 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
317 Result.Name = "ChangeCodeOffsetAndLineOffset";
318 uint32_t Annotation = GetCompressedAnnotation(Next);
319 Result.S1 = DecodeSignedOperand(Annotation >> 4);
320 Result.U1 = Annotation & 0xf;
323 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
324 Result.Name = "ChangeCodeLengthAndCodeOffset";
325 Result.U1 = GetCompressedAnnotation(Next);
326 Result.U2 = GetCompressedAnnotation(Next);
334 Optional<AnnotationData> Current;
335 ArrayRef<uint8_t> Data;
336 ArrayRef<uint8_t> Next;
340 class InlineSiteSym : public SymbolRecord {
342 explicit InlineSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
343 InlineSiteSym(uint32_t RecordOffset)
344 : SymbolRecord(SymbolRecordKind::InlineSiteSym),
345 RecordOffset(RecordOffset) {}
347 llvm::iterator_range<BinaryAnnotationIterator> annotations() const {
348 return llvm::make_range(BinaryAnnotationIterator(AnnotationData),
349 BinaryAnnotationIterator());
355 std::vector<uint8_t> AnnotationData;
357 uint32_t RecordOffset;
361 class PublicSym32 : public SymbolRecord {
363 explicit PublicSym32(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
364 explicit PublicSym32(uint32_t RecordOffset)
365 : SymbolRecord(SymbolRecordKind::PublicSym32),
366 RecordOffset(RecordOffset) {}
373 uint32_t RecordOffset;
377 class RegisterSym : public SymbolRecord {
379 explicit RegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
380 RegisterSym(uint32_t RecordOffset)
381 : SymbolRecord(SymbolRecordKind::RegisterSym),
382 RecordOffset(RecordOffset) {}
388 uint32_t RecordOffset;
391 // S_PROCREF, S_LPROCREF
392 class ProcRefSym : public SymbolRecord {
394 explicit ProcRefSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
395 explicit ProcRefSym(uint32_t RecordOffset)
396 : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset) {
404 uint32_t RecordOffset;
408 class LocalSym : public SymbolRecord {
410 explicit LocalSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
411 explicit LocalSym(uint32_t RecordOffset)
412 : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset) {}
418 uint32_t RecordOffset;
421 struct LocalVariableAddrRange {
422 uint32_t OffsetStart;
427 struct LocalVariableAddrGap {
428 uint16_t GapStartOffset;
432 enum : uint16_t { MaxDefRange = 0xf000 };
435 class DefRangeSym : public SymbolRecord {
436 static constexpr uint32_t RelocationOffset = 8;
439 explicit DefRangeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
440 explicit DefRangeSym(uint32_t RecordOffset)
441 : SymbolRecord(SymbolRecordKind::DefRangeSym),
442 RecordOffset(RecordOffset) {}
444 uint32_t getRelocationOffset() const {
445 return RecordOffset + RelocationOffset;
449 LocalVariableAddrRange Range;
450 std::vector<LocalVariableAddrGap> Gaps;
452 uint32_t RecordOffset;
455 // S_DEFRANGE_SUBFIELD
456 class DefRangeSubfieldSym : public SymbolRecord {
457 static constexpr uint32_t RelocationOffset = 12;
460 explicit DefRangeSubfieldSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
461 DefRangeSubfieldSym(uint32_t RecordOffset)
462 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
463 RecordOffset(RecordOffset) {}
465 uint32_t getRelocationOffset() const {
466 return RecordOffset + RelocationOffset;
470 uint16_t OffsetInParent;
471 LocalVariableAddrRange Range;
472 std::vector<LocalVariableAddrGap> Gaps;
474 uint32_t RecordOffset;
477 // S_DEFRANGE_REGISTER
478 class DefRangeRegisterSym : public SymbolRecord {
481 ulittle16_t Register;
482 ulittle16_t MayHaveNoName;
484 explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
485 DefRangeRegisterSym(uint32_t RecordOffset)
486 : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
487 RecordOffset(RecordOffset) {}
489 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
492 LocalVariableAddrRange Range;
493 std::vector<LocalVariableAddrGap> Gaps;
495 uint32_t RecordOffset;
498 // S_DEFRANGE_SUBFIELD_REGISTER
499 class DefRangeSubfieldRegisterSym : public SymbolRecord {
502 ulittle16_t Register;
503 ulittle16_t MayHaveNoName;
504 ulittle32_t OffsetInParent;
506 explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
507 : SymbolRecord(Kind) {}
508 DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
509 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
510 RecordOffset(RecordOffset) {}
512 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
515 LocalVariableAddrRange Range;
516 std::vector<LocalVariableAddrGap> Gaps;
518 uint32_t RecordOffset;
521 // S_DEFRANGE_FRAMEPOINTER_REL
522 class DefRangeFramePointerRelSym : public SymbolRecord {
523 static constexpr uint32_t RelocationOffset = 8;
526 explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind)
527 : SymbolRecord(Kind) {}
528 DefRangeFramePointerRelSym(uint32_t RecordOffset)
529 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
530 RecordOffset(RecordOffset) {}
532 uint32_t getRelocationOffset() const {
533 return RecordOffset + RelocationOffset;
537 LocalVariableAddrRange Range;
538 std::vector<LocalVariableAddrGap> Gaps;
540 uint32_t RecordOffset;
543 // S_DEFRANGE_REGISTER_REL
544 class DefRangeRegisterRelSym : public SymbolRecord {
547 ulittle16_t Register;
549 little32_t BasePointerOffset;
551 explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
552 explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
553 : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
554 RecordOffset(RecordOffset) {}
556 // The flags implement this notional bitfield:
557 // uint16_t IsSubfield : 1;
558 // uint16_t Padding : 3;
559 // uint16_t OffsetInParent : 12;
562 OffsetInParentShift = 4,
565 bool hasSpilledUDTMember() const { return Hdr.Flags & IsSubfieldFlag; }
566 uint16_t offsetInParent() const { return Hdr.Flags >> OffsetInParentShift; }
568 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
571 LocalVariableAddrRange Range;
572 std::vector<LocalVariableAddrGap> Gaps;
574 uint32_t RecordOffset;
577 // S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
578 class DefRangeFramePointerRelFullScopeSym : public SymbolRecord {
580 explicit DefRangeFramePointerRelFullScopeSym(SymbolRecordKind Kind)
581 : SymbolRecord(Kind) {}
582 explicit DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset)
583 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
584 RecordOffset(RecordOffset) {}
588 uint32_t RecordOffset;
592 class BlockSym : public SymbolRecord {
593 static constexpr uint32_t RelocationOffset = 16;
596 explicit BlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
597 explicit BlockSym(uint32_t RecordOffset)
598 : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset) {}
600 uint32_t getRelocationOffset() const {
601 return RecordOffset + RelocationOffset;
611 uint32_t RecordOffset;
615 class LabelSym : public SymbolRecord {
616 static constexpr uint32_t RelocationOffset = 4;
619 explicit LabelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
620 explicit LabelSym(uint32_t RecordOffset)
621 : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset) {}
623 uint32_t getRelocationOffset() const {
624 return RecordOffset + RelocationOffset;
632 uint32_t RecordOffset;
636 class ObjNameSym : public SymbolRecord {
638 explicit ObjNameSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
639 ObjNameSym(uint32_t RecordOffset)
640 : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset) {
646 uint32_t RecordOffset;
650 class EnvBlockSym : public SymbolRecord {
652 explicit EnvBlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
653 EnvBlockSym(uint32_t RecordOffset)
654 : SymbolRecord(SymbolRecordKind::EnvBlockSym),
655 RecordOffset(RecordOffset) {}
657 std::vector<StringRef> Fields;
659 uint32_t RecordOffset;
663 class ExportSym : public SymbolRecord {
665 explicit ExportSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
666 ExportSym(uint32_t RecordOffset)
667 : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset) {}
673 uint32_t RecordOffset;
677 class FileStaticSym : public SymbolRecord {
679 explicit FileStaticSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
680 FileStaticSym(uint32_t RecordOffset)
681 : SymbolRecord(SymbolRecordKind::FileStaticSym),
682 RecordOffset(RecordOffset) {}
685 uint32_t ModFilenameOffset;
689 uint32_t RecordOffset;
693 class Compile2Sym : public SymbolRecord {
695 explicit Compile2Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
696 Compile2Sym(uint32_t RecordOffset)
697 : SymbolRecord(SymbolRecordKind::Compile2Sym),
698 RecordOffset(RecordOffset) {}
700 CompileSym2Flags Flags;
702 uint16_t VersionFrontendMajor;
703 uint16_t VersionFrontendMinor;
704 uint16_t VersionFrontendBuild;
705 uint16_t VersionBackendMajor;
706 uint16_t VersionBackendMinor;
707 uint16_t VersionBackendBuild;
709 std::vector<StringRef> ExtraStrings;
711 uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
712 uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
714 uint32_t RecordOffset;
718 class Compile3Sym : public SymbolRecord {
720 explicit Compile3Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
721 Compile3Sym(uint32_t RecordOffset)
722 : SymbolRecord(SymbolRecordKind::Compile3Sym),
723 RecordOffset(RecordOffset) {}
725 CompileSym3Flags Flags;
727 uint16_t VersionFrontendMajor;
728 uint16_t VersionFrontendMinor;
729 uint16_t VersionFrontendBuild;
730 uint16_t VersionFrontendQFE;
731 uint16_t VersionBackendMajor;
732 uint16_t VersionBackendMinor;
733 uint16_t VersionBackendBuild;
734 uint16_t VersionBackendQFE;
737 uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
738 uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
740 uint32_t RecordOffset;
744 class FrameProcSym : public SymbolRecord {
746 explicit FrameProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
747 explicit FrameProcSym(uint32_t RecordOffset)
748 : SymbolRecord(SymbolRecordKind::FrameProcSym),
749 RecordOffset(RecordOffset) {}
751 uint32_t TotalFrameBytes;
752 uint32_t PaddingFrameBytes;
753 uint32_t OffsetToPadding;
754 uint32_t BytesOfCalleeSavedRegisters;
755 uint32_t OffsetOfExceptionHandler;
756 uint16_t SectionIdOfExceptionHandler;
757 FrameProcedureOptions Flags;
759 uint32_t RecordOffset;
763 class CallSiteInfoSym : public SymbolRecord {
764 static constexpr uint32_t RelocationOffset = 4;
767 explicit CallSiteInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
768 explicit CallSiteInfoSym(uint32_t RecordOffset)
769 : SymbolRecord(SymbolRecordKind::CallSiteInfoSym) {}
771 uint32_t getRelocationOffset() const {
772 return RecordOffset + RelocationOffset;
779 uint32_t RecordOffset;
783 class HeapAllocationSiteSym : public SymbolRecord {
784 static constexpr uint32_t RelocationOffset = 4;
787 explicit HeapAllocationSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
788 explicit HeapAllocationSiteSym(uint32_t RecordOffset)
789 : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
790 RecordOffset(RecordOffset) {}
792 uint32_t getRelocationOffset() const {
793 return RecordOffset + RelocationOffset;
798 uint16_t CallInstructionSize;
801 uint32_t RecordOffset;
805 class FrameCookieSym : public SymbolRecord {
806 static constexpr uint32_t RelocationOffset = 4;
809 explicit FrameCookieSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
810 explicit FrameCookieSym(uint32_t RecordOffset)
811 : SymbolRecord(SymbolRecordKind::FrameCookieSym) {}
813 uint32_t getRelocationOffset() const {
814 return RecordOffset + RelocationOffset;
822 uint32_t RecordOffset;
826 class UDTSym : public SymbolRecord {
828 explicit UDTSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
829 explicit UDTSym(uint32_t RecordOffset)
830 : SymbolRecord(SymbolRecordKind::UDTSym) {}
835 uint32_t RecordOffset;
839 class BuildInfoSym : public SymbolRecord {
841 explicit BuildInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
842 BuildInfoSym(uint32_t RecordOffset)
843 : SymbolRecord(SymbolRecordKind::BuildInfoSym),
844 RecordOffset(RecordOffset) {}
848 uint32_t RecordOffset;
852 class BPRelativeSym : public SymbolRecord {
854 explicit BPRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
855 explicit BPRelativeSym(uint32_t RecordOffset)
856 : SymbolRecord(SymbolRecordKind::BPRelativeSym),
857 RecordOffset(RecordOffset) {}
863 uint32_t RecordOffset;
867 class RegRelativeSym : public SymbolRecord {
869 explicit RegRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
870 explicit RegRelativeSym(uint32_t RecordOffset)
871 : SymbolRecord(SymbolRecordKind::RegRelativeSym),
872 RecordOffset(RecordOffset) {}
879 uint32_t RecordOffset;
882 // S_CONSTANT, S_MANCONSTANT
883 class ConstantSym : public SymbolRecord {
885 explicit ConstantSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
886 ConstantSym(uint32_t RecordOffset)
887 : SymbolRecord(SymbolRecordKind::ConstantSym),
888 RecordOffset(RecordOffset) {}
894 uint32_t RecordOffset;
897 // S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
898 class DataSym : public SymbolRecord {
899 static constexpr uint32_t RelocationOffset = 8;
902 explicit DataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
903 DataSym(uint32_t RecordOffset)
904 : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset) {}
906 uint32_t getRelocationOffset() const {
907 return RecordOffset + RelocationOffset;
915 uint32_t RecordOffset;
918 // S_LTHREAD32, S_GTHREAD32
919 class ThreadLocalDataSym : public SymbolRecord {
920 static constexpr uint32_t RelocationOffset = 8;
923 explicit ThreadLocalDataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
924 explicit ThreadLocalDataSym(uint32_t RecordOffset)
925 : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
926 RecordOffset(RecordOffset) {}
928 uint32_t getRelocationOffset() const {
929 return RecordOffset + RelocationOffset;
937 uint32_t RecordOffset;
940 typedef CVRecord<SymbolKind> CVSymbol;
941 typedef VarStreamArray<CVSymbol> CVSymbolArray;
943 } // end namespace codeview
944 } // end namespace llvm
946 #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H