LLVM  9.0.0svn
CodeViewYAMLSymbols.cpp
Go to the documentation of this file.
1 //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines classes for handling the YAML representation of CodeView
10 // Debug Info.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/StringRef.h"
25 #include "llvm/ObjectYAML/YAML.h"
26 #include "llvm/Support/Allocator.h"
27 #include "llvm/Support/Error.h"
29 #include <algorithm>
30 #include <cstdint>
31 #include <cstring>
32 #include <string>
33 #include <vector>
34 
35 using namespace llvm;
36 using namespace llvm::codeview;
37 using namespace llvm::CodeViewYAML;
38 using namespace llvm::CodeViewYAML::detail;
39 using namespace llvm::yaml;
40 
41 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
42 LLVM_YAML_IS_SEQUENCE_VECTOR(LocalVariableAddrGap)
43 
44 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
45 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None)
46 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None)
47 
48 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
49 LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind)
50 
51 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
52 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
53 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
54 LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags)
55 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
56 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
57 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
58 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
59 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
60 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
61 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
62 
63 LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName)
64 
65 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
66 
67 StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
68  return ScalarTraits<StringRef>::input(S, V, T.value);
69 }
70 
71 void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
72  raw_ostream &R) {
73  ScalarTraits<StringRef>::output(T.value, V, R);
74 }
75 
76 void 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 
83 void 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 
92 void 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 
101 void 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 
109 void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
110  auto FlagNames = getPublicSymFlagNames();
111  for (const auto &E : FlagNames) {
112  io.bitSetCase(Flags, E.Name.str().c_str(),
113  static_cast<PublicSymFlags>(E.Value));
114  }
115 }
116 
117 void 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 
125 void 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 
133 void 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 
142 void 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 
149 void 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 
157 void 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 
166 void 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 
174 void 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 
183 namespace llvm {
184 namespace yaml {
186  static void mapping(IO &io, LocalVariableAddrRange &Range) {
187  io.mapRequired("OffsetStart", Range.OffsetStart);
188  io.mapRequired("ISectStart", Range.ISectStart);
189  io.mapRequired("Range", Range.Range);
190  }
191 };
192 template <> struct MappingTraits<LocalVariableAddrGap> {
193  static void mapping(IO &io, LocalVariableAddrGap &Gap) {
194  io.mapRequired("GapStartOffset", Gap.GapStartOffset);
195  io.mapRequired("Range", Gap.Range);
196  }
197 };
198 } // namespace yaml
199 } // namespace llvm
200 
201 namespace llvm {
202 namespace CodeViewYAML {
203 namespace detail {
204 
207 
208  explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
209  virtual ~SymbolRecordBase() = default;
210 
211  virtual void map(yaml::IO &io) = 0;
212  virtual codeview::CVSymbol
213  toCodeViewSymbol(BumpPtrAllocator &Allocator,
214  CodeViewContainer Container) const = 0;
215  virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
216 };
217 
218 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
220  : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
221 
222  void map(yaml::IO &io) override;
223 
226  CodeViewContainer Container) const override {
227  return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
228  }
229 
231  return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
232  }
233 
234  mutable T Symbol;
235 };
236 
239 
240  void map(yaml::IO &io) override;
241 
243  CodeViewContainer Container) const override {
245  uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
246  Prefix.RecordKind = Kind;
247  Prefix.RecordLen = TotalLen - 2;
248  uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
249  ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
250  ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
251  return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
252  }
253 
255  this->Kind = CVS.kind();
256  Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
257  return Error::success();
258  }
259 
260  std::vector<uint8_t> Data;
261 };
262 
263 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
264 
265 void UnknownSymbolRecord::map(yaml::IO &io) {
266  yaml::BinaryRef Binary;
267  if (io.outputting())
268  Binary = yaml::BinaryRef(Data);
269  io.mapRequired("Data", Binary);
270  if (!io.outputting()) {
271  std::string Str;
272  raw_string_ostream OS(Str);
273  Binary.writeAsBinary(OS);
274  OS.flush();
275  Data.assign(Str.begin(), Str.end());
276  }
277 }
278 
279 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
280  IO.mapRequired("Parent", Symbol.Parent);
281  IO.mapRequired("End", Symbol.End);
282  IO.mapRequired("Next", Symbol.Next);
283  IO.mapRequired("Off", Symbol.Offset);
284  IO.mapRequired("Seg", Symbol.Segment);
285  IO.mapRequired("Len", Symbol.Length);
286  IO.mapRequired("Ordinal", Symbol.Thunk);
287 }
288 
289 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
290  IO.mapRequired("Type", Symbol.Type);
291  IO.mapRequired("Size", Symbol.Size);
292  IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
293  IO.mapRequired("TargetOff", Symbol.TargetOffset);
294  IO.mapRequired("ThunkSection", Symbol.ThunkSection);
295  IO.mapRequired("TargetSection", Symbol.TargetSection);
296 }
297 
298 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
299  IO.mapRequired("SectionNumber", Symbol.SectionNumber);
300  IO.mapRequired("Alignment", Symbol.Alignment);
301  IO.mapRequired("Rva", Symbol.Rva);
302  IO.mapRequired("Length", Symbol.Length);
303  IO.mapRequired("Characteristics", Symbol.Characteristics);
304  IO.mapRequired("Name", Symbol.Name);
305 }
306 
307 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
308  IO.mapRequired("Size", Symbol.Size);
309  IO.mapRequired("Characteristics", Symbol.Characteristics);
310  IO.mapRequired("Offset", Symbol.Offset);
311  IO.mapRequired("Segment", Symbol.Segment);
312  IO.mapRequired("Name", Symbol.Name);
313 }
314 
315 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
316  IO.mapRequired("Ordinal", Symbol.Ordinal);
317  IO.mapRequired("Flags", Symbol.Flags);
318  IO.mapRequired("Name", Symbol.Name);
319 }
320 
321 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
322  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
323  IO.mapOptional("PtrEnd", Symbol.End, 0U);
324  IO.mapOptional("PtrNext", Symbol.Next, 0U);
325  IO.mapRequired("CodeSize", Symbol.CodeSize);
326  IO.mapRequired("DbgStart", Symbol.DbgStart);
327  IO.mapRequired("DbgEnd", Symbol.DbgEnd);
328  IO.mapRequired("FunctionType", Symbol.FunctionType);
329  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
330  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
331  IO.mapRequired("Flags", Symbol.Flags);
332  IO.mapRequired("DisplayName", Symbol.Name);
333 }
334 
335 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
336  IO.mapRequired("Type", Symbol.Index);
337  IO.mapRequired("Seg", Symbol.Register);
338  IO.mapRequired("Name", Symbol.Name);
339 }
340 
341 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
342  IO.mapRequired("Flags", Symbol.Flags);
343  IO.mapOptional("Offset", Symbol.Offset, 0U);
344  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
345  IO.mapRequired("Name", Symbol.Name);
346 }
347 
348 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
349  IO.mapRequired("SumName", Symbol.SumName);
350  IO.mapRequired("SymOffset", Symbol.SymOffset);
351  IO.mapRequired("Mod", Symbol.Module);
352  IO.mapRequired("Name", Symbol.Name);
353 }
354 
355 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
356  IO.mapRequired("Entries", Symbol.Fields);
357 }
358 
359 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
360  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
361  IO.mapOptional("PtrEnd", Symbol.End, 0U);
362  IO.mapRequired("Inlinee", Symbol.Inlinee);
363  // TODO: The binary annotations
364 }
365 
366 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
367  IO.mapRequired("Type", Symbol.Type);
368  IO.mapRequired("Flags", Symbol.Flags);
369 
370  IO.mapRequired("VarName", Symbol.Name);
371 }
372 
373 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
374  IO.mapRequired("Program", Symbol.Program);
375  IO.mapRequired("Range", Symbol.Range);
376  IO.mapRequired("Gaps", Symbol.Gaps);
377 }
378 
380  IO.mapRequired("Program", Symbol.Program);
381  IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
382  IO.mapRequired("Range", Symbol.Range);
383  IO.mapRequired("Gaps", Symbol.Gaps);
384 }
385 
387  IO.mapRequired("Register", Symbol.Hdr.Register);
388  IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
389  IO.mapRequired("Range", Symbol.Range);
390  IO.mapRequired("Gaps", Symbol.Gaps);
391 }
392 
394  IO.mapRequired("Offset", Symbol.Offset);
395  IO.mapRequired("Range", Symbol.Range);
396  IO.mapRequired("Gaps", Symbol.Gaps);
397 }
398 
400  IO.mapRequired("Register", Symbol.Hdr.Register);
401  IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
402  IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
403  IO.mapRequired("Range", Symbol.Range);
404  IO.mapRequired("Gaps", Symbol.Gaps);
405 }
406 
407 template <>
409  IO.mapRequired("Register", Symbol.Offset);
410 }
411 
413  IO.mapRequired("Register", Symbol.Hdr.Register);
414  IO.mapRequired("Flags", Symbol.Hdr.Flags);
415  IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
416  IO.mapRequired("Range", Symbol.Range);
417  IO.mapRequired("Gaps", Symbol.Gaps);
418 }
419 
420 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
421  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
422  IO.mapOptional("PtrEnd", Symbol.End, 0U);
423  IO.mapRequired("CodeSize", Symbol.CodeSize);
424  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
425  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
426  IO.mapRequired("BlockName", Symbol.Name);
427 }
428 
429 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
430  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
431  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
432  IO.mapRequired("Flags", Symbol.Flags);
433  IO.mapRequired("Flags", Symbol.Flags);
434  IO.mapRequired("DisplayName", Symbol.Name);
435 }
436 
437 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
438  IO.mapRequired("Signature", Symbol.Signature);
439  IO.mapRequired("ObjectName", Symbol.Name);
440 }
441 
442 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
443  IO.mapRequired("Flags", Symbol.Flags);
444  IO.mapRequired("Machine", Symbol.Machine);
445  IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
446  IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
447  IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
448  IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
449  IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
450  IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
451  IO.mapRequired("Version", Symbol.Version);
452 }
453 
454 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
455  IO.mapRequired("Flags", Symbol.Flags);
456  IO.mapRequired("Machine", Symbol.Machine);
457  IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
458  IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
459  IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
460  IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
461  IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
462  IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
463  IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
464  IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
465  IO.mapRequired("Version", Symbol.Version);
466 }
467 
468 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
469  IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
470  IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
471  IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
472  IO.mapRequired("BytesOfCalleeSavedRegisters",
473  Symbol.BytesOfCalleeSavedRegisters);
474  IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
475  IO.mapRequired("SectionIdOfExceptionHandler",
476  Symbol.SectionIdOfExceptionHandler);
477  IO.mapRequired("Flags", Symbol.Flags);
478 }
479 
480 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
481  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
482  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
483  IO.mapRequired("Type", Symbol.Type);
484 }
485 
486 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
487  IO.mapRequired("Index", Symbol.Index);
488  IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
489  IO.mapRequired("Flags", Symbol.Flags);
490  IO.mapRequired("Name", Symbol.Name);
491 }
492 
494  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
495  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
496  IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
497  IO.mapRequired("Type", Symbol.Type);
498 }
499 
500 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
501  IO.mapRequired("Register", Symbol.Register);
502  IO.mapRequired("CookieKind", Symbol.CookieKind);
503  IO.mapRequired("Flags", Symbol.Flags);
504 }
505 
506 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
507  IO.mapRequired("FuncID", Symbol.Indices);
508 }
509 
510 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
511  IO.mapRequired("Type", Symbol.Type);
512  IO.mapRequired("UDTName", Symbol.Name);
513 }
514 
515 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
516  IO.mapRequired("BuildId", Symbol.BuildId);
517 }
518 
519 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
520  IO.mapRequired("Offset", Symbol.Offset);
521  IO.mapRequired("Type", Symbol.Type);
522  IO.mapRequired("VarName", Symbol.Name);
523 }
524 
525 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
526  IO.mapRequired("Offset", Symbol.Offset);
527  IO.mapRequired("Type", Symbol.Type);
528  IO.mapRequired("Register", Symbol.Register);
529  IO.mapRequired("VarName", Symbol.Name);
530 }
531 
532 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
533  IO.mapRequired("Type", Symbol.Type);
534  IO.mapRequired("Value", Symbol.Value);
535  IO.mapRequired("Name", Symbol.Name);
536 }
537 
538 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
539  IO.mapRequired("Type", Symbol.Type);
540  IO.mapOptional("Offset", Symbol.DataOffset, 0U);
541  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
542  IO.mapRequired("DisplayName", Symbol.Name);
543 }
544 
546  IO.mapRequired("Type", Symbol.Type);
547  IO.mapOptional("Offset", Symbol.DataOffset, 0U);
548  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
549  IO.mapRequired("DisplayName", Symbol.Name);
550 }
551 
553  IO.mapRequired("Namespace", Symbol.Name);
554 }
555 
556 } // end namespace detail
557 } // end namespace CodeViewYAML
558 } // end namespace llvm
559 
561  BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
562  return Symbol->toCodeViewSymbol(Allocator, Container);
563 }
564 
565 namespace llvm {
566 namespace yaml {
567 
568 template <> struct MappingTraits<SymbolRecordBase> {
569  static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
570 };
571 
572 } // end namespace yaml
573 } // end namespace llvm
574 
575 template <typename SymbolType>
579 
580  auto Impl = std::make_shared<SymbolType>(Symbol.kind());
581  if (auto EC = Impl->fromCodeViewSymbol(Symbol))
582  return std::move(EC);
583  Result.Symbol = Impl;
584  return Result;
585 }
586 
589 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
590  case EnumName: \
591  return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
592 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
593  SYMBOL_RECORD(EnumName, EnumVal, ClassName)
594  switch (Symbol.kind()) {
595 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
596  default:
597  return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
598  }
599  return make_error<CodeViewError>(cv_error_code::corrupt_record);
600 }
601 
602 template <typename ConcreteType>
603 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
605  if (!IO.outputting())
606  Obj.Symbol = std::make_shared<ConcreteType>(Kind);
607 
608  IO.mapRequired(Class, *Obj.Symbol);
609 }
610 
612  IO &IO, CodeViewYAML::SymbolRecord &Obj) {
614  if (IO.outputting())
615  Kind = Obj.Symbol->Kind;
616  IO.mapRequired("Kind", Kind);
617 
618 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
619  case EnumName: \
620  mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
621  Obj); \
622  break;
623 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
624  SYMBOL_RECORD(EnumName, EnumVal, ClassName)
625  switch (Kind) {
626 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
627  default:
628  mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
629  }
630 }
static void mapping(IO &io, LocalVariableAddrRange &Range)
Kind kind() const
Definition: CVRecord.h:43
SymbolRecordKind
Distinguishes individual records in the Symbols subsection of a .debug$S section. ...
Definition: CodeView.h:40
This class represents lattice values for constants.
Definition: AllocatorList.h:23
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:986
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:22
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:95
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:45
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:140
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:40
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:214
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:326
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:78
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:63
ArrayRef< uint8_t > RecordData
Definition: CVRecord.h:61
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:187
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:47
ThunkOrdinal
These values correspond to the THUNK_ORDINAL enumeration.
Definition: CodeView.h:531
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:482
LLVM Value Representation.
Definition: Value.h:72
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:157
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:45
static void mapping(IO &io, SymbolRecordBase &Record)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
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
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
Definition: CVRecord.h:30
CompileSym2Flags
Corresponds to COMPILESYM2::Flags bitfield.
Definition: CodeView.h:439
codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, codeview::CodeViewContainer Container) const