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
)
65 LLVM_YAML_STRONG_TYPEDEF(StringRef
, TypeName
)
67 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName
, QuotingType::Single
)
69 StringRef ScalarTraits
<TypeName
>::input(StringRef S
, void *V
, TypeName
&T
) {
70 return ScalarTraits
<StringRef
>::input(S
, V
, T
.value
);
73 void ScalarTraits
<TypeName
>::output(const TypeName
&T
, void *V
,
75 ScalarTraits
<StringRef
>::output(T
.value
, V
, R
);
78 void ScalarEnumerationTraits
<SymbolKind
>::enumeration(IO
&io
,
80 auto SymbolNames
= getSymbolTypeNames();
81 for (const auto &E
: SymbolNames
)
82 io
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
85 void ScalarBitSetTraits
<CompileSym2Flags
>::bitset(IO
&io
,
86 CompileSym2Flags
&Flags
) {
87 auto FlagNames
= getCompileSym2FlagNames();
88 for (const auto &E
: FlagNames
) {
89 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
90 static_cast<CompileSym2Flags
>(E
.Value
));
94 void ScalarBitSetTraits
<CompileSym3Flags
>::bitset(IO
&io
,
95 CompileSym3Flags
&Flags
) {
96 auto FlagNames
= getCompileSym3FlagNames();
97 for (const auto &E
: FlagNames
) {
98 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
99 static_cast<CompileSym3Flags
>(E
.Value
));
103 void ScalarBitSetTraits
<ExportFlags
>::bitset(IO
&io
, ExportFlags
&Flags
) {
104 auto FlagNames
= getExportSymFlagNames();
105 for (const auto &E
: FlagNames
) {
106 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
107 static_cast<ExportFlags
>(E
.Value
));
111 void ScalarBitSetTraits
<PublicSymFlags
>::bitset(IO
&io
, PublicSymFlags
&Flags
) {
112 auto FlagNames
= getPublicSymFlagNames();
113 for (const auto &E
: FlagNames
) {
114 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
115 static_cast<PublicSymFlags
>(E
.Value
));
119 void ScalarBitSetTraits
<LocalSymFlags
>::bitset(IO
&io
, LocalSymFlags
&Flags
) {
120 auto FlagNames
= getLocalFlagNames();
121 for (const auto &E
: FlagNames
) {
122 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
123 static_cast<LocalSymFlags
>(E
.Value
));
127 void ScalarBitSetTraits
<ProcSymFlags
>::bitset(IO
&io
, ProcSymFlags
&Flags
) {
128 auto FlagNames
= getProcSymFlagNames();
129 for (const auto &E
: FlagNames
) {
130 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
131 static_cast<ProcSymFlags
>(E
.Value
));
135 void ScalarBitSetTraits
<FrameProcedureOptions
>::bitset(
136 IO
&io
, FrameProcedureOptions
&Flags
) {
137 auto FlagNames
= getFrameProcSymFlagNames();
138 for (const auto &E
: FlagNames
) {
139 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
140 static_cast<FrameProcedureOptions
>(E
.Value
));
144 void ScalarEnumerationTraits
<CPUType
>::enumeration(IO
&io
, CPUType
&Cpu
) {
145 auto CpuNames
= getCPUTypeNames();
146 for (const auto &E
: CpuNames
) {
147 io
.enumCase(Cpu
, E
.Name
.str().c_str(), static_cast<CPUType
>(E
.Value
));
151 void ScalarEnumerationTraits
<RegisterId
>::enumeration(IO
&io
, RegisterId
&Reg
) {
152 const auto *Header
= static_cast<COFF::header
*>(io
.getContext());
153 assert(Header
&& "The IO context is not initialized");
155 std::optional
<CPUType
> CpuType
;
156 ArrayRef
<EnumEntry
<uint16_t>> RegNames
;
158 switch (Header
->Machine
) {
159 case COFF::IMAGE_FILE_MACHINE_I386
:
160 CpuType
= CPUType::Pentium3
;
162 case COFF::IMAGE_FILE_MACHINE_AMD64
:
163 CpuType
= CPUType::X64
;
165 case COFF::IMAGE_FILE_MACHINE_ARMNT
:
166 CpuType
= CPUType::ARMNT
;
168 case COFF::IMAGE_FILE_MACHINE_ARM64
:
169 case COFF::IMAGE_FILE_MACHINE_ARM64EC
:
170 case COFF::IMAGE_FILE_MACHINE_ARM64X
:
171 CpuType
= CPUType::ARM64
;
176 RegNames
= getRegisterNames(*CpuType
);
178 for (const auto &E
: RegNames
) {
179 io
.enumCase(Reg
, E
.Name
.str().c_str(), static_cast<RegisterId
>(E
.Value
));
181 io
.enumFallback
<Hex16
>(Reg
);
184 void ScalarEnumerationTraits
<TrampolineType
>::enumeration(
185 IO
&io
, TrampolineType
&Tramp
) {
186 auto TrampNames
= getTrampolineNames();
187 for (const auto &E
: TrampNames
) {
188 io
.enumCase(Tramp
, E
.Name
.str().c_str(),
189 static_cast<TrampolineType
>(E
.Value
));
193 void ScalarEnumerationTraits
<ThunkOrdinal
>::enumeration(IO
&io
,
195 auto ThunkNames
= getThunkOrdinalNames();
196 for (const auto &E
: ThunkNames
) {
197 io
.enumCase(Ord
, E
.Name
.str().c_str(), static_cast<ThunkOrdinal
>(E
.Value
));
201 void ScalarEnumerationTraits
<FrameCookieKind
>::enumeration(
202 IO
&io
, FrameCookieKind
&FC
) {
203 auto ThunkNames
= getFrameCookieKindNames();
204 for (const auto &E
: ThunkNames
) {
205 io
.enumCase(FC
, E
.Name
.str().c_str(),
206 static_cast<FrameCookieKind
>(E
.Value
));
212 template <> struct MappingTraits
<LocalVariableAddrRange
> {
213 static void mapping(IO
&io
, LocalVariableAddrRange
&Range
) {
214 io
.mapRequired("OffsetStart", Range
.OffsetStart
);
215 io
.mapRequired("ISectStart", Range
.ISectStart
);
216 io
.mapRequired("Range", Range
.Range
);
219 template <> struct MappingTraits
<LocalVariableAddrGap
> {
220 static void mapping(IO
&io
, LocalVariableAddrGap
&Gap
) {
221 io
.mapRequired("GapStartOffset", Gap
.GapStartOffset
);
222 io
.mapRequired("Range", Gap
.Range
);
229 namespace CodeViewYAML
{
232 struct SymbolRecordBase
{
233 codeview::SymbolKind Kind
;
235 explicit SymbolRecordBase(codeview::SymbolKind K
) : Kind(K
) {}
236 virtual ~SymbolRecordBase() = default;
238 virtual void map(yaml::IO
&io
) = 0;
239 virtual codeview::CVSymbol
240 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
241 CodeViewContainer Container
) const = 0;
242 virtual Error
fromCodeViewSymbol(codeview::CVSymbol Type
) = 0;
245 template <typename T
> struct SymbolRecordImpl
: public SymbolRecordBase
{
246 explicit SymbolRecordImpl(codeview::SymbolKind K
)
247 : SymbolRecordBase(K
), Symbol(static_cast<SymbolRecordKind
>(K
)) {}
249 void map(yaml::IO
&io
) override
;
252 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
253 CodeViewContainer Container
) const override
{
254 return SymbolSerializer::writeOneSymbol(Symbol
, Allocator
, Container
);
257 Error
fromCodeViewSymbol(codeview::CVSymbol CVS
) override
{
258 return SymbolDeserializer::deserializeAs
<T
>(CVS
, Symbol
);
264 struct UnknownSymbolRecord
: public SymbolRecordBase
{
265 explicit UnknownSymbolRecord(codeview::SymbolKind K
) : SymbolRecordBase(K
) {}
267 void map(yaml::IO
&io
) override
;
269 CVSymbol
toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
270 CodeViewContainer Container
) const override
{
272 uint32_t TotalLen
= sizeof(RecordPrefix
) + Data
.size();
273 Prefix
.RecordKind
= Kind
;
274 Prefix
.RecordLen
= TotalLen
- 2;
275 uint8_t *Buffer
= Allocator
.Allocate
<uint8_t>(TotalLen
);
276 ::memcpy(Buffer
, &Prefix
, sizeof(RecordPrefix
));
277 ::memcpy(Buffer
+ sizeof(RecordPrefix
), Data
.data(), Data
.size());
278 return CVSymbol(ArrayRef
<uint8_t>(Buffer
, TotalLen
));
281 Error
fromCodeViewSymbol(CVSymbol CVS
) override
{
282 this->Kind
= CVS
.kind();
283 Data
= CVS
.RecordData
.drop_front(sizeof(RecordPrefix
));
284 return Error::success();
287 std::vector
<uint8_t> Data
;
290 template <> void SymbolRecordImpl
<ScopeEndSym
>::map(IO
&IO
) {}
292 void UnknownSymbolRecord::map(yaml::IO
&io
) {
293 yaml::BinaryRef Binary
;
295 Binary
= yaml::BinaryRef(Data
);
296 io
.mapRequired("Data", Binary
);
297 if (!io
.outputting()) {
299 raw_string_ostream
OS(Str
);
300 Binary
.writeAsBinary(OS
);
302 Data
.assign(Str
.begin(), Str
.end());
306 template <> void SymbolRecordImpl
<Thunk32Sym
>::map(IO
&IO
) {
307 IO
.mapRequired("Parent", Symbol
.Parent
);
308 IO
.mapRequired("End", Symbol
.End
);
309 IO
.mapRequired("Next", Symbol
.Next
);
310 IO
.mapRequired("Off", Symbol
.Offset
);
311 IO
.mapRequired("Seg", Symbol
.Segment
);
312 IO
.mapRequired("Len", Symbol
.Length
);
313 IO
.mapRequired("Ordinal", Symbol
.Thunk
);
316 template <> void SymbolRecordImpl
<TrampolineSym
>::map(IO
&IO
) {
317 IO
.mapRequired("Type", Symbol
.Type
);
318 IO
.mapRequired("Size", Symbol
.Size
);
319 IO
.mapRequired("ThunkOff", Symbol
.ThunkOffset
);
320 IO
.mapRequired("TargetOff", Symbol
.TargetOffset
);
321 IO
.mapRequired("ThunkSection", Symbol
.ThunkSection
);
322 IO
.mapRequired("TargetSection", Symbol
.TargetSection
);
325 template <> void SymbolRecordImpl
<SectionSym
>::map(IO
&IO
) {
326 IO
.mapRequired("SectionNumber", Symbol
.SectionNumber
);
327 IO
.mapRequired("Alignment", Symbol
.Alignment
);
328 IO
.mapRequired("Rva", Symbol
.Rva
);
329 IO
.mapRequired("Length", Symbol
.Length
);
330 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
331 IO
.mapRequired("Name", Symbol
.Name
);
334 template <> void SymbolRecordImpl
<CoffGroupSym
>::map(IO
&IO
) {
335 IO
.mapRequired("Size", Symbol
.Size
);
336 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
337 IO
.mapRequired("Offset", Symbol
.Offset
);
338 IO
.mapRequired("Segment", Symbol
.Segment
);
339 IO
.mapRequired("Name", Symbol
.Name
);
342 template <> void SymbolRecordImpl
<ExportSym
>::map(IO
&IO
) {
343 IO
.mapRequired("Ordinal", Symbol
.Ordinal
);
344 IO
.mapRequired("Flags", Symbol
.Flags
);
345 IO
.mapRequired("Name", Symbol
.Name
);
348 template <> void SymbolRecordImpl
<ProcSym
>::map(IO
&IO
) {
349 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
350 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
351 IO
.mapOptional("PtrNext", Symbol
.Next
, 0U);
352 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
353 IO
.mapRequired("DbgStart", Symbol
.DbgStart
);
354 IO
.mapRequired("DbgEnd", Symbol
.DbgEnd
);
355 IO
.mapRequired("FunctionType", Symbol
.FunctionType
);
356 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
357 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
358 IO
.mapRequired("Flags", Symbol
.Flags
);
359 IO
.mapRequired("DisplayName", Symbol
.Name
);
362 template <> void SymbolRecordImpl
<RegisterSym
>::map(IO
&IO
) {
363 IO
.mapRequired("Type", Symbol
.Index
);
364 IO
.mapRequired("Seg", Symbol
.Register
);
365 IO
.mapRequired("Name", Symbol
.Name
);
368 template <> void SymbolRecordImpl
<PublicSym32
>::map(IO
&IO
) {
369 IO
.mapRequired("Flags", Symbol
.Flags
);
370 IO
.mapOptional("Offset", Symbol
.Offset
, 0U);
371 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
372 IO
.mapRequired("Name", Symbol
.Name
);
375 template <> void SymbolRecordImpl
<ProcRefSym
>::map(IO
&IO
) {
376 IO
.mapRequired("SumName", Symbol
.SumName
);
377 IO
.mapRequired("SymOffset", Symbol
.SymOffset
);
378 IO
.mapRequired("Mod", Symbol
.Module
);
379 IO
.mapRequired("Name", Symbol
.Name
);
382 template <> void SymbolRecordImpl
<EnvBlockSym
>::map(IO
&IO
) {
383 IO
.mapRequired("Entries", Symbol
.Fields
);
386 template <> void SymbolRecordImpl
<InlineSiteSym
>::map(IO
&IO
) {
387 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
388 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
389 IO
.mapRequired("Inlinee", Symbol
.Inlinee
);
390 // TODO: The binary annotations
393 template <> void SymbolRecordImpl
<LocalSym
>::map(IO
&IO
) {
394 IO
.mapRequired("Type", Symbol
.Type
);
395 IO
.mapRequired("Flags", Symbol
.Flags
);
397 IO
.mapRequired("VarName", Symbol
.Name
);
400 template <> void SymbolRecordImpl
<DefRangeSym
>::map(IO
&IO
) {
401 IO
.mapRequired("Program", Symbol
.Program
);
402 IO
.mapRequired("Range", Symbol
.Range
);
403 IO
.mapRequired("Gaps", Symbol
.Gaps
);
406 template <> void SymbolRecordImpl
<DefRangeSubfieldSym
>::map(IO
&IO
) {
407 IO
.mapRequired("Program", Symbol
.Program
);
408 IO
.mapRequired("OffsetInParent", Symbol
.OffsetInParent
);
409 IO
.mapRequired("Range", Symbol
.Range
);
410 IO
.mapRequired("Gaps", Symbol
.Gaps
);
413 template <> void SymbolRecordImpl
<DefRangeRegisterSym
>::map(IO
&IO
) {
414 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
415 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
416 IO
.mapRequired("Range", Symbol
.Range
);
417 IO
.mapRequired("Gaps", Symbol
.Gaps
);
420 template <> void SymbolRecordImpl
<DefRangeFramePointerRelSym
>::map(IO
&IO
) {
421 IO
.mapRequired("Offset", Symbol
.Hdr
.Offset
);
422 IO
.mapRequired("Range", Symbol
.Range
);
423 IO
.mapRequired("Gaps", Symbol
.Gaps
);
426 template <> void SymbolRecordImpl
<DefRangeSubfieldRegisterSym
>::map(IO
&IO
) {
427 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
428 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
429 IO
.mapRequired("OffsetInParent", Symbol
.Hdr
.OffsetInParent
);
430 IO
.mapRequired("Range", Symbol
.Range
);
431 IO
.mapRequired("Gaps", Symbol
.Gaps
);
435 void SymbolRecordImpl
<DefRangeFramePointerRelFullScopeSym
>::map(IO
&IO
) {
436 IO
.mapRequired("Register", Symbol
.Offset
);
439 template <> void SymbolRecordImpl
<DefRangeRegisterRelSym
>::map(IO
&IO
) {
440 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
441 IO
.mapRequired("Flags", Symbol
.Hdr
.Flags
);
442 IO
.mapRequired("BasePointerOffset", Symbol
.Hdr
.BasePointerOffset
);
443 IO
.mapRequired("Range", Symbol
.Range
);
444 IO
.mapRequired("Gaps", Symbol
.Gaps
);
447 template <> void SymbolRecordImpl
<BlockSym
>::map(IO
&IO
) {
448 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
449 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
450 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
451 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
452 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
453 IO
.mapRequired("BlockName", Symbol
.Name
);
456 template <> void SymbolRecordImpl
<LabelSym
>::map(IO
&IO
) {
457 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
458 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
459 IO
.mapRequired("Flags", Symbol
.Flags
);
460 IO
.mapRequired("Flags", Symbol
.Flags
);
461 IO
.mapRequired("DisplayName", Symbol
.Name
);
464 template <> void SymbolRecordImpl
<ObjNameSym
>::map(IO
&IO
) {
465 IO
.mapRequired("Signature", Symbol
.Signature
);
466 IO
.mapRequired("ObjectName", Symbol
.Name
);
469 template <> void SymbolRecordImpl
<Compile2Sym
>::map(IO
&IO
) {
470 IO
.mapRequired("Flags", Symbol
.Flags
);
471 IO
.mapRequired("Machine", Symbol
.Machine
);
472 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
473 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
474 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
475 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
476 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
477 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
478 IO
.mapRequired("Version", Symbol
.Version
);
481 template <> void SymbolRecordImpl
<Compile3Sym
>::map(IO
&IO
) {
482 IO
.mapRequired("Flags", Symbol
.Flags
);
483 IO
.mapRequired("Machine", Symbol
.Machine
);
484 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
485 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
486 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
487 IO
.mapRequired("FrontendQFE", Symbol
.VersionFrontendQFE
);
488 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
489 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
490 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
491 IO
.mapRequired("BackendQFE", Symbol
.VersionBackendQFE
);
492 IO
.mapRequired("Version", Symbol
.Version
);
495 template <> void SymbolRecordImpl
<FrameProcSym
>::map(IO
&IO
) {
496 IO
.mapRequired("TotalFrameBytes", Symbol
.TotalFrameBytes
);
497 IO
.mapRequired("PaddingFrameBytes", Symbol
.PaddingFrameBytes
);
498 IO
.mapRequired("OffsetToPadding", Symbol
.OffsetToPadding
);
499 IO
.mapRequired("BytesOfCalleeSavedRegisters",
500 Symbol
.BytesOfCalleeSavedRegisters
);
501 IO
.mapRequired("OffsetOfExceptionHandler", Symbol
.OffsetOfExceptionHandler
);
502 IO
.mapRequired("SectionIdOfExceptionHandler",
503 Symbol
.SectionIdOfExceptionHandler
);
504 IO
.mapRequired("Flags", Symbol
.Flags
);
507 template <> void SymbolRecordImpl
<CallSiteInfoSym
>::map(IO
&IO
) {
508 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
509 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
510 IO
.mapRequired("Type", Symbol
.Type
);
513 template <> void SymbolRecordImpl
<FileStaticSym
>::map(IO
&IO
) {
514 IO
.mapRequired("Index", Symbol
.Index
);
515 IO
.mapRequired("ModFilenameOffset", Symbol
.ModFilenameOffset
);
516 IO
.mapRequired("Flags", Symbol
.Flags
);
517 IO
.mapRequired("Name", Symbol
.Name
);
520 template <> void SymbolRecordImpl
<HeapAllocationSiteSym
>::map(IO
&IO
) {
521 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
522 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
523 IO
.mapRequired("CallInstructionSize", Symbol
.CallInstructionSize
);
524 IO
.mapRequired("Type", Symbol
.Type
);
527 template <> void SymbolRecordImpl
<FrameCookieSym
>::map(IO
&IO
) {
528 IO
.mapRequired("Register", Symbol
.Register
);
529 IO
.mapRequired("CookieKind", Symbol
.CookieKind
);
530 IO
.mapRequired("Flags", Symbol
.Flags
);
533 template <> void SymbolRecordImpl
<CallerSym
>::map(IO
&IO
) {
534 IO
.mapRequired("FuncID", Symbol
.Indices
);
537 template <> void SymbolRecordImpl
<UDTSym
>::map(IO
&IO
) {
538 IO
.mapRequired("Type", Symbol
.Type
);
539 IO
.mapRequired("UDTName", Symbol
.Name
);
542 template <> void SymbolRecordImpl
<BuildInfoSym
>::map(IO
&IO
) {
543 IO
.mapRequired("BuildId", Symbol
.BuildId
);
546 template <> void SymbolRecordImpl
<BPRelativeSym
>::map(IO
&IO
) {
547 IO
.mapRequired("Offset", Symbol
.Offset
);
548 IO
.mapRequired("Type", Symbol
.Type
);
549 IO
.mapRequired("VarName", Symbol
.Name
);
552 template <> void SymbolRecordImpl
<RegRelativeSym
>::map(IO
&IO
) {
553 IO
.mapRequired("Offset", Symbol
.Offset
);
554 IO
.mapRequired("Type", Symbol
.Type
);
555 IO
.mapRequired("Register", Symbol
.Register
);
556 IO
.mapRequired("VarName", Symbol
.Name
);
559 template <> void SymbolRecordImpl
<ConstantSym
>::map(IO
&IO
) {
560 IO
.mapRequired("Type", Symbol
.Type
);
561 IO
.mapRequired("Value", Symbol
.Value
);
562 IO
.mapRequired("Name", Symbol
.Name
);
565 template <> void SymbolRecordImpl
<DataSym
>::map(IO
&IO
) {
566 IO
.mapRequired("Type", Symbol
.Type
);
567 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
568 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
569 IO
.mapRequired("DisplayName", Symbol
.Name
);
572 template <> void SymbolRecordImpl
<ThreadLocalDataSym
>::map(IO
&IO
) {
573 IO
.mapRequired("Type", Symbol
.Type
);
574 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
575 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
576 IO
.mapRequired("DisplayName", Symbol
.Name
);
579 template <> void SymbolRecordImpl
<UsingNamespaceSym
>::map(IO
&IO
) {
580 IO
.mapRequired("Namespace", Symbol
.Name
);
583 template <> void SymbolRecordImpl
<AnnotationSym
>::map(IO
&IO
) {
584 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
585 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
586 IO
.mapRequired("Strings", Symbol
.Strings
);
589 } // end namespace detail
590 } // end namespace CodeViewYAML
591 } // end namespace llvm
593 CVSymbol
CodeViewYAML::SymbolRecord::toCodeViewSymbol(
594 BumpPtrAllocator
&Allocator
, CodeViewContainer Container
) const {
595 return Symbol
->toCodeViewSymbol(Allocator
, Container
);
601 template <> struct MappingTraits
<SymbolRecordBase
> {
602 static void mapping(IO
&io
, SymbolRecordBase
&Record
) { Record
.map(io
); }
605 } // end namespace yaml
606 } // end namespace llvm
608 template <typename SymbolType
>
609 static inline Expected
<CodeViewYAML::SymbolRecord
>
610 fromCodeViewSymbolImpl(CVSymbol Symbol
) {
611 CodeViewYAML::SymbolRecord Result
;
613 auto Impl
= std::make_shared
<SymbolType
>(Symbol
.kind());
614 if (auto EC
= Impl
->fromCodeViewSymbol(Symbol
))
615 return std::move(EC
);
616 Result
.Symbol
= Impl
;
620 Expected
<CodeViewYAML::SymbolRecord
>
621 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol
) {
622 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
624 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
625 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
626 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
627 switch (Symbol
.kind()) {
628 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
630 return fromCodeViewSymbolImpl
<UnknownSymbolRecord
>(Symbol
);
632 return make_error
<CodeViewError
>(cv_error_code::corrupt_record
);
635 template <typename ConcreteType
>
636 static void mapSymbolRecordImpl(IO
&IO
, const char *Class
, SymbolKind Kind
,
637 CodeViewYAML::SymbolRecord
&Obj
) {
638 if (!IO
.outputting())
639 Obj
.Symbol
= std::make_shared
<ConcreteType
>(Kind
);
641 IO
.mapRequired(Class
, *Obj
.Symbol
);
644 void MappingTraits
<CodeViewYAML::SymbolRecord
>::mapping(
645 IO
&IO
, CodeViewYAML::SymbolRecord
&Obj
) {
648 Kind
= Obj
.Symbol
->Kind
;
649 IO
.mapRequired("Kind", Kind
);
651 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
653 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
656 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
657 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
659 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
661 mapSymbolRecordImpl
<UnknownSymbolRecord
>(IO
, "UnknownSym", Kind
, Obj
);