1 //===- SymbolRecord.h -------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
10 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
12 #include "llvm/ADT/APSInt.h"
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/Optional.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/iterator.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 DecodedAnnotation
{
161 ArrayRef
<uint8_t> Bytes
;
162 BinaryAnnotationsOpCode OpCode
;
168 struct BinaryAnnotationIterator
169 : public iterator_facade_base
<BinaryAnnotationIterator
,
170 std::forward_iterator_tag
,
172 BinaryAnnotationIterator() = default;
173 BinaryAnnotationIterator(ArrayRef
<uint8_t> Annotations
) : Data(Annotations
) {}
174 BinaryAnnotationIterator(const BinaryAnnotationIterator
&Other
)
175 : Data(Other
.Data
) {}
177 bool operator==(BinaryAnnotationIterator Other
) const {
178 return Data
== Other
.Data
;
181 BinaryAnnotationIterator
&operator=(const BinaryAnnotationIterator Other
) {
186 BinaryAnnotationIterator
&operator++() {
187 if (!ParseCurrentAnnotation()) {
188 *this = BinaryAnnotationIterator();
192 Next
= ArrayRef
<uint8_t>();
197 const DecodedAnnotation
&operator*() {
198 ParseCurrentAnnotation();
199 return Current
.getValue();
203 static uint32_t GetCompressedAnnotation(ArrayRef
<uint8_t> &Annotations
) {
204 if (Annotations
.empty())
207 uint8_t FirstByte
= Annotations
.front();
208 Annotations
= Annotations
.drop_front();
210 if ((FirstByte
& 0x80) == 0x00)
213 if (Annotations
.empty())
216 uint8_t SecondByte
= Annotations
.front();
217 Annotations
= Annotations
.drop_front();
219 if ((FirstByte
& 0xC0) == 0x80)
220 return ((FirstByte
& 0x3F) << 8) | SecondByte
;
222 if (Annotations
.empty())
225 uint8_t ThirdByte
= Annotations
.front();
226 Annotations
= Annotations
.drop_front();
228 if (Annotations
.empty())
231 uint8_t FourthByte
= Annotations
.front();
232 Annotations
= Annotations
.drop_front();
234 if ((FirstByte
& 0xE0) == 0xC0)
235 return ((FirstByte
& 0x1F) << 24) | (SecondByte
<< 16) |
236 (ThirdByte
<< 8) | FourthByte
;
241 static int32_t DecodeSignedOperand(uint32_t Operand
) {
243 return -(Operand
>> 1);
247 static int32_t DecodeSignedOperand(ArrayRef
<uint8_t> &Annotations
) {
248 return DecodeSignedOperand(GetCompressedAnnotation(Annotations
));
251 bool ParseCurrentAnnotation() {
252 if (Current
.hasValue())
256 uint32_t Op
= GetCompressedAnnotation(Next
);
257 DecodedAnnotation Result
;
258 Result
.OpCode
= static_cast<BinaryAnnotationsOpCode
>(Op
);
259 switch (Result
.OpCode
) {
260 case BinaryAnnotationsOpCode::Invalid
:
261 Result
.Name
= "Invalid";
262 Next
= ArrayRef
<uint8_t>();
264 case BinaryAnnotationsOpCode::CodeOffset
:
265 Result
.Name
= "CodeOffset";
266 Result
.U1
= GetCompressedAnnotation(Next
);
268 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase
:
269 Result
.Name
= "ChangeCodeOffsetBase";
270 Result
.U1
= GetCompressedAnnotation(Next
);
272 case BinaryAnnotationsOpCode::ChangeCodeOffset
:
273 Result
.Name
= "ChangeCodeOffset";
274 Result
.U1
= GetCompressedAnnotation(Next
);
276 case BinaryAnnotationsOpCode::ChangeCodeLength
:
277 Result
.Name
= "ChangeCodeLength";
278 Result
.U1
= GetCompressedAnnotation(Next
);
280 case BinaryAnnotationsOpCode::ChangeFile
:
281 Result
.Name
= "ChangeFile";
282 Result
.U1
= GetCompressedAnnotation(Next
);
284 case BinaryAnnotationsOpCode::ChangeLineEndDelta
:
285 Result
.Name
= "ChangeLineEndDelta";
286 Result
.U1
= GetCompressedAnnotation(Next
);
288 case BinaryAnnotationsOpCode::ChangeRangeKind
:
289 Result
.Name
= "ChangeRangeKind";
290 Result
.U1
= GetCompressedAnnotation(Next
);
292 case BinaryAnnotationsOpCode::ChangeColumnStart
:
293 Result
.Name
= "ChangeColumnStart";
294 Result
.U1
= GetCompressedAnnotation(Next
);
296 case BinaryAnnotationsOpCode::ChangeColumnEnd
:
297 Result
.Name
= "ChangeColumnEnd";
298 Result
.U1
= GetCompressedAnnotation(Next
);
300 case BinaryAnnotationsOpCode::ChangeLineOffset
:
301 Result
.Name
= "ChangeLineOffset";
302 Result
.S1
= DecodeSignedOperand(Next
);
304 case BinaryAnnotationsOpCode::ChangeColumnEndDelta
:
305 Result
.Name
= "ChangeColumnEndDelta";
306 Result
.S1
= DecodeSignedOperand(Next
);
308 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset
: {
309 Result
.Name
= "ChangeCodeOffsetAndLineOffset";
310 uint32_t Annotation
= GetCompressedAnnotation(Next
);
311 Result
.S1
= DecodeSignedOperand(Annotation
>> 4);
312 Result
.U1
= Annotation
& 0xf;
315 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset
: {
316 Result
.Name
= "ChangeCodeLengthAndCodeOffset";
317 Result
.U1
= GetCompressedAnnotation(Next
);
318 Result
.U2
= GetCompressedAnnotation(Next
);
322 Result
.Bytes
= Data
.take_front(Data
.size() - Next
.size());
327 Optional
<DecodedAnnotation
> Current
;
328 ArrayRef
<uint8_t> Data
;
329 ArrayRef
<uint8_t> Next
;
333 class InlineSiteSym
: public SymbolRecord
{
335 explicit InlineSiteSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
336 InlineSiteSym(uint32_t RecordOffset
)
337 : SymbolRecord(SymbolRecordKind::InlineSiteSym
),
338 RecordOffset(RecordOffset
) {}
340 iterator_range
<BinaryAnnotationIterator
> annotations() const {
341 return make_range(BinaryAnnotationIterator(AnnotationData
),
342 BinaryAnnotationIterator());
348 std::vector
<uint8_t> AnnotationData
;
350 uint32_t RecordOffset
;
354 class PublicSym32
: public SymbolRecord
{
356 PublicSym32() : SymbolRecord(SymbolRecordKind::PublicSym32
) {}
357 explicit PublicSym32(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
358 explicit PublicSym32(uint32_t RecordOffset
)
359 : SymbolRecord(SymbolRecordKind::PublicSym32
),
360 RecordOffset(RecordOffset
) {}
362 PublicSymFlags Flags
= PublicSymFlags::None
;
364 uint16_t Segment
= 0;
367 uint32_t RecordOffset
= 0;
371 class RegisterSym
: public SymbolRecord
{
373 explicit RegisterSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
374 RegisterSym(uint32_t RecordOffset
)
375 : SymbolRecord(SymbolRecordKind::RegisterSym
),
376 RecordOffset(RecordOffset
) {}
382 uint32_t RecordOffset
;
385 // S_PROCREF, S_LPROCREF
386 class ProcRefSym
: public SymbolRecord
{
388 explicit ProcRefSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
389 explicit ProcRefSym(uint32_t RecordOffset
)
390 : SymbolRecord(SymbolRecordKind::ProcRefSym
), RecordOffset(RecordOffset
) {
398 uint16_t modi() const { return Module
- 1; }
399 uint32_t RecordOffset
;
403 class LocalSym
: public SymbolRecord
{
405 explicit LocalSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
406 explicit LocalSym(uint32_t RecordOffset
)
407 : SymbolRecord(SymbolRecordKind::LocalSym
), RecordOffset(RecordOffset
) {}
413 uint32_t RecordOffset
;
416 struct LocalVariableAddrRange
{
417 uint32_t OffsetStart
;
422 struct LocalVariableAddrGap
{
423 uint16_t GapStartOffset
;
427 enum : uint16_t { MaxDefRange
= 0xf000 };
430 class DefRangeSym
: public SymbolRecord
{
431 static constexpr uint32_t RelocationOffset
= 8;
434 explicit DefRangeSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
435 explicit DefRangeSym(uint32_t RecordOffset
)
436 : SymbolRecord(SymbolRecordKind::DefRangeSym
),
437 RecordOffset(RecordOffset
) {}
439 uint32_t getRelocationOffset() const {
440 return RecordOffset
+ RelocationOffset
;
444 LocalVariableAddrRange Range
;
445 std::vector
<LocalVariableAddrGap
> Gaps
;
447 uint32_t RecordOffset
;
450 // S_DEFRANGE_SUBFIELD
451 class DefRangeSubfieldSym
: public SymbolRecord
{
452 static constexpr uint32_t RelocationOffset
= 12;
455 explicit DefRangeSubfieldSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
456 DefRangeSubfieldSym(uint32_t RecordOffset
)
457 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym
),
458 RecordOffset(RecordOffset
) {}
460 uint32_t getRelocationOffset() const {
461 return RecordOffset
+ RelocationOffset
;
465 uint16_t OffsetInParent
;
466 LocalVariableAddrRange Range
;
467 std::vector
<LocalVariableAddrGap
> Gaps
;
469 uint32_t RecordOffset
;
472 // S_DEFRANGE_REGISTER
473 class DefRangeRegisterSym
: public SymbolRecord
{
476 ulittle16_t Register
;
477 ulittle16_t MayHaveNoName
;
480 explicit DefRangeRegisterSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
481 DefRangeRegisterSym(uint32_t RecordOffset
)
482 : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym
),
483 RecordOffset(RecordOffset
) {}
485 uint32_t getRelocationOffset() const { return RecordOffset
+ sizeof(Header
); }
488 LocalVariableAddrRange Range
;
489 std::vector
<LocalVariableAddrGap
> Gaps
;
491 uint32_t RecordOffset
;
494 // S_DEFRANGE_SUBFIELD_REGISTER
495 class DefRangeSubfieldRegisterSym
: public SymbolRecord
{
498 ulittle16_t Register
;
499 ulittle16_t MayHaveNoName
;
500 ulittle32_t OffsetInParent
;
503 explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind
)
504 : SymbolRecord(Kind
) {}
505 DefRangeSubfieldRegisterSym(uint32_t RecordOffset
)
506 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym
),
507 RecordOffset(RecordOffset
) {}
509 uint32_t getRelocationOffset() const { return RecordOffset
+ sizeof(Header
); }
512 LocalVariableAddrRange Range
;
513 std::vector
<LocalVariableAddrGap
> Gaps
;
515 uint32_t RecordOffset
;
518 // S_DEFRANGE_FRAMEPOINTER_REL
519 class DefRangeFramePointerRelSym
: public SymbolRecord
{
520 static constexpr uint32_t RelocationOffset
= 8;
527 explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind
)
528 : SymbolRecord(Kind
) {}
529 DefRangeFramePointerRelSym(uint32_t RecordOffset
)
530 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym
),
531 RecordOffset(RecordOffset
) {}
533 uint32_t getRelocationOffset() const {
534 return RecordOffset
+ RelocationOffset
;
538 LocalVariableAddrRange Range
;
539 std::vector
<LocalVariableAddrGap
> Gaps
;
541 uint32_t RecordOffset
;
544 // S_DEFRANGE_REGISTER_REL
545 class DefRangeRegisterRelSym
: public SymbolRecord
{
548 ulittle16_t Register
;
550 little32_t BasePointerOffset
;
553 explicit DefRangeRegisterRelSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
554 explicit DefRangeRegisterRelSym(uint32_t RecordOffset
)
555 : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym
),
556 RecordOffset(RecordOffset
) {}
558 // The flags implement this notional bitfield:
559 // uint16_t IsSubfield : 1;
560 // uint16_t Padding : 3;
561 // uint16_t OffsetInParent : 12;
564 OffsetInParentShift
= 4,
567 bool hasSpilledUDTMember() const { return Hdr
.Flags
& IsSubfieldFlag
; }
568 uint16_t offsetInParent() const { return Hdr
.Flags
>> OffsetInParentShift
; }
570 uint32_t getRelocationOffset() const { return RecordOffset
+ sizeof(Header
); }
573 LocalVariableAddrRange Range
;
574 std::vector
<LocalVariableAddrGap
> Gaps
;
576 uint32_t RecordOffset
;
579 // S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
580 class DefRangeFramePointerRelFullScopeSym
: public SymbolRecord
{
582 explicit DefRangeFramePointerRelFullScopeSym(SymbolRecordKind Kind
)
583 : SymbolRecord(Kind
) {}
584 explicit DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset
)
585 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym
),
586 RecordOffset(RecordOffset
) {}
590 uint32_t RecordOffset
;
594 class BlockSym
: public SymbolRecord
{
595 static constexpr uint32_t RelocationOffset
= 16;
598 explicit BlockSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
599 explicit BlockSym(uint32_t RecordOffset
)
600 : SymbolRecord(SymbolRecordKind::BlockSym
), RecordOffset(RecordOffset
) {}
602 uint32_t getRelocationOffset() const {
603 return RecordOffset
+ RelocationOffset
;
613 uint32_t RecordOffset
;
617 class LabelSym
: public SymbolRecord
{
618 static constexpr uint32_t RelocationOffset
= 4;
621 explicit LabelSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
622 explicit LabelSym(uint32_t RecordOffset
)
623 : SymbolRecord(SymbolRecordKind::LabelSym
), RecordOffset(RecordOffset
) {}
625 uint32_t getRelocationOffset() const {
626 return RecordOffset
+ RelocationOffset
;
634 uint32_t RecordOffset
;
638 class ObjNameSym
: public SymbolRecord
{
640 explicit ObjNameSym() : SymbolRecord(SymbolRecordKind::ObjNameSym
) {}
641 explicit ObjNameSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
642 ObjNameSym(uint32_t RecordOffset
)
643 : SymbolRecord(SymbolRecordKind::ObjNameSym
), RecordOffset(RecordOffset
) {
649 uint32_t RecordOffset
;
653 class EnvBlockSym
: public SymbolRecord
{
655 explicit EnvBlockSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
656 EnvBlockSym(uint32_t RecordOffset
)
657 : SymbolRecord(SymbolRecordKind::EnvBlockSym
),
658 RecordOffset(RecordOffset
) {}
660 std::vector
<StringRef
> Fields
;
662 uint32_t RecordOffset
;
666 class ExportSym
: public SymbolRecord
{
668 explicit ExportSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
669 ExportSym(uint32_t RecordOffset
)
670 : SymbolRecord(SymbolRecordKind::ExportSym
), RecordOffset(RecordOffset
) {}
676 uint32_t RecordOffset
;
680 class FileStaticSym
: public SymbolRecord
{
682 explicit FileStaticSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
683 FileStaticSym(uint32_t RecordOffset
)
684 : SymbolRecord(SymbolRecordKind::FileStaticSym
),
685 RecordOffset(RecordOffset
) {}
688 uint32_t ModFilenameOffset
;
692 uint32_t RecordOffset
;
696 class Compile2Sym
: public SymbolRecord
{
698 explicit Compile2Sym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
699 Compile2Sym(uint32_t RecordOffset
)
700 : SymbolRecord(SymbolRecordKind::Compile2Sym
),
701 RecordOffset(RecordOffset
) {}
703 CompileSym2Flags Flags
;
705 uint16_t VersionFrontendMajor
;
706 uint16_t VersionFrontendMinor
;
707 uint16_t VersionFrontendBuild
;
708 uint16_t VersionBackendMajor
;
709 uint16_t VersionBackendMinor
;
710 uint16_t VersionBackendBuild
;
712 std::vector
<StringRef
> ExtraStrings
;
714 uint8_t getLanguage() const { return static_cast<uint32_t>(Flags
) & 0xFF; }
715 uint32_t getFlags() const { return static_cast<uint32_t>(Flags
) & ~0xFF; }
717 uint32_t RecordOffset
;
721 class Compile3Sym
: public SymbolRecord
{
723 Compile3Sym() : SymbolRecord(SymbolRecordKind::Compile3Sym
) {}
724 explicit Compile3Sym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
725 Compile3Sym(uint32_t RecordOffset
)
726 : SymbolRecord(SymbolRecordKind::Compile3Sym
),
727 RecordOffset(RecordOffset
) {}
729 CompileSym3Flags Flags
;
731 uint16_t VersionFrontendMajor
;
732 uint16_t VersionFrontendMinor
;
733 uint16_t VersionFrontendBuild
;
734 uint16_t VersionFrontendQFE
;
735 uint16_t VersionBackendMajor
;
736 uint16_t VersionBackendMinor
;
737 uint16_t VersionBackendBuild
;
738 uint16_t VersionBackendQFE
;
741 void setLanguage(SourceLanguage Lang
) {
742 Flags
= CompileSym3Flags((uint32_t(Flags
) & 0xFFFFFF00) | uint32_t(Lang
));
745 SourceLanguage
getLanguage() const {
746 return static_cast<SourceLanguage
>(static_cast<uint32_t>(Flags
) & 0xFF);
748 CompileSym3Flags
getFlags() const {
749 return static_cast<CompileSym3Flags
>(static_cast<uint32_t>(Flags
) & ~0xFF);
752 bool hasOptimizations() const {
753 return CompileSym3Flags::None
!=
754 (getFlags() & (CompileSym3Flags::PGO
| CompileSym3Flags::LTCG
));
757 uint32_t RecordOffset
;
761 class FrameProcSym
: public SymbolRecord
{
763 explicit FrameProcSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
764 explicit FrameProcSym(uint32_t RecordOffset
)
765 : SymbolRecord(SymbolRecordKind::FrameProcSym
),
766 RecordOffset(RecordOffset
) {}
768 uint32_t TotalFrameBytes
;
769 uint32_t PaddingFrameBytes
;
770 uint32_t OffsetToPadding
;
771 uint32_t BytesOfCalleeSavedRegisters
;
772 uint32_t OffsetOfExceptionHandler
;
773 uint16_t SectionIdOfExceptionHandler
;
774 FrameProcedureOptions Flags
;
776 /// Extract the register this frame uses to refer to local variables.
777 RegisterId
getLocalFramePtrReg(CPUType CPU
) const {
778 return decodeFramePtrReg(
779 EncodedFramePtrReg((uint32_t(Flags
) >> 14U) & 0x3U
), CPU
);
782 /// Extract the register this frame uses to refer to parameters.
783 RegisterId
getParamFramePtrReg(CPUType CPU
) const {
784 return decodeFramePtrReg(
785 EncodedFramePtrReg((uint32_t(Flags
) >> 16U) & 0x3U
), CPU
);
788 uint32_t RecordOffset
;
794 class CallSiteInfoSym
: public SymbolRecord
{
795 static constexpr uint32_t RelocationOffset
= 4;
798 explicit CallSiteInfoSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
799 explicit CallSiteInfoSym(uint32_t RecordOffset
)
800 : SymbolRecord(SymbolRecordKind::CallSiteInfoSym
) {}
802 uint32_t getRelocationOffset() const {
803 return RecordOffset
+ RelocationOffset
;
810 uint32_t RecordOffset
;
814 class HeapAllocationSiteSym
: public SymbolRecord
{
815 static constexpr uint32_t RelocationOffset
= 4;
818 explicit HeapAllocationSiteSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
819 explicit HeapAllocationSiteSym(uint32_t RecordOffset
)
820 : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym
),
821 RecordOffset(RecordOffset
) {}
823 uint32_t getRelocationOffset() const {
824 return RecordOffset
+ RelocationOffset
;
829 uint16_t CallInstructionSize
;
832 uint32_t RecordOffset
;
836 class FrameCookieSym
: public SymbolRecord
{
837 static constexpr uint32_t RelocationOffset
= 4;
840 explicit FrameCookieSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
841 explicit FrameCookieSym(uint32_t RecordOffset
)
842 : SymbolRecord(SymbolRecordKind::FrameCookieSym
) {}
844 uint32_t getRelocationOffset() const {
845 return RecordOffset
+ RelocationOffset
;
850 FrameCookieKind CookieKind
;
853 uint32_t RecordOffset
;
857 class UDTSym
: public SymbolRecord
{
859 explicit UDTSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
860 explicit UDTSym(uint32_t RecordOffset
)
861 : SymbolRecord(SymbolRecordKind::UDTSym
) {}
866 uint32_t RecordOffset
;
870 class BuildInfoSym
: public SymbolRecord
{
872 explicit BuildInfoSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
873 BuildInfoSym(uint32_t RecordOffset
)
874 : SymbolRecord(SymbolRecordKind::BuildInfoSym
),
875 RecordOffset(RecordOffset
) {}
879 uint32_t RecordOffset
;
883 class BPRelativeSym
: public SymbolRecord
{
885 explicit BPRelativeSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
886 explicit BPRelativeSym(uint32_t RecordOffset
)
887 : SymbolRecord(SymbolRecordKind::BPRelativeSym
),
888 RecordOffset(RecordOffset
) {}
894 uint32_t RecordOffset
;
898 class RegRelativeSym
: public SymbolRecord
{
900 explicit RegRelativeSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
901 explicit RegRelativeSym(uint32_t RecordOffset
)
902 : SymbolRecord(SymbolRecordKind::RegRelativeSym
),
903 RecordOffset(RecordOffset
) {}
910 uint32_t RecordOffset
;
913 // S_CONSTANT, S_MANCONSTANT
914 class ConstantSym
: public SymbolRecord
{
916 explicit ConstantSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
917 ConstantSym(uint32_t RecordOffset
)
918 : SymbolRecord(SymbolRecordKind::ConstantSym
),
919 RecordOffset(RecordOffset
) {}
925 uint32_t RecordOffset
;
928 // S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
929 class DataSym
: public SymbolRecord
{
930 static constexpr uint32_t RelocationOffset
= 8;
933 explicit DataSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
934 DataSym(uint32_t RecordOffset
)
935 : SymbolRecord(SymbolRecordKind::DataSym
), RecordOffset(RecordOffset
) {}
937 uint32_t getRelocationOffset() const {
938 return RecordOffset
+ RelocationOffset
;
946 uint32_t RecordOffset
;
949 // S_LTHREAD32, S_GTHREAD32
950 class ThreadLocalDataSym
: public SymbolRecord
{
951 static constexpr uint32_t RelocationOffset
= 8;
954 explicit ThreadLocalDataSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
955 explicit ThreadLocalDataSym(uint32_t RecordOffset
)
956 : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym
),
957 RecordOffset(RecordOffset
) {}
959 uint32_t getRelocationOffset() const {
960 return RecordOffset
+ RelocationOffset
;
968 uint32_t RecordOffset
;
972 class UsingNamespaceSym
: public SymbolRecord
{
974 explicit UsingNamespaceSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
975 explicit UsingNamespaceSym(uint32_t RecordOffset
)
976 : SymbolRecord(SymbolRecordKind::UsingNamespaceSym
),
977 RecordOffset(RecordOffset
) {}
981 uint32_t RecordOffset
;
985 class AnnotationSym
: public SymbolRecord
{
987 explicit AnnotationSym(SymbolRecordKind Kind
) : SymbolRecord(Kind
) {}
988 explicit AnnotationSym(uint32_t RecordOffset
)
989 : SymbolRecord(SymbolRecordKind::AnnotationSym
),
990 RecordOffset(RecordOffset
) {}
992 uint32_t CodeOffset
= 0;
993 uint16_t Segment
= 0;
994 std::vector
<StringRef
> Strings
;
996 uint32_t RecordOffset
;
999 using CVSymbol
= CVRecord
<SymbolKind
>;
1000 using CVSymbolArray
= VarStreamArray
<CVSymbol
>;
1002 Expected
<CVSymbol
> readSymbolFromStream(BinaryStreamRef Stream
,
1005 } // end namespace codeview
1006 } // end namespace llvm
1008 #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H