blob: 713e9a710e945a88fc14a73e3f04530bdf10574b [file] [log] [blame]
Zachary Turner7b436b02017-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 Zelenkocd903442017-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 Turner7b436b02017-05-31 04:17:13 +000019#include "llvm/DebugInfo/CodeView/CodeViewError.h"
20#include "llvm/DebugInfo/CodeView/EnumTables.h"
Eugene Zelenkocd903442017-07-01 01:35:55 +000021#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
Zachary Turner7b436b02017-05-31 04:17:13 +000022#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
Eugene Zelenkocd903442017-07-01 01:35:55 +000023#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
Zachary Turner7b436b02017-05-31 04:17:13 +000024#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
Eugene Zelenkocd903442017-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 Turner7b436b02017-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 Turner7b436b02017-05-31 04:17:13 +000042LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
Zachary Turner3693c1f2018-01-08 21:38:50 +000043LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
Zachary Turner7b436b02017-05-31 04:17:13 +000044
45// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
Francis Visoiu Mistrih65ad22d2017-12-18 17:38:03 +000046LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
47LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
Zachary Turner7b436b02017-05-31 04:17:13 +000048
49LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
Zachary Turner7e5d31e2017-06-15 22:24:24 +000050LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
Zachary Turner7b436b02017-05-31 04:17:13 +000051
52LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
53LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
54LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
Reid Klecknere075b102017-06-19 16:54:51 +000055LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
Zachary Turner7b436b02017-05-31 04:17:13 +000056LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
57LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
58LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
59LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
60LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
61LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
62LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
63
Eugene Zelenkocd903442017-07-01 01:35:55 +000064LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
Zachary Turner11d16782017-06-05 21:40:33 +000065
Francis Visoiu Mistrih65ad22d2017-12-18 17:38:03 +000066LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
Zachary Turner11d16782017-06-05 21:40:33 +000067
68StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
69 return ScalarTraits<StringRef>::input(S, V, T.value);
70}
Eugene Zelenkocd903442017-07-01 01:35:55 +000071
Zachary Turner11d16782017-06-05 21:40:33 +000072void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
Eugene Zelenkocd903442017-07-01 01:35:55 +000073 raw_ostream &R) {
Zachary Turner11d16782017-06-05 21:40:33 +000074 ScalarTraits<StringRef>::output(T.value, V, R);
75}
76
Zachary Turner7b436b02017-05-31 04:17:13 +000077void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
78 SymbolKind &Value) {
79 auto SymbolNames = getSymbolTypeNames();
80 for (const auto &E : SymbolNames)
81 io.enumCase(Value, E.Name.str().c_str(), E.Value);
82}
83
84void 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));
90 }
91}
92
93void 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));
99 }
100}
101
102void 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));
107 }
108}
109
Reid Klecknere075b102017-06-19 16:54:51 +0000110void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
Zachary Turnere446f792018-10-30 18:25:38 +0000111 auto FlagNames = getPublicSymFlagNames();
Reid Klecknere075b102017-06-19 16:54:51 +0000112 for (const auto &E : FlagNames) {
113 io.bitSetCase(Flags, E.Name.str().c_str(),
114 static_cast<PublicSymFlags>(E.Value));
115 }
116}
117
Zachary Turner7b436b02017-05-31 04:17:13 +0000118void 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));
123 }
124}
125
126void 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));
131 }
132}
133
134void 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));
140 }
141}
142
143void 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));
147 }
148}
149
150void 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));
154 }
155 io.enumFallback<Hex16>(Reg);
156}
157
158void 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));
164 }
165}
166
167void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
168 ThunkOrdinal &Ord) {
169 auto ThunkNames = getThunkOrdinalNames();
170 for (const auto &E : ThunkNames) {
171 io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
172 }
173}
174
Zachary Turner7e5d31e2017-06-15 22:24:24 +0000175void 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));
181 }
182}
183
Zachary Turner7b436b02017-05-31 04:17:13 +0000184namespace llvm {
Zachary Turner3693c1f2018-01-08 21:38:50 +0000185namespace yaml {
186template <> 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);
191 }
192};
193template <> struct MappingTraits<LocalVariableAddrGap> {
194 static void mapping(IO &io, LocalVariableAddrGap &Gap) {
195 io.mapRequired("GapStartOffset", Gap.GapStartOffset);
196 io.mapRequired("Range", Gap.Range);
197 }
198};
199} // namespace yaml
200} // namespace llvm
201
202namespace llvm {
Zachary Turner7b436b02017-05-31 04:17:13 +0000203namespace CodeViewYAML {
204namespace detail {
205
206struct SymbolRecordBase {
207 codeview::SymbolKind Kind;
Zachary Turner7b436b02017-05-31 04:17:13 +0000208
Eugene Zelenkocd903442017-07-01 01:35:55 +0000209 explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
210 virtual ~SymbolRecordBase() = default;
211
Zachary Turner7b436b02017-05-31 04:17:13 +0000212 virtual void map(yaml::IO &io) = 0;
213 virtual codeview::CVSymbol
Zachary Turner6a330c62017-06-01 21:52:41 +0000214 toCodeViewSymbol(BumpPtrAllocator &Allocator,
215 CodeViewContainer Container) const = 0;
Zachary Turner7b436b02017-05-31 04:17:13 +0000216 virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
217};
218
219template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
220 explicit SymbolRecordImpl(codeview::SymbolKind K)
221 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
222
223 void map(yaml::IO &io) override;
224
225 codeview::CVSymbol
Zachary Turner6a330c62017-06-01 21:52:41 +0000226 toCodeViewSymbol(BumpPtrAllocator &Allocator,
227 CodeViewContainer Container) const override {
228 return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
Zachary Turner7b436b02017-05-31 04:17:13 +0000229 }
Eugene Zelenkocd903442017-07-01 01:35:55 +0000230
Zachary Turner7b436b02017-05-31 04:17:13 +0000231 Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
232 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
233 }
234
235 mutable T Symbol;
236};
237
Zachary Turnerab447682017-06-12 23:10:31 +0000238struct UnknownSymbolRecord : public SymbolRecordBase {
239 explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {}
240
241 void map(yaml::IO &io) override;
242
243 CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator,
244 CodeViewContainer Container) const override {
245 RecordPrefix Prefix;
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));
253 }
Eugene Zelenkocd903442017-07-01 01:35:55 +0000254
Zachary Turnerab447682017-06-12 23:10:31 +0000255 Error fromCodeViewSymbol(CVSymbol CVS) override {
256 this->Kind = CVS.kind();
257 Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
258 return Error::success();
259 }
260
261 std::vector<uint8_t> Data;
262};
263
Zachary Turner7b436b02017-05-31 04:17:13 +0000264template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
265
Zachary Turnerab447682017-06-12 23:10:31 +0000266void UnknownSymbolRecord::map(yaml::IO &io) {
267 yaml::BinaryRef Binary;
268 if (io.outputting())
269 Binary = yaml::BinaryRef(Data);
270 io.mapRequired("Data", Binary);
271 if (!io.outputting()) {
272 std::string Str;
273 raw_string_ostream OS(Str);
274 Binary.writeAsBinary(OS);
275 OS.flush();
276 Data.assign(Str.begin(), Str.end());
277 }
278}
279
Zachary Turner7b436b02017-05-31 04:17:13 +0000280template <> 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);
288}
289
290template <> 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);
297}
298
299template <> 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);
306}
307
308template <> 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);
314}
315
316template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
317 IO.mapRequired("Ordinal", Symbol.Ordinal);
318 IO.mapRequired("Flags", Symbol.Flags);
319 IO.mapRequired("Name", Symbol.Name);
320}
321
322template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000323 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
324 IO.mapOptional("PtrEnd", Symbol.End, 0U);
325 IO.mapOptional("PtrNext", Symbol.Next, 0U);
Zachary Turner7b436b02017-05-31 04:17:13 +0000326 IO.mapRequired("CodeSize", Symbol.CodeSize);
327 IO.mapRequired("DbgStart", Symbol.DbgStart);
328 IO.mapRequired("DbgEnd", Symbol.DbgEnd);
329 IO.mapRequired("FunctionType", Symbol.FunctionType);
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000330 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
331 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner7b436b02017-05-31 04:17:13 +0000332 IO.mapRequired("Flags", Symbol.Flags);
333 IO.mapRequired("DisplayName", Symbol.Name);
334}
335
336template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
337 IO.mapRequired("Type", Symbol.Index);
338 IO.mapRequired("Seg", Symbol.Register);
339 IO.mapRequired("Name", Symbol.Name);
340}
341
342template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
Reid Klecknere075b102017-06-19 16:54:51 +0000343 IO.mapRequired("Flags", Symbol.Flags);
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000344 IO.mapOptional("Offset", Symbol.Offset, 0U);
345 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner7b436b02017-05-31 04:17:13 +0000346 IO.mapRequired("Name", Symbol.Name);
347}
348
349template <> 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);
354}
355
356template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
357 IO.mapRequired("Entries", Symbol.Fields);
358}
359
360template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000361 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
362 IO.mapOptional("PtrEnd", Symbol.End, 0U);
Zachary Turner7b436b02017-05-31 04:17:13 +0000363 IO.mapRequired("Inlinee", Symbol.Inlinee);
364 // TODO: The binary annotations
365}
366
367template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
368 IO.mapRequired("Type", Symbol.Type);
369 IO.mapRequired("Flags", Symbol.Flags);
Zachary Turner11d16782017-06-05 21:40:33 +0000370
Zachary Turner7b436b02017-05-31 04:17:13 +0000371 IO.mapRequired("VarName", Symbol.Name);
372}
373
374template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
Zachary Turner3693c1f2018-01-08 21:38:50 +0000375 IO.mapRequired("Program", Symbol.Program);
376 IO.mapRequired("Range", Symbol.Range);
377 IO.mapRequired("Gaps", Symbol.Gaps);
Zachary Turner7b436b02017-05-31 04:17:13 +0000378}
379
380template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
Zachary Turner3693c1f2018-01-08 21:38:50 +0000381 IO.mapRequired("Program", Symbol.Program);
382 IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
383 IO.mapRequired("Range", Symbol.Range);
384 IO.mapRequired("Gaps", Symbol.Gaps);
Zachary Turner7b436b02017-05-31 04:17:13 +0000385}
386
387template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
Zachary Turner3693c1f2018-01-08 21:38:50 +0000388 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);
Zachary Turner7b436b02017-05-31 04:17:13 +0000392}
393
394template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
Zachary Turner3693c1f2018-01-08 21:38:50 +0000395 IO.mapRequired("Offset", Symbol.Offset);
396 IO.mapRequired("Range", Symbol.Range);
397 IO.mapRequired("Gaps", Symbol.Gaps);
Zachary Turner7b436b02017-05-31 04:17:13 +0000398}
399
400template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
Zachary Turner3693c1f2018-01-08 21:38:50 +0000401 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);
Zachary Turner7b436b02017-05-31 04:17:13 +0000406}
407
408template <>
409void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
Zachary Turner3693c1f2018-01-08 21:38:50 +0000410 IO.mapRequired("Register", Symbol.Offset);
Zachary Turner7b436b02017-05-31 04:17:13 +0000411}
412
413template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
Zachary Turner3693c1f2018-01-08 21:38:50 +0000414 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);
Zachary Turner7b436b02017-05-31 04:17:13 +0000419}
420
421template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000422 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
423 IO.mapOptional("PtrEnd", Symbol.End, 0U);
Zachary Turner7b436b02017-05-31 04:17:13 +0000424 IO.mapRequired("CodeSize", Symbol.CodeSize);
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000425 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
426 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner7b436b02017-05-31 04:17:13 +0000427 IO.mapRequired("BlockName", Symbol.Name);
428}
429
430template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000431 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
432 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner7b436b02017-05-31 04:17:13 +0000433 IO.mapRequired("Flags", Symbol.Flags);
434 IO.mapRequired("Flags", Symbol.Flags);
435 IO.mapRequired("DisplayName", Symbol.Name);
436}
437
438template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
439 IO.mapRequired("Signature", Symbol.Signature);
440 IO.mapRequired("ObjectName", Symbol.Name);
441}
442
443template <> 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);
453}
454
455template <> 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);
467}
468
469template <> 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);
479}
480
481template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000482 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
483 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner7b436b02017-05-31 04:17:13 +0000484 IO.mapRequired("Type", Symbol.Type);
485}
486
487template <> 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);
492}
493
494template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000495 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
496 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner7b436b02017-05-31 04:17:13 +0000497 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
498 IO.mapRequired("Type", Symbol.Type);
499}
500
501template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
Zachary Turner7b436b02017-05-31 04:17:13 +0000502 IO.mapRequired("Register", Symbol.Register);
503 IO.mapRequired("CookieKind", Symbol.CookieKind);
504 IO.mapRequired("Flags", Symbol.Flags);
505}
506
507template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
508 IO.mapRequired("FuncID", Symbol.Indices);
509}
510
511template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
512 IO.mapRequired("Type", Symbol.Type);
513 IO.mapRequired("UDTName", Symbol.Name);
514}
515
516template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
517 IO.mapRequired("BuildId", Symbol.BuildId);
518}
519
520template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
521 IO.mapRequired("Offset", Symbol.Offset);
522 IO.mapRequired("Type", Symbol.Type);
523 IO.mapRequired("VarName", Symbol.Name);
524}
525
526template <> 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);
531}
532
533template <> 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}
538
539template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
Zachary Turner7b436b02017-05-31 04:17:13 +0000540 IO.mapRequired("Type", Symbol.Type);
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000541 IO.mapOptional("Offset", Symbol.DataOffset, 0U);
Reid Klecknerd3be3772017-06-20 20:34:37 +0000542 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner7b436b02017-05-31 04:17:13 +0000543 IO.mapRequired("DisplayName", Symbol.Name);
544}
545
546template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
Zachary Turner7b436b02017-05-31 04:17:13 +0000547 IO.mapRequired("Type", Symbol.Type);
Reid Kleckner09ff5f22017-06-20 21:19:22 +0000548 IO.mapOptional("Offset", Symbol.DataOffset, 0U);
549 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
Zachary Turner7b436b02017-05-31 04:17:13 +0000550 IO.mapRequired("DisplayName", Symbol.Name);
551}
Eugene Zelenkocd903442017-07-01 01:35:55 +0000552
Alexandre Ganeaa7336f22018-07-31 19:15:50 +0000553template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) {
554 IO.mapRequired("Namespace", Symbol.Name);
555}
556
Eugene Zelenkocd903442017-07-01 01:35:55 +0000557} // end namespace detail
558} // end namespace CodeViewYAML
559} // end namespace llvm
Zachary Turner7b436b02017-05-31 04:17:13 +0000560
561CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
Zachary Turner6a330c62017-06-01 21:52:41 +0000562 BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
563 return Symbol->toCodeViewSymbol(Allocator, Container);
Zachary Turner7b436b02017-05-31 04:17:13 +0000564}
565
566namespace llvm {
567namespace yaml {
Eugene Zelenkocd903442017-07-01 01:35:55 +0000568
Zachary Turner7b436b02017-05-31 04:17:13 +0000569template <> struct MappingTraits<SymbolRecordBase> {
570 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
571};
Eugene Zelenkocd903442017-07-01 01:35:55 +0000572
573} // end namespace yaml
574} // end namespace llvm
Zachary Turner7b436b02017-05-31 04:17:13 +0000575
576template <typename SymbolType>
577static inline Expected<CodeViewYAML::SymbolRecord>
578fromCodeViewSymbolImpl(CVSymbol Symbol) {
579 CodeViewYAML::SymbolRecord Result;
580
Zachary Turnerab447682017-06-12 23:10:31 +0000581 auto Impl = std::make_shared<SymbolType>(Symbol.kind());
Zachary Turner7b436b02017-05-31 04:17:13 +0000582 if (auto EC = Impl->fromCodeViewSymbol(Symbol))
583 return std::move(EC);
584 Result.Symbol = Impl;
585 return Result;
586}
587
588Expected<CodeViewYAML::SymbolRecord>
589CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
590#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
591 case EnumName: \
Zachary Turnerab447682017-06-12 23:10:31 +0000592 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
Zachary Turner7b436b02017-05-31 04:17:13 +0000593#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
594 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
595 switch (Symbol.kind()) {
596#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
Zachary Turnerab447682017-06-12 23:10:31 +0000597 default:
598 return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
Zachary Turner7b436b02017-05-31 04:17:13 +0000599 }
600 return make_error<CodeViewError>(cv_error_code::corrupt_record);
601}
602
603template <typename ConcreteType>
604static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
605 CodeViewYAML::SymbolRecord &Obj) {
606 if (!IO.outputting())
Zachary Turnerab447682017-06-12 23:10:31 +0000607 Obj.Symbol = std::make_shared<ConcreteType>(Kind);
Zachary Turner7b436b02017-05-31 04:17:13 +0000608
609 IO.mapRequired(Class, *Obj.Symbol);
610}
611
612void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
613 IO &IO, CodeViewYAML::SymbolRecord &Obj) {
614 SymbolKind Kind;
615 if (IO.outputting())
616 Kind = Obj.Symbol->Kind;
617 IO.mapRequired("Kind", Kind);
618
619#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
620 case EnumName: \
Zachary Turnerab447682017-06-12 23:10:31 +0000621 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
622 Obj); \
Zachary Turner7b436b02017-05-31 04:17:13 +0000623 break;
624#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
625 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
626 switch (Kind) {
627#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
Zachary Turnerab447682017-06-12 23:10:31 +0000628 default:
629 mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
Zachary Turner7b436b02017-05-31 04:17:13 +0000630 }
631}