1 //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines classes for handling the YAML representation of CodeView
13 //===----------------------------------------------------------------------===//
15 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/DebugInfo/CodeView/CodeView.h"
19 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
20 #include "llvm/DebugInfo/CodeView/EnumTables.h"
21 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
22 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
23 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
24 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
25 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
26 #include "llvm/ObjectYAML/YAML.h"
27 #include "llvm/Support/Allocator.h"
28 #include "llvm/Support/Error.h"
29 #include "llvm/Support/YAMLTraits.h"
37 using namespace llvm::codeview
;
38 using namespace llvm::CodeViewYAML
;
39 using namespace llvm::CodeViewYAML::detail
;
40 using namespace llvm::yaml
;
42 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex
)
43 LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap
)
45 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
46 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt
, QuotingType::None
)
47 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex
, QuotingType::None
)
49 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind
)
50 LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind
)
52 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags
)
53 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags
)
54 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags
)
55 LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags
)
56 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags
)
57 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags
)
58 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions
)
59 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType
)
60 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId
)
61 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType
)
62 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal
)
64 LLVM_YAML_STRONG_TYPEDEF(StringRef
, TypeName
)
66 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName
, QuotingType::Single
)
68 StringRef ScalarTraits
<TypeName
>::input(StringRef S
, void *V
, TypeName
&T
) {
69 return ScalarTraits
<StringRef
>::input(S
, V
, T
.value
);
72 void ScalarTraits
<TypeName
>::output(const TypeName
&T
, void *V
,
74 ScalarTraits
<StringRef
>::output(T
.value
, V
, R
);
77 void ScalarEnumerationTraits
<SymbolKind
>::enumeration(IO
&io
,
79 auto SymbolNames
= getSymbolTypeNames();
80 for (const auto &E
: SymbolNames
)
81 io
.enumCase(Value
, E
.Name
.str().c_str(), E
.Value
);
84 void ScalarBitSetTraits
<CompileSym2Flags
>::bitset(IO
&io
,
85 CompileSym2Flags
&Flags
) {
86 auto FlagNames
= getCompileSym2FlagNames();
87 for (const auto &E
: FlagNames
) {
88 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
89 static_cast<CompileSym2Flags
>(E
.Value
));
93 void ScalarBitSetTraits
<CompileSym3Flags
>::bitset(IO
&io
,
94 CompileSym3Flags
&Flags
) {
95 auto FlagNames
= getCompileSym3FlagNames();
96 for (const auto &E
: FlagNames
) {
97 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
98 static_cast<CompileSym3Flags
>(E
.Value
));
102 void ScalarBitSetTraits
<ExportFlags
>::bitset(IO
&io
, ExportFlags
&Flags
) {
103 auto FlagNames
= getExportSymFlagNames();
104 for (const auto &E
: FlagNames
) {
105 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
106 static_cast<ExportFlags
>(E
.Value
));
110 void ScalarBitSetTraits
<PublicSymFlags
>::bitset(IO
&io
, PublicSymFlags
&Flags
) {
111 auto FlagNames
= getProcSymFlagNames();
112 for (const auto &E
: FlagNames
) {
113 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
114 static_cast<PublicSymFlags
>(E
.Value
));
118 void ScalarBitSetTraits
<LocalSymFlags
>::bitset(IO
&io
, LocalSymFlags
&Flags
) {
119 auto FlagNames
= getLocalFlagNames();
120 for (const auto &E
: FlagNames
) {
121 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
122 static_cast<LocalSymFlags
>(E
.Value
));
126 void ScalarBitSetTraits
<ProcSymFlags
>::bitset(IO
&io
, ProcSymFlags
&Flags
) {
127 auto FlagNames
= getProcSymFlagNames();
128 for (const auto &E
: FlagNames
) {
129 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
130 static_cast<ProcSymFlags
>(E
.Value
));
134 void ScalarBitSetTraits
<FrameProcedureOptions
>::bitset(
135 IO
&io
, FrameProcedureOptions
&Flags
) {
136 auto FlagNames
= getFrameProcSymFlagNames();
137 for (const auto &E
: FlagNames
) {
138 io
.bitSetCase(Flags
, E
.Name
.str().c_str(),
139 static_cast<FrameProcedureOptions
>(E
.Value
));
143 void ScalarEnumerationTraits
<CPUType
>::enumeration(IO
&io
, CPUType
&Cpu
) {
144 auto CpuNames
= getCPUTypeNames();
145 for (const auto &E
: CpuNames
) {
146 io
.enumCase(Cpu
, E
.Name
.str().c_str(), static_cast<CPUType
>(E
.Value
));
150 void ScalarEnumerationTraits
<RegisterId
>::enumeration(IO
&io
, RegisterId
&Reg
) {
151 auto RegNames
= getRegisterNames();
152 for (const auto &E
: RegNames
) {
153 io
.enumCase(Reg
, E
.Name
.str().c_str(), static_cast<RegisterId
>(E
.Value
));
155 io
.enumFallback
<Hex16
>(Reg
);
158 void ScalarEnumerationTraits
<TrampolineType
>::enumeration(
159 IO
&io
, TrampolineType
&Tramp
) {
160 auto TrampNames
= getTrampolineNames();
161 for (const auto &E
: TrampNames
) {
162 io
.enumCase(Tramp
, E
.Name
.str().c_str(),
163 static_cast<TrampolineType
>(E
.Value
));
167 void ScalarEnumerationTraits
<ThunkOrdinal
>::enumeration(IO
&io
,
169 auto ThunkNames
= getThunkOrdinalNames();
170 for (const auto &E
: ThunkNames
) {
171 io
.enumCase(Ord
, E
.Name
.str().c_str(), static_cast<ThunkOrdinal
>(E
.Value
));
175 void ScalarEnumerationTraits
<FrameCookieKind
>::enumeration(
176 IO
&io
, FrameCookieKind
&FC
) {
177 auto ThunkNames
= getFrameCookieKindNames();
178 for (const auto &E
: ThunkNames
) {
179 io
.enumCase(FC
, E
.Name
.str().c_str(),
180 static_cast<FrameCookieKind
>(E
.Value
));
186 template <> struct MappingTraits
<LocalVariableAddrRange
> {
187 static void mapping(IO
&io
, LocalVariableAddrRange
&Range
) {
188 io
.mapRequired("OffsetStart", Range
.OffsetStart
);
189 io
.mapRequired("ISectStart", Range
.ISectStart
);
190 io
.mapRequired("Range", Range
.Range
);
193 template <> struct MappingTraits
<LocalVariableAddrGap
> {
194 static void mapping(IO
&io
, LocalVariableAddrGap
&Gap
) {
195 io
.mapRequired("GapStartOffset", Gap
.GapStartOffset
);
196 io
.mapRequired("Range", Gap
.Range
);
203 namespace CodeViewYAML
{
206 struct SymbolRecordBase
{
207 codeview::SymbolKind Kind
;
209 explicit SymbolRecordBase(codeview::SymbolKind K
) : Kind(K
) {}
210 virtual ~SymbolRecordBase() = default;
212 virtual void map(yaml::IO
&io
) = 0;
213 virtual codeview::CVSymbol
214 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
215 CodeViewContainer Container
) const = 0;
216 virtual Error
fromCodeViewSymbol(codeview::CVSymbol Type
) = 0;
219 template <typename T
> struct SymbolRecordImpl
: public SymbolRecordBase
{
220 explicit SymbolRecordImpl(codeview::SymbolKind K
)
221 : SymbolRecordBase(K
), Symbol(static_cast<SymbolRecordKind
>(K
)) {}
223 void map(yaml::IO
&io
) override
;
226 toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
227 CodeViewContainer Container
) const override
{
228 return SymbolSerializer::writeOneSymbol(Symbol
, Allocator
, Container
);
231 Error
fromCodeViewSymbol(codeview::CVSymbol CVS
) override
{
232 return SymbolDeserializer::deserializeAs
<T
>(CVS
, Symbol
);
238 struct UnknownSymbolRecord
: public SymbolRecordBase
{
239 explicit UnknownSymbolRecord(codeview::SymbolKind K
) : SymbolRecordBase(K
) {}
241 void map(yaml::IO
&io
) override
;
243 CVSymbol
toCodeViewSymbol(BumpPtrAllocator
&Allocator
,
244 CodeViewContainer Container
) const override
{
246 uint32_t TotalLen
= sizeof(RecordPrefix
) + Data
.size();
247 Prefix
.RecordKind
= Kind
;
248 Prefix
.RecordLen
= TotalLen
- 2;
249 uint8_t *Buffer
= Allocator
.Allocate
<uint8_t>(TotalLen
);
250 ::memcpy(Buffer
, &Prefix
, sizeof(RecordPrefix
));
251 ::memcpy(Buffer
+ sizeof(RecordPrefix
), Data
.data(), Data
.size());
252 return CVSymbol(Kind
, ArrayRef
<uint8_t>(Buffer
, TotalLen
));
255 Error
fromCodeViewSymbol(CVSymbol CVS
) override
{
256 this->Kind
= CVS
.kind();
257 Data
= CVS
.RecordData
.drop_front(sizeof(RecordPrefix
));
258 return Error::success();
261 std::vector
<uint8_t> Data
;
264 template <> void SymbolRecordImpl
<ScopeEndSym
>::map(IO
&IO
) {}
266 void UnknownSymbolRecord::map(yaml::IO
&io
) {
267 yaml::BinaryRef Binary
;
269 Binary
= yaml::BinaryRef(Data
);
270 io
.mapRequired("Data", Binary
);
271 if (!io
.outputting()) {
273 raw_string_ostream
OS(Str
);
274 Binary
.writeAsBinary(OS
);
276 Data
.assign(Str
.begin(), Str
.end());
280 template <> void SymbolRecordImpl
<Thunk32Sym
>::map(IO
&IO
) {
281 IO
.mapRequired("Parent", Symbol
.Parent
);
282 IO
.mapRequired("End", Symbol
.End
);
283 IO
.mapRequired("Next", Symbol
.Next
);
284 IO
.mapRequired("Off", Symbol
.Offset
);
285 IO
.mapRequired("Seg", Symbol
.Segment
);
286 IO
.mapRequired("Len", Symbol
.Length
);
287 IO
.mapRequired("Ordinal", Symbol
.Thunk
);
290 template <> void SymbolRecordImpl
<TrampolineSym
>::map(IO
&IO
) {
291 IO
.mapRequired("Type", Symbol
.Type
);
292 IO
.mapRequired("Size", Symbol
.Size
);
293 IO
.mapRequired("ThunkOff", Symbol
.ThunkOffset
);
294 IO
.mapRequired("TargetOff", Symbol
.TargetOffset
);
295 IO
.mapRequired("ThunkSection", Symbol
.ThunkSection
);
296 IO
.mapRequired("TargetSection", Symbol
.TargetSection
);
299 template <> void SymbolRecordImpl
<SectionSym
>::map(IO
&IO
) {
300 IO
.mapRequired("SectionNumber", Symbol
.SectionNumber
);
301 IO
.mapRequired("Alignment", Symbol
.Alignment
);
302 IO
.mapRequired("Rva", Symbol
.Rva
);
303 IO
.mapRequired("Length", Symbol
.Length
);
304 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
305 IO
.mapRequired("Name", Symbol
.Name
);
308 template <> void SymbolRecordImpl
<CoffGroupSym
>::map(IO
&IO
) {
309 IO
.mapRequired("Size", Symbol
.Size
);
310 IO
.mapRequired("Characteristics", Symbol
.Characteristics
);
311 IO
.mapRequired("Offset", Symbol
.Offset
);
312 IO
.mapRequired("Segment", Symbol
.Segment
);
313 IO
.mapRequired("Name", Symbol
.Name
);
316 template <> void SymbolRecordImpl
<ExportSym
>::map(IO
&IO
) {
317 IO
.mapRequired("Ordinal", Symbol
.Ordinal
);
318 IO
.mapRequired("Flags", Symbol
.Flags
);
319 IO
.mapRequired("Name", Symbol
.Name
);
322 template <> void SymbolRecordImpl
<ProcSym
>::map(IO
&IO
) {
323 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
324 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
325 IO
.mapOptional("PtrNext", Symbol
.Next
, 0U);
326 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
327 IO
.mapRequired("DbgStart", Symbol
.DbgStart
);
328 IO
.mapRequired("DbgEnd", Symbol
.DbgEnd
);
329 IO
.mapRequired("FunctionType", Symbol
.FunctionType
);
330 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
331 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
332 IO
.mapRequired("Flags", Symbol
.Flags
);
333 IO
.mapRequired("DisplayName", Symbol
.Name
);
336 template <> void SymbolRecordImpl
<RegisterSym
>::map(IO
&IO
) {
337 IO
.mapRequired("Type", Symbol
.Index
);
338 IO
.mapRequired("Seg", Symbol
.Register
);
339 IO
.mapRequired("Name", Symbol
.Name
);
342 template <> void SymbolRecordImpl
<PublicSym32
>::map(IO
&IO
) {
343 IO
.mapRequired("Flags", Symbol
.Flags
);
344 IO
.mapOptional("Offset", Symbol
.Offset
, 0U);
345 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
346 IO
.mapRequired("Name", Symbol
.Name
);
349 template <> void SymbolRecordImpl
<ProcRefSym
>::map(IO
&IO
) {
350 IO
.mapRequired("SumName", Symbol
.SumName
);
351 IO
.mapRequired("SymOffset", Symbol
.SymOffset
);
352 IO
.mapRequired("Mod", Symbol
.Module
);
353 IO
.mapRequired("Name", Symbol
.Name
);
356 template <> void SymbolRecordImpl
<EnvBlockSym
>::map(IO
&IO
) {
357 IO
.mapRequired("Entries", Symbol
.Fields
);
360 template <> void SymbolRecordImpl
<InlineSiteSym
>::map(IO
&IO
) {
361 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
362 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
363 IO
.mapRequired("Inlinee", Symbol
.Inlinee
);
364 // TODO: The binary annotations
367 template <> void SymbolRecordImpl
<LocalSym
>::map(IO
&IO
) {
368 IO
.mapRequired("Type", Symbol
.Type
);
369 IO
.mapRequired("Flags", Symbol
.Flags
);
371 IO
.mapRequired("VarName", Symbol
.Name
);
374 template <> void SymbolRecordImpl
<DefRangeSym
>::map(IO
&IO
) {
375 IO
.mapRequired("Program", Symbol
.Program
);
376 IO
.mapRequired("Range", Symbol
.Range
);
377 IO
.mapRequired("Gaps", Symbol
.Gaps
);
380 template <> void SymbolRecordImpl
<DefRangeSubfieldSym
>::map(IO
&IO
) {
381 IO
.mapRequired("Program", Symbol
.Program
);
382 IO
.mapRequired("OffsetInParent", Symbol
.OffsetInParent
);
383 IO
.mapRequired("Range", Symbol
.Range
);
384 IO
.mapRequired("Gaps", Symbol
.Gaps
);
387 template <> void SymbolRecordImpl
<DefRangeRegisterSym
>::map(IO
&IO
) {
388 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
389 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
390 IO
.mapRequired("Range", Symbol
.Range
);
391 IO
.mapRequired("Gaps", Symbol
.Gaps
);
394 template <> void SymbolRecordImpl
<DefRangeFramePointerRelSym
>::map(IO
&IO
) {
395 IO
.mapRequired("Offset", Symbol
.Offset
);
396 IO
.mapRequired("Range", Symbol
.Range
);
397 IO
.mapRequired("Gaps", Symbol
.Gaps
);
400 template <> void SymbolRecordImpl
<DefRangeSubfieldRegisterSym
>::map(IO
&IO
) {
401 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
402 IO
.mapRequired("MayHaveNoName", Symbol
.Hdr
.MayHaveNoName
);
403 IO
.mapRequired("OffsetInParent", Symbol
.Hdr
.OffsetInParent
);
404 IO
.mapRequired("Range", Symbol
.Range
);
405 IO
.mapRequired("Gaps", Symbol
.Gaps
);
409 void SymbolRecordImpl
<DefRangeFramePointerRelFullScopeSym
>::map(IO
&IO
) {
410 IO
.mapRequired("Register", Symbol
.Offset
);
413 template <> void SymbolRecordImpl
<DefRangeRegisterRelSym
>::map(IO
&IO
) {
414 IO
.mapRequired("Register", Symbol
.Hdr
.Register
);
415 IO
.mapRequired("Flags", Symbol
.Hdr
.Flags
);
416 IO
.mapRequired("BasePointerOffset", Symbol
.Hdr
.BasePointerOffset
);
417 IO
.mapRequired("Range", Symbol
.Range
);
418 IO
.mapRequired("Gaps", Symbol
.Gaps
);
421 template <> void SymbolRecordImpl
<BlockSym
>::map(IO
&IO
) {
422 IO
.mapOptional("PtrParent", Symbol
.Parent
, 0U);
423 IO
.mapOptional("PtrEnd", Symbol
.End
, 0U);
424 IO
.mapRequired("CodeSize", Symbol
.CodeSize
);
425 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
426 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
427 IO
.mapRequired("BlockName", Symbol
.Name
);
430 template <> void SymbolRecordImpl
<LabelSym
>::map(IO
&IO
) {
431 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
432 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
433 IO
.mapRequired("Flags", Symbol
.Flags
);
434 IO
.mapRequired("Flags", Symbol
.Flags
);
435 IO
.mapRequired("DisplayName", Symbol
.Name
);
438 template <> void SymbolRecordImpl
<ObjNameSym
>::map(IO
&IO
) {
439 IO
.mapRequired("Signature", Symbol
.Signature
);
440 IO
.mapRequired("ObjectName", Symbol
.Name
);
443 template <> void SymbolRecordImpl
<Compile2Sym
>::map(IO
&IO
) {
444 IO
.mapRequired("Flags", Symbol
.Flags
);
445 IO
.mapRequired("Machine", Symbol
.Machine
);
446 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
447 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
448 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
449 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
450 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
451 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
452 IO
.mapRequired("Version", Symbol
.Version
);
455 template <> void SymbolRecordImpl
<Compile3Sym
>::map(IO
&IO
) {
456 IO
.mapRequired("Flags", Symbol
.Flags
);
457 IO
.mapRequired("Machine", Symbol
.Machine
);
458 IO
.mapRequired("FrontendMajor", Symbol
.VersionFrontendMajor
);
459 IO
.mapRequired("FrontendMinor", Symbol
.VersionFrontendMinor
);
460 IO
.mapRequired("FrontendBuild", Symbol
.VersionFrontendBuild
);
461 IO
.mapRequired("FrontendQFE", Symbol
.VersionFrontendQFE
);
462 IO
.mapRequired("BackendMajor", Symbol
.VersionBackendMajor
);
463 IO
.mapRequired("BackendMinor", Symbol
.VersionBackendMinor
);
464 IO
.mapRequired("BackendBuild", Symbol
.VersionBackendBuild
);
465 IO
.mapRequired("BackendQFE", Symbol
.VersionBackendQFE
);
466 IO
.mapRequired("Version", Symbol
.Version
);
469 template <> void SymbolRecordImpl
<FrameProcSym
>::map(IO
&IO
) {
470 IO
.mapRequired("TotalFrameBytes", Symbol
.TotalFrameBytes
);
471 IO
.mapRequired("PaddingFrameBytes", Symbol
.PaddingFrameBytes
);
472 IO
.mapRequired("OffsetToPadding", Symbol
.OffsetToPadding
);
473 IO
.mapRequired("BytesOfCalleeSavedRegisters",
474 Symbol
.BytesOfCalleeSavedRegisters
);
475 IO
.mapRequired("OffsetOfExceptionHandler", Symbol
.OffsetOfExceptionHandler
);
476 IO
.mapRequired("SectionIdOfExceptionHandler",
477 Symbol
.SectionIdOfExceptionHandler
);
478 IO
.mapRequired("Flags", Symbol
.Flags
);
481 template <> void SymbolRecordImpl
<CallSiteInfoSym
>::map(IO
&IO
) {
482 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
483 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
484 IO
.mapRequired("Type", Symbol
.Type
);
487 template <> void SymbolRecordImpl
<FileStaticSym
>::map(IO
&IO
) {
488 IO
.mapRequired("Index", Symbol
.Index
);
489 IO
.mapRequired("ModFilenameOffset", Symbol
.ModFilenameOffset
);
490 IO
.mapRequired("Flags", Symbol
.Flags
);
491 IO
.mapRequired("Name", Symbol
.Name
);
494 template <> void SymbolRecordImpl
<HeapAllocationSiteSym
>::map(IO
&IO
) {
495 IO
.mapOptional("Offset", Symbol
.CodeOffset
, 0U);
496 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
497 IO
.mapRequired("CallInstructionSize", Symbol
.CallInstructionSize
);
498 IO
.mapRequired("Type", Symbol
.Type
);
501 template <> void SymbolRecordImpl
<FrameCookieSym
>::map(IO
&IO
) {
502 IO
.mapRequired("Register", Symbol
.Register
);
503 IO
.mapRequired("CookieKind", Symbol
.CookieKind
);
504 IO
.mapRequired("Flags", Symbol
.Flags
);
507 template <> void SymbolRecordImpl
<CallerSym
>::map(IO
&IO
) {
508 IO
.mapRequired("FuncID", Symbol
.Indices
);
511 template <> void SymbolRecordImpl
<UDTSym
>::map(IO
&IO
) {
512 IO
.mapRequired("Type", Symbol
.Type
);
513 IO
.mapRequired("UDTName", Symbol
.Name
);
516 template <> void SymbolRecordImpl
<BuildInfoSym
>::map(IO
&IO
) {
517 IO
.mapRequired("BuildId", Symbol
.BuildId
);
520 template <> void SymbolRecordImpl
<BPRelativeSym
>::map(IO
&IO
) {
521 IO
.mapRequired("Offset", Symbol
.Offset
);
522 IO
.mapRequired("Type", Symbol
.Type
);
523 IO
.mapRequired("VarName", Symbol
.Name
);
526 template <> void SymbolRecordImpl
<RegRelativeSym
>::map(IO
&IO
) {
527 IO
.mapRequired("Offset", Symbol
.Offset
);
528 IO
.mapRequired("Type", Symbol
.Type
);
529 IO
.mapRequired("Register", Symbol
.Register
);
530 IO
.mapRequired("VarName", Symbol
.Name
);
533 template <> void SymbolRecordImpl
<ConstantSym
>::map(IO
&IO
) {
534 IO
.mapRequired("Type", Symbol
.Type
);
535 IO
.mapRequired("Value", Symbol
.Value
);
536 IO
.mapRequired("Name", Symbol
.Name
);
539 template <> void SymbolRecordImpl
<DataSym
>::map(IO
&IO
) {
540 IO
.mapRequired("Type", Symbol
.Type
);
541 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
542 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
543 IO
.mapRequired("DisplayName", Symbol
.Name
);
546 template <> void SymbolRecordImpl
<ThreadLocalDataSym
>::map(IO
&IO
) {
547 IO
.mapRequired("Type", Symbol
.Type
);
548 IO
.mapOptional("Offset", Symbol
.DataOffset
, 0U);
549 IO
.mapOptional("Segment", Symbol
.Segment
, uint16_t(0));
550 IO
.mapRequired("DisplayName", Symbol
.Name
);
553 } // end namespace detail
554 } // end namespace CodeViewYAML
555 } // end namespace llvm
557 CVSymbol
CodeViewYAML::SymbolRecord::toCodeViewSymbol(
558 BumpPtrAllocator
&Allocator
, CodeViewContainer Container
) const {
559 return Symbol
->toCodeViewSymbol(Allocator
, Container
);
565 template <> struct MappingTraits
<SymbolRecordBase
> {
566 static void mapping(IO
&io
, SymbolRecordBase
&Record
) { Record
.map(io
); }
569 } // end namespace yaml
570 } // end namespace llvm
572 template <typename SymbolType
>
573 static inline Expected
<CodeViewYAML::SymbolRecord
>
574 fromCodeViewSymbolImpl(CVSymbol Symbol
) {
575 CodeViewYAML::SymbolRecord Result
;
577 auto Impl
= std::make_shared
<SymbolType
>(Symbol
.kind());
578 if (auto EC
= Impl
->fromCodeViewSymbol(Symbol
))
579 return std::move(EC
);
580 Result
.Symbol
= Impl
;
584 Expected
<CodeViewYAML::SymbolRecord
>
585 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol
) {
586 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
588 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
589 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
590 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
591 switch (Symbol
.kind()) {
592 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
594 return fromCodeViewSymbolImpl
<UnknownSymbolRecord
>(Symbol
);
596 return make_error
<CodeViewError
>(cv_error_code::corrupt_record
);
599 template <typename ConcreteType
>
600 static void mapSymbolRecordImpl(IO
&IO
, const char *Class
, SymbolKind Kind
,
601 CodeViewYAML::SymbolRecord
&Obj
) {
602 if (!IO
.outputting())
603 Obj
.Symbol
= std::make_shared
<ConcreteType
>(Kind
);
605 IO
.mapRequired(Class
, *Obj
.Symbol
);
608 void MappingTraits
<CodeViewYAML::SymbolRecord
>::mapping(
609 IO
&IO
, CodeViewYAML::SymbolRecord
&Obj
) {
612 Kind
= Obj
.Symbol
->Kind
;
613 IO
.mapRequired("Kind", Kind
);
615 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
617 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
620 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
621 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
623 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
625 mapSymbolRecordImpl
<UnknownSymbolRecord
>(IO
, "UnknownSym", Kind
, Obj
);