blob: 199a65a2870e80f008fe8a56d9d0ee1c74f616fc [file] [log] [blame]
Zachary Turner1b88f4f2017-05-31 04:17:13 +00001//===- 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"
Eugene Zelenko28082ab2017-07-01 01:35:55 +000016#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/DebugInfo/CodeView/CodeView.h"
Zachary Turner1b88f4f2017-05-31 04:17:13 +000019#include "llvm/DebugInfo/CodeView/CodeViewError.h"
20#include "llvm/DebugInfo/CodeView/EnumTables.h"
Eugene Zelenko28082ab2017-07-01 01:35:55 +000021#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
Zachary Turner1b88f4f2017-05-31 04:17:13 +000022#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
Eugene Zelenko28082ab2017-07-01 01:35:55 +000023#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
Zachary Turner1b88f4f2017-05-31 04:17:13 +000024#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
Eugene Zelenko28082ab2017-07-01 01:35:55 +000025#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>
Zachary Turner1b88f4f2017-05-31 04:17:13 +000035
36using namespace llvm;
37using namespace llvm::codeview;
38using namespace llvm::CodeViewYAML;
39using namespace llvm::CodeViewYAML::detail;
40using namespace llvm::yaml;
41
Zachary Turner1b88f4f2017-05-31 04:17:13 +000042LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
43
44// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
Francis Visoiu Mistrihb213b272017-12-18 17:38:03 +000045LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
46LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
Zachary Turner1b88f4f2017-05-31 04:17:13 +000047
48LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
Zachary Turner63055452017-06-15 22:24:24 +000049LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
Zachary Turner1b88f4f2017-05-31 04:17:13 +000050
51LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
52LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
53LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
Reid Kleckner18d90e12017-06-19 16:54:51 +000054LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
Zachary Turner1b88f4f2017-05-31 04:17:13 +000055LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
56LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
57LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
58LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
59LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
60LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
61LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
62
Eugene Zelenko28082ab2017-07-01 01:35:55 +000063LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
Zachary Turner349c18f2017-06-05 21:40:33 +000064
Francis Visoiu Mistrihb213b272017-12-18 17:38:03 +000065LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
Zachary Turner349c18f2017-06-05 21:40:33 +000066
67StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
68 return ScalarTraits<StringRef>::input(S, V, T.value);
69}
Eugene Zelenko28082ab2017-07-01 01:35:55 +000070
Zachary Turner349c18f2017-06-05 21:40:33 +000071void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
Eugene Zelenko28082ab2017-07-01 01:35:55 +000072 raw_ostream &R) {
Zachary Turner349c18f2017-06-05 21:40:33 +000073 ScalarTraits<StringRef>::output(T.value, V, R);
74}
75
Zachary Turner1b88f4f2017-05-31 04:17:13 +000076void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
77 SymbolKind &Value) {
78 auto SymbolNames = getSymbolTypeNames();
79 for (const auto &E : SymbolNames)
80 io.enumCase(Value, E.Name.str().c_str(), E.Value);
81}
82
83void 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));
89 }
90}
91
92void 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));
98 }
99}
100
101void 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));
106 }
107}
108
Reid Kleckner18d90e12017-06-19 16:54:51 +0000109void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
110 auto FlagNames = getProcSymFlagNames();
111 for (const auto &E : FlagNames) {
112 io.bitSetCase(Flags, E.Name.str().c_str(),
113 static_cast<PublicSymFlags>(E.Value));
114 }
115}
116
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000117void 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));
122 }
123}
124
125void 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));
130 }
131}
132
133void 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));
139 }
140}
141
142void 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));
146 }
147}
148
149void 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));
153 }
154 io.enumFallback<Hex16>(Reg);
155}
156
157void 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));
163 }
164}
165
166void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
167 ThunkOrdinal &Ord) {
168 auto ThunkNames = getThunkOrdinalNames();
169 for (const auto &E : ThunkNames) {
170 io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
171 }
172}
173
Zachary Turner63055452017-06-15 22:24:24 +0000174void 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));
180 }
181}
182
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000183namespace llvm {
184namespace CodeViewYAML {
185namespace detail {
186
187struct SymbolRecordBase {
188 codeview::SymbolKind Kind;
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000189
Eugene Zelenko28082ab2017-07-01 01:35:55 +0000190 explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
191 virtual ~SymbolRecordBase() = default;
192
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000193 virtual void map(yaml::IO &io) = 0;
194 virtual codeview::CVSymbol
Zachary Turnerebd3ae82017-06-01 21:52:41 +0000195 toCodeViewSymbol(BumpPtrAllocator &Allocator,
196 CodeViewContainer Container) const = 0;
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000197 virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
198};
199
200template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
201 explicit SymbolRecordImpl(codeview::SymbolKind K)
202 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
203
204 void map(yaml::IO &io) override;
205
206 codeview::CVSymbol
Zachary Turnerebd3ae82017-06-01 21:52:41 +0000207 toCodeViewSymbol(BumpPtrAllocator &Allocator,
208 CodeViewContainer Container) const override {
209 return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000210 }
Eugene Zelenko28082ab2017-07-01 01:35:55 +0000211
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000212 Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
213 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
214 }
215
216 mutable T Symbol;
217};
218
Zachary Turner606d7662017-06-12 23:10:31 +0000219struct UnknownSymbolRecord : public SymbolRecordBase {
220 explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
221
222 void map(yaml::IO &io) override;
223
224 CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
225 CodeViewContainer Container) const override {
226 RecordPrefix Prefix;
227 uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
228 Prefix.RecordKind = Kind;
229 Prefix.RecordLen = TotalLen - 2;
230 uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
231 ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
232 ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
233 return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen));
234 }
Eugene Zelenko28082ab2017-07-01 01:35:55 +0000235
Zachary Turner606d7662017-06-12 23:10:31 +0000236 Error fromCodeViewSymbol(CVSymbol CVS) override {
237 this->Kind = CVS.kind();
238 Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
239 return Error::success();
240 }
241
242 std::vector<uint8_t> Data;
243};
244
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000245template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
246
Zachary Turner606d7662017-06-12 23:10:31 +0000247void UnknownSymbolRecord::map(yaml::IO &io) {
248 yaml::BinaryRef Binary;
249 if (io.outputting())
250 Binary = yaml::BinaryRef(Data);
251 io.mapRequired("Data", Binary);
252 if (!io.outputting()) {
253 std::string Str;
254 raw_string_ostream OS(Str);
255 Binary.writeAsBinary(OS);
256 OS.flush();
257 Data.assign(Str.begin(), Str.end());
258 }
259}
260
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000261template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
262 IO.mapRequired("Parent", Symbol.Parent);
263 IO.mapRequired("End", Symbol.End);
264 IO.mapRequired("Next", Symbol.Next);
265 IO.mapRequired("Off", Symbol.Offset);
266 IO.mapRequired("Seg", Symbol.Segment);
267 IO.mapRequired("Len", Symbol.Length);
268 IO.mapRequired("Ordinal", Symbol.Thunk);
269}
270
271template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
272 IO.mapRequired("Type", Symbol.Type);
273 IO.mapRequired("Size", Symbol.Size);
274 IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
275 IO.mapRequired("TargetOff", Symbol.TargetOffset);
276 IO.mapRequired("ThunkSection", Symbol.ThunkSection);
277 IO.mapRequired("TargetSection", Symbol.TargetSection);
278}
279
280template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
281 IO.mapRequired("SectionNumber", Symbol.SectionNumber);
282 IO.mapRequired("Alignment", Symbol.Alignment);
283 IO.mapRequired("Rva", Symbol.Rva);
284 IO.mapRequired("Length", Symbol.Length);
285 IO.mapRequired("Characteristics", Symbol.Characteristics);
286 IO.mapRequired("Name", Symbol.Name);
287}
288
289template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
290 IO.mapRequired("Size", Symbol.Size);
291 IO.mapRequired("Characteristics", Symbol.Characteristics);
292 IO.mapRequired("Offset", Symbol.Offset);
293 IO.mapRequired("Segment", Symbol.Segment);
294 IO.mapRequired("Name", Symbol.Name);
295}
296
297template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
298 IO.mapRequired("Ordinal", Symbol.Ordinal);
299 IO.mapRequired("Flags", Symbol.Flags);
300 IO.mapRequired("Name", Symbol.Name);
301}
302
303template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000304 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
305 IO.mapOptional("PtrEnd", Symbol.End, 0U);
306 IO.mapOptional("PtrNext", Symbol.Next, 0U);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000307 IO.mapRequired("CodeSize", Symbol.CodeSize);
308 IO.mapRequired("DbgStart", Symbol.DbgStart);
309 IO.mapRequired("DbgEnd", Symbol.DbgEnd);
310 IO.mapRequired("FunctionType", Symbol.FunctionType);
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000311 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
312 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000313 IO.mapRequired("Flags", Symbol.Flags);
314 IO.mapRequired("DisplayName", Symbol.Name);
315}
316
317template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
318 IO.mapRequired("Type", Symbol.Index);
319 IO.mapRequired("Seg", Symbol.Register);
320 IO.mapRequired("Name", Symbol.Name);
321}
322
323template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
Reid Kleckner18d90e12017-06-19 16:54:51 +0000324 IO.mapRequired("Flags", Symbol.Flags);
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000325 IO.mapOptional("Offset", Symbol.Offset, 0U);
326 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000327 IO.mapRequired("Name", Symbol.Name);
328}
329
330template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
331 IO.mapRequired("SumName", Symbol.SumName);
332 IO.mapRequired("SymOffset", Symbol.SymOffset);
333 IO.mapRequired("Mod", Symbol.Module);
334 IO.mapRequired("Name", Symbol.Name);
335}
336
337template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
338 IO.mapRequired("Entries", Symbol.Fields);
339}
340
341template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000342 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
343 IO.mapOptional("PtrEnd", Symbol.End, 0U);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000344 IO.mapRequired("Inlinee", Symbol.Inlinee);
345 // TODO: The binary annotations
346}
347
348template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
349 IO.mapRequired("Type", Symbol.Type);
350 IO.mapRequired("Flags", Symbol.Flags);
Zachary Turner349c18f2017-06-05 21:40:33 +0000351
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000352 IO.mapRequired("VarName", Symbol.Name);
353}
354
355template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
356 // TODO: Print the subfields
357}
358
359template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
360 // TODO: Print the subfields
361}
362
363template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
364 // TODO: Print the subfields
365}
366
367template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
368 // TODO: Print the subfields
369}
370
371template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
372 // TODO: Print the subfields
373}
374
375template <>
376void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
377 // TODO: Print the subfields
378}
379
380template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
381 // TODO: Print the subfields
382}
383
384template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000385 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
386 IO.mapOptional("PtrEnd", Symbol.End, 0U);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000387 IO.mapRequired("CodeSize", Symbol.CodeSize);
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000388 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
389 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000390 IO.mapRequired("BlockName", Symbol.Name);
391}
392
393template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000394 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
395 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000396 IO.mapRequired("Flags", Symbol.Flags);
397 IO.mapRequired("Flags", Symbol.Flags);
398 IO.mapRequired("DisplayName", Symbol.Name);
399}
400
401template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
402 IO.mapRequired("Signature", Symbol.Signature);
403 IO.mapRequired("ObjectName", Symbol.Name);
404}
405
406template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
407 IO.mapRequired("Flags", Symbol.Flags);
408 IO.mapRequired("Machine", Symbol.Machine);
409 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
410 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
411 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
412 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
413 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
414 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
415 IO.mapRequired("Version", Symbol.Version);
416}
417
418template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
419 IO.mapRequired("Flags", Symbol.Flags);
420 IO.mapRequired("Machine", Symbol.Machine);
421 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
422 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
423 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
424 IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
425 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
426 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
427 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
428 IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
429 IO.mapRequired("Version", Symbol.Version);
430}
431
432template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
433 IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
434 IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
435 IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
436 IO.mapRequired("BytesOfCalleeSavedRegisters",
437 Symbol.BytesOfCalleeSavedRegisters);
438 IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
439 IO.mapRequired("SectionIdOfExceptionHandler",
440 Symbol.SectionIdOfExceptionHandler);
441 IO.mapRequired("Flags", Symbol.Flags);
442}
443
444template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000445 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
446 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000447 IO.mapRequired("Type", Symbol.Type);
448}
449
450template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
451 IO.mapRequired("Index", Symbol.Index);
452 IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
453 IO.mapRequired("Flags", Symbol.Flags);
454 IO.mapRequired("Name", Symbol.Name);
455}
456
457template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000458 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
459 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000460 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
461 IO.mapRequired("Type", Symbol.Type);
462}
463
464template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000465 IO.mapRequired("Register", Symbol.Register);
466 IO.mapRequired("CookieKind", Symbol.CookieKind);
467 IO.mapRequired("Flags", Symbol.Flags);
468}
469
470template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
471 IO.mapRequired("FuncID", Symbol.Indices);
472}
473
474template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
475 IO.mapRequired("Type", Symbol.Type);
476 IO.mapRequired("UDTName", Symbol.Name);
477}
478
479template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
480 IO.mapRequired("BuildId", Symbol.BuildId);
481}
482
483template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
484 IO.mapRequired("Offset", Symbol.Offset);
485 IO.mapRequired("Type", Symbol.Type);
486 IO.mapRequired("VarName", Symbol.Name);
487}
488
489template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
490 IO.mapRequired("Offset", Symbol.Offset);
491 IO.mapRequired("Type", Symbol.Type);
492 IO.mapRequired("Register", Symbol.Register);
493 IO.mapRequired("VarName", Symbol.Name);
494}
495
496template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
497 IO.mapRequired("Type", Symbol.Type);
498 IO.mapRequired("Value", Symbol.Value);
499 IO.mapRequired("Name", Symbol.Name);
500}
501
502template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000503 IO.mapRequired("Type", Symbol.Type);
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000504 IO.mapOptional("Offset", Symbol.DataOffset, 0U);
Reid Kleckner665e1c92017-06-20 20:34:37 +0000505 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000506 IO.mapRequired("DisplayName", Symbol.Name);
507}
508
509template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000510 IO.mapRequired("Type", Symbol.Type);
Reid Kleckner91ef9de2017-06-20 21:19:22 +0000511 IO.mapOptional("Offset", Symbol.DataOffset, 0U);
512 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000513 IO.mapRequired("DisplayName", Symbol.Name);
514}
Eugene Zelenko28082ab2017-07-01 01:35:55 +0000515
516} // end namespace detail
517} // end namespace CodeViewYAML
518} // end namespace llvm
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000519
520CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
Zachary Turnerebd3ae82017-06-01 21:52:41 +0000521 BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
522 return Symbol->toCodeViewSymbol(Allocator, Container);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000523}
524
525namespace llvm {
526namespace yaml {
Eugene Zelenko28082ab2017-07-01 01:35:55 +0000527
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000528template <> struct MappingTraits<SymbolRecordBase> {
529 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
530};
Eugene Zelenko28082ab2017-07-01 01:35:55 +0000531
532} // end namespace yaml
533} // end namespace llvm
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000534
535template <typename SymbolType>
536static inline Expected<CodeViewYAML::SymbolRecord>
537fromCodeViewSymbolImpl(CVSymbol Symbol) {
538 CodeViewYAML::SymbolRecord Result;
539
Zachary Turner606d7662017-06-12 23:10:31 +0000540 auto Impl = std::make_shared<SymbolType>(Symbol.kind());
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000541 if (auto EC = Impl->fromCodeViewSymbol(Symbol))
542 return std::move(EC);
543 Result.Symbol = Impl;
544 return Result;
545}
546
547Expected<CodeViewYAML::SymbolRecord>
548CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
549#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
550 case EnumName: \
Zachary Turner606d7662017-06-12 23:10:31 +0000551 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000552#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
553 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
554 switch (Symbol.kind()) {
555#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
Zachary Turner606d7662017-06-12 23:10:31 +0000556 default:
557 return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000558 }
559 return make_error<CodeViewError>(cv_error_code::corrupt_record);
560}
561
562template <typename ConcreteType>
563static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
564 CodeViewYAML::SymbolRecord &Obj) {
565 if (!IO.outputting())
Zachary Turner606d7662017-06-12 23:10:31 +0000566 Obj.Symbol = std::make_shared<ConcreteType>(Kind);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000567
568 IO.mapRequired(Class, *Obj.Symbol);
569}
570
571void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
572 IO &IO, CodeViewYAML::SymbolRecord &Obj) {
573 SymbolKind Kind;
574 if (IO.outputting())
575 Kind = Obj.Symbol->Kind;
576 IO.mapRequired("Kind", Kind);
577
578#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
579 case EnumName: \
Zachary Turner606d7662017-06-12 23:10:31 +0000580 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
581 Obj); \
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000582 break;
583#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
584 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
585 switch (Kind) {
586#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
Zachary Turner606d7662017-06-12 23:10:31 +0000587 default:
588 mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
Zachary Turner1b88f4f2017-05-31 04:17:13 +0000589 }
590}