LLVM 22.0.0git
SymbolRecord.h
Go to the documentation of this file.
1//===- SymbolRecord.h -------------------------------------------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
10#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
11
12#include "llvm/ADT/APSInt.h"
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/iterator.h"
23#include "llvm/Support/Endian.h"
24#include <cstdint>
25#include <vector>
26
27namespace llvm {
28namespace codeview {
29
31protected:
33
34public:
35 SymbolRecordKind getKind() const { return Kind; }
36
38};
39
40// S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or
41// S_LPROC32_DPC_ID
68
69// S_THUNK32
88
89// S_TRAMPOLINE
105
106// S_SECTION
122
123// S_COFFGROUP
138
147
168
179
181public:
186
187 // This is an ItemID in the IPI stream, which points to an LF_FUNC_ID or
188 // LF_MFUNC_ID record.
191
193};
194
203
205 : public iterator_facade_base<BinaryAnnotationIterator,
206 std::forward_iterator_tag,
207 DecodedAnnotation> {
212
214 return Data == Other.Data;
215 }
216
218 Data = Other.Data;
219 return *this;
220 }
221
223 if (!ParseCurrentAnnotation()) {
224 *this = BinaryAnnotationIterator();
225 return *this;
226 }
227 Data = Next;
228 Next = ArrayRef<uint8_t>();
229 Current.reset();
230 return *this;
231 }
232
234 ParseCurrentAnnotation();
235 return *Current;
236 }
237
238private:
239 static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) {
240 if (Annotations.empty())
241 return -1;
242
243 uint8_t FirstByte = Annotations.consume_front();
244
245 if ((FirstByte & 0x80) == 0x00)
246 return FirstByte;
247
248 if (Annotations.empty())
249 return -1;
250
251 uint8_t SecondByte = Annotations.consume_front();
252
253 if ((FirstByte & 0xC0) == 0x80)
254 return ((FirstByte & 0x3F) << 8) | SecondByte;
255
256 if (Annotations.empty())
257 return -1;
258
259 uint8_t ThirdByte = Annotations.consume_front();
260
261 if (Annotations.empty())
262 return -1;
263
264 uint8_t FourthByte = Annotations.consume_front();
265
266 if ((FirstByte & 0xE0) == 0xC0)
267 return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) |
268 (ThirdByte << 8) | FourthByte;
269
270 return -1;
271 }
272
273 static int32_t DecodeSignedOperand(uint32_t Operand) {
274 if (Operand & 1)
275 return -(Operand >> 1);
276 return Operand >> 1;
277 }
278
279 static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
280 return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
281 }
282
283 bool ParseCurrentAnnotation() {
284 if (Current)
285 return true;
286
287 Next = Data;
288 uint32_t Op = GetCompressedAnnotation(Next);
289 DecodedAnnotation Result;
290 Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
291 switch (Result.OpCode) {
293 Result.Name = "Invalid";
294 Next = ArrayRef<uint8_t>();
295 break;
297 Result.Name = "CodeOffset";
298 Result.U1 = GetCompressedAnnotation(Next);
299 break;
301 Result.Name = "ChangeCodeOffsetBase";
302 Result.U1 = GetCompressedAnnotation(Next);
303 break;
305 Result.Name = "ChangeCodeOffset";
306 Result.U1 = GetCompressedAnnotation(Next);
307 break;
309 Result.Name = "ChangeCodeLength";
310 Result.U1 = GetCompressedAnnotation(Next);
311 break;
313 Result.Name = "ChangeFile";
314 Result.U1 = GetCompressedAnnotation(Next);
315 break;
317 Result.Name = "ChangeLineEndDelta";
318 Result.U1 = GetCompressedAnnotation(Next);
319 break;
321 Result.Name = "ChangeRangeKind";
322 Result.U1 = GetCompressedAnnotation(Next);
323 break;
325 Result.Name = "ChangeColumnStart";
326 Result.U1 = GetCompressedAnnotation(Next);
327 break;
329 Result.Name = "ChangeColumnEnd";
330 Result.U1 = GetCompressedAnnotation(Next);
331 break;
333 Result.Name = "ChangeLineOffset";
334 Result.S1 = DecodeSignedOperand(Next);
335 break;
337 Result.Name = "ChangeColumnEndDelta";
338 Result.S1 = DecodeSignedOperand(Next);
339 break;
341 Result.Name = "ChangeCodeOffsetAndLineOffset";
342 uint32_t Annotation = GetCompressedAnnotation(Next);
343 Result.S1 = DecodeSignedOperand(Annotation >> 4);
344 Result.U1 = Annotation & 0xf;
345 break;
346 }
348 Result.Name = "ChangeCodeLengthAndCodeOffset";
349 Result.U1 = GetCompressedAnnotation(Next);
350 Result.U2 = GetCompressedAnnotation(Next);
351 break;
352 }
353 }
354 Result.Bytes = Data.take_front(Data.size() - Next.size());
355 Current = Result;
356 return true;
357 }
358
359 std::optional<DecodedAnnotation> Current;
360 ArrayRef<uint8_t> Data;
361 ArrayRef<uint8_t> Next;
362};
363
364// S_INLINESITE
384
391
392// S_PUB32
408
409// S_REGISTER
423
424// S_PROCREF, S_LPROCREF
440
441// S_LOCAL
454
460
465
466enum : uint16_t { MaxDefRange = 0xf000 };
467
468// S_DEFRANGE
469class DefRangeSym : public SymbolRecord {
470 static constexpr uint32_t RelocationOffset = 8;
471
472public:
477
479 return RecordOffset + RelocationOffset;
480 }
481
484 std::vector<LocalVariableAddrGap> Gaps;
485
487};
488
489// S_DEFRANGE_SUBFIELD
491 static constexpr uint32_t RelocationOffset = 12;
492
493public:
498
500 return RecordOffset + RelocationOffset;
501 }
502
506 std::vector<LocalVariableAddrGap> Gaps;
507
509};
510
515
516// S_DEFRANGE_REGISTER
532
538
539// S_DEFRANGE_SUBFIELD_REGISTER
556
560
561// S_DEFRANGE_FRAMEPOINTER_REL
582
588
589// S_DEFRANGE_REGISTER_REL
591public:
596
597 // The flags implement this notional bitfield:
598 // uint16_t IsSubfield : 1;
599 // uint16_t Padding : 3;
600 // uint16_t OffsetInParent : 12;
601 enum : uint16_t {
604 };
605
606 bool hasSpilledUDTMember() const { return Hdr.Flags & IsSubfieldFlag; }
607 uint16_t offsetInParent() const { return Hdr.Flags >> OffsetInParentShift; }
608
610
613 std::vector<LocalVariableAddrGap> Gaps;
614
616};
617
618// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
631
632// S_BLOCK32
633class BlockSym : public SymbolRecord {
634 static constexpr uint32_t RelocationOffset = 16;
635
636public:
640
642 return RecordOffset + RelocationOffset;
643 }
644
651
653};
654
655// S_LABEL32
656class LabelSym : public SymbolRecord {
657 static constexpr uint32_t RelocationOffset = 4;
658
659public:
663
665 return RecordOffset + RelocationOffset;
666 }
667
672
674};
675
676// S_OBJNAME
690
691// S_ENVBLOCK
703
704// S_EXPORT
717
718// S_FILESTATIC
733
734// S_COMPILE2
758
759// S_COMPILE3
798
799// S_FRAMEPROC
801public:
806
814
815 /// Extract the register this frame uses to refer to local variables.
817 return decodeFramePtrReg(
818 EncodedFramePtrReg((uint32_t(Flags) >> 14U) & 0x3U), CPU);
819 }
820
821 /// Extract the register this frame uses to refer to parameters.
823 return decodeFramePtrReg(
824 EncodedFramePtrReg((uint32_t(Flags) >> 16U) & 0x3U), CPU);
825 }
826
828
829private:
830};
831
832// S_CALLSITEINFO
834 static constexpr uint32_t RelocationOffset = 4;
835
836public:
840
842 return RecordOffset + RelocationOffset;
843 }
844
848
850};
851
852// S_HEAPALLOCSITE
873
874// S_FRAMECOOKIE
876 static constexpr uint32_t RelocationOffset = 4;
877
878public:
882
884 return RecordOffset + RelocationOffset;
885 }
886
891
893};
894
895// S_UDT, S_COBOLUDT
907
908// S_BUILDINFO
920
921// S_BPREL32
935
936// S_REGREL32
951
952// S_CONSTANT, S_MANCONSTANT
966
967// S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
968class DataSym : public SymbolRecord {
969 static constexpr uint32_t RelocationOffset = 8;
970
971public:
975
977 return RecordOffset + RelocationOffset;
978 }
979
984
986};
987
988// S_LTHREAD32, S_GTHREAD32
1009
1010// S_UNAMESPACE
1022
1023// S_ANNOTATION
1037
1040
1041} // end namespace codeview
1042} // end namespace llvm
1043
1044#endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS, uint64_t Address=0, const MCDisassembler *Decoder=nullptr)
Lightweight arrays that are backed by an arbitrary BinaryStream.
#define LLVM_ABI
Definition Compiler.h:213
An arbitrary precision integer that knows its signedness.
Definition APSInt.h:24
Annotations lets you mark points and ranges inside source code, for tests:
Definition Annotations.h:53
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
Tagged union holding either a T or a Error.
Definition Error.h:485
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
std::vector< StringRef > Strings
AnnotationSym(uint32_t RecordOffset)
AnnotationSym(SymbolRecordKind Kind)
BPRelativeSym(uint32_t RecordOffset)
BPRelativeSym(SymbolRecordKind Kind)
uint32_t getRelocationOffset() const
BlockSym(uint32_t RecordOffset)
BlockSym(SymbolRecordKind Kind)
BuildInfoSym(SymbolRecordKind Kind)
BuildInfoSym(uint32_t RecordOffset)
uint32_t getRelocationOffset() const
CallSiteInfoSym(SymbolRecordKind Kind)
CallSiteInfoSym(uint32_t RecordOffset)
CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset)
std::vector< TypeIndex > Indices
CallerSym(SymbolRecordKind Kind)
CoffGroupSym(SymbolRecordKind Kind)
CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset)
Compile2Sym(uint32_t RecordOffset)
Compile2Sym(SymbolRecordKind Kind)
std::vector< StringRef > ExtraStrings
CompileSym3Flags getFlags() const
Compile3Sym(SymbolRecordKind Kind)
Compile3Sym(uint32_t RecordOffset)
SourceLanguage getLanguage() const
void setLanguage(SourceLanguage Lang)
ConstantSym(SymbolRecordKind Kind)
ConstantSym(uint32_t RecordOffset)
DataSym(uint32_t RecordOffset)
DataSym(SymbolRecordKind Kind)
uint32_t getRelocationOffset() const
DefRangeFramePointerRelSym(SymbolRecordKind Kind)
DefRangeFramePointerRelSym(uint32_t RecordOffset)
DefRangeFramePointerRelHeader Hdr
std::vector< LocalVariableAddrGap > Gaps
std::vector< LocalVariableAddrGap > Gaps
DefRangeRegisterRelSym(uint32_t RecordOffset)
DefRangeRegisterRelSym(SymbolRecordKind Kind)
DefRangeRegisterSym(SymbolRecordKind Kind)
std::vector< LocalVariableAddrGap > Gaps
DefRangeRegisterSym(uint32_t RecordOffset)
DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
std::vector< LocalVariableAddrGap > Gaps
DefRangeSubfieldRegisterHeader Hdr
DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
DefRangeSubfieldSym(SymbolRecordKind Kind)
std::vector< LocalVariableAddrGap > Gaps
DefRangeSubfieldSym(uint32_t RecordOffset)
DefRangeSym(SymbolRecordKind Kind)
std::vector< LocalVariableAddrGap > Gaps
uint32_t getRelocationOffset() const
DefRangeSym(uint32_t RecordOffset)
LocalVariableAddrRange Range
EnvBlockSym(SymbolRecordKind Kind)
std::vector< StringRef > Fields
EnvBlockSym(uint32_t RecordOffset)
ExportSym(SymbolRecordKind Kind)
ExportSym(uint32_t RecordOffset)
FileStaticSym(uint32_t RecordOffset)
FileStaticSym(SymbolRecordKind Kind)
FrameCookieSym(SymbolRecordKind Kind)
uint32_t getRelocationOffset() const
FrameCookieSym(uint32_t RecordOffset)
FrameProcSym(SymbolRecordKind Kind)
FrameProcSym(uint32_t RecordOffset)
RegisterId getLocalFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to local variables.
RegisterId getParamFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to parameters.
FrameProcedureOptions Flags
HeapAllocationSiteSym(uint32_t RecordOffset)
HeapAllocationSiteSym(SymbolRecordKind Kind)
HotPatchFuncSym(SymbolRecordKind Kind)
HotPatchFuncSym(uint32_t RecordOffset)
std::vector< uint8_t > AnnotationData
InlineSiteSym(SymbolRecordKind Kind)
iterator_range< BinaryAnnotationIterator > annotations() const
InlineSiteSym(uint32_t RecordOffset)
JumpTableSym(SymbolRecordKind Kind)
JumpTableEntrySize SwitchType
JumpTableSym(uint32_t RecordOffset)
uint32_t getRelocationOffset() const
LabelSym(SymbolRecordKind Kind)
LabelSym(uint32_t RecordOffset)
LocalSym(SymbolRecordKind Kind)
LocalSym(uint32_t RecordOffset)
ObjNameSym(SymbolRecordKind Kind)
ObjNameSym(uint32_t RecordOffset)
ProcRefSym(uint32_t RecordOffset)
ProcRefSym(SymbolRecordKind Kind)
ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset)
uint32_t getRelocationOffset() const
ProcSym(SymbolRecordKind Kind)
PublicSym32(SymbolRecordKind Kind)
PublicSym32(uint32_t RecordOffset)
RegRelativeSym(SymbolRecordKind Kind)
RegRelativeSym(uint32_t RecordOffset)
RegisterSym(uint32_t RecordOffset)
RegisterSym(SymbolRecordKind Kind)
ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
ScopeEndSym(SymbolRecordKind Kind)
SectionSym(SymbolRecordKind Kind)
SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset)
SymbolRecord(SymbolRecordKind Kind)
SymbolRecordKind getKind() const
ThreadLocalDataSym(uint32_t RecordOffset)
ThreadLocalDataSym(SymbolRecordKind Kind)
ArrayRef< uint8_t > VariantData
Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset)
Thunk32Sym(SymbolRecordKind Kind)
TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset)
TrampolineSym(SymbolRecordKind Kind)
A 32-bit type reference.
Definition TypeIndex.h:97
UDTSym(SymbolRecordKind Kind)
UDTSym(uint32_t RecordOffset)
UsingNamespaceSym(uint32_t RecordOffset)
UsingNamespaceSym(SymbolRecordKind Kind)
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterator.h:80
A range adaptor for a pair of iterators.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
ProcSymFlags
Corresponds to the CV_PROCFLAGS bitfield.
Definition CodeView.h:416
LocalSymFlags
Corresponds to CV_LVARFLAGS bitfield.
Definition CodeView.h:389
CompileSym2Flags
Corresponds to COMPILESYM2::Flags bitfield.
Definition CodeView.h:430
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
Definition CodeView.h:77
CompileSym3Flags
Corresponds to COMPILESYM3::Flags bitfield.
Definition CodeView.h:446
SymbolRecordKind
Distinguishes individual records in the Symbols subsection of a .debug$S section.
Definition CodeView.h:42
ThunkOrdinal
These values correspond to the THUNK_ORDINAL enumeration.
Definition CodeView.h:537
EncodedFramePtrReg
Two-bit value indicating which register is the designated frame pointer register.
Definition CodeView.h:524
LLVM_ABI RegisterId decodeFramePtrReg(EncodedFramePtrReg EncodedReg, CPUType CPU)
PublicSymFlags
Corresponds to the CV_PUBSYMFLAGS bitfield.
Definition CodeView.h:406
SourceLanguage
These values correspond to the CV_CFL_LANG enumeration in the Microsoft Debug Interface Access SDK,...
Definition CodeView.h:147
LLVM_ABI Expected< CVSymbol > readSymbolFromStream(BinaryStreamRef Stream, uint32_t Offset)
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
Definition Endian.h:287
detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t
Definition Endian.h:284
detail::packed_endian_specific_integral< int32_t, llvm::endianness::little, unaligned > little32_t
Definition Endian.h:297
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
DWARFExpression::Operation Op
BinaryAnnotationIterator & operator=(const BinaryAnnotationIterator Other)
BinaryAnnotationIterator & operator++()
BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
const DecodedAnnotation & operator*()
bool operator==(BinaryAnnotationIterator Other) const
BinaryAnnotationIterator(ArrayRef< uint8_t > Annotations)
BinaryAnnotationsOpCode OpCode