1 //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
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 // This file defines classes for handling the YAML representation of CodeView
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/DebugInfo/CodeView/CodeView.h"
18 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
19 #include "llvm/DebugInfo/CodeView/EnumTables.h"
20 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
21 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
22 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
23 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
24 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
25 #include "llvm/ObjectYAML/YAML.h"
26 #include "llvm/Support/Allocator.h"
27 #include "llvm/Support/Error.h"
28 #include "llvm/Support/ScopedPrinter.h"
29 #include "llvm/Support/YAMLTraits.h"
38 using namespace llvm::codeview
;
39 using namespace llvm::CodeViewYAML
;
40 using namespace llvm::CodeViewYAML::detail
;
41 using namespace llvm::yaml
;
43 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex
)
44 LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap
)
46 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
47 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt
, QuotingType::None
)
48 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex
, QuotingType::None
)
50 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind
)
51 LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind
)
53 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags
)
54 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags
)
55 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags
)
56 LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags
)
57 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags
)
58 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags
)
59 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions
)
60 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType
)
61 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId
)
62 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType
)
63 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal
)
64 LLVM_YAML_DECLARE_ENUM_TRAITS(JumpTableEntrySize
)
66 LLVM_YAML_STRONG_TYPEDEF(StringRef
, TypeName
)
68 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName
, QuotingType::Single
)
70 StringRef ScalarTraits
<TypeName
>::input(StringRef S
, void *V
, TypeName
&T
) {
71 return ScalarTraits
<StringRef
>::input(S
, V
, T
.value
);
74 void ScalarTraits
<TypeName
>::output(const TypeName
&T
, void *V
,
76 ScalarTraits
<StringRef
>::output(T
.value
, V
, R
);
79 void ScalarEnumerationTraits
<SymbolKind
>::enumeration(IO
&io
,
81 auto SymbolNames
= getSymbolTypeNames();
82 for (const auto &E
: SymbolNames
)
83 io
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
86 void ScalarBitSetTraits
<CompileSym2Flags
>::bitset(IO
&io
,
87 CompileSym2Flags
&Flags
) {
88 auto FlagNames
= getCompileSym2FlagNames();
89 for (const auto &E
: FlagNames
) {
90 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
91 static_cast<CompileSym2Flags
>(E
.Value
));
95 void ScalarBitSetTraits
<CompileSym3Flags
>::bitset(IO
&io
,
96 CompileSym3Flags
&Flags
) {
97 auto FlagNames
= getCompileSym3FlagNames();
98 for (const auto &E
: FlagNames
) {
99 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
100 static_cast<CompileSym3Flags
>(E
.Value
));
104 void ScalarBitSetTraits
<ExportFlags
>::bitset(IO
&io
, ExportFlags
&Flags
) {
105 auto FlagNames
= getExportSymFlagNames();
106 for (const auto &E
: FlagNames
) {
107 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
108 static_cast<ExportFlags
>(E
.Value
));
112 void ScalarBitSetTraits
<PublicSymFlags
>::bitset(IO
&io
, PublicSymFlags
&Flags
) {
113 auto FlagNames
= getPublicSymFlagNames();
114 for (const auto &E
: FlagNames
) {
115 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
116 static_cast<PublicSymFlags
>(E
.Value
));
120 void ScalarBitSetTraits
<LocalSymFlags
>::bitset(IO
&io
, LocalSymFlags
&Flags
) {
121 auto FlagNames
= getLocalFlagNames();
122 for (const auto &E
: FlagNames
) {
123 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
124 static_cast<LocalSymFlags
>(E
.Value
));
128 void ScalarBitSetTraits
<ProcSymFlags
>::bitset(IO
&io
, ProcSymFlags
&Flags
) {
129 auto FlagNames
= getProcSymFlagNames();
130 for (const auto &E
: FlagNames
) {
131 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
132 static_cast<ProcSymFlags
>(E
.Value
));
136 void ScalarBitSetTraits
<FrameProcedureOptions
>::bitset(
137 IO
&io
, FrameProcedureOptions
&Flags
) {
138 auto FlagNames
= getFrameProcSymFlagNames();
139 for (const auto &E
: FlagNames
) {
140 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
141 static_cast<FrameProcedureOptions
>(E
.Value
));
145 void ScalarEnumerationTraits
<CPUType
>::enumeration(IO
&io
, CPUType
&Cpu
) {
146 auto CpuNames
= getCPUTypeNames();
147 for (const auto &E
: CpuNames
) {
148 io
.enumCase(Cpu
, E
.Name
.str().c_str(), static_cast<CPUType
>(E
.Value
));
152 void ScalarEnumerationTraits
<RegisterId
>::enumeration(IO
&io
, RegisterId
&Reg
) {
153 const auto *Header
= static_cast<COFF::header
*>(io
.getContext());
154 assert(Header
&& "The IO context is not initialized");
156 std::optional
<CPUType
> CpuType
;
157 ArrayRef
<EnumEntry
<uint16_t>> RegNames
;
159 switch (Header
->Machine
) {
160 case COFF::IMAGE_FILE_MACHINE_I386
:
161 CpuType
= CPUType::Pentium3
;
163 case COFF::IMAGE_FILE_MACHINE_AMD64
:
164 CpuType
= CPUType::X64
;
166 case COFF::IMAGE_FILE_MACHINE_ARMNT
:
167 CpuType
= CPUType::ARMNT
;
169 case COFF::IMAGE_FILE_MACHINE_ARM64
:
170 case COFF::IMAGE_FILE_MACHINE_ARM64EC
:
171 case COFF::IMAGE_FILE_MACHINE_ARM64X
:
172 CpuType
= CPUType::ARM64
;
177 RegNames
= getRegisterNames(*CpuType
);
179 for (const auto &E
: RegNames
) {
180 io
.enumCase(Reg
, E
.Name
.str().c_str(), static_cast<RegisterId
>(E
.Value
));
182 io
.enumFallback
<Hex16
>(Reg
);
185 void ScalarEnumerationTraits
<TrampolineType
>::enumeration(
186 IO
&io
, TrampolineType
&Tramp
) {
187 auto TrampNames
= getTrampolineNames();
188 for (const auto &E
: TrampNames
) {
189 io
.enumCase(Tramp
, E
.Name
.str().c_str(),
190 static_cast<TrampolineType
>(E
.Value
));
194 void ScalarEnumerationTraits
<ThunkOrdinal
>::enumeration(IO
&io
,
196 auto ThunkNames
= getThunkOrdinalNames();
197 for (const auto &E
: ThunkNames
) {
198 io
.enumCase(Ord
, E
.Name
.str().c_str(), static_cast<ThunkOrdinal
>(E
.Value
));
202 void ScalarEnumerationTraits
<FrameCookieKind
>::enumeration(
203 IO
&io
, FrameCookieKind
&FC
) {
204 auto ThunkNames
= getFrameCookieKindNames();
205 for (const auto &E
: ThunkNames
) {
206 io
.enumCase(FC
, E
.Name
.str().c_str(),
207 static_cast<FrameCookieKind
>(E
.Value
));
211 void ScalarEnumerationTraits
<JumpTableEntrySize
>::enumeration(
212 IO
&io
, JumpTableEntrySize
&FC
) {
213 auto ThunkNames
= getJumpTableEntrySizeNames();
214 for (const auto &E
: ThunkNames
) {
215 io
.enumCase(FC
, E
.Name
.str().c_str(),
216 static_cast<JumpTableEntrySize
>(E
.Value
));
222 template <> struct MappingTraits
<LocalVariableAddrRange
> {
223 static void mapping(IO
&io
, LocalVariableAddrRange
&Range
) {
224 io
.mapRequired("OffsetStart", Range
.OffsetStart
);
225 io
.mapRequired("ISectStart", Range
.ISectStart
);
226 io
.mapRequired("Range", Range
.Range
);
229 template <> struct MappingTraits
<LocalVariableAddrGap
> {
230 static void mapping(IO
&io
, LocalVariableAddrGap
&Gap
) {
231 io
.mapRequired("GapStartOffset", Gap
.GapStartOffset
);
232 io
.mapRequired("Range", Gap
.Range
);
239 namespace CodeViewYAML
{
242 struct SymbolRecordBase
{
243 codeview::SymbolKind Kind
;
245 explicit SymbolRecordBase(codeview::SymbolKind K
) : Kind(K
) {}
246 virtual ~SymbolRecordBase() = default;
248 virtual void map(yaml::IO
&io
) = 0;
249 virtual codeview::CVSymbol
250 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
251 CodeViewContainer Container
) const = 0;
252 virtual Error
fromCodeViewSymbol(codeview::CVSymbol Type
) = 0;
255 template <typename T
> struct SymbolRecordImpl
: public SymbolRecordBase
{
256 explicit SymbolRecordImpl(codeview::SymbolKind K
)
257 : SymbolRecordBase(K
), Symbol(static_cast<SymbolRecordKind
>(K
)) {}
259 void map(yaml::IO
&io
) override
;
262 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
263 CodeViewContainer Container
) const override
{
264 return SymbolSerializer::writeOneSymbol(Symbol
, Allocator
, Container
);
267 Error
fromCodeViewSymbol(codeview::CVSymbol CVS
) override
{
268 return SymbolDeserializer::deserializeAs
<T
>(CVS
, Symbol
);
274 struct UnknownSymbolRecord
: public SymbolRecordBase
{
275 explicit UnknownSymbolRecord(codeview::SymbolKind K
) : SymbolRecordBase(K
) {}
277 void map(yaml::IO
&io
) override
;
279 CVSymbol
toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
280 CodeViewContainer Container
) const override
{
282 uint32_t TotalLen
= sizeof(RecordPrefix
) + Data
.size();
283 Prefix
.RecordKind
= Kind
;
284 Prefix
.RecordLen
= TotalLen
- 2;
285 uint8_t *Buffer
= Allocator
.Allocate
<uint8_t>(TotalLen
);
286 ::memcpy(Buffer
, &Prefix
, sizeof(RecordPrefix
));
287 ::memcpy(Buffer
+ sizeof(RecordPrefix
), Data
.data(), Data
.size());
288 return CVSymbol(ArrayRef
<uint8_t>(Buffer
, TotalLen
));
291 Error
fromCodeViewSymbol(CVSymbol CVS
) override
{
292 this->Kind
= CVS
.kind();
293 Data
= CVS
.RecordData
.drop_front(sizeof(RecordPrefix
));
294 return Error::success();
297 std::vector
<uint8_t> Data
;
300 template <> void SymbolRecordImpl
<ScopeEndSym
>::map(IO
&IO
) {}
302 void UnknownSymbolRecord::map(yaml::IO
&io
) {
303 yaml::BinaryRef Binary
;
305 Binary
= yaml::BinaryRef(Data
);
306 io
.mapRequired("Data", Binary
);
307 if (!io
.outputting()) {
309 raw_string_ostream
OS(Str
);
310 Binary
.writeAsBinary(OS
);
312 Data
.assign(Str
.begin(), Str
.end());
316 template <> void SymbolRecordImpl
<Thunk32Sym
>::map(IO
&IO
) {
317 IO
.mapRequired("Parent", Symbol
.Parent
);
318 IO
.mapRequired("End", Symbol
.End
);
319 IO
.mapRequired("Next", Symbol
.Next
);
320 IO
.mapRequired("Off", Symbol
.Offset
);
321 IO
.mapRequired("Seg", Symbol
.Segment
);
322 IO
.mapRequired("Len", Symbol
.Length
);
323 IO
.mapRequired("Ordinal", Symbol
.Thunk
);
326 template <> void SymbolRecordImpl
<TrampolineSym
>::map(IO
&IO
) {
327 IO
.mapRequired("Type", Symbol
.Type
);
328 IO
.mapRequired("Size", Symbol
.Size
);
329 IO
.mapRequired("ThunkOff", Symbol
.ThunkOffset
);
330 IO
.mapRequired("TargetOff", Symbol
.TargetOffset
);
331 IO
.mapRequired("ThunkSection", Symbol
.ThunkSection
);
332 IO
.mapRequired("TargetSection", Symbol
.TargetSection
);
335 template <> void SymbolRecordImpl
<SectionSym
>::map(IO
&IO
) {
336 IO
.mapRequired("SectionNumber", Symbol
.SectionNumber
);
337 IO
.mapRequired("Alignment", Symbol
.Alignment
);
338 IO
.mapRequired("Rva", Symbol
.Rva
);
339 IO
.mapRequired("Length", Symbol
.Length
);
340 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
341 IO
.mapRequired("Name", Symbol
.Name
);
344 template <> void SymbolRecordImpl
<CoffGroupSym
>::map(IO
&IO
) {
345 IO
.mapRequired("Size", Symbol
.Size
);
346 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
347 IO
.mapRequired("Offset", Symbol
.Offset
);
348 IO
.mapRequired("Segment", Symbol
.Segment
);
349 IO
.mapRequired("Name", Symbol
.Name
);
352 template <> void SymbolRecordImpl
<ExportSym
>::map(IO
&IO
) {
353 IO
.mapRequired("Ordinal", Symbol
.Ordinal
);
354 IO
.mapRequired("Flags", Symbol
.Flags
);
355 IO
.mapRequired("Name", Symbol
.Name
);
358 template <> void SymbolRecordImpl
<ProcSym
>::map(IO
&IO
) {
359 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
360 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
361 IO
.mapOptional("PtrNext", Symbol
.Next
, 0U);
362 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
363 IO
.mapRequired("DbgStart", Symbol
.DbgStart
);
364 IO
.mapRequired("DbgEnd", Symbol
.DbgEnd
);
365 IO
.mapRequired("FunctionType", Symbol
.FunctionType
);
366 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
367 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
368 IO
.mapRequired("Flags", Symbol
.Flags
);
369 IO
.mapRequired("DisplayName", Symbol
.Name
);
372 template <> void SymbolRecordImpl
<RegisterSym
>::map(IO
&IO
) {
373 IO
.mapRequired("Type", Symbol
.Index
);
374 IO
.mapRequired("Seg", Symbol
.Register
);
375 IO
.mapRequired("Name", Symbol
.Name
);
378 template <> void SymbolRecordImpl
<PublicSym32
>::map(IO
&IO
) {
379 IO
.mapRequired("Flags", Symbol
.Flags
);
380 IO
.mapOptional("Offset", Symbol
.Offset
, 0U);
381 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
382 IO
.mapRequired("Name", Symbol
.Name
);
385 template <> void SymbolRecordImpl
<ProcRefSym
>::map(IO
&IO
) {
386 IO
.mapRequired("SumName", Symbol
.SumName
);
387 IO
.mapRequired("SymOffset", Symbol
.SymOffset
);
388 IO
.mapRequired("Mod", Symbol
.Module
);
389 IO
.mapRequired("Name", Symbol
.Name
);
392 template <> void SymbolRecordImpl
<EnvBlockSym
>::map(IO
&IO
) {
393 IO
.mapRequired("Entries", Symbol
.Fields
);
396 template <> void SymbolRecordImpl
<InlineSiteSym
>::map(IO
&IO
) {
397 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
398 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
399 IO
.mapRequired("Inlinee", Symbol
.Inlinee
);
400 // TODO: The binary annotations
403 template <> void SymbolRecordImpl
<LocalSym
>::map(IO
&IO
) {
404 IO
.mapRequired("Type", Symbol
.Type
);
405 IO
.mapRequired("Flags", Symbol
.Flags
);
407 IO
.mapRequired("VarName", Symbol
.Name
);
410 template <> void SymbolRecordImpl
<DefRangeSym
>::map(IO
&IO
) {
411 IO
.mapRequired("Program", Symbol
.Program
);
412 IO
.mapRequired("Range", Symbol
.Range
);
413 IO
.mapRequired("Gaps", Symbol
.Gaps
);
416 template <> void SymbolRecordImpl
<DefRangeSubfieldSym
>::map(IO
&IO
) {
417 IO
.mapRequired("Program", Symbol
.Program
);
418 IO
.mapRequired("OffsetInParent", Symbol
.OffsetInParent
);
419 IO
.mapRequired("Range", Symbol
.Range
);
420 IO
.mapRequired("Gaps", Symbol
.Gaps
);
423 template <> void SymbolRecordImpl
<DefRangeRegisterSym
>::map(IO
&IO
) {
424 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
425 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
426 IO
.mapRequired("Range", Symbol
.Range
);
427 IO
.mapRequired("Gaps", Symbol
.Gaps
);
430 template <> void SymbolRecordImpl
<DefRangeFramePointerRelSym
>::map(IO
&IO
) {
431 IO
.mapRequired("Offset", Symbol
.Hdr
.Offset
);
432 IO
.mapRequired("Range", Symbol
.Range
);
433 IO
.mapRequired("Gaps", Symbol
.Gaps
);
436 template <> void SymbolRecordImpl
<DefRangeSubfieldRegisterSym
>::map(IO
&IO
) {
437 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
438 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
439 IO
.mapRequired("OffsetInParent", Symbol
.Hdr
.OffsetInParent
);
440 IO
.mapRequired("Range", Symbol
.Range
);
441 IO
.mapRequired("Gaps", Symbol
.Gaps
);
445 void SymbolRecordImpl
<DefRangeFramePointerRelFullScopeSym
>::map(IO
&IO
) {
446 IO
.mapRequired("Register", Symbol
.Offset
);
449 template <> void SymbolRecordImpl
<DefRangeRegisterRelSym
>::map(IO
&IO
) {
450 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
451 IO
.mapRequired("Flags", Symbol
.Hdr
.Flags
);
452 IO
.mapRequired("BasePointerOffset", Symbol
.Hdr
.BasePointerOffset
);
453 IO
.mapRequired("Range", Symbol
.Range
);
454 IO
.mapRequired("Gaps", Symbol
.Gaps
);
457 template <> void SymbolRecordImpl
<BlockSym
>::map(IO
&IO
) {
458 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
459 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
460 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
461 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
462 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
463 IO
.mapRequired("BlockName", Symbol
.Name
);
466 template <> void SymbolRecordImpl
<LabelSym
>::map(IO
&IO
) {
467 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
468 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
469 IO
.mapRequired("Flags", Symbol
.Flags
);
470 IO
.mapRequired("Flags", Symbol
.Flags
);
471 IO
.mapRequired("DisplayName", Symbol
.Name
);
474 template <> void SymbolRecordImpl
<ObjNameSym
>::map(IO
&IO
) {
475 IO
.mapRequired("Signature", Symbol
.Signature
);
476 IO
.mapRequired("ObjectName", Symbol
.Name
);
479 template <> void SymbolRecordImpl
<Compile2Sym
>::map(IO
&IO
) {
480 IO
.mapRequired("Flags", Symbol
.Flags
);
481 IO
.mapRequired("Machine", Symbol
.Machine
);
482 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
483 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
484 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
485 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
486 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
487 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
488 IO
.mapRequired("Version", Symbol
.Version
);
491 template <> void SymbolRecordImpl
<Compile3Sym
>::map(IO
&IO
) {
492 IO
.mapRequired("Flags", Symbol
.Flags
);
493 IO
.mapRequired("Machine", Symbol
.Machine
);
494 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
495 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
496 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
497 IO
.mapRequired("FrontendQFE", Symbol
.VersionFrontendQFE
);
498 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
499 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
500 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
501 IO
.mapRequired("BackendQFE", Symbol
.VersionBackendQFE
);
502 IO
.mapRequired("Version", Symbol
.Version
);
505 template <> void SymbolRecordImpl
<FrameProcSym
>::map(IO
&IO
) {
506 IO
.mapRequired("TotalFrameBytes", Symbol
.TotalFrameBytes
);
507 IO
.mapRequired("PaddingFrameBytes", Symbol
.PaddingFrameBytes
);
508 IO
.mapRequired("OffsetToPadding", Symbol
.OffsetToPadding
);
509 IO
.mapRequired("BytesOfCalleeSavedRegisters",
510 Symbol
.BytesOfCalleeSavedRegisters
);
511 IO
.mapRequired("OffsetOfExceptionHandler", Symbol
.OffsetOfExceptionHandler
);
512 IO
.mapRequired("SectionIdOfExceptionHandler",
513 Symbol
.SectionIdOfExceptionHandler
);
514 IO
.mapRequired("Flags", Symbol
.Flags
);
517 template <> void SymbolRecordImpl
<CallSiteInfoSym
>::map(IO
&IO
) {
518 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
519 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
520 IO
.mapRequired("Type", Symbol
.Type
);
523 template <> void SymbolRecordImpl
<FileStaticSym
>::map(IO
&IO
) {
524 IO
.mapRequired("Index", Symbol
.Index
);
525 IO
.mapRequired("ModFilenameOffset", Symbol
.ModFilenameOffset
);
526 IO
.mapRequired("Flags", Symbol
.Flags
);
527 IO
.mapRequired("Name", Symbol
.Name
);
530 template <> void SymbolRecordImpl
<HeapAllocationSiteSym
>::map(IO
&IO
) {
531 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
532 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
533 IO
.mapRequired("CallInstructionSize", Symbol
.CallInstructionSize
);
534 IO
.mapRequired("Type", Symbol
.Type
);
537 template <> void SymbolRecordImpl
<FrameCookieSym
>::map(IO
&IO
) {
538 IO
.mapRequired("Register", Symbol
.Register
);
539 IO
.mapRequired("CookieKind", Symbol
.CookieKind
);
540 IO
.mapRequired("Flags", Symbol
.Flags
);
543 template <> void SymbolRecordImpl
<CallerSym
>::map(IO
&IO
) {
544 IO
.mapRequired("FuncID", Symbol
.Indices
);
547 template <> void SymbolRecordImpl
<UDTSym
>::map(IO
&IO
) {
548 IO
.mapRequired("Type", Symbol
.Type
);
549 IO
.mapRequired("UDTName", Symbol
.Name
);
552 template <> void SymbolRecordImpl
<BuildInfoSym
>::map(IO
&IO
) {
553 IO
.mapRequired("BuildId", Symbol
.BuildId
);
556 template <> void SymbolRecordImpl
<BPRelativeSym
>::map(IO
&IO
) {
557 IO
.mapRequired("Offset", Symbol
.Offset
);
558 IO
.mapRequired("Type", Symbol
.Type
);
559 IO
.mapRequired("VarName", Symbol
.Name
);
562 template <> void SymbolRecordImpl
<RegRelativeSym
>::map(IO
&IO
) {
563 IO
.mapRequired("Offset", Symbol
.Offset
);
564 IO
.mapRequired("Type", Symbol
.Type
);
565 IO
.mapRequired("Register", Symbol
.Register
);
566 IO
.mapRequired("VarName", Symbol
.Name
);
569 template <> void SymbolRecordImpl
<ConstantSym
>::map(IO
&IO
) {
570 IO
.mapRequired("Type", Symbol
.Type
);
571 IO
.mapRequired("Value", Symbol
.Value
);
572 IO
.mapRequired("Name", Symbol
.Name
);
575 template <> void SymbolRecordImpl
<DataSym
>::map(IO
&IO
) {
576 IO
.mapRequired("Type", Symbol
.Type
);
577 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
578 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
579 IO
.mapRequired("DisplayName", Symbol
.Name
);
582 template <> void SymbolRecordImpl
<ThreadLocalDataSym
>::map(IO
&IO
) {
583 IO
.mapRequired("Type", Symbol
.Type
);
584 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
585 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
586 IO
.mapRequired("DisplayName", Symbol
.Name
);
589 template <> void SymbolRecordImpl
<UsingNamespaceSym
>::map(IO
&IO
) {
590 IO
.mapRequired("Namespace", Symbol
.Name
);
593 template <> void SymbolRecordImpl
<AnnotationSym
>::map(IO
&IO
) {
594 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
595 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
596 IO
.mapRequired("Strings", Symbol
.Strings
);
599 template <> void SymbolRecordImpl
<JumpTableSym
>::map(IO
&IO
) {
600 IO
.mapRequired("BaseOffset", Symbol
.BaseOffset
);
601 IO
.mapRequired("BaseSegment", Symbol
.BaseSegment
);
602 IO
.mapRequired("SwitchType", Symbol
.SwitchType
);
603 IO
.mapRequired("BranchOffset", Symbol
.BranchOffset
);
604 IO
.mapRequired("TableOffset", Symbol
.TableOffset
);
605 IO
.mapRequired("BranchSegment", Symbol
.BranchSegment
);
606 IO
.mapRequired("TableSegment", Symbol
.TableSegment
);
607 IO
.mapRequired("EntriesCount", Symbol
.EntriesCount
);
610 } // end namespace detail
611 } // end namespace CodeViewYAML
612 } // end namespace llvm
614 CVSymbol
CodeViewYAML::SymbolRecord::toCodeViewSymbol(
615 BumpPtrAllocator
&Allocator
, CodeViewContainer Container
) const {
616 return Symbol
->toCodeViewSymbol(Allocator
, Container
);
622 template <> struct MappingTraits
<SymbolRecordBase
> {
623 static void mapping(IO
&io
, SymbolRecordBase
&Record
) { Record
.map(io
); }
626 } // end namespace yaml
627 } // end namespace llvm
629 template <typename SymbolType
>
630 static inline Expected
<CodeViewYAML::SymbolRecord
>
631 fromCodeViewSymbolImpl(CVSymbol Symbol
) {
632 CodeViewYAML::SymbolRecord Result
;
634 auto Impl
= std::make_shared
<SymbolType
>(Symbol
.kind());
635 if (auto EC
= Impl
->fromCodeViewSymbol(Symbol
))
636 return std::move(EC
);
637 Result
.Symbol
= Impl
;
641 Expected
<CodeViewYAML::SymbolRecord
>
642 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol
) {
643 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
645 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
646 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
647 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
648 switch (Symbol
.kind()) {
649 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
651 return fromCodeViewSymbolImpl
<UnknownSymbolRecord
>(Symbol
);
653 return make_error
<CodeViewError
>(cv_error_code::corrupt_record
);
656 template <typename ConcreteType
>
657 static void mapSymbolRecordImpl(IO
&IO
, const char *Class
, SymbolKind Kind
,
658 CodeViewYAML::SymbolRecord
&Obj
) {
659 if (!IO
.outputting())
660 Obj
.Symbol
= std::make_shared
<ConcreteType
>(Kind
);
662 IO
.mapRequired(Class
, *Obj
.Symbol
);
665 void MappingTraits
<CodeViewYAML::SymbolRecord
>::mapping(
666 IO
&IO
, CodeViewYAML::SymbolRecord
&Obj
) {
669 Kind
= Obj
.Symbol
->Kind
;
670 IO
.mapRequired("Kind", Kind
);
672 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
674 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
677 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
678 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
680 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
682 mapSymbolRecordImpl
<UnknownSymbolRecord
>(IO
, "UnknownSym", Kind
, Obj
);