LLVM  16.0.0git
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"
30 #include <algorithm>
31 #include <cstdint>
32 #include <cstring>
33 #include <optional>
34 #include <string>
35 #include <vector>
36 
37 using namespace llvm;
38 using namespace llvm::codeview;
39 using namespace llvm::CodeViewYAML;
40 using namespace llvm::CodeViewYAML::detail;
41 using namespace llvm::yaml;
42 
45 
46 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
49 
52 
64 
66 
68 
70  return ScalarTraits<StringRef>::input(S, V, T.value);
71 }
72 
73 void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
74  raw_ostream &R) {
76 }
77 
78 void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
79  SymbolKind &Value) {
80  auto SymbolNames = getSymbolTypeNames();
81  for (const auto &E : SymbolNames)
82  io.enumCase(Value, E.Name.str().c_str(), E.Value);
83 }
84 
85 void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
86  CompileSym2Flags &Flags) {
87  auto FlagNames = getCompileSym2FlagNames();
88  for (const auto &E : FlagNames) {
89  io.bitSetCase(Flags, E.Name.str().c_str(),
90  static_cast<CompileSym2Flags>(E.Value));
91  }
92 }
93 
94 void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
95  CompileSym3Flags &Flags) {
96  auto FlagNames = getCompileSym3FlagNames();
97  for (const auto &E : FlagNames) {
98  io.bitSetCase(Flags, E.Name.str().c_str(),
99  static_cast<CompileSym3Flags>(E.Value));
100  }
101 }
102 
103 void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
104  auto FlagNames = getExportSymFlagNames();
105  for (const auto &E : FlagNames) {
106  io.bitSetCase(Flags, E.Name.str().c_str(),
107  static_cast<ExportFlags>(E.Value));
108  }
109 }
110 
111 void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
112  auto FlagNames = getPublicSymFlagNames();
113  for (const auto &E : FlagNames) {
114  io.bitSetCase(Flags, E.Name.str().c_str(),
115  static_cast<PublicSymFlags>(E.Value));
116  }
117 }
118 
119 void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
120  auto FlagNames = getLocalFlagNames();
121  for (const auto &E : FlagNames) {
122  io.bitSetCase(Flags, E.Name.str().c_str(),
123  static_cast<LocalSymFlags>(E.Value));
124  }
125 }
126 
127 void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
128  auto FlagNames = getProcSymFlagNames();
129  for (const auto &E : FlagNames) {
130  io.bitSetCase(Flags, E.Name.str().c_str(),
131  static_cast<ProcSymFlags>(E.Value));
132  }
133 }
134 
135 void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
136  IO &io, FrameProcedureOptions &Flags) {
137  auto FlagNames = getFrameProcSymFlagNames();
138  for (const auto &E : FlagNames) {
139  io.bitSetCase(Flags, E.Name.str().c_str(),
140  static_cast<FrameProcedureOptions>(E.Value));
141  }
142 }
143 
144 void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
145  auto CpuNames = getCPUTypeNames();
146  for (const auto &E : CpuNames) {
147  io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
148  }
149 }
150 
151 void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
152  const auto *Header = static_cast<COFF::header *>(io.getContext());
153  assert(Header && "The IO context is not initialized");
154 
155  std::optional<CPUType> CpuType;
157 
158  switch (Header->Machine) {
160  CpuType = CPUType::Pentium3;
161  break;
163  CpuType = CPUType::X64;
164  break;
166  CpuType = CPUType::ARMNT;
167  break;
170  CpuType = CPUType::ARM64;
171  break;
172  }
173 
174  if (CpuType)
175  RegNames = getRegisterNames(*CpuType);
176 
177  for (const auto &E : RegNames) {
178  io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
179  }
180  io.enumFallback<Hex16>(Reg);
181 }
182 
183 void ScalarEnumerationTraits<TrampolineType>::enumeration(
184  IO &io, TrampolineType &Tramp) {
185  auto TrampNames = getTrampolineNames();
186  for (const auto &E : TrampNames) {
187  io.enumCase(Tramp, E.Name.str().c_str(),
188  static_cast<TrampolineType>(E.Value));
189  }
190 }
191 
192 void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
193  ThunkOrdinal &Ord) {
194  auto ThunkNames = getThunkOrdinalNames();
195  for (const auto &E : ThunkNames) {
196  io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
197  }
198 }
199 
200 void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
201  IO &io, FrameCookieKind &FC) {
202  auto ThunkNames = getFrameCookieKindNames();
203  for (const auto &E : ThunkNames) {
204  io.enumCase(FC, E.Name.str().c_str(),
205  static_cast<FrameCookieKind>(E.Value));
206  }
207 }
208 
209 namespace llvm {
210 namespace yaml {
212  static void mapping(IO &io, LocalVariableAddrRange &Range) {
213  io.mapRequired("OffsetStart", Range.OffsetStart);
214  io.mapRequired("ISectStart", Range.ISectStart);
215  io.mapRequired("Range", Range.Range);
216  }
217 };
218 template <> struct MappingTraits<LocalVariableAddrGap> {
219  static void mapping(IO &io, LocalVariableAddrGap &Gap) {
220  io.mapRequired("GapStartOffset", Gap.GapStartOffset);
221  io.mapRequired("Range", Gap.Range);
222  }
223 };
224 } // namespace yaml
225 } // namespace llvm
226 
227 namespace llvm {
228 namespace CodeViewYAML {
229 namespace detail {
230 
233 
234  explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
235  virtual ~SymbolRecordBase() = default;
236 
237  virtual void map(yaml::IO &io) = 0;
238  virtual codeview::CVSymbol
239  toCodeViewSymbol(BumpPtrAllocator &Allocator,
240  CodeViewContainer Container) const = 0;
241  virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
242 };
243 
244 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
246  : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
247 
248  void map(yaml::IO &io) override;
249 
252  CodeViewContainer Container) const override {
253  return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container);
254  }
255 
257  return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
258  }
259 
260  mutable T Symbol;
261 };
262 
265 
266  void map(yaml::IO &io) override;
267 
269  CodeViewContainer Container) const override {
271  uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
272  Prefix.RecordKind = Kind;
273  Prefix.RecordLen = TotalLen - 2;
274  uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
275  ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
276  ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
277  return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
278  }
279 
281  this->Kind = CVS.kind();
282  Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
283  return Error::success();
284  }
285 
286  std::vector<uint8_t> Data;
287 };
288 
289 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
290 
291 void UnknownSymbolRecord::map(yaml::IO &io) {
292  yaml::BinaryRef Binary;
293  if (io.outputting())
294  Binary = yaml::BinaryRef(Data);
295  io.mapRequired("Data", Binary);
296  if (!io.outputting()) {
297  std::string Str;
298  raw_string_ostream OS(Str);
299  Binary.writeAsBinary(OS);
300  OS.flush();
301  Data.assign(Str.begin(), Str.end());
302  }
303 }
304 
305 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
306  IO.mapRequired("Parent", Symbol.Parent);
307  IO.mapRequired("End", Symbol.End);
308  IO.mapRequired("Next", Symbol.Next);
309  IO.mapRequired("Off", Symbol.Offset);
310  IO.mapRequired("Seg", Symbol.Segment);
311  IO.mapRequired("Len", Symbol.Length);
312  IO.mapRequired("Ordinal", Symbol.Thunk);
313 }
314 
315 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
316  IO.mapRequired("Type", Symbol.Type);
317  IO.mapRequired("Size", Symbol.Size);
318  IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
319  IO.mapRequired("TargetOff", Symbol.TargetOffset);
320  IO.mapRequired("ThunkSection", Symbol.ThunkSection);
321  IO.mapRequired("TargetSection", Symbol.TargetSection);
322 }
323 
324 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
325  IO.mapRequired("SectionNumber", Symbol.SectionNumber);
326  IO.mapRequired("Alignment", Symbol.Alignment);
327  IO.mapRequired("Rva", Symbol.Rva);
328  IO.mapRequired("Length", Symbol.Length);
329  IO.mapRequired("Characteristics", Symbol.Characteristics);
330  IO.mapRequired("Name", Symbol.Name);
331 }
332 
333 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
334  IO.mapRequired("Size", Symbol.Size);
335  IO.mapRequired("Characteristics", Symbol.Characteristics);
336  IO.mapRequired("Offset", Symbol.Offset);
337  IO.mapRequired("Segment", Symbol.Segment);
338  IO.mapRequired("Name", Symbol.Name);
339 }
340 
341 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
342  IO.mapRequired("Ordinal", Symbol.Ordinal);
343  IO.mapRequired("Flags", Symbol.Flags);
344  IO.mapRequired("Name", Symbol.Name);
345 }
346 
347 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
348  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
349  IO.mapOptional("PtrEnd", Symbol.End, 0U);
350  IO.mapOptional("PtrNext", Symbol.Next, 0U);
351  IO.mapRequired("CodeSize", Symbol.CodeSize);
352  IO.mapRequired("DbgStart", Symbol.DbgStart);
353  IO.mapRequired("DbgEnd", Symbol.DbgEnd);
354  IO.mapRequired("FunctionType", Symbol.FunctionType);
355  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
356  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
357  IO.mapRequired("Flags", Symbol.Flags);
358  IO.mapRequired("DisplayName", Symbol.Name);
359 }
360 
361 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
362  IO.mapRequired("Type", Symbol.Index);
363  IO.mapRequired("Seg", Symbol.Register);
364  IO.mapRequired("Name", Symbol.Name);
365 }
366 
367 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
368  IO.mapRequired("Flags", Symbol.Flags);
369  IO.mapOptional("Offset", Symbol.Offset, 0U);
370  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
371  IO.mapRequired("Name", Symbol.Name);
372 }
373 
374 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
375  IO.mapRequired("SumName", Symbol.SumName);
376  IO.mapRequired("SymOffset", Symbol.SymOffset);
377  IO.mapRequired("Mod", Symbol.Module);
378  IO.mapRequired("Name", Symbol.Name);
379 }
380 
381 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
382  IO.mapRequired("Entries", Symbol.Fields);
383 }
384 
385 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
386  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
387  IO.mapOptional("PtrEnd", Symbol.End, 0U);
388  IO.mapRequired("Inlinee", Symbol.Inlinee);
389  // TODO: The binary annotations
390 }
391 
392 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
393  IO.mapRequired("Type", Symbol.Type);
394  IO.mapRequired("Flags", Symbol.Flags);
395 
396  IO.mapRequired("VarName", Symbol.Name);
397 }
398 
399 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
400  IO.mapRequired("Program", Symbol.Program);
401  IO.mapRequired("Range", Symbol.Range);
402  IO.mapRequired("Gaps", Symbol.Gaps);
403 }
404 
406  IO.mapRequired("Program", Symbol.Program);
407  IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
408  IO.mapRequired("Range", Symbol.Range);
409  IO.mapRequired("Gaps", Symbol.Gaps);
410 }
411 
413  IO.mapRequired("Register", Symbol.Hdr.Register);
414  IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
415  IO.mapRequired("Range", Symbol.Range);
416  IO.mapRequired("Gaps", Symbol.Gaps);
417 }
418 
420  IO.mapRequired("Offset", Symbol.Hdr.Offset);
421  IO.mapRequired("Range", Symbol.Range);
422  IO.mapRequired("Gaps", Symbol.Gaps);
423 }
424 
426  IO.mapRequired("Register", Symbol.Hdr.Register);
427  IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
428  IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
429  IO.mapRequired("Range", Symbol.Range);
430  IO.mapRequired("Gaps", Symbol.Gaps);
431 }
432 
433 template <>
435  IO.mapRequired("Register", Symbol.Offset);
436 }
437 
439  IO.mapRequired("Register", Symbol.Hdr.Register);
440  IO.mapRequired("Flags", Symbol.Hdr.Flags);
441  IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
442  IO.mapRequired("Range", Symbol.Range);
443  IO.mapRequired("Gaps", Symbol.Gaps);
444 }
445 
446 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
447  IO.mapOptional("PtrParent", Symbol.Parent, 0U);
448  IO.mapOptional("PtrEnd", Symbol.End, 0U);
449  IO.mapRequired("CodeSize", Symbol.CodeSize);
450  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
451  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
452  IO.mapRequired("BlockName", Symbol.Name);
453 }
454 
455 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
456  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
457  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
458  IO.mapRequired("Flags", Symbol.Flags);
459  IO.mapRequired("Flags", Symbol.Flags);
460  IO.mapRequired("DisplayName", Symbol.Name);
461 }
462 
463 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
464  IO.mapRequired("Signature", Symbol.Signature);
465  IO.mapRequired("ObjectName", Symbol.Name);
466 }
467 
468 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
469  IO.mapRequired("Flags", Symbol.Flags);
470  IO.mapRequired("Machine", Symbol.Machine);
471  IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
472  IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
473  IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
474  IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
475  IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
476  IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
477  IO.mapRequired("Version", Symbol.Version);
478 }
479 
480 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
481  IO.mapRequired("Flags", Symbol.Flags);
482  IO.mapRequired("Machine", Symbol.Machine);
483  IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
484  IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
485  IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
486  IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
487  IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
488  IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
489  IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
490  IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
491  IO.mapRequired("Version", Symbol.Version);
492 }
493 
494 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
495  IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
496  IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
497  IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
498  IO.mapRequired("BytesOfCalleeSavedRegisters",
499  Symbol.BytesOfCalleeSavedRegisters);
500  IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
501  IO.mapRequired("SectionIdOfExceptionHandler",
502  Symbol.SectionIdOfExceptionHandler);
503  IO.mapRequired("Flags", Symbol.Flags);
504 }
505 
506 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
507  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
508  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
509  IO.mapRequired("Type", Symbol.Type);
510 }
511 
512 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
513  IO.mapRequired("Index", Symbol.Index);
514  IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
515  IO.mapRequired("Flags", Symbol.Flags);
516  IO.mapRequired("Name", Symbol.Name);
517 }
518 
520  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
521  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
522  IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
523  IO.mapRequired("Type", Symbol.Type);
524 }
525 
526 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
527  IO.mapRequired("Register", Symbol.Register);
528  IO.mapRequired("CookieKind", Symbol.CookieKind);
529  IO.mapRequired("Flags", Symbol.Flags);
530 }
531 
532 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
533  IO.mapRequired("FuncID", Symbol.Indices);
534 }
535 
536 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
537  IO.mapRequired("Type", Symbol.Type);
538  IO.mapRequired("UDTName", Symbol.Name);
539 }
540 
541 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
542  IO.mapRequired("BuildId", Symbol.BuildId);
543 }
544 
545 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
546  IO.mapRequired("Offset", Symbol.Offset);
547  IO.mapRequired("Type", Symbol.Type);
548  IO.mapRequired("VarName", Symbol.Name);
549 }
550 
551 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
552  IO.mapRequired("Offset", Symbol.Offset);
553  IO.mapRequired("Type", Symbol.Type);
554  IO.mapRequired("Register", Symbol.Register);
555  IO.mapRequired("VarName", Symbol.Name);
556 }
557 
558 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
559  IO.mapRequired("Type", Symbol.Type);
560  IO.mapRequired("Value", Symbol.Value);
561  IO.mapRequired("Name", Symbol.Name);
562 }
563 
564 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
565  IO.mapRequired("Type", Symbol.Type);
566  IO.mapOptional("Offset", Symbol.DataOffset, 0U);
567  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
568  IO.mapRequired("DisplayName", Symbol.Name);
569 }
570 
572  IO.mapRequired("Type", Symbol.Type);
573  IO.mapOptional("Offset", Symbol.DataOffset, 0U);
574  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
575  IO.mapRequired("DisplayName", Symbol.Name);
576 }
577 
579  IO.mapRequired("Namespace", Symbol.Name);
580 }
581 
582 template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
583  IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
584  IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
585  IO.mapRequired("Strings", Symbol.Strings);
586 }
587 
588 } // end namespace detail
589 } // end namespace CodeViewYAML
590 } // end namespace llvm
591 
593  BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
594  return Symbol->toCodeViewSymbol(Allocator, Container);
595 }
596 
597 namespace llvm {
598 namespace yaml {
599 
600 template <> struct MappingTraits<SymbolRecordBase> {
601  static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
602 };
603 
604 } // end namespace yaml
605 } // end namespace llvm
606 
607 template <typename SymbolType>
611 
612  auto Impl = std::make_shared<SymbolType>(Symbol.kind());
613  if (auto EC = Impl->fromCodeViewSymbol(Symbol))
614  return std::move(EC);
615  Result.Symbol = Impl;
616  return Result;
617 }
618 
621 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
622  case EnumName: \
623  return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
624 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
625  SYMBOL_RECORD(EnumName, EnumVal, ClassName)
626  switch (Symbol.kind()) {
627 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
628  default:
629  return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
630  }
631  return make_error<CodeViewError>(cv_error_code::corrupt_record);
632 }
633 
634 template <typename ConcreteType>
635 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
637  if (!IO.outputting())
638  Obj.Symbol = std::make_shared<ConcreteType>(Kind);
639 
640  IO.mapRequired(Class, *Obj.Symbol);
641 }
642 
644  IO &IO, CodeViewYAML::SymbolRecord &Obj) {
646  if (IO.outputting())
647  Kind = Obj.Symbol->Kind;
648  IO.mapRequired("Kind", Kind);
649 
650 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
651  case EnumName: \
652  mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
653  Obj); \
654  break;
655 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
656  SYMBOL_RECORD(EnumName, EnumVal, ClassName)
657  switch (Kind) {
658 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
659  default:
660  mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
661  }
662 }
llvm::codeview::CPUType::ARM64
@ ARM64
llvm::CodeViewYAML::detail::UnknownSymbolRecord::fromCodeViewSymbol
Error fromCodeViewSymbol(CVSymbol CVS) override
Definition: CodeViewYAMLSymbols.cpp:280
llvm::CodeViewYAML::SymbolRecord::toCodeViewSymbol
codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, codeview::CodeViewContainer Container) const
Definition: CodeViewYAMLSymbols.cpp:592
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
RecordSerialization.h
LLVM_YAML_DECLARE_ENUM_TRAITS
#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)
llvm::cl::Prefix
@ Prefix
Definition: CommandLine.h:161
llvm::codeview::getCompileSym3FlagNames
ArrayRef< EnumEntry< uint32_t > > getCompileSym3FlagNames()
Definition: EnumTables.cpp:480
StringRef.h
llvm::codeview::SymbolKind
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:47
llvm::codeview::ProcSymFlags
ProcSymFlags
Corresponds to the CV_PROCFLAGS bitfield.
Definition: CodeView.h:433
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:629
SymbolRecord.h
output
Current output
Definition: README.txt:1350
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
Allocator.h
llvm::COFF::IMAGE_FILE_MACHINE_AMD64
@ IMAGE_FILE_MACHINE_AMD64
Definition: COFF.h:97
R600_InstFlag::FC
@ FC
Definition: R600Defines.h:32
Error.h
LLVM_YAML_IS_SEQUENCE_VECTOR
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
llvm::codeview::getLocalFlagNames
ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
Definition: EnumTables.cpp:464
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
CodeViewYAMLSymbols.h
mapSymbolRecordImpl
static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, CodeViewYAML::SymbolRecord &Obj)
Definition: CodeViewYAMLSymbols.cpp:635
llvm::COFF::IMAGE_FILE_MACHINE_ARMNT
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::codeview::CPUType::X64
@ X64
llvm::yaml::MappingTraits
Definition: ModuleSummaryIndex.h:52
llvm::codeview::RecordPrefix
Definition: RecordSerialization.h:32
llvm::codeview::CPUType::ARMNT
@ ARMNT
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::codeview::CVRecord::RecordData
ArrayRef< uint8_t > RecordData
Definition: CVRecord.h:60
llvm::codeview::LocalVariableAddrGap
Definition: SymbolRecord.h:429
EnumTables.h
llvm::CodeViewYAML::detail::SymbolRecordBase::SymbolRecordBase
SymbolRecordBase(codeview::SymbolKind K)
Definition: CodeViewYAMLSymbols.cpp:234
llvm::CodeViewYAML::detail
Definition: CodeViewYAMLDebugSections.h:39
llvm::COFF::IMAGE_FILE_MACHINE_I386
@ IMAGE_FILE_MACHINE_I386
Definition: COFF.h:103
llvm::codeview::LocalVariableAddrGap::GapStartOffset
uint16_t GapStartOffset
Definition: SymbolRecord.h:430
llvm::codeview::getThunkOrdinalNames
ArrayRef< EnumEntry< uint8_t > > getThunkOrdinalNames()
Definition: EnumTables.cpp:504
llvm::CodeViewYAML::SymbolRecord::fromCodeViewSymbol
static Expected< SymbolRecord > fromCodeViewSymbol(codeview::CVSymbol Symbol)
Definition: CodeViewYAMLSymbols.cpp:620
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
SymbolDeserializer.h
llvm::CodeViewYAML::detail::UnknownSymbolRecord
Definition: CodeViewYAMLSymbols.cpp:263
llvm::codeview::CVSymbol
CVRecord< SymbolKind > CVSymbol
Definition: CVRecord.h:65
llvm::codeview::LocalVariableAddrRange
Definition: SymbolRecord.h:423
llvm::codeview::SymbolSerializer::writeOneSymbol
static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage, CodeViewContainer Container)
Definition: SymbolSerializer.h:53
llvm::CodeViewYAML::detail::SymbolRecordImpl
Definition: CodeViewYAMLSymbols.cpp:244
YAML.h
llvm::CodeViewYAML::detail::SymbolRecordImpl::fromCodeViewSymbol
Error fromCodeViewSymbol(codeview::CVSymbol CVS) override
Definition: CodeViewYAMLSymbols.cpp:256
llvm::codeview::getPublicSymFlagNames
ArrayRef< EnumEntry< uint32_t > > getPublicSymFlagNames()
Definition: EnumTables.cpp:456
llvm::APSInt
An arbitrary precision integer that knows its signedness.
Definition: APSInt.h:23
llvm::codeview::FrameCookieKind
FrameCookieKind
Definition: CodeView.h:511
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::CodeViewYAML::detail::SymbolRecordImpl::toCodeViewSymbol
codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, CodeViewContainer Container) const override
Definition: CodeViewYAMLSymbols.cpp:251
llvm::raw_ostream::flush
void flush()
Definition: raw_ostream.h:186
llvm::codeview::getProcSymFlagNames
ArrayRef< EnumEntry< uint8_t > > getProcSymFlagNames()
Definition: EnumTables.cpp:460
input
The initial backend is deliberately restricted to z10 We should add support for later architectures at some point If an asm ties an i32 r result to an i64 input
Definition: README.txt:10
llvm::yaml::MappingTraits< LocalVariableAddrGap >::mapping
static void mapping(IO &io, LocalVariableAddrGap &Gap)
Definition: CodeViewYAMLSymbols.cpp:219
CodeView.h
llvm::CodeViewYAML::detail::UnknownSymbolRecord::UnknownSymbolRecord
UnknownSymbolRecord(codeview::SymbolKind K)
Definition: CodeViewYAMLSymbols.cpp:264
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
LLVM_YAML_DECLARE_SCALAR_TRAITS
#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)
llvm::codeview::getCPUTypeNames
ArrayRef< EnumEntry< unsigned > > getCPUTypeNames()
Definition: EnumTables.cpp:488
llvm::codeview::FrameProcedureOptions
FrameProcedureOptions
Definition: CodeView.h:220
llvm::CodeViewYAML::detail::UnknownSymbolRecord::Data
std::vector< uint8_t > Data
Definition: CodeViewYAMLSymbols.cpp:286
llvm::codeview::TrampolineType
TrampolineType
Definition: CodeView.h:563
llvm::ArrayRef::drop_front
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:203
LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR
#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)
llvm::codeview::PublicSymFlags
PublicSymFlags
Corresponds to the CV_PUBSYMFLAGS bitfield.
Definition: CodeView.h:423
llvm::codeview::CVRecord::kind
Kind kind() const
Definition: CVRecord.h:42
llvm::BumpPtrAllocatorImpl
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:63
LLVM_YAML_STRONG_TYPEDEF
#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::CodeViewYAML::detail::SymbolRecordBase::Kind
codeview::SymbolKind Kind
Definition: CodeViewYAMLSymbols.cpp:232
ArrayRef.h
LLVM_YAML_DECLARE_BITSET_TRAITS
#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)
llvm::CodeViewYAML::detail::SymbolRecordBase
Definition: CodeViewYAMLSymbols.cpp:231
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::CodeViewYAML
Definition: CodeViewYAMLDebugSections.h:37
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::codeview::getFrameCookieKindNames
ArrayRef< EnumEntry< uint8_t > > getFrameCookieKindNames()
Definition: EnumTables.cpp:468
llvm::codeview::CompileSym2Flags::EC
@ EC
SymbolSerializer.h
llvm::codeview::RegisterId
RegisterId
Definition: CodeView.h:519
llvm::COFF::IMAGE_FILE_MACHINE_ARM64EC
@ IMAGE_FILE_MACHINE_ARM64EC
Definition: COFF.h:101
llvm::Record
Definition: Record.h:1573
llvm::codeview::getSymbolTypeNames
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
Definition: EnumTables.cpp:439
YAMLTraits.h
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::codeview::CVRecord
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
Definition: CVRecord.h:29
llvm::yaml::BinaryRef
Specialized YAMLIO scalar type for representing a binary blob.
Definition: YAML.h:63
uint32_t
llvm::CodeViewYAML::SymbolRecord
Definition: CodeViewYAMLSymbols.h:32
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::COFF::IMAGE_FILE_MACHINE_ARM64
@ IMAGE_FILE_MACHINE_ARM64
Definition: COFF.h:100
llvm::codeview::CompileSym2Flags
CompileSym2Flags
Corresponds to COMPILESYM2::Flags bitfield.
Definition: CodeView.h:447
llvm::pdb::Single
@ Single
Definition: PDBTypes.h:401
llvm::CodeViewYAML::detail::SymbolRecordImpl::SymbolRecordImpl
SymbolRecordImpl(codeview::SymbolKind K)
Definition: CodeViewYAMLSymbols.cpp:245
llvm::codeview::getTrampolineNames
ArrayRef< EnumEntry< uint16_t > > getTrampolineNames()
Definition: EnumTables.cpp:508
llvm::None
constexpr std::nullopt_t None
Definition: None.h:27
uint16_t
llvm::CodeViewYAML::detail::UnknownSymbolRecord::toCodeViewSymbol
CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, CodeViewContainer Container) const override
Definition: CodeViewYAMLSymbols.cpp:268
llvm::AMDGPU::HSAMD::Kernel::Arg::Key::TypeName
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
Definition: AMDGPUMetadata.h:175
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::codeview::CPUType
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
Definition: CodeView.h:75
llvm::codeview::getFrameProcSymFlagNames
ArrayRef< EnumEntry< uint32_t > > getFrameProcSymFlagNames()
Definition: EnumTables.cpp:492
llvm::CodeViewYAML::SymbolRecord::Symbol
std::shared_ptr< detail::SymbolRecordBase > Symbol
Definition: CodeViewYAMLSymbols.h:33
llvm::codeview::cv_error_code::corrupt_record
@ corrupt_record
llvm::yaml
Definition: MIRYamlMapping.h:30
TypeIndex.h
llvm::codeview::SymbolRecordKind
SymbolRecordKind
Distinguishes individual records in the Symbols subsection of a .debug$S section.
Definition: CodeView.h:40
llvm::codeview::getCompileSym2FlagNames
ArrayRef< EnumEntry< uint32_t > > getCompileSym2FlagNames()
Definition: EnumTables.cpp:476
llvm::codeview
Definition: AppendingTypeTableBuilder.h:22
llvm::codeview::ThunkOrdinal
ThunkOrdinal
These values correspond to the THUNK_ORDINAL enumeration.
Definition: CodeView.h:553
llvm::codeview::LocalSymFlags
LocalSymFlags
Corresponds to CV_LVARFLAGS bitfield.
Definition: CodeView.h:406
Allocator
Basic Register Allocator
Definition: RegAllocBasic.cpp:143
llvm::codeview::CodeViewContainer
CodeViewContainer
Definition: CodeView.h:609
llvm::yaml::MappingTraits< LocalVariableAddrRange >::mapping
static void mapping(IO &io, LocalVariableAddrRange &Range)
Definition: CodeViewYAMLSymbols.cpp:212
llvm::COFF::header
Definition: COFF.h:64
fromCodeViewSymbolImpl
static Expected< CodeViewYAML::SymbolRecord > fromCodeViewSymbolImpl(CVSymbol Symbol)
Definition: CodeViewYAMLSymbols.cpp:609
llvm::codeview::TypeIndex
A 32-bit type reference.
Definition: TypeIndex.h:96
llvm::codeview::getExportSymFlagNames
ArrayRef< EnumEntry< uint16_t > > getExportSymFlagNames()
Definition: EnumTables.cpp:496
llvm::codeview::CompileSym3Flags
CompileSym3Flags
Corresponds to COMPILESYM3::Flags bitfield.
Definition: CodeView.h:463
CodeViewError.h
llvm::codeview::ExportFlags
ExportFlags
Definition: CodeView.h:481
llvm::yaml::MappingTraits< SymbolRecordBase >::mapping
static void mapping(IO &io, SymbolRecordBase &Record)
Definition: CodeViewYAMLSymbols.cpp:601
llvm::codeview::CPUType::Pentium3
@ Pentium3
llvm::CodeViewYAML::detail::SymbolRecordImpl::Symbol
T Symbol
Definition: CodeViewYAMLSymbols.cpp:260
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::codeview::LocalVariableAddrGap::Range
uint16_t Range
Definition: SymbolRecord.h:431
llvm::codeview::getRegisterNames
ArrayRef< EnumEntry< uint16_t > > getRegisterNames(CPUType Cpu)
Definition: EnumTables.cpp:447
ScopedPrinter.h