Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
35233 views
1
//===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines classes for handling the YAML representation of CodeView
10
// Debug Info.
11
//
12
//===----------------------------------------------------------------------===//
13
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"
30
#include <algorithm>
31
#include <cstdint>
32
#include <cstring>
33
#include <optional>
34
#include <string>
35
#include <vector>
36
37
using namespace llvm;
38
using namespace llvm::codeview;
39
using namespace llvm::CodeViewYAML;
40
using namespace llvm::CodeViewYAML::detail;
41
using namespace llvm::yaml;
42
43
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
44
LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
45
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)
49
50
LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
51
LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
52
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)
65
66
LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
67
68
LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
69
70
StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
71
return ScalarTraits<StringRef>::input(S, V, T.value);
72
}
73
74
void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
75
raw_ostream &R) {
76
ScalarTraits<StringRef>::output(T.value, V, R);
77
}
78
79
void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
80
SymbolKind &Value) {
81
auto SymbolNames = getSymbolTypeNames();
82
for (const auto &E : SymbolNames)
83
io.enumCase(Value, E.Name.str().c_str(), E.Value);
84
}
85
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));
92
}
93
}
94
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));
101
}
102
}
103
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));
109
}
110
}
111
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));
117
}
118
}
119
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));
125
}
126
}
127
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));
133
}
134
}
135
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));
142
}
143
}
144
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));
149
}
150
}
151
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");
155
156
std::optional<CPUType> CpuType;
157
ArrayRef<EnumEntry<uint16_t>> RegNames;
158
159
switch (Header->Machine) {
160
case COFF::IMAGE_FILE_MACHINE_I386:
161
CpuType = CPUType::Pentium3;
162
break;
163
case COFF::IMAGE_FILE_MACHINE_AMD64:
164
CpuType = CPUType::X64;
165
break;
166
case COFF::IMAGE_FILE_MACHINE_ARMNT:
167
CpuType = CPUType::ARMNT;
168
break;
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;
173
break;
174
}
175
176
if (CpuType)
177
RegNames = getRegisterNames(*CpuType);
178
179
for (const auto &E : RegNames) {
180
io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
181
}
182
io.enumFallback<Hex16>(Reg);
183
}
184
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));
191
}
192
}
193
194
void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
195
ThunkOrdinal &Ord) {
196
auto ThunkNames = getThunkOrdinalNames();
197
for (const auto &E : ThunkNames) {
198
io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
199
}
200
}
201
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));
208
}
209
}
210
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));
217
}
218
}
219
220
namespace llvm {
221
namespace yaml {
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);
227
}
228
};
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);
233
}
234
};
235
} // namespace yaml
236
} // namespace llvm
237
238
namespace llvm {
239
namespace CodeViewYAML {
240
namespace detail {
241
242
struct SymbolRecordBase {
243
codeview::SymbolKind Kind;
244
245
explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
246
virtual ~SymbolRecordBase() = default;
247
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;
253
};
254
255
template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
256
explicit SymbolRecordImpl(codeview::SymbolKind K)
257
: SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
258
259
void map(yaml::IO &io) override;
260
261
codeview::CVSymbol
262
toCodeViewSymbol(BumpPtrAllocator &Allocator,
263
CodeViewContainer Container) const override {
264
return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
265
}
266
267
Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
268
return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
269
}
270
271
mutable T Symbol;
272
};
273
274
struct UnknownSymbolRecord : public SymbolRecordBase {
275
explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
276
277
void map(yaml::IO &io) override;
278
279
CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
280
CodeViewContainer Container) const override {
281
RecordPrefix Prefix;
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));
289
}
290
291
Error fromCodeViewSymbol(CVSymbol CVS) override {
292
this->Kind = CVS.kind();
293
Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
294
return Error::success();
295
}
296
297
std::vector<uint8_t> Data;
298
};
299
300
template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
301
302
void UnknownSymbolRecord::map(yaml::IO &io) {
303
yaml::BinaryRef Binary;
304
if (io.outputting())
305
Binary = yaml::BinaryRef(Data);
306
io.mapRequired("Data", Binary);
307
if (!io.outputting()) {
308
std::string Str;
309
raw_string_ostream OS(Str);
310
Binary.writeAsBinary(OS);
311
OS.flush();
312
Data.assign(Str.begin(), Str.end());
313
}
314
}
315
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);
324
}
325
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);
333
}
334
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);
342
}
343
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);
350
}
351
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);
356
}
357
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);
370
}
371
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);
376
}
377
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);
383
}
384
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);
390
}
391
392
template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
393
IO.mapRequired("Entries", Symbol.Fields);
394
}
395
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
401
}
402
403
template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
404
IO.mapRequired("Type", Symbol.Type);
405
IO.mapRequired("Flags", Symbol.Flags);
406
407
IO.mapRequired("VarName", Symbol.Name);
408
}
409
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);
414
}
415
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);
421
}
422
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);
428
}
429
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);
434
}
435
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);
442
}
443
444
template <>
445
void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
446
IO.mapRequired("Register", Symbol.Offset);
447
}
448
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);
455
}
456
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);
464
}
465
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("DisplayName", Symbol.Name);
471
}
472
473
template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
474
IO.mapRequired("Signature", Symbol.Signature);
475
IO.mapRequired("ObjectName", Symbol.Name);
476
}
477
478
template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
479
IO.mapRequired("Flags", Symbol.Flags);
480
IO.mapRequired("Machine", Symbol.Machine);
481
IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
482
IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
483
IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
484
IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
485
IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
486
IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
487
IO.mapRequired("Version", Symbol.Version);
488
}
489
490
template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
491
IO.mapRequired("Flags", Symbol.Flags);
492
IO.mapRequired("Machine", Symbol.Machine);
493
IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
494
IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
495
IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
496
IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
497
IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
498
IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
499
IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
500
IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
501
IO.mapRequired("Version", Symbol.Version);
502
}
503
504
template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
505
IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
506
IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
507
IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
508
IO.mapRequired("BytesOfCalleeSavedRegisters",
509
Symbol.BytesOfCalleeSavedRegisters);
510
IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
511
IO.mapRequired("SectionIdOfExceptionHandler",
512
Symbol.SectionIdOfExceptionHandler);
513
IO.mapRequired("Flags", Symbol.Flags);
514
}
515
516
template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
517
IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
518
IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
519
IO.mapRequired("Type", Symbol.Type);
520
}
521
522
template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
523
IO.mapRequired("Index", Symbol.Index);
524
IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
525
IO.mapRequired("Flags", Symbol.Flags);
526
IO.mapRequired("Name", Symbol.Name);
527
}
528
529
template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
530
IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
531
IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
532
IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
533
IO.mapRequired("Type", Symbol.Type);
534
}
535
536
template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
537
IO.mapRequired("Register", Symbol.Register);
538
IO.mapRequired("CookieKind", Symbol.CookieKind);
539
IO.mapRequired("Flags", Symbol.Flags);
540
}
541
542
template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
543
IO.mapRequired("FuncID", Symbol.Indices);
544
}
545
546
template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
547
IO.mapRequired("Type", Symbol.Type);
548
IO.mapRequired("UDTName", Symbol.Name);
549
}
550
551
template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
552
IO.mapRequired("BuildId", Symbol.BuildId);
553
}
554
555
template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
556
IO.mapRequired("Offset", Symbol.Offset);
557
IO.mapRequired("Type", Symbol.Type);
558
IO.mapRequired("VarName", Symbol.Name);
559
}
560
561
template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
562
IO.mapRequired("Offset", Symbol.Offset);
563
IO.mapRequired("Type", Symbol.Type);
564
IO.mapRequired("Register", Symbol.Register);
565
IO.mapRequired("VarName", Symbol.Name);
566
}
567
568
template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
569
IO.mapRequired("Type", Symbol.Type);
570
IO.mapRequired("Value", Symbol.Value);
571
IO.mapRequired("Name", Symbol.Name);
572
}
573
574
template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
575
IO.mapRequired("Type", Symbol.Type);
576
IO.mapOptional("Offset", Symbol.DataOffset, 0U);
577
IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
578
IO.mapRequired("DisplayName", Symbol.Name);
579
}
580
581
template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
582
IO.mapRequired("Type", Symbol.Type);
583
IO.mapOptional("Offset", Symbol.DataOffset, 0U);
584
IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
585
IO.mapRequired("DisplayName", Symbol.Name);
586
}
587
588
template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
589
IO.mapRequired("Namespace", Symbol.Name);
590
}
591
592
template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
593
IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
594
IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
595
IO.mapRequired("Strings", Symbol.Strings);
596
}
597
598
template <> void SymbolRecordImpl<JumpTableSym>::map(IO &IO) {
599
IO.mapRequired("BaseOffset", Symbol.BaseOffset);
600
IO.mapRequired("BaseSegment", Symbol.BaseSegment);
601
IO.mapRequired("SwitchType", Symbol.SwitchType);
602
IO.mapRequired("BranchOffset", Symbol.BranchOffset);
603
IO.mapRequired("TableOffset", Symbol.TableOffset);
604
IO.mapRequired("BranchSegment", Symbol.BranchSegment);
605
IO.mapRequired("TableSegment", Symbol.TableSegment);
606
IO.mapRequired("EntriesCount", Symbol.EntriesCount);
607
}
608
609
} // end namespace detail
610
} // end namespace CodeViewYAML
611
} // end namespace llvm
612
613
CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
614
BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
615
return Symbol->toCodeViewSymbol(Allocator, Container);
616
}
617
618
namespace llvm {
619
namespace yaml {
620
621
template <> struct MappingTraits<SymbolRecordBase> {
622
static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
623
};
624
625
} // end namespace yaml
626
} // end namespace llvm
627
628
template <typename SymbolType>
629
static inline Expected<CodeViewYAML::SymbolRecord>
630
fromCodeViewSymbolImpl(CVSymbol Symbol) {
631
CodeViewYAML::SymbolRecord Result;
632
633
auto Impl = std::make_shared<SymbolType>(Symbol.kind());
634
if (auto EC = Impl->fromCodeViewSymbol(Symbol))
635
return std::move(EC);
636
Result.Symbol = Impl;
637
return Result;
638
}
639
640
Expected<CodeViewYAML::SymbolRecord>
641
CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
642
#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
643
case EnumName: \
644
return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
645
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
646
SYMBOL_RECORD(EnumName, EnumVal, ClassName)
647
switch (Symbol.kind()) {
648
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
649
default:
650
return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
651
}
652
return make_error<CodeViewError>(cv_error_code::corrupt_record);
653
}
654
655
template <typename ConcreteType>
656
static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
657
CodeViewYAML::SymbolRecord &Obj) {
658
if (!IO.outputting())
659
Obj.Symbol = std::make_shared<ConcreteType>(Kind);
660
661
IO.mapRequired(Class, *Obj.Symbol);
662
}
663
664
void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
665
IO &IO, CodeViewYAML::SymbolRecord &Obj) {
666
SymbolKind Kind;
667
if (IO.outputting())
668
Kind = Obj.Symbol->Kind;
669
IO.mapRequired("Kind", Kind);
670
671
#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
672
case EnumName: \
673
mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
674
Obj); \
675
break;
676
#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
677
SYMBOL_RECORD(EnumName, EnumVal, ClassName)
678
switch (Kind) {
679
#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
680
default:
681
mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
682
}
683
}
684
685