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 auto RegNames
= getRegisterNames();
151 for (const auto &E
: RegNames
) {
152 io
.enumCase(Reg
, E
.Name
.str().c_str(), static_cast<RegisterId
>(E
.Value
));
154 io
.enumFallback
<Hex16
>(Reg
);
157 void ScalarEnumerationTraits
<TrampolineType
>::enumeration(
158 IO
&io
, TrampolineType
&Tramp
) {
159 auto TrampNames
= getTrampolineNames();
160 for (const auto &E
: TrampNames
) {
161 io
.enumCase(Tramp
, E
.Name
.str().c_str(),
162 static_cast<TrampolineType
>(E
.Value
));
166 void ScalarEnumerationTraits
<ThunkOrdinal
>::enumeration(IO
&io
,
168 auto ThunkNames
= getThunkOrdinalNames();
169 for (const auto &E
: ThunkNames
) {
170 io
.enumCase(Ord
, E
.Name
.str().c_str(), static_cast<ThunkOrdinal
>(E
.Value
));
174 void ScalarEnumerationTraits
<FrameCookieKind
>::enumeration(
175 IO
&io
, FrameCookieKind
&FC
) {
176 auto ThunkNames
= getFrameCookieKindNames();
177 for (const auto &E
: ThunkNames
) {
178 io
.enumCase(FC
, E
.Name
.str().c_str(),
179 static_cast<FrameCookieKind
>(E
.Value
));
185 template <> struct MappingTraits
<LocalVariableAddrRange
> {
186 static void mapping(IO
&io
, LocalVariableAddrRange
&Range
) {
187 io
.mapRequired("OffsetStart", Range
.OffsetStart
);
188 io
.mapRequired("ISectStart", Range
.ISectStart
);
189 io
.mapRequired("Range", Range
.Range
);
192 template <> struct MappingTraits
<LocalVariableAddrGap
> {
193 static void mapping(IO
&io
, LocalVariableAddrGap
&Gap
) {
194 io
.mapRequired("GapStartOffset", Gap
.GapStartOffset
);
195 io
.mapRequired("Range", Gap
.Range
);
202 namespace CodeViewYAML
{
205 struct SymbolRecordBase
{
206 codeview::SymbolKind Kind
;
208 explicit SymbolRecordBase(codeview::SymbolKind K
) : Kind(K
) {}
209 virtual ~SymbolRecordBase() = default;
211 virtual void map(yaml::IO
&io
) = 0;
212 virtual codeview::CVSymbol
213 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
214 CodeViewContainer Container
) const = 0;
215 virtual Error
fromCodeViewSymbol(codeview::CVSymbol Type
) = 0;
218 template <typename T
> struct SymbolRecordImpl
: public SymbolRecordBase
{
219 explicit SymbolRecordImpl(codeview::SymbolKind K
)
220 : SymbolRecordBase(K
), Symbol(static_cast<SymbolRecordKind
>(K
)) {}
222 void map(yaml::IO
&io
) override
;
225 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
226 CodeViewContainer Container
) const override
{
227 return SymbolSerializer::writeOneSymbol(Symbol
, Allocator
, Container
);
230 Error
fromCodeViewSymbol(codeview::CVSymbol CVS
) override
{
231 return SymbolDeserializer::deserializeAs
<T
>(CVS
, Symbol
);
237 struct UnknownSymbolRecord
: public SymbolRecordBase
{
238 explicit UnknownSymbolRecord(codeview::SymbolKind K
) : SymbolRecordBase(K
) {}
240 void map(yaml::IO
&io
) override
;
242 CVSymbol
toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
243 CodeViewContainer Container
) const override
{
245 uint32_t TotalLen
= sizeof(RecordPrefix
) + Data
.size();
246 Prefix
.RecordKind
= Kind
;
247 Prefix
.RecordLen
= TotalLen
- 2;
248 uint8_t *Buffer
= Allocator
.Allocate
<uint8_t>(TotalLen
);
249 ::memcpy(Buffer
, &Prefix
, sizeof(RecordPrefix
));
250 ::memcpy(Buffer
+ sizeof(RecordPrefix
), Data
.data(), Data
.size());
251 return CVSymbol(Kind
, ArrayRef
<uint8_t>(Buffer
, TotalLen
));
254 Error
fromCodeViewSymbol(CVSymbol CVS
) override
{
255 this->Kind
= CVS
.kind();
256 Data
= CVS
.RecordData
.drop_front(sizeof(RecordPrefix
));
257 return Error::success();
260 std::vector
<uint8_t> Data
;
263 template <> void SymbolRecordImpl
<ScopeEndSym
>::map(IO
&IO
) {}
265 void UnknownSymbolRecord::map(yaml::IO
&io
) {
266 yaml::BinaryRef Binary
;
268 Binary
= yaml::BinaryRef(Data
);
269 io
.mapRequired("Data", Binary
);
270 if (!io
.outputting()) {
272 raw_string_ostream
OS(Str
);
273 Binary
.writeAsBinary(OS
);
275 Data
.assign(Str
.begin(), Str
.end());
279 template <> void SymbolRecordImpl
<Thunk32Sym
>::map(IO
&IO
) {
280 IO
.mapRequired("Parent", Symbol
.Parent
);
281 IO
.mapRequired("End", Symbol
.End
);
282 IO
.mapRequired("Next", Symbol
.Next
);
283 IO
.mapRequired("Off", Symbol
.Offset
);
284 IO
.mapRequired("Seg", Symbol
.Segment
);
285 IO
.mapRequired("Len", Symbol
.Length
);
286 IO
.mapRequired("Ordinal", Symbol
.Thunk
);
289 template <> void SymbolRecordImpl
<TrampolineSym
>::map(IO
&IO
) {
290 IO
.mapRequired("Type", Symbol
.Type
);
291 IO
.mapRequired("Size", Symbol
.Size
);
292 IO
.mapRequired("ThunkOff", Symbol
.ThunkOffset
);
293 IO
.mapRequired("TargetOff", Symbol
.TargetOffset
);
294 IO
.mapRequired("ThunkSection", Symbol
.ThunkSection
);
295 IO
.mapRequired("TargetSection", Symbol
.TargetSection
);
298 template <> void SymbolRecordImpl
<SectionSym
>::map(IO
&IO
) {
299 IO
.mapRequired("SectionNumber", Symbol
.SectionNumber
);
300 IO
.mapRequired("Alignment", Symbol
.Alignment
);
301 IO
.mapRequired("Rva", Symbol
.Rva
);
302 IO
.mapRequired("Length", Symbol
.Length
);
303 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
304 IO
.mapRequired("Name", Symbol
.Name
);
307 template <> void SymbolRecordImpl
<CoffGroupSym
>::map(IO
&IO
) {
308 IO
.mapRequired("Size", Symbol
.Size
);
309 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
310 IO
.mapRequired("Offset", Symbol
.Offset
);
311 IO
.mapRequired("Segment", Symbol
.Segment
);
312 IO
.mapRequired("Name", Symbol
.Name
);
315 template <> void SymbolRecordImpl
<ExportSym
>::map(IO
&IO
) {
316 IO
.mapRequired("Ordinal", Symbol
.Ordinal
);
317 IO
.mapRequired("Flags", Symbol
.Flags
);
318 IO
.mapRequired("Name", Symbol
.Name
);
321 template <> void SymbolRecordImpl
<ProcSym
>::map(IO
&IO
) {
322 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
323 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
324 IO
.mapOptional("PtrNext", Symbol
.Next
, 0U);
325 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
326 IO
.mapRequired("DbgStart", Symbol
.DbgStart
);
327 IO
.mapRequired("DbgEnd", Symbol
.DbgEnd
);
328 IO
.mapRequired("FunctionType", Symbol
.FunctionType
);
329 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
330 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
331 IO
.mapRequired("Flags", Symbol
.Flags
);
332 IO
.mapRequired("DisplayName", Symbol
.Name
);
335 template <> void SymbolRecordImpl
<RegisterSym
>::map(IO
&IO
) {
336 IO
.mapRequired("Type", Symbol
.Index
);
337 IO
.mapRequired("Seg", Symbol
.Register
);
338 IO
.mapRequired("Name", Symbol
.Name
);
341 template <> void SymbolRecordImpl
<PublicSym32
>::map(IO
&IO
) {
342 IO
.mapRequired("Flags", Symbol
.Flags
);
343 IO
.mapOptional("Offset", Symbol
.Offset
, 0U);
344 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
345 IO
.mapRequired("Name", Symbol
.Name
);
348 template <> void SymbolRecordImpl
<ProcRefSym
>::map(IO
&IO
) {
349 IO
.mapRequired("SumName", Symbol
.SumName
);
350 IO
.mapRequired("SymOffset", Symbol
.SymOffset
);
351 IO
.mapRequired("Mod", Symbol
.Module
);
352 IO
.mapRequired("Name", Symbol
.Name
);
355 template <> void SymbolRecordImpl
<EnvBlockSym
>::map(IO
&IO
) {
356 IO
.mapRequired("Entries", Symbol
.Fields
);
359 template <> void SymbolRecordImpl
<InlineSiteSym
>::map(IO
&IO
) {
360 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
361 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
362 IO
.mapRequired("Inlinee", Symbol
.Inlinee
);
363 // TODO: The binary annotations
366 template <> void SymbolRecordImpl
<LocalSym
>::map(IO
&IO
) {
367 IO
.mapRequired("Type", Symbol
.Type
);
368 IO
.mapRequired("Flags", Symbol
.Flags
);
370 IO
.mapRequired("VarName", Symbol
.Name
);
373 template <> void SymbolRecordImpl
<DefRangeSym
>::map(IO
&IO
) {
374 IO
.mapRequired("Program", Symbol
.Program
);
375 IO
.mapRequired("Range", Symbol
.Range
);
376 IO
.mapRequired("Gaps", Symbol
.Gaps
);
379 template <> void SymbolRecordImpl
<DefRangeSubfieldSym
>::map(IO
&IO
) {
380 IO
.mapRequired("Program", Symbol
.Program
);
381 IO
.mapRequired("OffsetInParent", Symbol
.OffsetInParent
);
382 IO
.mapRequired("Range", Symbol
.Range
);
383 IO
.mapRequired("Gaps", Symbol
.Gaps
);
386 template <> void SymbolRecordImpl
<DefRangeRegisterSym
>::map(IO
&IO
) {
387 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
388 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
389 IO
.mapRequired("Range", Symbol
.Range
);
390 IO
.mapRequired("Gaps", Symbol
.Gaps
);
393 template <> void SymbolRecordImpl
<DefRangeFramePointerRelSym
>::map(IO
&IO
) {
394 IO
.mapRequired("Offset", Symbol
.Offset
);
395 IO
.mapRequired("Range", Symbol
.Range
);
396 IO
.mapRequired("Gaps", Symbol
.Gaps
);
399 template <> void SymbolRecordImpl
<DefRangeSubfieldRegisterSym
>::map(IO
&IO
) {
400 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
401 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
402 IO
.mapRequired("OffsetInParent", Symbol
.Hdr
.OffsetInParent
);
403 IO
.mapRequired("Range", Symbol
.Range
);
404 IO
.mapRequired("Gaps", Symbol
.Gaps
);
408 void SymbolRecordImpl
<DefRangeFramePointerRelFullScopeSym
>::map(IO
&IO
) {
409 IO
.mapRequired("Register", Symbol
.Offset
);
412 template <> void SymbolRecordImpl
<DefRangeRegisterRelSym
>::map(IO
&IO
) {
413 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
414 IO
.mapRequired("Flags", Symbol
.Hdr
.Flags
);
415 IO
.mapRequired("BasePointerOffset", Symbol
.Hdr
.BasePointerOffset
);
416 IO
.mapRequired("Range", Symbol
.Range
);
417 IO
.mapRequired("Gaps", Symbol
.Gaps
);
420 template <> void SymbolRecordImpl
<BlockSym
>::map(IO
&IO
) {
421 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
422 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
423 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
424 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
425 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
426 IO
.mapRequired("BlockName", Symbol
.Name
);
429 template <> void SymbolRecordImpl
<LabelSym
>::map(IO
&IO
) {
430 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
431 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
432 IO
.mapRequired("Flags", Symbol
.Flags
);
433 IO
.mapRequired("Flags", Symbol
.Flags
);
434 IO
.mapRequired("DisplayName", Symbol
.Name
);
437 template <> void SymbolRecordImpl
<ObjNameSym
>::map(IO
&IO
) {
438 IO
.mapRequired("Signature", Symbol
.Signature
);
439 IO
.mapRequired("ObjectName", Symbol
.Name
);
442 template <> void SymbolRecordImpl
<Compile2Sym
>::map(IO
&IO
) {
443 IO
.mapRequired("Flags", Symbol
.Flags
);
444 IO
.mapRequired("Machine", Symbol
.Machine
);
445 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
446 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
447 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
448 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
449 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
450 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
451 IO
.mapRequired("Version", Symbol
.Version
);
454 template <> void SymbolRecordImpl
<Compile3Sym
>::map(IO
&IO
) {
455 IO
.mapRequired("Flags", Symbol
.Flags
);
456 IO
.mapRequired("Machine", Symbol
.Machine
);
457 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
458 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
459 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
460 IO
.mapRequired("FrontendQFE", Symbol
.VersionFrontendQFE
);
461 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
462 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
463 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
464 IO
.mapRequired("BackendQFE", Symbol
.VersionBackendQFE
);
465 IO
.mapRequired("Version", Symbol
.Version
);
468 template <> void SymbolRecordImpl
<FrameProcSym
>::map(IO
&IO
) {
469 IO
.mapRequired("TotalFrameBytes", Symbol
.TotalFrameBytes
);
470 IO
.mapRequired("PaddingFrameBytes", Symbol
.PaddingFrameBytes
);
471 IO
.mapRequired("OffsetToPadding", Symbol
.OffsetToPadding
);
472 IO
.mapRequired("BytesOfCalleeSavedRegisters",
473 Symbol
.BytesOfCalleeSavedRegisters
);
474 IO
.mapRequired("OffsetOfExceptionHandler", Symbol
.OffsetOfExceptionHandler
);
475 IO
.mapRequired("SectionIdOfExceptionHandler",
476 Symbol
.SectionIdOfExceptionHandler
);
477 IO
.mapRequired("Flags", Symbol
.Flags
);
480 template <> void SymbolRecordImpl
<CallSiteInfoSym
>::map(IO
&IO
) {
481 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
482 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
483 IO
.mapRequired("Type", Symbol
.Type
);
486 template <> void SymbolRecordImpl
<FileStaticSym
>::map(IO
&IO
) {
487 IO
.mapRequired("Index", Symbol
.Index
);
488 IO
.mapRequired("ModFilenameOffset", Symbol
.ModFilenameOffset
);
489 IO
.mapRequired("Flags", Symbol
.Flags
);
490 IO
.mapRequired("Name", Symbol
.Name
);
493 template <> void SymbolRecordImpl
<HeapAllocationSiteSym
>::map(IO
&IO
) {
494 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
495 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
496 IO
.mapRequired("CallInstructionSize", Symbol
.CallInstructionSize
);
497 IO
.mapRequired("Type", Symbol
.Type
);
500 template <> void SymbolRecordImpl
<FrameCookieSym
>::map(IO
&IO
) {
501 IO
.mapRequired("Register", Symbol
.Register
);
502 IO
.mapRequired("CookieKind", Symbol
.CookieKind
);
503 IO
.mapRequired("Flags", Symbol
.Flags
);
506 template <> void SymbolRecordImpl
<CallerSym
>::map(IO
&IO
) {
507 IO
.mapRequired("FuncID", Symbol
.Indices
);
510 template <> void SymbolRecordImpl
<UDTSym
>::map(IO
&IO
) {
511 IO
.mapRequired("Type", Symbol
.Type
);
512 IO
.mapRequired("UDTName", Symbol
.Name
);
515 template <> void SymbolRecordImpl
<BuildInfoSym
>::map(IO
&IO
) {
516 IO
.mapRequired("BuildId", Symbol
.BuildId
);
519 template <> void SymbolRecordImpl
<BPRelativeSym
>::map(IO
&IO
) {
520 IO
.mapRequired("Offset", Symbol
.Offset
);
521 IO
.mapRequired("Type", Symbol
.Type
);
522 IO
.mapRequired("VarName", Symbol
.Name
);
525 template <> void SymbolRecordImpl
<RegRelativeSym
>::map(IO
&IO
) {
526 IO
.mapRequired("Offset", Symbol
.Offset
);
527 IO
.mapRequired("Type", Symbol
.Type
);
528 IO
.mapRequired("Register", Symbol
.Register
);
529 IO
.mapRequired("VarName", Symbol
.Name
);
532 template <> void SymbolRecordImpl
<ConstantSym
>::map(IO
&IO
) {
533 IO
.mapRequired("Type", Symbol
.Type
);
534 IO
.mapRequired("Value", Symbol
.Value
);
535 IO
.mapRequired("Name", Symbol
.Name
);
538 template <> void SymbolRecordImpl
<DataSym
>::map(IO
&IO
) {
539 IO
.mapRequired("Type", Symbol
.Type
);
540 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
541 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
542 IO
.mapRequired("DisplayName", Symbol
.Name
);
545 template <> void SymbolRecordImpl
<ThreadLocalDataSym
>::map(IO
&IO
) {
546 IO
.mapRequired("Type", Symbol
.Type
);
547 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
548 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
549 IO
.mapRequired("DisplayName", Symbol
.Name
);
552 template <> void SymbolRecordImpl
<UsingNamespaceSym
>::map(IO
&IO
) {
553 IO
.mapRequired("Namespace", Symbol
.Name
);
556 } // end namespace detail
557 } // end namespace CodeViewYAML
558 } // end namespace llvm
560 CVSymbol
CodeViewYAML::SymbolRecord::toCodeViewSymbol(
561 BumpPtrAllocator
&Allocator
, CodeViewContainer Container
) const {
562 return Symbol
->toCodeViewSymbol(Allocator
, Container
);
568 template <> struct MappingTraits
<SymbolRecordBase
> {
569 static void mapping(IO
&io
, SymbolRecordBase
&Record
) { Record
.map(io
); }
572 } // end namespace yaml
573 } // end namespace llvm
575 template <typename SymbolType
>
576 static inline Expected
<CodeViewYAML::SymbolRecord
>
577 fromCodeViewSymbolImpl(CVSymbol Symbol
) {
578 CodeViewYAML::SymbolRecord Result
;
580 auto Impl
= std::make_shared
<SymbolType
>(Symbol
.kind());
581 if (auto EC
= Impl
->fromCodeViewSymbol(Symbol
))
582 return std::move(EC
);
583 Result
.Symbol
= Impl
;
587 Expected
<CodeViewYAML::SymbolRecord
>
588 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol
) {
589 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
591 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
592 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
593 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
594 switch (Symbol
.kind()) {
595 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
597 return fromCodeViewSymbolImpl
<UnknownSymbolRecord
>(Symbol
);
599 return make_error
<CodeViewError
>(cv_error_code::corrupt_record
);
602 template <typename ConcreteType
>
603 static void mapSymbolRecordImpl(IO
&IO
, const char *Class
, SymbolKind Kind
,
604 CodeViewYAML::SymbolRecord
&Obj
) {
605 if (!IO
.outputting())
606 Obj
.Symbol
= std::make_shared
<ConcreteType
>(Kind
);
608 IO
.mapRequired(Class
, *Obj
.Symbol
);
611 void MappingTraits
<CodeViewYAML::SymbolRecord
>::mapping(
612 IO
&IO
, CodeViewYAML::SymbolRecord
&Obj
) {
615 Kind
= Obj
.Symbol
->Kind
;
616 IO
.mapRequired("Kind", Kind
);
618 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
620 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
623 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
624 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
626 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
628 mapSymbolRecordImpl
<UnknownSymbolRecord
>(IO
, "UnknownSym", Kind
, Obj
);