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"
32 explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {}
35 SymbolRecordKind getKind() const { return Kind; }
37 SymbolRecordKind Kind;
40 // S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or
42 class ProcSym : public SymbolRecord {
43 static constexpr uint32_t RelocationOffset = 32;
46 explicit ProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
47 ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset)
48 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
50 uint32_t getRelocationOffset() const {
51 return RecordOffset + RelocationOffset;
57 uint32_t CodeSize = 0;
58 uint32_t DbgStart = 0;
60 TypeIndex FunctionType;
61 uint32_t CodeOffset = 0;
63 ProcSymFlags Flags = ProcSymFlags::None;
66 uint32_t RecordOffset = 0;
70 class Thunk32Sym : public SymbolRecord {
72 explicit Thunk32Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
73 Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset)
74 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
84 ArrayRef<uint8_t> VariantData;
86 uint32_t RecordOffset;
90 class TrampolineSym : public SymbolRecord {
92 explicit TrampolineSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
93 TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset)
94 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
99 uint32_t TargetOffset;
100 uint16_t ThunkSection;
101 uint16_t TargetSection;
103 uint32_t RecordOffset;
107 class SectionSym : public SymbolRecord {
109 explicit SectionSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
110 SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset)
111 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
113 uint16_t SectionNumber;
117 uint32_t Characteristics;
120 uint32_t RecordOffset;
124 class CoffGroupSym : public SymbolRecord {
126 explicit CoffGroupSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
127 CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset)
128 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
131 uint32_t Characteristics;
136 uint32_t RecordOffset;
139 class ScopeEndSym : public SymbolRecord {
141 explicit ScopeEndSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
142 ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
143 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
145 uint32_t RecordOffset;
148 class CallerSym : public SymbolRecord {
150 explicit CallerSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
151 CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset)
152 : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
154 std::vector<TypeIndex> Indices;
156 uint32_t RecordOffset;
159 struct BinaryAnnotationIterator {
160 struct AnnotationData {
161 BinaryAnnotationsOpCode OpCode;
168 BinaryAnnotationIterator() = default;
169 BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
170 BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
171 : Data(Other.Data) {}
173 bool operator==(BinaryAnnotationIterator Other) const {
174 return Data == Other.Data;
177 bool operator!=(const BinaryAnnotationIterator &Other) const {
178 return !(*this == Other);
181 BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
186 BinaryAnnotationIterator &operator++() {
187 if (!ParseCurrentAnnotation()) {
188 *this = BinaryAnnotationIterator();
192 Next = ArrayRef<uint8_t>();
197 BinaryAnnotationIterator operator++(int) {
198 BinaryAnnotationIterator Orig(*this);
203 const AnnotationData &operator*() {
204 ParseCurrentAnnotation();
205 return Current.getValue();
209 static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) {
210 if (Annotations.empty())
213 uint8_t FirstByte = Annotations.front();
214 Annotations = Annotations.drop_front();
216 if ((FirstByte & 0x80) == 0x00)
219 if (Annotations.empty())
222 uint8_t SecondByte = Annotations.front();
223 Annotations = Annotations.drop_front();
225 if ((FirstByte & 0xC0) == 0x80)
226 return ((FirstByte & 0x3F) << 8) | SecondByte;
228 if (Annotations.empty())
231 uint8_t ThirdByte = Annotations.front();
232 Annotations = Annotations.drop_front();
234 if (Annotations.empty())
237 uint8_t FourthByte = Annotations.front();
238 Annotations = Annotations.drop_front();
240 if ((FirstByte & 0xE0) == 0xC0)
241 return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) |
242 (ThirdByte << 8) | FourthByte;
247 static int32_t DecodeSignedOperand(uint32_t Operand) {
249 return -(Operand >> 1);
253 static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
254 return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
257 bool ParseCurrentAnnotation() {
258 if (Current.hasValue())
262 uint32_t Op = GetCompressedAnnotation(Next);
263 AnnotationData Result;
264 Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
265 switch (Result.OpCode) {
266 case BinaryAnnotationsOpCode::Invalid:
267 Result.Name = "Invalid";
268 Next = ArrayRef<uint8_t>();
270 case BinaryAnnotationsOpCode::CodeOffset:
271 Result.Name = "CodeOffset";
272 Result.U1 = GetCompressedAnnotation(Next);
274 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
275 Result.Name = "ChangeCodeOffsetBase";
276 Result.U1 = GetCompressedAnnotation(Next);
278 case BinaryAnnotationsOpCode::ChangeCodeOffset:
279 Result.Name = "ChangeCodeOffset";
280 Result.U1 = GetCompressedAnnotation(Next);
282 case BinaryAnnotationsOpCode::ChangeCodeLength:
283 Result.Name = "ChangeCodeLength";
284 Result.U1 = GetCompressedAnnotation(Next);
286 case BinaryAnnotationsOpCode::ChangeFile:
287 Result.Name = "ChangeFile";
288 Result.U1 = GetCompressedAnnotation(Next);
290 case BinaryAnnotationsOpCode::ChangeLineEndDelta:
291 Result.Name = "ChangeLineEndDelta";
292 Result.U1 = GetCompressedAnnotation(Next);
294 case BinaryAnnotationsOpCode::ChangeRangeKind:
295 Result.Name = "ChangeRangeKind";
296 Result.U1 = GetCompressedAnnotation(Next);
298 case BinaryAnnotationsOpCode::ChangeColumnStart:
299 Result.Name = "ChangeColumnStart";
300 Result.U1 = GetCompressedAnnotation(Next);
302 case BinaryAnnotationsOpCode::ChangeColumnEnd:
303 Result.Name = "ChangeColumnEnd";
304 Result.U1 = GetCompressedAnnotation(Next);
306 case BinaryAnnotationsOpCode::ChangeLineOffset:
307 Result.Name = "ChangeLineOffset";
308 Result.S1 = DecodeSignedOperand(Next);
310 case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
311 Result.Name = "ChangeColumnEndDelta";
312 Result.S1 = DecodeSignedOperand(Next);
314 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
315 Result.Name = "ChangeCodeOffsetAndLineOffset";
316 uint32_t Annotation = GetCompressedAnnotation(Next);
317 Result.S1 = DecodeSignedOperand(Annotation >> 4);
318 Result.U1 = Annotation & 0xf;
321 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
322 Result.Name = "ChangeCodeLengthAndCodeOffset";
323 Result.U1 = GetCompressedAnnotation(Next);
324 Result.U2 = GetCompressedAnnotation(Next);
332 Optional<AnnotationData> Current;
333 ArrayRef<uint8_t> Data;
334 ArrayRef<uint8_t> Next;
338 class InlineSiteSym : public SymbolRecord {
340 explicit InlineSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
341 InlineSiteSym(uint32_t RecordOffset)
342 : SymbolRecord(SymbolRecordKind::InlineSiteSym),
343 RecordOffset(RecordOffset) {}
345 iterator_range<BinaryAnnotationIterator> annotations() const {
346 return make_range(BinaryAnnotationIterator(AnnotationData),
347 BinaryAnnotationIterator());
353 std::vector<uint8_t> AnnotationData;
355 uint32_t RecordOffset;
359 class PublicSym32 : public SymbolRecord {
361 PublicSym32() : SymbolRecord(SymbolRecordKind::PublicSym32) {}
362 explicit PublicSym32(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
363 explicit PublicSym32(uint32_t RecordOffset)
364 : SymbolRecord(SymbolRecordKind::PublicSym32),
365 RecordOffset(RecordOffset) {}
367 PublicSymFlags Flags = PublicSymFlags::None;
369 uint16_t Segment = 0;
372 uint32_t RecordOffset = 0;
376 class RegisterSym : public SymbolRecord {
378 explicit RegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
379 RegisterSym(uint32_t RecordOffset)
380 : SymbolRecord(SymbolRecordKind::RegisterSym),
381 RecordOffset(RecordOffset) {}
387 uint32_t RecordOffset;
390 // S_PROCREF, S_LPROCREF
391 class ProcRefSym : public SymbolRecord {
393 explicit ProcRefSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
394 explicit ProcRefSym(uint32_t RecordOffset)
395 : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset) {
403 uint16_t modi() const { return Module - 1; }
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;
485 explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
486 DefRangeRegisterSym(uint32_t RecordOffset)
487 : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
488 RecordOffset(RecordOffset) {}
490 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
493 LocalVariableAddrRange Range;
494 std::vector<LocalVariableAddrGap> Gaps;
496 uint32_t RecordOffset;
499 // S_DEFRANGE_SUBFIELD_REGISTER
500 class DefRangeSubfieldRegisterSym : public SymbolRecord {
503 ulittle16_t Register;
504 ulittle16_t MayHaveNoName;
505 ulittle32_t OffsetInParent;
508 explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
509 : SymbolRecord(Kind) {}
510 DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
511 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
512 RecordOffset(RecordOffset) {}
514 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
517 LocalVariableAddrRange Range;
518 std::vector<LocalVariableAddrGap> Gaps;
520 uint32_t RecordOffset;
523 // S_DEFRANGE_FRAMEPOINTER_REL
524 class DefRangeFramePointerRelSym : public SymbolRecord {
525 static constexpr uint32_t RelocationOffset = 8;
528 explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind)
529 : SymbolRecord(Kind) {}
530 DefRangeFramePointerRelSym(uint32_t RecordOffset)
531 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
532 RecordOffset(RecordOffset) {}
534 uint32_t getRelocationOffset() const {
535 return RecordOffset + RelocationOffset;
539 LocalVariableAddrRange Range;
540 std::vector<LocalVariableAddrGap> Gaps;
542 uint32_t RecordOffset;
545 // S_DEFRANGE_REGISTER_REL
546 class DefRangeRegisterRelSym : public SymbolRecord {
549 ulittle16_t Register;
551 little32_t BasePointerOffset;
554 explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
555 explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
556 : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
557 RecordOffset(RecordOffset) {}
559 // The flags implement this notional bitfield:
560 // uint16_t IsSubfield : 1;
561 // uint16_t Padding : 3;
562 // uint16_t OffsetInParent : 12;
565 OffsetInParentShift = 4,
568 bool hasSpilledUDTMember() const { return Hdr.Flags & IsSubfieldFlag; }
569 uint16_t offsetInParent() const { return Hdr.Flags >> OffsetInParentShift; }
571 uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
574 LocalVariableAddrRange Range;
575 std::vector<LocalVariableAddrGap> Gaps;
577 uint32_t RecordOffset;
580 // S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
581 class DefRangeFramePointerRelFullScopeSym : public SymbolRecord {
583 explicit DefRangeFramePointerRelFullScopeSym(SymbolRecordKind Kind)
584 : SymbolRecord(Kind) {}
585 explicit DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset)
586 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
587 RecordOffset(RecordOffset) {}
591 uint32_t RecordOffset;
595 class BlockSym : public SymbolRecord {
596 static constexpr uint32_t RelocationOffset = 16;
599 explicit BlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
600 explicit BlockSym(uint32_t RecordOffset)
601 : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset) {}
603 uint32_t getRelocationOffset() const {
604 return RecordOffset + RelocationOffset;
614 uint32_t RecordOffset;
618 class LabelSym : public SymbolRecord {
619 static constexpr uint32_t RelocationOffset = 4;
622 explicit LabelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
623 explicit LabelSym(uint32_t RecordOffset)
624 : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset) {}
626 uint32_t getRelocationOffset() const {
627 return RecordOffset + RelocationOffset;
635 uint32_t RecordOffset;
639 class ObjNameSym : public SymbolRecord {
641 explicit ObjNameSym() : SymbolRecord(SymbolRecordKind::ObjNameSym) {}
642 explicit ObjNameSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
643 ObjNameSym(uint32_t RecordOffset)
644 : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset) {
650 uint32_t RecordOffset;
654 class EnvBlockSym : public SymbolRecord {
656 explicit EnvBlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
657 EnvBlockSym(uint32_t RecordOffset)
658 : SymbolRecord(SymbolRecordKind::EnvBlockSym),
659 RecordOffset(RecordOffset) {}
661 std::vector<StringRef> Fields;
663 uint32_t RecordOffset;
667 class ExportSym : public SymbolRecord {
669 explicit ExportSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
670 ExportSym(uint32_t RecordOffset)
671 : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset) {}
677 uint32_t RecordOffset;
681 class FileStaticSym : public SymbolRecord {
683 explicit FileStaticSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
684 FileStaticSym(uint32_t RecordOffset)
685 : SymbolRecord(SymbolRecordKind::FileStaticSym),
686 RecordOffset(RecordOffset) {}
689 uint32_t ModFilenameOffset;
693 uint32_t RecordOffset;
697 class Compile2Sym : public SymbolRecord {
699 explicit Compile2Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
700 Compile2Sym(uint32_t RecordOffset)
701 : SymbolRecord(SymbolRecordKind::Compile2Sym),
702 RecordOffset(RecordOffset) {}
704 CompileSym2Flags Flags;
706 uint16_t VersionFrontendMajor;
707 uint16_t VersionFrontendMinor;
708 uint16_t VersionFrontendBuild;
709 uint16_t VersionBackendMajor;
710 uint16_t VersionBackendMinor;
711 uint16_t VersionBackendBuild;
713 std::vector<StringRef> ExtraStrings;
715 uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
716 uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
718 uint32_t RecordOffset;
722 class Compile3Sym : public SymbolRecord {
724 Compile3Sym() : SymbolRecord(SymbolRecordKind::Compile3Sym) {}
725 explicit Compile3Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
726 Compile3Sym(uint32_t RecordOffset)
727 : SymbolRecord(SymbolRecordKind::Compile3Sym),
728 RecordOffset(RecordOffset) {}
730 CompileSym3Flags Flags;
732 uint16_t VersionFrontendMajor;
733 uint16_t VersionFrontendMinor;
734 uint16_t VersionFrontendBuild;
735 uint16_t VersionFrontendQFE;
736 uint16_t VersionBackendMajor;
737 uint16_t VersionBackendMinor;
738 uint16_t VersionBackendBuild;
739 uint16_t VersionBackendQFE;
742 void setLanguage(SourceLanguage Lang) {
743 Flags = CompileSym3Flags((uint32_t(Flags) & 0xFFFFFF00) | uint32_t(Lang));
746 SourceLanguage getLanguage() const {
747 return static_cast<SourceLanguage>(static_cast<uint32_t>(Flags) & 0xFF);
749 CompileSym3Flags getFlags() const {
750 return static_cast<CompileSym3Flags>(static_cast<uint32_t>(Flags) & ~0xFF);
753 bool hasOptimizations() const {
754 return CompileSym3Flags::None !=
755 (getFlags() & (CompileSym3Flags::PGO | CompileSym3Flags::LTCG));
758 uint32_t RecordOffset;
762 class FrameProcSym : public SymbolRecord {
764 explicit FrameProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
765 explicit FrameProcSym(uint32_t RecordOffset)
766 : SymbolRecord(SymbolRecordKind::FrameProcSym),
767 RecordOffset(RecordOffset) {}
769 uint32_t TotalFrameBytes;
770 uint32_t PaddingFrameBytes;
771 uint32_t OffsetToPadding;
772 uint32_t BytesOfCalleeSavedRegisters;
773 uint32_t OffsetOfExceptionHandler;
774 uint16_t SectionIdOfExceptionHandler;
775 FrameProcedureOptions Flags;
777 /// Extract the register this frame uses to refer to local variables.
778 RegisterId getLocalFramePtrReg(CPUType CPU) const {
779 return decodeFramePtrReg(
780 EncodedFramePtrReg((uint32_t(Flags) >> 14U) & 0x3U), CPU);
783 /// Extract the register this frame uses to refer to parameters.
784 RegisterId getParamFramePtrReg(CPUType CPU) const {
785 return decodeFramePtrReg(
786 EncodedFramePtrReg((uint32_t(Flags) >> 16U) & 0x3U), CPU);
789 uint32_t RecordOffset;
795 class CallSiteInfoSym : public SymbolRecord {
796 static constexpr uint32_t RelocationOffset = 4;
799 explicit CallSiteInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
800 explicit CallSiteInfoSym(uint32_t RecordOffset)
801 : SymbolRecord(SymbolRecordKind::CallSiteInfoSym) {}
803 uint32_t getRelocationOffset() const {
804 return RecordOffset + RelocationOffset;
811 uint32_t RecordOffset;
815 class HeapAllocationSiteSym : public SymbolRecord {
816 static constexpr uint32_t RelocationOffset = 4;
819 explicit HeapAllocationSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
820 explicit HeapAllocationSiteSym(uint32_t RecordOffset)
821 : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
822 RecordOffset(RecordOffset) {}
824 uint32_t getRelocationOffset() const {
825 return RecordOffset + RelocationOffset;
830 uint16_t CallInstructionSize;
833 uint32_t RecordOffset;
837 class FrameCookieSym : public SymbolRecord {
838 static constexpr uint32_t RelocationOffset = 4;
841 explicit FrameCookieSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
842 explicit FrameCookieSym(uint32_t RecordOffset)
843 : SymbolRecord(SymbolRecordKind::FrameCookieSym) {}
845 uint32_t getRelocationOffset() const {
846 return RecordOffset + RelocationOffset;
851 FrameCookieKind CookieKind;
854 uint32_t RecordOffset;
858 class UDTSym : public SymbolRecord {
860 explicit UDTSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
861 explicit UDTSym(uint32_t RecordOffset)
862 : SymbolRecord(SymbolRecordKind::UDTSym) {}
867 uint32_t RecordOffset;
871 class BuildInfoSym : public SymbolRecord {
873 explicit BuildInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
874 BuildInfoSym(uint32_t RecordOffset)
875 : SymbolRecord(SymbolRecordKind::BuildInfoSym),
876 RecordOffset(RecordOffset) {}
880 uint32_t RecordOffset;
884 class BPRelativeSym : public SymbolRecord {
886 explicit BPRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
887 explicit BPRelativeSym(uint32_t RecordOffset)
888 : SymbolRecord(SymbolRecordKind::BPRelativeSym),
889 RecordOffset(RecordOffset) {}
895 uint32_t RecordOffset;
899 class RegRelativeSym : public SymbolRecord {
901 explicit RegRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
902 explicit RegRelativeSym(uint32_t RecordOffset)
903 : SymbolRecord(SymbolRecordKind::RegRelativeSym),
904 RecordOffset(RecordOffset) {}
911 uint32_t RecordOffset;
914 // S_CONSTANT, S_MANCONSTANT
915 class ConstantSym : public SymbolRecord {
917 explicit ConstantSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
918 ConstantSym(uint32_t RecordOffset)
919 : SymbolRecord(SymbolRecordKind::ConstantSym),
920 RecordOffset(RecordOffset) {}
926 uint32_t RecordOffset;
929 // S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
930 class DataSym : public SymbolRecord {
931 static constexpr uint32_t RelocationOffset = 8;
934 explicit DataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
935 DataSym(uint32_t RecordOffset)
936 : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset) {}
938 uint32_t getRelocationOffset() const {
939 return RecordOffset + RelocationOffset;
947 uint32_t RecordOffset;
950 // S_LTHREAD32, S_GTHREAD32
951 class ThreadLocalDataSym : public SymbolRecord {
952 static constexpr uint32_t RelocationOffset = 8;
955 explicit ThreadLocalDataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
956 explicit ThreadLocalDataSym(uint32_t RecordOffset)
957 : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
958 RecordOffset(RecordOffset) {}
960 uint32_t getRelocationOffset() const {
961 return RecordOffset + RelocationOffset;
969 uint32_t RecordOffset;
973 class UsingNamespaceSym : public SymbolRecord {
975 explicit UsingNamespaceSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
976 explicit UsingNamespaceSym(uint32_t RecordOffset)
977 : SymbolRecord(SymbolRecordKind::RegRelativeSym),
978 RecordOffset(RecordOffset) {}
982 uint32_t RecordOffset;
987 using CVSymbol = CVRecord<SymbolKind>;
988 using CVSymbolArray = VarStreamArray<CVSymbol>;
990 Expected<CVSymbol> readSymbolFromStream(BinaryStreamRef Stream,
993 } // end namespace codeview
994 } // end namespace llvm
996 #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H