Line data Source code
1 : //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines classes for handling the YAML representation of CodeView
11 : // Debug Info.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
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"
30 : #include <algorithm>
31 : #include <cstdint>
32 : #include <cstring>
33 : #include <string>
34 : #include <vector>
35 :
36 : using namespace llvm;
37 : using namespace llvm::codeview;
38 : using namespace llvm::CodeViewYAML;
39 : using namespace llvm::CodeViewYAML::detail;
40 : using namespace llvm::yaml;
41 :
42 : LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
43 : LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
44 :
45 : // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
46 0 : LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
47 0 : LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
48 :
49 : LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
50 : LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
51 :
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)
63 :
64 : LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
65 :
66 : LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
67 :
68 0 : StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
69 0 : return ScalarTraits<StringRef>::input(S, V, T.value);
70 : }
71 :
72 0 : void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
73 : raw_ostream &R) {
74 0 : ScalarTraits<StringRef>::output(T.value, V, R);
75 0 : }
76 :
77 984 : void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
78 : SymbolKind &Value) {
79 984 : auto SymbolNames = getSymbolTypeNames();
80 193848 : for (const auto &E : SymbolNames)
81 578592 : io.enumCase(Value, E.Name.str().c_str(), E.Value);
82 984 : }
83 :
84 0 : void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
85 : CompileSym2Flags &Flags) {
86 0 : auto FlagNames = getCompileSym2FlagNames();
87 0 : for (const auto &E : FlagNames) {
88 0 : io.bitSetCase(Flags, E.Name.str().c_str(),
89 0 : static_cast<CompileSym2Flags>(E.Value));
90 : }
91 0 : }
92 :
93 64 : void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
94 : CompileSym3Flags &Flags) {
95 64 : auto FlagNames = getCompileSym3FlagNames();
96 832 : for (const auto &E : FlagNames) {
97 1536 : io.bitSetCase(Flags, E.Name.str().c_str(),
98 768 : static_cast<CompileSym3Flags>(E.Value));
99 : }
100 64 : }
101 :
102 0 : void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
103 0 : auto FlagNames = getExportSymFlagNames();
104 0 : for (const auto &E : FlagNames) {
105 0 : io.bitSetCase(Flags, E.Name.str().c_str(),
106 0 : static_cast<ExportFlags>(E.Value));
107 : }
108 0 : }
109 :
110 0 : void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
111 0 : auto FlagNames = getProcSymFlagNames();
112 0 : for (const auto &E : FlagNames) {
113 0 : io.bitSetCase(Flags, E.Name.str().c_str(),
114 0 : static_cast<PublicSymFlags>(E.Value));
115 : }
116 0 : }
117 :
118 32 : void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
119 32 : auto FlagNames = getLocalFlagNames();
120 384 : for (const auto &E : FlagNames) {
121 704 : io.bitSetCase(Flags, E.Name.str().c_str(),
122 352 : static_cast<LocalSymFlags>(E.Value));
123 : }
124 32 : }
125 :
126 80 : void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
127 80 : auto FlagNames = getProcSymFlagNames();
128 720 : for (const auto &E : FlagNames) {
129 1280 : io.bitSetCase(Flags, E.Name.str().c_str(),
130 640 : static_cast<ProcSymFlags>(E.Value));
131 : }
132 80 : }
133 :
134 60 : void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
135 : IO &io, FrameProcedureOptions &Flags) {
136 60 : auto FlagNames = getFrameProcSymFlagNames();
137 1320 : for (const auto &E : FlagNames) {
138 2520 : io.bitSetCase(Flags, E.Name.str().c_str(),
139 1260 : static_cast<FrameProcedureOptions>(E.Value));
140 : }
141 60 : }
142 :
143 64 : void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
144 64 : auto CpuNames = getCPUTypeNames();
145 3840 : for (const auto &E : CpuNames) {
146 11328 : io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
147 : }
148 64 : }
149 :
150 22 : void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
151 22 : auto RegNames = getRegisterNames();
152 6512 : for (const auto &E : RegNames) {
153 19470 : io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
154 : }
155 22 : io.enumFallback<Hex16>(Reg);
156 22 : }
157 :
158 5 : void ScalarEnumerationTraits<TrampolineType>::enumeration(
159 : IO &io, TrampolineType &Tramp) {
160 5 : auto TrampNames = getTrampolineNames();
161 15 : for (const auto &E : TrampNames) {
162 20 : io.enumCase(Tramp, E.Name.str().c_str(),
163 10 : static_cast<TrampolineType>(E.Value));
164 : }
165 5 : }
166 :
167 1 : void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
168 : ThunkOrdinal &Ord) {
169 1 : auto ThunkNames = getThunkOrdinalNames();
170 8 : for (const auto &E : ThunkNames) {
171 21 : io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
172 : }
173 1 : }
174 :
175 0 : void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
176 : IO &io, FrameCookieKind &FC) {
177 0 : auto ThunkNames = getFrameCookieKindNames();
178 0 : for (const auto &E : ThunkNames) {
179 0 : io.enumCase(FC, E.Name.str().c_str(),
180 0 : static_cast<FrameCookieKind>(E.Value));
181 : }
182 0 : }
183 :
184 : namespace llvm {
185 : namespace yaml {
186 : template <> struct MappingTraits<LocalVariableAddrRange> {
187 29 : static void mapping(IO &io, LocalVariableAddrRange &Range) {
188 29 : io.mapRequired("OffsetStart", Range.OffsetStart);
189 29 : io.mapRequired("ISectStart", Range.ISectStart);
190 29 : io.mapRequired("Range", Range.Range);
191 29 : }
192 : };
193 : template <> struct MappingTraits<LocalVariableAddrGap> {
194 1 : static void mapping(IO &io, LocalVariableAddrGap &Gap) {
195 1 : io.mapRequired("GapStartOffset", Gap.GapStartOffset);
196 1 : io.mapRequired("Range", Gap.Range);
197 1 : }
198 : };
199 : } // namespace yaml
200 : } // namespace llvm
201 :
202 : namespace llvm {
203 : namespace CodeViewYAML {
204 : namespace detail {
205 :
206 : struct SymbolRecordBase {
207 : codeview::SymbolKind Kind;
208 :
209 984 : explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
210 0 : virtual ~SymbolRecordBase() = default;
211 :
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;
217 : };
218 :
219 : template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
220 982 : explicit SymbolRecordImpl(codeview::SymbolKind K)
221 982 : : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
222 :
223 : void map(yaml::IO &io) override;
224 :
225 : codeview::CVSymbol
226 434 : toCodeViewSymbol(BumpPtrAllocator &Allocator,
227 : CodeViewContainer Container) const override {
228 434 : return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
229 : }
230 0 :
231 : Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
232 0 : return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
233 : }
234 4 :
235 : mutable T Symbol;
236 4 : };
237 :
238 0 : struct UnknownSymbolRecord : public SymbolRecordBase {
239 : explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
240 0 :
241 : void map(yaml::IO &io) override;
242 40 :
243 : CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
244 40 : CodeViewContainer Container) const override {
245 : RecordPrefix Prefix;
246 0 : uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
247 : Prefix.RecordKind = Kind;
248 0 : Prefix.RecordLen = TotalLen - 2;
249 : uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
250 37 : ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
251 : ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
252 37 : return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
253 : }
254 51 :
255 : Error fromCodeViewSymbol(CVSymbol CVS) override {
256 51 : this->Kind = CVS.kind();
257 : Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
258 0 : return Error::success();
259 : }
260 0 :
261 : std::vector<uint8_t> Data;
262 3 : };
263 :
264 3 : template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
265 :
266 1 : void UnknownSymbolRecord::map(yaml::IO &io) {
267 : yaml::BinaryRef Binary;
268 1 : if (io.outputting())
269 : Binary = yaml::BinaryRef(Data);
270 4 : io.mapRequired("Data", Binary);
271 : if (!io.outputting()) {
272 4 : std::string Str;
273 : raw_string_ostream OS(Str);
274 4 : Binary.writeAsBinary(OS);
275 : OS.flush();
276 4 : Data.assign(Str.begin(), Str.end());
277 : }
278 71 : }
279 :
280 71 : template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
281 : IO.mapRequired("Parent", Symbol.Parent);
282 34 : IO.mapRequired("End", Symbol.End);
283 : IO.mapRequired("Next", Symbol.Next);
284 34 : IO.mapRequired("Off", Symbol.Offset);
285 : IO.mapRequired("Seg", Symbol.Segment);
286 0 : IO.mapRequired("Len", Symbol.Length);
287 : IO.mapRequired("Ordinal", Symbol.Thunk);
288 0 : }
289 :
290 22 : template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
291 : IO.mapRequired("Type", Symbol.Type);
292 22 : IO.mapRequired("Size", Symbol.Size);
293 : IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
294 0 : IO.mapRequired("TargetOff", Symbol.TargetOffset);
295 : IO.mapRequired("ThunkSection", Symbol.ThunkSection);
296 0 : IO.mapRequired("TargetSection", Symbol.TargetSection);
297 : }
298 13 :
299 : template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
300 13 : IO.mapRequired("SectionNumber", Symbol.SectionNumber);
301 : IO.mapRequired("Alignment", Symbol.Alignment);
302 0 : IO.mapRequired("Rva", Symbol.Rva);
303 : IO.mapRequired("Length", Symbol.Length);
304 0 : IO.mapRequired("Characteristics", Symbol.Characteristics);
305 : IO.mapRequired("Name", Symbol.Name);
306 4 : }
307 :
308 4 : template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
309 : IO.mapRequired("Size", Symbol.Size);
310 1 : IO.mapRequired("Characteristics", Symbol.Characteristics);
311 : IO.mapRequired("Offset", Symbol.Offset);
312 1 : IO.mapRequired("Segment", Symbol.Segment);
313 : IO.mapRequired("Name", Symbol.Name);
314 1 : }
315 :
316 1 : template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
317 : IO.mapRequired("Ordinal", Symbol.Ordinal);
318 1 : IO.mapRequired("Flags", Symbol.Flags);
319 : IO.mapRequired("Name", Symbol.Name);
320 1 : }
321 :
322 4 : template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
323 : IO.mapOptional("PtrParent", Symbol.Parent, 0U);
324 4 : IO.mapOptional("PtrEnd", Symbol.End, 0U);
325 : IO.mapOptional("PtrNext", Symbol.Next, 0U);
326 5 : IO.mapRequired("CodeSize", Symbol.CodeSize);
327 : IO.mapRequired("DbgStart", Symbol.DbgStart);
328 5 : IO.mapRequired("DbgEnd", Symbol.DbgEnd);
329 : IO.mapRequired("FunctionType", Symbol.FunctionType);
330 0 : IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
331 : IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
332 0 : IO.mapRequired("Flags", Symbol.Flags);
333 : IO.mapRequired("DisplayName", Symbol.Name);
334 53 : }
335 :
336 53 : template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
337 : IO.mapRequired("Type", Symbol.Index);
338 0 : IO.mapRequired("Seg", Symbol.Register);
339 : IO.mapRequired("Name", Symbol.Name);
340 0 : }
341 :
342 0 : template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
343 : IO.mapRequired("Flags", Symbol.Flags);
344 0 : IO.mapOptional("Offset", Symbol.Offset, 0U);
345 : IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
346 0 : IO.mapRequired("Name", Symbol.Name);
347 : }
348 0 :
349 : template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
350 59 : IO.mapRequired("SumName", Symbol.SumName);
351 : IO.mapRequired("SymOffset", Symbol.SymOffset);
352 59 : IO.mapRequired("Mod", Symbol.Module);
353 : IO.mapRequired("Name", Symbol.Name);
354 1 : }
355 :
356 1 : template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
357 : IO.mapRequired("Entries", Symbol.Fields);
358 8 : }
359 :
360 8 : template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
361 : IO.mapOptional("PtrParent", Symbol.Parent, 0U);
362 0 : IO.mapOptional("PtrEnd", Symbol.End, 0U);
363 : IO.mapRequired("Inlinee", Symbol.Inlinee);
364 0 : // TODO: The binary annotations
365 : }
366 0 :
367 : template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
368 0 : IO.mapRequired("Type", Symbol.Type);
369 : IO.mapRequired("Flags", Symbol.Flags);
370 9 :
371 : IO.mapRequired("VarName", Symbol.Name);
372 9 : }
373 :
374 0 : template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
375 : IO.mapRequired("Program", Symbol.Program);
376 0 : IO.mapRequired("Range", Symbol.Range);
377 : IO.mapRequired("Gaps", Symbol.Gaps);
378 0 : }
379 :
380 0 : template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
381 : IO.mapRequired("Program", Symbol.Program);
382 4 : IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
383 : IO.mapRequired("Range", Symbol.Range);
384 4 : IO.mapRequired("Gaps", Symbol.Gaps);
385 : }
386 :
387 312 : template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
388 312 : IO.mapRequired("Register", Symbol.Hdr.Register);
389 : IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
390 0 : IO.mapRequired("Range", Symbol.Range);
391 0 : IO.mapRequired("Gaps", Symbol.Gaps);
392 : }
393 0 :
394 0 : template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
395 : IO.mapRequired("Offset", Symbol.Offset);
396 7 : IO.mapRequired("Range", Symbol.Range);
397 7 : IO.mapRequired("Gaps", Symbol.Gaps);
398 : }
399 0 :
400 0 : template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
401 : IO.mapRequired("Register", Symbol.Hdr.Register);
402 0 : IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
403 0 : IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
404 : IO.mapRequired("Range", Symbol.Range);
405 0 : IO.mapRequired("Gaps", Symbol.Gaps);
406 0 : }
407 :
408 7 : template <>
409 7 : void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
410 : IO.mapRequired("Register", Symbol.Offset);
411 0 : }
412 0 :
413 : template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
414 6 : IO.mapRequired("Register", Symbol.Hdr.Register);
415 6 : IO.mapRequired("Flags", Symbol.Hdr.Flags);
416 : IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
417 0 : IO.mapRequired("Range", Symbol.Range);
418 0 : IO.mapRequired("Gaps", Symbol.Gaps);
419 : }
420 0 :
421 0 : template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
422 : IO.mapOptional("PtrParent", Symbol.Parent, 0U);
423 0 : IO.mapOptional("PtrEnd", Symbol.End, 0U);
424 0 : IO.mapRequired("CodeSize", Symbol.CodeSize);
425 : IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
426 14 : IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
427 14 : IO.mapRequired("BlockName", Symbol.Name);
428 : }
429 0 :
430 0 : template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
431 : IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
432 20 : IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
433 20 : IO.mapRequired("Flags", Symbol.Flags);
434 : IO.mapRequired("Flags", Symbol.Flags);
435 22 : IO.mapRequired("DisplayName", Symbol.Name);
436 22 : }
437 :
438 4 : template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
439 4 : IO.mapRequired("Signature", Symbol.Signature);
440 : IO.mapRequired("ObjectName", Symbol.Name);
441 0 : }
442 0 :
443 : template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
444 14 : IO.mapRequired("Flags", Symbol.Flags);
445 14 : IO.mapRequired("Machine", Symbol.Machine);
446 : IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
447 0 : IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
448 0 : IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
449 : IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
450 0 : IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
451 0 : IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
452 : IO.mapRequired("Version", Symbol.Version);
453 1 : }
454 1 :
455 : template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
456 4 : IO.mapRequired("Flags", Symbol.Flags);
457 4 : IO.mapRequired("Machine", Symbol.Machine);
458 : IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
459 0 : IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
460 0 : IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
461 : IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
462 0 : IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
463 0 : IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
464 : IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
465 0 : IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
466 0 : IO.mapRequired("Version", Symbol.Version);
467 : }
468 8 :
469 8 : template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
470 : IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
471 165 : IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
472 165 : IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
473 : IO.mapRequired("BytesOfCalleeSavedRegisters",
474 0 : Symbol.BytesOfCalleeSavedRegisters);
475 0 : IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
476 : IO.mapRequired("SectionIdOfExceptionHandler",
477 0 : Symbol.SectionIdOfExceptionHandler);
478 0 : IO.mapRequired("Flags", Symbol.Flags);
479 : }
480 0 :
481 0 : template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
482 : IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
483 0 : IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
484 0 : IO.mapRequired("Type", Symbol.Type);
485 : }
486 8 :
487 8 : template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
488 : IO.mapRequired("Index", Symbol.Index);
489 18 : IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
490 18 : IO.mapRequired("Flags", Symbol.Flags);
491 : IO.mapRequired("Name", Symbol.Name);
492 0 : }
493 0 :
494 : template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
495 14 : IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
496 14 : IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
497 : IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
498 0 : IO.mapRequired("Type", Symbol.Type);
499 0 : }
500 :
501 0 : template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
502 0 : IO.mapRequired("Register", Symbol.Register);
503 : IO.mapRequired("CookieKind", Symbol.CookieKind);
504 0 : IO.mapRequired("Flags", Symbol.Flags);
505 0 : }
506 :
507 : template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
508 : IO.mapRequired("FuncID", Symbol.Indices);
509 : }
510 :
511 : template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
512 4 : IO.mapRequired("Type", Symbol.Type);
513 : IO.mapRequired("UDTName", Symbol.Name);
514 : }
515 :
516 1 : template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
517 : IO.mapRequired("BuildId", Symbol.BuildId);
518 : }
519 1 :
520 1 : template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
521 1 : IO.mapRequired("Offset", Symbol.Offset);
522 1 : IO.mapRequired("Type", Symbol.Type);
523 1 : IO.mapRequired("VarName", Symbol.Name);
524 2 : }
525 2 :
526 : template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
527 : IO.mapRequired("Offset", Symbol.Offset);
528 1 : IO.mapRequired("Type", Symbol.Type);
529 1 : IO.mapRequired("Register", Symbol.Register);
530 1 : IO.mapRequired("VarName", Symbol.Name);
531 1 : }
532 :
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);
537 86 : }
538 :
539 2 : template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
540 2 : IO.mapRequired("Type", Symbol.Type);
541 2 : IO.mapOptional("Offset", Symbol.DataOffset, 0U);
542 1 : IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
543 : IO.mapRequired("DisplayName", Symbol.Name);
544 2 : }
545 :
546 1 : template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
547 1 : IO.mapRequired("Type", Symbol.Type);
548 : IO.mapOptional("Offset", Symbol.DataOffset, 0U);
549 1 : IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
550 : IO.mapRequired("DisplayName", Symbol.Name);
551 2 : }
552 :
553 1 : template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
554 1 : IO.mapRequired("Namespace", Symbol.Name);
555 1 : }
556 1 :
557 1 : } // end namespace detail
558 1 : } // end namespace CodeViewYAML
559 1 : } // end namespace llvm
560 1 :
561 1 : CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
562 : BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
563 5 : return Symbol->toCodeViewSymbol(Allocator, Container);
564 5 : }
565 5 :
566 5 : namespace llvm {
567 5 : namespace yaml {
568 5 :
569 5 : template <> struct MappingTraits<SymbolRecordBase> {
570 5 : static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
571 : };
572 26 :
573 26 : } // end namespace yaml
574 26 : } // end namespace llvm
575 26 :
576 26 : template <typename SymbolType>
577 26 : static inline Expected<CodeViewYAML::SymbolRecord>
578 26 : fromCodeViewSymbolImpl(CVSymbol Symbol) {
579 26 : CodeViewYAML::SymbolRecord Result;
580 :
581 25 : auto Impl = std::make_shared<SymbolType>(Symbol.kind());
582 25 : if (auto EC = Impl->fromCodeViewSymbol(Symbol))
583 25 : return std::move(EC);
584 25 : Result.Symbol = Impl;
585 25 : return Result;
586 25 : }
587 25 :
588 : Expected<CodeViewYAML::SymbolRecord>
589 0 : CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
590 0 : #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
591 0 : case EnumName: \
592 0 : return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
593 0 : #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
594 : SYMBOL_RECORD(EnumName, EnumVal, ClassName)
595 80 : switch (Symbol.kind()) {
596 80 : #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
597 80 : default:
598 80 : return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
599 80 : }
600 80 : return make_error<CodeViewError>(cv_error_code::corrupt_record);
601 80 : }
602 80 :
603 80 : template <typename ConcreteType>
604 80 : static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
605 80 : CodeViewYAML::SymbolRecord &Obj) {
606 80 : if (!IO.outputting())
607 80 : Obj.Symbol = std::make_shared<ConcreteType>(Kind);
608 :
609 0 : IO.mapRequired(Class, *Obj.Symbol);
610 0 : }
611 0 :
612 0 : void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
613 0 : IO &IO, CodeViewYAML::SymbolRecord &Obj) {
614 : SymbolKind Kind;
615 0 : if (IO.outputting())
616 0 : Kind = Obj.Symbol->Kind;
617 0 : IO.mapRequired("Kind", Kind);
618 0 :
619 0 : #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
620 0 : case EnumName: \
621 : mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
622 0 : Obj); \
623 0 : break;
624 0 : #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
625 0 : SYMBOL_RECORD(EnumName, EnumVal, ClassName)
626 0 : switch (Kind) {
627 0 : #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
628 : default:
629 7 : mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
630 7 : }
631 7 : }
|