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/YAMLTraits.h"
36 using namespace llvm::codeview
;
37 using namespace llvm::CodeViewYAML
;
38 using namespace llvm::CodeViewYAML::detail
;
39 using namespace llvm::yaml
;
41 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex
)
42 LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap
)
44 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
45 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt
, QuotingType::None
)
46 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex
, QuotingType::None
)
48 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind
)
49 LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind
)
51 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags
)
52 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags
)
53 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags
)
54 LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags
)
55 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags
)
56 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags
)
57 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions
)
58 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType
)
59 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId
)
60 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType
)
61 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal
)
63 LLVM_YAML_STRONG_TYPEDEF(StringRef
, TypeName
)
65 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName
, QuotingType::Single
)
67 StringRef ScalarTraits
<TypeName
>::input(StringRef S
, void *V
, TypeName
&T
) {
68 return ScalarTraits
<StringRef
>::input(S
, V
, T
.value
);
71 void ScalarTraits
<TypeName
>::output(const TypeName
&T
, void *V
,
73 ScalarTraits
<StringRef
>::output(T
.value
, V
, R
);
76 void ScalarEnumerationTraits
<SymbolKind
>::enumeration(IO
&io
,
78 auto SymbolNames
= getSymbolTypeNames();
79 for (const auto &E
: SymbolNames
)
80 io
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
83 void ScalarBitSetTraits
<CompileSym2Flags
>::bitset(IO
&io
,
84 CompileSym2Flags
&Flags
) {
85 auto FlagNames
= getCompileSym2FlagNames();
86 for (const auto &E
: FlagNames
) {
87 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
88 static_cast<CompileSym2Flags
>(E
.Value
));
92 void ScalarBitSetTraits
<CompileSym3Flags
>::bitset(IO
&io
,
93 CompileSym3Flags
&Flags
) {
94 auto FlagNames
= getCompileSym3FlagNames();
95 for (const auto &E
: FlagNames
) {
96 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
97 static_cast<CompileSym3Flags
>(E
.Value
));
101 void ScalarBitSetTraits
<ExportFlags
>::bitset(IO
&io
, ExportFlags
&Flags
) {
102 auto FlagNames
= getExportSymFlagNames();
103 for (const auto &E
: FlagNames
) {
104 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
105 static_cast<ExportFlags
>(E
.Value
));
109 void ScalarBitSetTraits
<PublicSymFlags
>::bitset(IO
&io
, PublicSymFlags
&Flags
) {
110 auto FlagNames
= getPublicSymFlagNames();
111 for (const auto &E
: FlagNames
) {
112 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
113 static_cast<PublicSymFlags
>(E
.Value
));
117 void ScalarBitSetTraits
<LocalSymFlags
>::bitset(IO
&io
, LocalSymFlags
&Flags
) {
118 auto FlagNames
= getLocalFlagNames();
119 for (const auto &E
: FlagNames
) {
120 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
121 static_cast<LocalSymFlags
>(E
.Value
));
125 void ScalarBitSetTraits
<ProcSymFlags
>::bitset(IO
&io
, ProcSymFlags
&Flags
) {
126 auto FlagNames
= getProcSymFlagNames();
127 for (const auto &E
: FlagNames
) {
128 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
129 static_cast<ProcSymFlags
>(E
.Value
));
133 void ScalarBitSetTraits
<FrameProcedureOptions
>::bitset(
134 IO
&io
, FrameProcedureOptions
&Flags
) {
135 auto FlagNames
= getFrameProcSymFlagNames();
136 for (const auto &E
: FlagNames
) {
137 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
138 static_cast<FrameProcedureOptions
>(E
.Value
));
142 void ScalarEnumerationTraits
<CPUType
>::enumeration(IO
&io
, CPUType
&Cpu
) {
143 auto CpuNames
= getCPUTypeNames();
144 for (const auto &E
: CpuNames
) {
145 io
.enumCase(Cpu
, E
.Name
.str().c_str(), static_cast<CPUType
>(E
.Value
));
149 void ScalarEnumerationTraits
<RegisterId
>::enumeration(IO
&io
, RegisterId
&Reg
) {
150 const auto *Header
= static_cast<COFF::header
*>(io
.getContext());
151 assert(Header
&& "The IO context is not initialized");
153 Optional
<CPUType
> CpuType
;
154 ArrayRef
<EnumEntry
<uint16_t>> RegNames
;
156 switch (Header
->Machine
) {
157 case COFF::IMAGE_FILE_MACHINE_I386
:
158 CpuType
= CPUType::Pentium3
;
160 case COFF::IMAGE_FILE_MACHINE_AMD64
:
161 CpuType
= CPUType::X64
;
163 case COFF::IMAGE_FILE_MACHINE_ARMNT
:
164 CpuType
= CPUType::ARMNT
;
166 case COFF::IMAGE_FILE_MACHINE_ARM64
:
167 CpuType
= CPUType::ARM64
;
172 RegNames
= getRegisterNames(*CpuType
);
174 for (const auto &E
: RegNames
) {
175 io
.enumCase(Reg
, E
.Name
.str().c_str(), static_cast<RegisterId
>(E
.Value
));
177 io
.enumFallback
<Hex16
>(Reg
);
180 void ScalarEnumerationTraits
<TrampolineType
>::enumeration(
181 IO
&io
, TrampolineType
&Tramp
) {
182 auto TrampNames
= getTrampolineNames();
183 for (const auto &E
: TrampNames
) {
184 io
.enumCase(Tramp
, E
.Name
.str().c_str(),
185 static_cast<TrampolineType
>(E
.Value
));
189 void ScalarEnumerationTraits
<ThunkOrdinal
>::enumeration(IO
&io
,
191 auto ThunkNames
= getThunkOrdinalNames();
192 for (const auto &E
: ThunkNames
) {
193 io
.enumCase(Ord
, E
.Name
.str().c_str(), static_cast<ThunkOrdinal
>(E
.Value
));
197 void ScalarEnumerationTraits
<FrameCookieKind
>::enumeration(
198 IO
&io
, FrameCookieKind
&FC
) {
199 auto ThunkNames
= getFrameCookieKindNames();
200 for (const auto &E
: ThunkNames
) {
201 io
.enumCase(FC
, E
.Name
.str().c_str(),
202 static_cast<FrameCookieKind
>(E
.Value
));
208 template <> struct MappingTraits
<LocalVariableAddrRange
> {
209 static void mapping(IO
&io
, LocalVariableAddrRange
&Range
) {
210 io
.mapRequired("OffsetStart", Range
.OffsetStart
);
211 io
.mapRequired("ISectStart", Range
.ISectStart
);
212 io
.mapRequired("Range", Range
.Range
);
215 template <> struct MappingTraits
<LocalVariableAddrGap
> {
216 static void mapping(IO
&io
, LocalVariableAddrGap
&Gap
) {
217 io
.mapRequired("GapStartOffset", Gap
.GapStartOffset
);
218 io
.mapRequired("Range", Gap
.Range
);
225 namespace CodeViewYAML
{
228 struct SymbolRecordBase
{
229 codeview::SymbolKind Kind
;
231 explicit SymbolRecordBase(codeview::SymbolKind K
) : Kind(K
) {}
232 virtual ~SymbolRecordBase() = default;
234 virtual void map(yaml::IO
&io
) = 0;
235 virtual codeview::CVSymbol
236 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
237 CodeViewContainer Container
) const = 0;
238 virtual Error
fromCodeViewSymbol(codeview::CVSymbol Type
) = 0;
241 template <typename T
> struct SymbolRecordImpl
: public SymbolRecordBase
{
242 explicit SymbolRecordImpl(codeview::SymbolKind K
)
243 : SymbolRecordBase(K
), Symbol(static_cast<SymbolRecordKind
>(K
)) {}
245 void map(yaml::IO
&io
) override
;
248 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
249 CodeViewContainer Container
) const override
{
250 return SymbolSerializer::writeOneSymbol(Symbol
, Allocator
, Container
);
253 Error
fromCodeViewSymbol(codeview::CVSymbol CVS
) override
{
254 return SymbolDeserializer::deserializeAs
<T
>(CVS
, Symbol
);
260 struct UnknownSymbolRecord
: public SymbolRecordBase
{
261 explicit UnknownSymbolRecord(codeview::SymbolKind K
) : SymbolRecordBase(K
) {}
263 void map(yaml::IO
&io
) override
;
265 CVSymbol
toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
266 CodeViewContainer Container
) const override
{
268 uint32_t TotalLen
= sizeof(RecordPrefix
) + Data
.size();
269 Prefix
.RecordKind
= Kind
;
270 Prefix
.RecordLen
= TotalLen
- 2;
271 uint8_t *Buffer
= Allocator
.Allocate
<uint8_t>(TotalLen
);
272 ::memcpy(Buffer
, &Prefix
, sizeof(RecordPrefix
));
273 ::memcpy(Buffer
+ sizeof(RecordPrefix
), Data
.data(), Data
.size());
274 return CVSymbol(ArrayRef
<uint8_t>(Buffer
, TotalLen
));
277 Error
fromCodeViewSymbol(CVSymbol CVS
) override
{
278 this->Kind
= CVS
.kind();
279 Data
= CVS
.RecordData
.drop_front(sizeof(RecordPrefix
));
280 return Error::success();
283 std::vector
<uint8_t> Data
;
286 template <> void SymbolRecordImpl
<ScopeEndSym
>::map(IO
&IO
) {}
288 void UnknownSymbolRecord::map(yaml::IO
&io
) {
289 yaml::BinaryRef Binary
;
291 Binary
= yaml::BinaryRef(Data
);
292 io
.mapRequired("Data", Binary
);
293 if (!io
.outputting()) {
295 raw_string_ostream
OS(Str
);
296 Binary
.writeAsBinary(OS
);
298 Data
.assign(Str
.begin(), Str
.end());
302 template <> void SymbolRecordImpl
<Thunk32Sym
>::map(IO
&IO
) {
303 IO
.mapRequired("Parent", Symbol
.Parent
);
304 IO
.mapRequired("End", Symbol
.End
);
305 IO
.mapRequired("Next", Symbol
.Next
);
306 IO
.mapRequired("Off", Symbol
.Offset
);
307 IO
.mapRequired("Seg", Symbol
.Segment
);
308 IO
.mapRequired("Len", Symbol
.Length
);
309 IO
.mapRequired("Ordinal", Symbol
.Thunk
);
312 template <> void SymbolRecordImpl
<TrampolineSym
>::map(IO
&IO
) {
313 IO
.mapRequired("Type", Symbol
.Type
);
314 IO
.mapRequired("Size", Symbol
.Size
);
315 IO
.mapRequired("ThunkOff", Symbol
.ThunkOffset
);
316 IO
.mapRequired("TargetOff", Symbol
.TargetOffset
);
317 IO
.mapRequired("ThunkSection", Symbol
.ThunkSection
);
318 IO
.mapRequired("TargetSection", Symbol
.TargetSection
);
321 template <> void SymbolRecordImpl
<SectionSym
>::map(IO
&IO
) {
322 IO
.mapRequired("SectionNumber", Symbol
.SectionNumber
);
323 IO
.mapRequired("Alignment", Symbol
.Alignment
);
324 IO
.mapRequired("Rva", Symbol
.Rva
);
325 IO
.mapRequired("Length", Symbol
.Length
);
326 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
327 IO
.mapRequired("Name", Symbol
.Name
);
330 template <> void SymbolRecordImpl
<CoffGroupSym
>::map(IO
&IO
) {
331 IO
.mapRequired("Size", Symbol
.Size
);
332 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
333 IO
.mapRequired("Offset", Symbol
.Offset
);
334 IO
.mapRequired("Segment", Symbol
.Segment
);
335 IO
.mapRequired("Name", Symbol
.Name
);
338 template <> void SymbolRecordImpl
<ExportSym
>::map(IO
&IO
) {
339 IO
.mapRequired("Ordinal", Symbol
.Ordinal
);
340 IO
.mapRequired("Flags", Symbol
.Flags
);
341 IO
.mapRequired("Name", Symbol
.Name
);
344 template <> void SymbolRecordImpl
<ProcSym
>::map(IO
&IO
) {
345 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
346 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
347 IO
.mapOptional("PtrNext", Symbol
.Next
, 0U);
348 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
349 IO
.mapRequired("DbgStart", Symbol
.DbgStart
);
350 IO
.mapRequired("DbgEnd", Symbol
.DbgEnd
);
351 IO
.mapRequired("FunctionType", Symbol
.FunctionType
);
352 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
353 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
354 IO
.mapRequired("Flags", Symbol
.Flags
);
355 IO
.mapRequired("DisplayName", Symbol
.Name
);
358 template <> void SymbolRecordImpl
<RegisterSym
>::map(IO
&IO
) {
359 IO
.mapRequired("Type", Symbol
.Index
);
360 IO
.mapRequired("Seg", Symbol
.Register
);
361 IO
.mapRequired("Name", Symbol
.Name
);
364 template <> void SymbolRecordImpl
<PublicSym32
>::map(IO
&IO
) {
365 IO
.mapRequired("Flags", Symbol
.Flags
);
366 IO
.mapOptional("Offset", Symbol
.Offset
, 0U);
367 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
368 IO
.mapRequired("Name", Symbol
.Name
);
371 template <> void SymbolRecordImpl
<ProcRefSym
>::map(IO
&IO
) {
372 IO
.mapRequired("SumName", Symbol
.SumName
);
373 IO
.mapRequired("SymOffset", Symbol
.SymOffset
);
374 IO
.mapRequired("Mod", Symbol
.Module
);
375 IO
.mapRequired("Name", Symbol
.Name
);
378 template <> void SymbolRecordImpl
<EnvBlockSym
>::map(IO
&IO
) {
379 IO
.mapRequired("Entries", Symbol
.Fields
);
382 template <> void SymbolRecordImpl
<InlineSiteSym
>::map(IO
&IO
) {
383 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
384 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
385 IO
.mapRequired("Inlinee", Symbol
.Inlinee
);
386 // TODO: The binary annotations
389 template <> void SymbolRecordImpl
<LocalSym
>::map(IO
&IO
) {
390 IO
.mapRequired("Type", Symbol
.Type
);
391 IO
.mapRequired("Flags", Symbol
.Flags
);
393 IO
.mapRequired("VarName", Symbol
.Name
);
396 template <> void SymbolRecordImpl
<DefRangeSym
>::map(IO
&IO
) {
397 IO
.mapRequired("Program", Symbol
.Program
);
398 IO
.mapRequired("Range", Symbol
.Range
);
399 IO
.mapRequired("Gaps", Symbol
.Gaps
);
402 template <> void SymbolRecordImpl
<DefRangeSubfieldSym
>::map(IO
&IO
) {
403 IO
.mapRequired("Program", Symbol
.Program
);
404 IO
.mapRequired("OffsetInParent", Symbol
.OffsetInParent
);
405 IO
.mapRequired("Range", Symbol
.Range
);
406 IO
.mapRequired("Gaps", Symbol
.Gaps
);
409 template <> void SymbolRecordImpl
<DefRangeRegisterSym
>::map(IO
&IO
) {
410 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
411 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
412 IO
.mapRequired("Range", Symbol
.Range
);
413 IO
.mapRequired("Gaps", Symbol
.Gaps
);
416 template <> void SymbolRecordImpl
<DefRangeFramePointerRelSym
>::map(IO
&IO
) {
417 IO
.mapRequired("Offset", Symbol
.Hdr
.Offset
);
418 IO
.mapRequired("Range", Symbol
.Range
);
419 IO
.mapRequired("Gaps", Symbol
.Gaps
);
422 template <> void SymbolRecordImpl
<DefRangeSubfieldRegisterSym
>::map(IO
&IO
) {
423 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
424 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
425 IO
.mapRequired("OffsetInParent", Symbol
.Hdr
.OffsetInParent
);
426 IO
.mapRequired("Range", Symbol
.Range
);
427 IO
.mapRequired("Gaps", Symbol
.Gaps
);
431 void SymbolRecordImpl
<DefRangeFramePointerRelFullScopeSym
>::map(IO
&IO
) {
432 IO
.mapRequired("Register", Symbol
.Offset
);
435 template <> void SymbolRecordImpl
<DefRangeRegisterRelSym
>::map(IO
&IO
) {
436 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
437 IO
.mapRequired("Flags", Symbol
.Hdr
.Flags
);
438 IO
.mapRequired("BasePointerOffset", Symbol
.Hdr
.BasePointerOffset
);
439 IO
.mapRequired("Range", Symbol
.Range
);
440 IO
.mapRequired("Gaps", Symbol
.Gaps
);
443 template <> void SymbolRecordImpl
<BlockSym
>::map(IO
&IO
) {
444 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
445 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
446 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
447 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
448 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
449 IO
.mapRequired("BlockName", Symbol
.Name
);
452 template <> void SymbolRecordImpl
<LabelSym
>::map(IO
&IO
) {
453 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
454 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
455 IO
.mapRequired("Flags", Symbol
.Flags
);
456 IO
.mapRequired("Flags", Symbol
.Flags
);
457 IO
.mapRequired("DisplayName", Symbol
.Name
);
460 template <> void SymbolRecordImpl
<ObjNameSym
>::map(IO
&IO
) {
461 IO
.mapRequired("Signature", Symbol
.Signature
);
462 IO
.mapRequired("ObjectName", Symbol
.Name
);
465 template <> void SymbolRecordImpl
<Compile2Sym
>::map(IO
&IO
) {
466 IO
.mapRequired("Flags", Symbol
.Flags
);
467 IO
.mapRequired("Machine", Symbol
.Machine
);
468 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
469 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
470 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
471 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
472 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
473 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
474 IO
.mapRequired("Version", Symbol
.Version
);
477 template <> void SymbolRecordImpl
<Compile3Sym
>::map(IO
&IO
) {
478 IO
.mapRequired("Flags", Symbol
.Flags
);
479 IO
.mapRequired("Machine", Symbol
.Machine
);
480 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
481 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
482 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
483 IO
.mapRequired("FrontendQFE", Symbol
.VersionFrontendQFE
);
484 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
485 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
486 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
487 IO
.mapRequired("BackendQFE", Symbol
.VersionBackendQFE
);
488 IO
.mapRequired("Version", Symbol
.Version
);
491 template <> void SymbolRecordImpl
<FrameProcSym
>::map(IO
&IO
) {
492 IO
.mapRequired("TotalFrameBytes", Symbol
.TotalFrameBytes
);
493 IO
.mapRequired("PaddingFrameBytes", Symbol
.PaddingFrameBytes
);
494 IO
.mapRequired("OffsetToPadding", Symbol
.OffsetToPadding
);
495 IO
.mapRequired("BytesOfCalleeSavedRegisters",
496 Symbol
.BytesOfCalleeSavedRegisters
);
497 IO
.mapRequired("OffsetOfExceptionHandler", Symbol
.OffsetOfExceptionHandler
);
498 IO
.mapRequired("SectionIdOfExceptionHandler",
499 Symbol
.SectionIdOfExceptionHandler
);
500 IO
.mapRequired("Flags", Symbol
.Flags
);
503 template <> void SymbolRecordImpl
<CallSiteInfoSym
>::map(IO
&IO
) {
504 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
505 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
506 IO
.mapRequired("Type", Symbol
.Type
);
509 template <> void SymbolRecordImpl
<FileStaticSym
>::map(IO
&IO
) {
510 IO
.mapRequired("Index", Symbol
.Index
);
511 IO
.mapRequired("ModFilenameOffset", Symbol
.ModFilenameOffset
);
512 IO
.mapRequired("Flags", Symbol
.Flags
);
513 IO
.mapRequired("Name", Symbol
.Name
);
516 template <> void SymbolRecordImpl
<HeapAllocationSiteSym
>::map(IO
&IO
) {
517 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
518 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
519 IO
.mapRequired("CallInstructionSize", Symbol
.CallInstructionSize
);
520 IO
.mapRequired("Type", Symbol
.Type
);
523 template <> void SymbolRecordImpl
<FrameCookieSym
>::map(IO
&IO
) {
524 IO
.mapRequired("Register", Symbol
.Register
);
525 IO
.mapRequired("CookieKind", Symbol
.CookieKind
);
526 IO
.mapRequired("Flags", Symbol
.Flags
);
529 template <> void SymbolRecordImpl
<CallerSym
>::map(IO
&IO
) {
530 IO
.mapRequired("FuncID", Symbol
.Indices
);
533 template <> void SymbolRecordImpl
<UDTSym
>::map(IO
&IO
) {
534 IO
.mapRequired("Type", Symbol
.Type
);
535 IO
.mapRequired("UDTName", Symbol
.Name
);
538 template <> void SymbolRecordImpl
<BuildInfoSym
>::map(IO
&IO
) {
539 IO
.mapRequired("BuildId", Symbol
.BuildId
);
542 template <> void SymbolRecordImpl
<BPRelativeSym
>::map(IO
&IO
) {
543 IO
.mapRequired("Offset", Symbol
.Offset
);
544 IO
.mapRequired("Type", Symbol
.Type
);
545 IO
.mapRequired("VarName", Symbol
.Name
);
548 template <> void SymbolRecordImpl
<RegRelativeSym
>::map(IO
&IO
) {
549 IO
.mapRequired("Offset", Symbol
.Offset
);
550 IO
.mapRequired("Type", Symbol
.Type
);
551 IO
.mapRequired("Register", Symbol
.Register
);
552 IO
.mapRequired("VarName", Symbol
.Name
);
555 template <> void SymbolRecordImpl
<ConstantSym
>::map(IO
&IO
) {
556 IO
.mapRequired("Type", Symbol
.Type
);
557 IO
.mapRequired("Value", Symbol
.Value
);
558 IO
.mapRequired("Name", Symbol
.Name
);
561 template <> void SymbolRecordImpl
<DataSym
>::map(IO
&IO
) {
562 IO
.mapRequired("Type", Symbol
.Type
);
563 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
564 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
565 IO
.mapRequired("DisplayName", Symbol
.Name
);
568 template <> void SymbolRecordImpl
<ThreadLocalDataSym
>::map(IO
&IO
) {
569 IO
.mapRequired("Type", Symbol
.Type
);
570 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
571 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
572 IO
.mapRequired("DisplayName", Symbol
.Name
);
575 template <> void SymbolRecordImpl
<UsingNamespaceSym
>::map(IO
&IO
) {
576 IO
.mapRequired("Namespace", Symbol
.Name
);
579 template <> void SymbolRecordImpl
<AnnotationSym
>::map(IO
&IO
) {
580 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
581 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
582 IO
.mapRequired("Strings", Symbol
.Strings
);
585 } // end namespace detail
586 } // end namespace CodeViewYAML
587 } // end namespace llvm
589 CVSymbol
CodeViewYAML::SymbolRecord::toCodeViewSymbol(
590 BumpPtrAllocator
&Allocator
, CodeViewContainer Container
) const {
591 return Symbol
->toCodeViewSymbol(Allocator
, Container
);
597 template <> struct MappingTraits
<SymbolRecordBase
> {
598 static void mapping(IO
&io
, SymbolRecordBase
&Record
) { Record
.map(io
); }
601 } // end namespace yaml
602 } // end namespace llvm
604 template <typename SymbolType
>
605 static inline Expected
<CodeViewYAML::SymbolRecord
>
606 fromCodeViewSymbolImpl(CVSymbol Symbol
) {
607 CodeViewYAML::SymbolRecord Result
;
609 auto Impl
= std::make_shared
<SymbolType
>(Symbol
.kind());
610 if (auto EC
= Impl
->fromCodeViewSymbol(Symbol
))
611 return std::move(EC
);
612 Result
.Symbol
= Impl
;
616 Expected
<CodeViewYAML::SymbolRecord
>
617 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol
) {
618 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
620 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
621 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
622 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
623 switch (Symbol
.kind()) {
624 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
626 return fromCodeViewSymbolImpl
<UnknownSymbolRecord
>(Symbol
);
628 return make_error
<CodeViewError
>(cv_error_code::corrupt_record
);
631 template <typename ConcreteType
>
632 static void mapSymbolRecordImpl(IO
&IO
, const char *Class
, SymbolKind Kind
,
633 CodeViewYAML::SymbolRecord
&Obj
) {
634 if (!IO
.outputting())
635 Obj
.Symbol
= std::make_shared
<ConcreteType
>(Kind
);
637 IO
.mapRequired(Class
, *Obj
.Symbol
);
640 void MappingTraits
<CodeViewYAML::SymbolRecord
>::mapping(
641 IO
&IO
, CodeViewYAML::SymbolRecord
&Obj
) {
644 Kind
= Obj
.Symbol
->Kind
;
645 IO
.mapRequired("Kind", Kind
);
647 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
649 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
652 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
653 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
655 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
657 mapSymbolRecordImpl
<UnknownSymbolRecord
>(IO
, "UnknownSym", Kind
, Obj
);