]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/ObjectYAML/CodeViewYAMLSymbols.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r304460, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / ObjectYAML / CodeViewYAMLSymbols.cpp
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/StringExtras.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
19 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
20 #include "llvm/DebugInfo/CodeView/EnumTables.h"
21 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
22 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
23
24 using namespace llvm;
25 using namespace llvm::codeview;
26 using namespace llvm::CodeViewYAML;
27 using namespace llvm::CodeViewYAML::detail;
28 using namespace llvm::yaml;
29
30 LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
31 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
32
33 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
34 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
35 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
36
37 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
38
39 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
40 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
41 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
42 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
43 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
44 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
45 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
46 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
47 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
48 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
49
50 void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
51                                                       SymbolKind &Value) {
52   auto SymbolNames = getSymbolTypeNames();
53   for (const auto &E : SymbolNames)
54     io.enumCase(Value, E.Name.str().c_str(), E.Value);
55 }
56
57 void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
58                                                   CompileSym2Flags &Flags) {
59   auto FlagNames = getCompileSym2FlagNames();
60   for (const auto &E : FlagNames) {
61     io.bitSetCase(Flags, E.Name.str().c_str(),
62                   static_cast<CompileSym2Flags>(E.Value));
63   }
64 }
65
66 void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
67                                                   CompileSym3Flags &Flags) {
68   auto FlagNames = getCompileSym3FlagNames();
69   for (const auto &E : FlagNames) {
70     io.bitSetCase(Flags, E.Name.str().c_str(),
71                   static_cast<CompileSym3Flags>(E.Value));
72   }
73 }
74
75 void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
76   auto FlagNames = getExportSymFlagNames();
77   for (const auto &E : FlagNames) {
78     io.bitSetCase(Flags, E.Name.str().c_str(),
79                   static_cast<ExportFlags>(E.Value));
80   }
81 }
82
83 void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
84   auto FlagNames = getLocalFlagNames();
85   for (const auto &E : FlagNames) {
86     io.bitSetCase(Flags, E.Name.str().c_str(),
87                   static_cast<LocalSymFlags>(E.Value));
88   }
89 }
90
91 void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
92   auto FlagNames = getProcSymFlagNames();
93   for (const auto &E : FlagNames) {
94     io.bitSetCase(Flags, E.Name.str().c_str(),
95                   static_cast<ProcSymFlags>(E.Value));
96   }
97 }
98
99 void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
100     IO &io, FrameProcedureOptions &Flags) {
101   auto FlagNames = getFrameProcSymFlagNames();
102   for (const auto &E : FlagNames) {
103     io.bitSetCase(Flags, E.Name.str().c_str(),
104                   static_cast<FrameProcedureOptions>(E.Value));
105   }
106 }
107
108 void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
109   auto CpuNames = getCPUTypeNames();
110   for (const auto &E : CpuNames) {
111     io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
112   }
113 }
114
115 void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
116   auto RegNames = getRegisterNames();
117   for (const auto &E : RegNames) {
118     io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
119   }
120   io.enumFallback<Hex16>(Reg);
121 }
122
123 void ScalarEnumerationTraits<TrampolineType>::enumeration(
124     IO &io, TrampolineType &Tramp) {
125   auto TrampNames = getTrampolineNames();
126   for (const auto &E : TrampNames) {
127     io.enumCase(Tramp, E.Name.str().c_str(),
128                 static_cast<TrampolineType>(E.Value));
129   }
130 }
131
132 void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
133                                                         ThunkOrdinal &Ord) {
134   auto ThunkNames = getThunkOrdinalNames();
135   for (const auto &E : ThunkNames) {
136     io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
137   }
138 }
139
140 namespace llvm {
141 namespace CodeViewYAML {
142 namespace detail {
143
144 struct SymbolRecordBase {
145   codeview::SymbolKind Kind;
146   explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
147
148   virtual ~SymbolRecordBase() {}
149   virtual void map(yaml::IO &io) = 0;
150   virtual codeview::CVSymbol
151   toCodeViewSymbol(BumpPtrAllocator &Allocator) const = 0;
152   virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
153 };
154
155 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
156   explicit SymbolRecordImpl(codeview::SymbolKind K)
157       : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
158
159   void map(yaml::IO &io) override;
160
161   codeview::CVSymbol
162   toCodeViewSymbol(BumpPtrAllocator &Allocator) const override {
163     return SymbolSerializer::writeOneSymbol(Symbol, Allocator);
164   }
165   Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
166     return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
167   }
168
169   mutable T Symbol;
170 };
171
172 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
173
174 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
175   IO.mapRequired("Parent", Symbol.Parent);
176   IO.mapRequired("End", Symbol.End);
177   IO.mapRequired("Next", Symbol.Next);
178   IO.mapRequired("Off", Symbol.Offset);
179   IO.mapRequired("Seg", Symbol.Segment);
180   IO.mapRequired("Len", Symbol.Length);
181   IO.mapRequired("Ordinal", Symbol.Thunk);
182 }
183
184 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
185   IO.mapRequired("Type", Symbol.Type);
186   IO.mapRequired("Size", Symbol.Size);
187   IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
188   IO.mapRequired("TargetOff", Symbol.TargetOffset);
189   IO.mapRequired("ThunkSection", Symbol.ThunkSection);
190   IO.mapRequired("TargetSection", Symbol.TargetSection);
191 }
192
193 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
194   IO.mapRequired("SectionNumber", Symbol.SectionNumber);
195   IO.mapRequired("Alignment", Symbol.Alignment);
196   IO.mapRequired("Rva", Symbol.Rva);
197   IO.mapRequired("Length", Symbol.Length);
198   IO.mapRequired("Characteristics", Symbol.Characteristics);
199   IO.mapRequired("Name", Symbol.Name);
200 }
201
202 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
203   IO.mapRequired("Size", Symbol.Size);
204   IO.mapRequired("Characteristics", Symbol.Characteristics);
205   IO.mapRequired("Offset", Symbol.Offset);
206   IO.mapRequired("Segment", Symbol.Segment);
207   IO.mapRequired("Name", Symbol.Name);
208 }
209
210 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
211   IO.mapRequired("Ordinal", Symbol.Ordinal);
212   IO.mapRequired("Flags", Symbol.Flags);
213   IO.mapRequired("Name", Symbol.Name);
214 }
215
216 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
217   // TODO: Print the linkage name
218
219   IO.mapRequired("PtrParent", Symbol.Parent);
220   IO.mapRequired("PtrEnd", Symbol.End);
221   IO.mapRequired("PtrNext", Symbol.Next);
222   IO.mapRequired("CodeSize", Symbol.CodeSize);
223   IO.mapRequired("DbgStart", Symbol.DbgStart);
224   IO.mapRequired("DbgEnd", Symbol.DbgEnd);
225   IO.mapRequired("FunctionType", Symbol.FunctionType);
226   IO.mapRequired("Segment", Symbol.Segment);
227   IO.mapRequired("Flags", Symbol.Flags);
228   IO.mapRequired("DisplayName", Symbol.Name);
229 }
230
231 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
232   IO.mapRequired("Type", Symbol.Index);
233   IO.mapRequired("Seg", Symbol.Register);
234   IO.mapRequired("Name", Symbol.Name);
235 }
236
237 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
238   IO.mapRequired("Type", Symbol.Index);
239   IO.mapRequired("Seg", Symbol.Segment);
240   IO.mapRequired("Off", Symbol.Offset);
241   IO.mapRequired("Name", Symbol.Name);
242 }
243
244 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
245   IO.mapRequired("SumName", Symbol.SumName);
246   IO.mapRequired("SymOffset", Symbol.SymOffset);
247   IO.mapRequired("Mod", Symbol.Module);
248   IO.mapRequired("Name", Symbol.Name);
249 }
250
251 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
252   IO.mapRequired("Entries", Symbol.Fields);
253 }
254
255 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
256   IO.mapRequired("PtrParent", Symbol.Parent);
257   IO.mapRequired("PtrEnd", Symbol.End);
258   IO.mapRequired("Inlinee", Symbol.Inlinee);
259   // TODO: The binary annotations
260 }
261
262 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
263   IO.mapRequired("Type", Symbol.Type);
264   IO.mapRequired("Flags", Symbol.Flags);
265   IO.mapRequired("VarName", Symbol.Name);
266 }
267
268 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
269   // TODO: Print the subfields
270 }
271
272 template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
273   // TODO: Print the subfields
274 }
275
276 template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
277   // TODO: Print the subfields
278 }
279
280 template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
281   // TODO: Print the subfields
282 }
283
284 template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
285   // TODO: Print the subfields
286 }
287
288 template <>
289 void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
290   // TODO: Print the subfields
291 }
292
293 template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
294   // TODO: Print the subfields
295 }
296
297 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
298   // TODO: Print the linkage name
299   IO.mapRequired("PtrParent", Symbol.Parent);
300   IO.mapRequired("PtrEnd", Symbol.End);
301   IO.mapRequired("CodeSize", Symbol.CodeSize);
302   IO.mapRequired("Segment", Symbol.Segment);
303   IO.mapRequired("BlockName", Symbol.Name);
304 }
305
306 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
307   // TODO: Print the linkage name
308   IO.mapRequired("Segment", Symbol.Segment);
309   IO.mapRequired("Flags", Symbol.Flags);
310   IO.mapRequired("Flags", Symbol.Flags);
311   IO.mapRequired("DisplayName", Symbol.Name);
312 }
313
314 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
315   IO.mapRequired("Signature", Symbol.Signature);
316   IO.mapRequired("ObjectName", Symbol.Name);
317 }
318
319 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
320   IO.mapRequired("Flags", Symbol.Flags);
321   IO.mapRequired("Machine", Symbol.Machine);
322   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
323   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
324   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
325   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
326   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
327   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
328   IO.mapRequired("Version", Symbol.Version);
329 }
330
331 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
332   IO.mapRequired("Flags", Symbol.Flags);
333   IO.mapRequired("Machine", Symbol.Machine);
334   IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
335   IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
336   IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
337   IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
338   IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
339   IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
340   IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
341   IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
342   IO.mapRequired("Version", Symbol.Version);
343 }
344
345 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
346   IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
347   IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
348   IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
349   IO.mapRequired("BytesOfCalleeSavedRegisters",
350                  Symbol.BytesOfCalleeSavedRegisters);
351   IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
352   IO.mapRequired("SectionIdOfExceptionHandler",
353                  Symbol.SectionIdOfExceptionHandler);
354   IO.mapRequired("Flags", Symbol.Flags);
355 }
356
357 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
358   // TODO: Map Linkage Name
359   IO.mapRequired("Segment", Symbol.Segment);
360   IO.mapRequired("Type", Symbol.Type);
361 }
362
363 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
364   IO.mapRequired("Index", Symbol.Index);
365   IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
366   IO.mapRequired("Flags", Symbol.Flags);
367   IO.mapRequired("Name", Symbol.Name);
368 }
369
370 template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
371   // TODO: Map Linkage Name
372   IO.mapRequired("Segment", Symbol.Segment);
373   IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
374   IO.mapRequired("Type", Symbol.Type);
375 }
376
377 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
378   // TODO: Map Linkage Name
379   IO.mapRequired("Register", Symbol.Register);
380   IO.mapRequired("CookieKind", Symbol.CookieKind);
381   IO.mapRequired("Flags", Symbol.Flags);
382 }
383
384 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
385   IO.mapRequired("FuncID", Symbol.Indices);
386 }
387
388 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
389   IO.mapRequired("Type", Symbol.Type);
390   IO.mapRequired("UDTName", Symbol.Name);
391 }
392
393 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
394   IO.mapRequired("BuildId", Symbol.BuildId);
395 }
396
397 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
398   IO.mapRequired("Offset", Symbol.Offset);
399   IO.mapRequired("Type", Symbol.Type);
400   IO.mapRequired("VarName", Symbol.Name);
401 }
402
403 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
404   IO.mapRequired("Offset", Symbol.Offset);
405   IO.mapRequired("Type", Symbol.Type);
406   IO.mapRequired("Register", Symbol.Register);
407   IO.mapRequired("VarName", Symbol.Name);
408 }
409
410 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
411   IO.mapRequired("Type", Symbol.Type);
412   IO.mapRequired("Value", Symbol.Value);
413   IO.mapRequired("Name", Symbol.Name);
414 }
415
416 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
417   // TODO: Map linkage name
418   IO.mapRequired("Type", Symbol.Type);
419   IO.mapRequired("DisplayName", Symbol.Name);
420 }
421
422 template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
423   // TODO: Map linkage name
424   IO.mapRequired("Type", Symbol.Type);
425   IO.mapRequired("DisplayName", Symbol.Name);
426 }
427 }
428 }
429 }
430
431 CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
432     BumpPtrAllocator &Allocator) const {
433   return Symbol->toCodeViewSymbol(Allocator);
434 }
435
436 namespace llvm {
437 namespace yaml {
438 template <> struct MappingTraits<SymbolRecordBase> {
439   static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
440 };
441 }
442 }
443
444 template <typename SymbolType>
445 static inline Expected<CodeViewYAML::SymbolRecord>
446 fromCodeViewSymbolImpl(CVSymbol Symbol) {
447   CodeViewYAML::SymbolRecord Result;
448
449   auto Impl = std::make_shared<SymbolRecordImpl<SymbolType>>(Symbol.kind());
450   if (auto EC = Impl->fromCodeViewSymbol(Symbol))
451     return std::move(EC);
452   Result.Symbol = Impl;
453   return Result;
454 }
455
456 Expected<CodeViewYAML::SymbolRecord>
457 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
458 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
459   case EnumName:                                                               \
460     return fromCodeViewSymbolImpl<ClassName>(Symbol);
461 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
462   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
463   switch (Symbol.kind()) {
464 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
465   default: { llvm_unreachable("Unknown symbol kind!"); }
466   }
467   return make_error<CodeViewError>(cv_error_code::corrupt_record);
468 }
469
470 template <typename ConcreteType>
471 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
472                                 CodeViewYAML::SymbolRecord &Obj) {
473   if (!IO.outputting())
474     Obj.Symbol = std::make_shared<SymbolRecordImpl<ConcreteType>>(Kind);
475
476   IO.mapRequired(Class, *Obj.Symbol);
477 }
478
479 void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
480     IO &IO, CodeViewYAML::SymbolRecord &Obj) {
481   SymbolKind Kind;
482   if (IO.outputting())
483     Kind = Obj.Symbol->Kind;
484   IO.mapRequired("Kind", Kind);
485
486 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName)                            \
487   case EnumName:                                                               \
488     mapSymbolRecordImpl<ClassName>(IO, #ClassName, Kind, Obj);                 \
489     break;
490 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName)           \
491   SYMBOL_RECORD(EnumName, EnumVal, ClassName)
492   switch (Kind) {
493 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
494   default: { llvm_unreachable("Unknown symbol kind!"); }
495   }
496 }