LLVM 17.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"
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
37using namespace llvm;
38using namespace llvm::codeview;
39using namespace llvm::CodeViewYAML;
40using namespace llvm::CodeViewYAML::detail;
41using namespace llvm::yaml;
42
45
46// We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
49
52
64
66
67LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
68
69StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
70 return ScalarTraits<StringRef>::input(S, V, T.value);
71}
72
73void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
74 raw_ostream &R) {
75 ScalarTraits<StringRef>::output(T.value, V, R);
76}
77
78void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
80 auto SymbolNames = getSymbolTypeNames();
81 for (const auto &E : SymbolNames)
82 io.enumCase(Value, E.Name.str().c_str(), E.Value);
83}
84
85void 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
94void 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
103void 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
111void 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
119void 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
127void 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
135void 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
144void 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
151void 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
183void 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
192void 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
200void 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
209namespace llvm {
210namespace 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};
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
227namespace llvm {
228namespace CodeViewYAML {
229namespace detail {
230
233
235 virtual ~SymbolRecordBase() = default;
236
237 virtual void map(yaml::IO &io) = 0;
238 virtual codeview::CVSymbol
240 CodeViewContainer Container) const = 0;
242};
243
244template <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 {
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 {
270 RecordPrefix Prefix;
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
289template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
290
291void 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;
299 Binary.writeAsBinary(OS);
300 OS.flush();
301 Data.assign(Str.begin(), Str.end());
302 }
303}
304
305template <> 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
315template <> 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
324template <> 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
333template <> 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
341template <> 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
347template <> 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
361template <> 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
367template <> 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
374template <> 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
381template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
382 IO.mapRequired("Entries", Symbol.Fields);
383}
384
385template <> 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
392template <> 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
399template <> 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
433template <>
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
446template <> 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
455template <> 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
463template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
464 IO.mapRequired("Signature", Symbol.Signature);
465 IO.mapRequired("ObjectName", Symbol.Name);
466}
467
468template <> 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
480template <> 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
494template <> 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
507 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
508 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
509 IO.mapRequired("Type", Symbol.Type);
510}
511
512template <> 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
527 IO.mapRequired("Register", Symbol.Register);
528 IO.mapRequired("CookieKind", Symbol.CookieKind);
529 IO.mapRequired("Flags", Symbol.Flags);
530}
531
532template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
533 IO.mapRequired("FuncID", Symbol.Indices);
534}
535
536template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
537 IO.mapRequired("Type", Symbol.Type);
538 IO.mapRequired("UDTName", Symbol.Name);
539}
540
541template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
542 IO.mapRequired("BuildId", Symbol.BuildId);
543}
544
545template <> 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
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
558template <> 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
564template <> 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
582template <> 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
597namespace llvm {
598namespace yaml {
599
600template <> 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
607template <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
634template <typename ConcreteType>
635static 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}
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, CodeViewYAML::SymbolRecord &Obj)
static Expected< CodeViewYAML::SymbolRecord > fromCodeViewSymbolImpl(CVSymbol Symbol)
Basic Register Allocator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
#define LLVM_YAML_DECLARE_BITSET_TRAITS(Type)
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
#define LLVM_YAML_DECLARE_SCALAR_TRAITS(Type, MustQuote)
#define LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(type)
#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)
#define LLVM_YAML_DECLARE_ENUM_TRAITS(Type)
An arbitrary precision integer that knows its signedness.
Definition: APSInt.h:23
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition: ArrayRef.h:202
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
Tagged union holding either a T or a Error.
Definition: Error.h:470
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
CVRecord is a fat pointer (base + size pair) to a symbol or type record.
Definition: CVRecord.h:29
Kind kind() const
Definition: CVRecord.h:42
ArrayRef< uint8_t > RecordData
Definition: CVRecord.h:60
static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage, CodeViewContainer Container)
A 32-bit type reference.
Definition: TypeIndex.h:96
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
Specialized YAMLIO scalar type for representing a binary blob.
Definition: YAML.h:63
@ IMAGE_FILE_MACHINE_ARM64
Definition: COFF.h:100
@ IMAGE_FILE_MACHINE_AMD64
Definition: COFF.h:97
@ IMAGE_FILE_MACHINE_ARM64EC
Definition: COFF.h:101
@ IMAGE_FILE_MACHINE_I386
Definition: COFF.h:103
@ IMAGE_FILE_MACHINE_ARMNT
Definition: COFF.h:99
Reg
All possible values of the reg field in the ModR/M byte.
ProcSymFlags
Corresponds to the CV_PROCFLAGS bitfield.
Definition: CodeView.h:435
LocalSymFlags
Corresponds to CV_LVARFLAGS bitfield.
Definition: CodeView.h:408
CompileSym2Flags
Corresponds to COMPILESYM2::Flags bitfield.
Definition: CodeView.h:449
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
Definition: CodeView.h:75
CompileSym3Flags
Corresponds to COMPILESYM3::Flags bitfield.
Definition: CodeView.h:465
ArrayRef< EnumEntry< uint32_t > > getCompileSym2FlagNames()
Definition: EnumTables.cpp:477
ArrayRef< EnumEntry< uint16_t > > getExportSymFlagNames()
Definition: EnumTables.cpp:497
SymbolRecordKind
Distinguishes individual records in the Symbols subsection of a .debug$S section.
Definition: CodeView.h:40
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
Definition: EnumTables.cpp:440
ThunkOrdinal
These values correspond to the THUNK_ORDINAL enumeration.
Definition: CodeView.h:555
ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
Definition: EnumTables.cpp:465
ArrayRef< EnumEntry< uint16_t > > getRegisterNames(CPUType Cpu)
Definition: EnumTables.cpp:448
ArrayRef< EnumEntry< uint8_t > > getThunkOrdinalNames()
Definition: EnumTables.cpp:505
ArrayRef< EnumEntry< uint8_t > > getProcSymFlagNames()
Definition: EnumTables.cpp:461
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:47
ArrayRef< EnumEntry< unsigned > > getCPUTypeNames()
Definition: EnumTables.cpp:489
CVRecord< SymbolKind > CVSymbol
Definition: CVRecord.h:65
ArrayRef< EnumEntry< uint32_t > > getFrameProcSymFlagNames()
Definition: EnumTables.cpp:493
ArrayRef< EnumEntry< uint16_t > > getTrampolineNames()
Definition: EnumTables.cpp:509
PublicSymFlags
Corresponds to the CV_PUBSYMFLAGS bitfield.
Definition: CodeView.h:425
ArrayRef< EnumEntry< uint32_t > > getPublicSymFlagNames()
Definition: EnumTables.cpp:457
ArrayRef< EnumEntry< uint32_t > > getCompileSym3FlagNames()
Definition: EnumTables.cpp:481
ArrayRef< EnumEntry< uint8_t > > getFrameCookieKindNames()
Definition: EnumTables.cpp:469
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, codeview::CodeViewContainer Container) const
std::shared_ptr< detail::SymbolRecordBase > Symbol
static Expected< SymbolRecord > fromCodeViewSymbol(codeview::CVSymbol Symbol)
virtual codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, CodeViewContainer Container) const =0
virtual Error fromCodeViewSymbol(codeview::CVSymbol Type)=0
codeview::CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, CodeViewContainer Container) const override
Error fromCodeViewSymbol(codeview::CVSymbol CVS) override
CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, CodeViewContainer Container) const override
static void mapping(IO &io, LocalVariableAddrGap &Gap)
static void mapping(IO &io, LocalVariableAddrRange &Range)
static void mapping(IO &io, SymbolRecordBase &Record)