LLVM  8.0.1
CodeViewYAMLSymbols.cpp
Go to the documentation of this file.
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 
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/StringRef.h"
26 #include "llvm/ObjectYAML/YAML.h"
27 #include "llvm/Support/Allocator.h"
28 #include "llvm/Support/Error.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 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
47 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 StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
69  return ScalarTraits<StringRef>::input(S, V, T.value);
70 }
71 
72 void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
73  raw_ostream &R) {
74  ScalarTraits<StringRef>::output(T.value, V, R);
75 }
76 
77 void 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 
84 void 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 
93 void 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 
102 void 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 
110 void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
111  auto FlagNames = getPublicSymFlagNames();
112  for (const auto &E : FlagNames) {
113  io.bitSetCase(Flags, E.Name.str().c_str(),
114  static_cast<PublicSymFlags>(E.Value));
115  }
116 }
117 
118 void 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 
126 void 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 
134 void 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 
143 void 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 
150 void 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 
158 void 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 
167 void 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 
175 void 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 
184 namespace llvm {
185 namespace yaml {
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 };
193 template <> 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 
202 namespace llvm {
203 namespace CodeViewYAML {
204 namespace detail {
205 
208 
209  explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
210  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 {
221  : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
222 
223  void map(yaml::IO &io) override;
224 
227  CodeViewContainer Container) const override {
228  return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
229  }
230 
232  return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
233  }
234 
235  mutable T Symbol;
236 };
237 
240 
241  void map(yaml::IO &io) override;
242 
244  CodeViewContainer Container) const override {
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  }
254 
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 
264 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
265 
266 void 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 
280 template <> 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 
290 template <> 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 
299 template <> 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 
308 template <> 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 
316 template <> 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 
322 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
323  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
324  IO.mapOptional("PtrEnd", Symbol.End, 0U);
325  IO.mapOptional("PtrNext", Symbol.Next, 0U);
326  IO.mapRequired("CodeSize", Symbol.CodeSize);
327  IO.mapRequired("DbgStart", Symbol.DbgStart);
328  IO.mapRequired("DbgEnd", Symbol.DbgEnd);
329  IO.mapRequired("FunctionType", Symbol.FunctionType);
330  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
331  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
332  IO.mapRequired("Flags", Symbol.Flags);
333  IO.mapRequired("DisplayName", Symbol.Name);
334 }
335 
336 template <> 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 
342 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
343  IO.mapRequired("Flags", Symbol.Flags);
344  IO.mapOptional("Offset", Symbol.Offset, 0U);
345  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
346  IO.mapRequired("Name", Symbol.Name);
347 }
348 
349 template <> 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 
356 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
357  IO.mapRequired("Entries", Symbol.Fields);
358 }
359 
360 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
361  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
362  IO.mapOptional("PtrEnd", Symbol.End, 0U);
363  IO.mapRequired("Inlinee", Symbol.Inlinee);
364  // TODO: The binary annotations
365 }
366 
367 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
368  IO.mapRequired("Type", Symbol.Type);
369  IO.mapRequired("Flags", Symbol.Flags);
370 
371  IO.mapRequired("VarName", Symbol.Name);
372 }
373 
374 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
375  IO.mapRequired("Program", Symbol.Program);
376  IO.mapRequired("Range", Symbol.Range);
377  IO.mapRequired("Gaps", Symbol.Gaps);
378 }
379 
381  IO.mapRequired("Program", Symbol.Program);
382  IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
383  IO.mapRequired("Range", Symbol.Range);
384  IO.mapRequired("Gaps", Symbol.Gaps);
385 }
386 
388  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);
392 }
393 
395  IO.mapRequired("Offset", Symbol.Offset);
396  IO.mapRequired("Range", Symbol.Range);
397  IO.mapRequired("Gaps", Symbol.Gaps);
398 }
399 
401  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);
406 }
407 
408 template <>
410  IO.mapRequired("Register", Symbol.Offset);
411 }
412 
414  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);
419 }
420 
421 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
422  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
423  IO.mapOptional("PtrEnd", Symbol.End, 0U);
424  IO.mapRequired("CodeSize", Symbol.CodeSize);
425  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
426  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
427  IO.mapRequired("BlockName", Symbol.Name);
428 }
429 
430 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
431  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
432  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
433  IO.mapRequired("Flags", Symbol.Flags);
434  IO.mapRequired("Flags", Symbol.Flags);
435  IO.mapRequired("DisplayName", Symbol.Name);
436 }
437 
438 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
439  IO.mapRequired("Signature", Symbol.Signature);
440  IO.mapRequired("ObjectName", Symbol.Name);
441 }
442 
443 template <> 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 
455 template <> 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 
469 template <> 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 
481 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
482  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
483  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
484  IO.mapRequired("Type", Symbol.Type);
485 }
486 
487 template <> 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 
495  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
496  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
497  IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
498  IO.mapRequired("Type", Symbol.Type);
499 }
500 
501 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
502  IO.mapRequired("Register", Symbol.Register);
503  IO.mapRequired("CookieKind", Symbol.CookieKind);
504  IO.mapRequired("Flags", Symbol.Flags);
505 }
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  IO.mapRequired("Type", Symbol.Type);
513  IO.mapRequired("UDTName", Symbol.Name);
514 }
515 
516 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
517  IO.mapRequired("BuildId", Symbol.BuildId);
518 }
519 
520 template <> 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 
526 template <> 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 
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 }
538 
539 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
540  IO.mapRequired("Type", Symbol.Type);
541  IO.mapOptional("Offset", Symbol.DataOffset, 0U);
542  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
543  IO.mapRequired("DisplayName", Symbol.Name);
544 }
545 
547  IO.mapRequired("Type", Symbol.Type);
548  IO.mapOptional("Offset", Symbol.DataOffset, 0U);
549  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
550  IO.mapRequired("DisplayName", Symbol.Name);
551 }
552 
554  IO.mapRequired("Namespace", Symbol.Name);
555 }
556 
557 } // end namespace detail
558 } // end namespace CodeViewYAML
559 } // end namespace llvm
560 
562  BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
563  return Symbol->toCodeViewSymbol(Allocator, Container);
564 }
565 
566 namespace llvm {
567 namespace yaml {
568 
569 template <> struct MappingTraits<SymbolRecordBase> {
570  static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
571 };
572 
573 } // end namespace yaml
574 } // end namespace llvm
575 
576 template <typename SymbolType>
580 
581  auto Impl = std::make_shared<SymbolType>(Symbol.kind());
582  if (auto EC = Impl->fromCodeViewSymbol(Symbol))
583  return std::move(EC);
584  Result.Symbol = Impl;
585  return Result;
586 }
587 
590 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
591  case EnumName: \
592  return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
593 #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"
597  default:
598  return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
599  }
600  return make_error<CodeViewError>(cv_error_code::corrupt_record);
601 }
602 
603 template <typename ConcreteType>
604 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
606  if (!IO.outputting())
607  Obj.Symbol = std::make_shared<ConcreteType>(Kind);
608 
609  IO.mapRequired(Class, *Obj.Symbol);
610 }
611 
613  IO &IO, CodeViewYAML::SymbolRecord &Obj) {
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: \
621  mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
622  Obj); \
623  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"
628  default:
629  mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
630  }
631 }
static void mapping(IO &io, LocalVariableAddrRange &Range)
Kind kind() const
Definition: CVRecord.h:37
SymbolRecordKind
Distinguishes individual records in the Symbols subsection of a .debug$S section. ...
Definition: CodeView.h:41
This class represents lattice values for constants.
Definition: AllocatorList.h:24
ArrayRef< EnumEntry< uint16_t > > getExportSymFlagNames()
Definition: EnumTables.cpp:347
ArrayRef< EnumEntry< uint32_t > > getCompileSym3FlagNames()
Definition: EnumTables.cpp:331
CompileSym3Flags
Corresponds to COMPILESYM3::Flags bitfield.
Definition: CodeView.h:455
unsigned Reg
ArrayRef< EnumEntry< uint16_t > > getRegisterNames()
Definition: EnumTables.cpp:303
codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, CodeViewContainer Container) const override
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
ArrayRef< EnumEntry< uint32_t > > getPublicSymFlagNames()
Definition: EnumTables.cpp:307
CVRecord< SymbolKind > CVSymbol
Definition: SymbolRecord.h:987
ArrayRef< EnumEntry< uint8_t > > getThunkOrdinalNames()
Definition: EnumTables.cpp:355
Error fromCodeViewSymbol(codeview::CVSymbol CVS) override
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
ArrayRef< EnumEntry< uint8_t > > getFrameCookieKindNames()
Definition: EnumTables.cpp:319
PublicSymFlags
Corresponds to the CV_PUBSYMFLAGS bitfield.
Definition: CodeView.h:415
A 32-bit type reference.
Definition: TypeIndex.h:96
ArrayRef< EnumEntry< unsigned > > getCPUTypeNames()
Definition: EnumTables.cpp:339
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:141
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void writeAsBinary(raw_ostream &OS) const
Write the contents (regardless of whether it is binary or a hex string) as binary to the given raw_os...
Definition: YAML.cpp:41
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:215
static Expected< SymbolRecord > fromCodeViewSymbol(codeview::CVSymbol Symbol)
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
static void mapping(IO &io, LocalVariableAddrGap &Gap)
static Expected< CodeViewYAML::SymbolRecord > fromCodeViewSymbolImpl(CVSymbol Symbol)
static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage, CodeViewContainer Container)
Basic Register Allocator
ArrayRef< EnumEntry< uint32_t > > getFrameProcSymFlagNames()
Definition: EnumTables.cpp:343
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
Definition: EnumTables.cpp:295
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn...
Definition: CodeView.h:79
ArrayRef< EnumEntry< uint8_t > > getProcSymFlagNames()
Definition: EnumTables.cpp:311
ArrayRef< EnumEntry< uint32_t > > getCompileSym2FlagNames()
Definition: EnumTables.cpp:327
std::shared_ptr< detail::SymbolRecordBase > Symbol
ArrayRef< EnumEntry< uint16_t > > getTrampolineNames()
Definition: EnumTables.cpp:359
Specialized YAMLIO scalar type for representing a binary blob.
Definition: YAML.h:64
ArrayRef< uint8_t > RecordData
Definition: CVRecord.h:49
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:188
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:48
ThunkOrdinal
These values correspond to the THUNK_ORDINAL enumeration.
Definition: CodeView.h:531
const unsigned Kind
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:483
LLVM Value Representation.
Definition: Value.h:73
static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, CodeViewYAML::SymbolRecord &Obj)
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
Definition: EnumTables.cpp:315
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
static void mapping(IO &io, SymbolRecordBase &Record)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, CodeViewContainer Container) const override
ProcSymFlags
Corresponds to the CV_PROCFLAGS bitfield.
Definition: CodeView.h:425
LocalSymFlags
Corresponds to CV_LVARFLAGS bitfield.
Definition: CodeView.h:398
CompileSym2Flags
Corresponds to COMPILESYM2::Flags bitfield.
Definition: CodeView.h:439
codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, codeview::CodeViewContainer Container) const