LLVM 19.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
65
67
68LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single)
69
70StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) {
71 return ScalarTraits<StringRef>::input(S, V, T.value);
72}
73
74void ScalarTraits<TypeName>::output(const TypeName &T, void *V,
75 raw_ostream &R) {
76 ScalarTraits<StringRef>::output(T.value, V, R);
77}
78
79void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
81 auto SymbolNames = getSymbolTypeNames();
82 for (const auto &E : SymbolNames)
83 io.enumCase(Value, E.Name.str().c_str(), E.Value);
84}
85
86void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
87 CompileSym2Flags &Flags) {
88 auto FlagNames = getCompileSym2FlagNames();
89 for (const auto &E : FlagNames) {
90 io.bitSetCase(Flags, E.Name.str().c_str(),
91 static_cast<CompileSym2Flags>(E.Value));
92 }
93}
94
95void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
96 CompileSym3Flags &Flags) {
97 auto FlagNames = getCompileSym3FlagNames();
98 for (const auto &E : FlagNames) {
99 io.bitSetCase(Flags, E.Name.str().c_str(),
100 static_cast<CompileSym3Flags>(E.Value));
101 }
102}
103
104void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
105 auto FlagNames = getExportSymFlagNames();
106 for (const auto &E : FlagNames) {
107 io.bitSetCase(Flags, E.Name.str().c_str(),
108 static_cast<ExportFlags>(E.Value));
109 }
110}
111
112void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) {
113 auto FlagNames = getPublicSymFlagNames();
114 for (const auto &E : FlagNames) {
115 io.bitSetCase(Flags, E.Name.str().c_str(),
116 static_cast<PublicSymFlags>(E.Value));
117 }
118}
119
120void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
121 auto FlagNames = getLocalFlagNames();
122 for (const auto &E : FlagNames) {
123 io.bitSetCase(Flags, E.Name.str().c_str(),
124 static_cast<LocalSymFlags>(E.Value));
125 }
126}
127
128void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
129 auto FlagNames = getProcSymFlagNames();
130 for (const auto &E : FlagNames) {
131 io.bitSetCase(Flags, E.Name.str().c_str(),
132 static_cast<ProcSymFlags>(E.Value));
133 }
134}
135
136void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
137 IO &io, FrameProcedureOptions &Flags) {
138 auto FlagNames = getFrameProcSymFlagNames();
139 for (const auto &E : FlagNames) {
140 io.bitSetCase(Flags, E.Name.str().c_str(),
141 static_cast<FrameProcedureOptions>(E.Value));
142 }
143}
144
145void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
146 auto CpuNames = getCPUTypeNames();
147 for (const auto &E : CpuNames) {
148 io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
149 }
150}
151
152void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
153 const auto *Header = static_cast<COFF::header *>(io.getContext());
154 assert(Header && "The IO context is not initialized");
155
156 std::optional<CPUType> CpuType;
158
159 switch (Header->Machine) {
161 CpuType = CPUType::Pentium3;
162 break;
164 CpuType = CPUType::X64;
165 break;
167 CpuType = CPUType::ARMNT;
168 break;
172 CpuType = CPUType::ARM64;
173 break;
174 }
175
176 if (CpuType)
177 RegNames = getRegisterNames(*CpuType);
178
179 for (const auto &E : RegNames) {
180 io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
181 }
182 io.enumFallback<Hex16>(Reg);
183}
184
185void ScalarEnumerationTraits<TrampolineType>::enumeration(
186 IO &io, TrampolineType &Tramp) {
187 auto TrampNames = getTrampolineNames();
188 for (const auto &E : TrampNames) {
189 io.enumCase(Tramp, E.Name.str().c_str(),
190 static_cast<TrampolineType>(E.Value));
191 }
192}
193
194void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
195 ThunkOrdinal &Ord) {
196 auto ThunkNames = getThunkOrdinalNames();
197 for (const auto &E : ThunkNames) {
198 io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
199 }
200}
201
202void ScalarEnumerationTraits<FrameCookieKind>::enumeration(
203 IO &io, FrameCookieKind &FC) {
204 auto ThunkNames = getFrameCookieKindNames();
205 for (const auto &E : ThunkNames) {
206 io.enumCase(FC, E.Name.str().c_str(),
207 static_cast<FrameCookieKind>(E.Value));
208 }
209}
210
211void ScalarEnumerationTraits<JumpTableEntrySize>::enumeration(
212 IO &io, JumpTableEntrySize &FC) {
213 auto ThunkNames = getJumpTableEntrySizeNames();
214 for (const auto &E : ThunkNames) {
215 io.enumCase(FC, E.Name.str().c_str(),
216 static_cast<JumpTableEntrySize>(E.Value));
217 }
218}
219
220namespace llvm {
221namespace yaml {
223 static void mapping(IO &io, LocalVariableAddrRange &Range) {
224 io.mapRequired("OffsetStart", Range.OffsetStart);
225 io.mapRequired("ISectStart", Range.ISectStart);
226 io.mapRequired("Range", Range.Range);
227 }
228};
230 static void mapping(IO &io, LocalVariableAddrGap &Gap) {
231 io.mapRequired("GapStartOffset", Gap.GapStartOffset);
232 io.mapRequired("Range", Gap.Range);
233 }
234};
235} // namespace yaml
236} // namespace llvm
237
238namespace llvm {
239namespace CodeViewYAML {
240namespace detail {
241
244
246 virtual ~SymbolRecordBase() = default;
247
248 virtual void map(yaml::IO &io) = 0;
249 virtual codeview::CVSymbol
251 CodeViewContainer Container) const = 0;
253};
254
255template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
257 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
258
259 void map(yaml::IO &io) override;
260
263 CodeViewContainer Container) const override {
265 }
266
268 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
269 }
270
271 mutable T Symbol;
272};
273
276
277 void map(yaml::IO &io) override;
278
280 CodeViewContainer Container) const override {
281 RecordPrefix Prefix;
282 uint32_t TotalLen = sizeof(RecordPrefix) + Data.size();
283 Prefix.RecordKind = Kind;
284 Prefix.RecordLen = TotalLen - 2;
285 uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen);
286 ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix));
287 ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size());
288 return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen));
289 }
290
292 this->Kind = CVS.kind();
293 Data = CVS.RecordData.drop_front(sizeof(RecordPrefix));
294 return Error::success();
295 }
296
297 std::vector<uint8_t> Data;
298};
299
300template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
301
302void UnknownSymbolRecord::map(yaml::IO &io) {
303 yaml::BinaryRef Binary;
304 if (io.outputting())
305 Binary = yaml::BinaryRef(Data);
306 io.mapRequired("Data", Binary);
307 if (!io.outputting()) {
308 std::string Str;
310 Binary.writeAsBinary(OS);
311 OS.flush();
312 Data.assign(Str.begin(), Str.end());
313 }
314}
315
316template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
317 IO.mapRequired("Parent", Symbol.Parent);
318 IO.mapRequired("End", Symbol.End);
319 IO.mapRequired("Next", Symbol.Next);
320 IO.mapRequired("Off", Symbol.Offset);
321 IO.mapRequired("Seg", Symbol.Segment);
322 IO.mapRequired("Len", Symbol.Length);
323 IO.mapRequired("Ordinal", Symbol.Thunk);
324}
325
326template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
327 IO.mapRequired("Type", Symbol.Type);
328 IO.mapRequired("Size", Symbol.Size);
329 IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
330 IO.mapRequired("TargetOff", Symbol.TargetOffset);
331 IO.mapRequired("ThunkSection", Symbol.ThunkSection);
332 IO.mapRequired("TargetSection", Symbol.TargetSection);
333}
334
335template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
336 IO.mapRequired("SectionNumber", Symbol.SectionNumber);
337 IO.mapRequired("Alignment", Symbol.Alignment);
338 IO.mapRequired("Rva", Symbol.Rva);
339 IO.mapRequired("Length", Symbol.Length);
340 IO.mapRequired("Characteristics", Symbol.Characteristics);
341 IO.mapRequired("Name", Symbol.Name);
342}
343
344template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
345 IO.mapRequired("Size", Symbol.Size);
346 IO.mapRequired("Characteristics", Symbol.Characteristics);
347 IO.mapRequired("Offset", Symbol.Offset);
348 IO.mapRequired("Segment", Symbol.Segment);
349 IO.mapRequired("Name", Symbol.Name);
350}
351
352template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
353 IO.mapRequired("Ordinal", Symbol.Ordinal);
354 IO.mapRequired("Flags", Symbol.Flags);
355 IO.mapRequired("Name", Symbol.Name);
356}
357
358template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
359 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
360 IO.mapOptional("PtrEnd", Symbol.End, 0U);
361 IO.mapOptional("PtrNext", Symbol.Next, 0U);
362 IO.mapRequired("CodeSize", Symbol.CodeSize);
363 IO.mapRequired("DbgStart", Symbol.DbgStart);
364 IO.mapRequired("DbgEnd", Symbol.DbgEnd);
365 IO.mapRequired("FunctionType", Symbol.FunctionType);
366 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
367 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
368 IO.mapRequired("Flags", Symbol.Flags);
369 IO.mapRequired("DisplayName", Symbol.Name);
370}
371
372template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
373 IO.mapRequired("Type", Symbol.Index);
374 IO.mapRequired("Seg", Symbol.Register);
375 IO.mapRequired("Name", Symbol.Name);
376}
377
378template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
379 IO.mapRequired("Flags", Symbol.Flags);
380 IO.mapOptional("Offset", Symbol.Offset, 0U);
381 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
382 IO.mapRequired("Name", Symbol.Name);
383}
384
385template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
386 IO.mapRequired("SumName", Symbol.SumName);
387 IO.mapRequired("SymOffset", Symbol.SymOffset);
388 IO.mapRequired("Mod", Symbol.Module);
389 IO.mapRequired("Name", Symbol.Name);
390}
391
392template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
393 IO.mapRequired("Entries", Symbol.Fields);
394}
395
396template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
397 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
398 IO.mapOptional("PtrEnd", Symbol.End, 0U);
399 IO.mapRequired("Inlinee", Symbol.Inlinee);
400 // TODO: The binary annotations
401}
402
403template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
404 IO.mapRequired("Type", Symbol.Type);
405 IO.mapRequired("Flags", Symbol.Flags);
406
407 IO.mapRequired("VarName", Symbol.Name);
408}
409
410template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
411 IO.mapRequired("Program", Symbol.Program);
412 IO.mapRequired("Range", Symbol.Range);
413 IO.mapRequired("Gaps", Symbol.Gaps);
414}
415
417 IO.mapRequired("Program", Symbol.Program);
418 IO.mapRequired("OffsetInParent", Symbol.OffsetInParent);
419 IO.mapRequired("Range", Symbol.Range);
420 IO.mapRequired("Gaps", Symbol.Gaps);
421}
422
424 IO.mapRequired("Register", Symbol.Hdr.Register);
425 IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
426 IO.mapRequired("Range", Symbol.Range);
427 IO.mapRequired("Gaps", Symbol.Gaps);
428}
429
431 IO.mapRequired("Offset", Symbol.Hdr.Offset);
432 IO.mapRequired("Range", Symbol.Range);
433 IO.mapRequired("Gaps", Symbol.Gaps);
434}
435
437 IO.mapRequired("Register", Symbol.Hdr.Register);
438 IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName);
439 IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent);
440 IO.mapRequired("Range", Symbol.Range);
441 IO.mapRequired("Gaps", Symbol.Gaps);
442}
443
444template <>
446 IO.mapRequired("Register", Symbol.Offset);
447}
448
450 IO.mapRequired("Register", Symbol.Hdr.Register);
451 IO.mapRequired("Flags", Symbol.Hdr.Flags);
452 IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset);
453 IO.mapRequired("Range", Symbol.Range);
454 IO.mapRequired("Gaps", Symbol.Gaps);
455}
456
457template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
458 IO.mapOptional("PtrParent", Symbol.Parent, 0U);
459 IO.mapOptional("PtrEnd", Symbol.End, 0U);
460 IO.mapRequired("CodeSize", Symbol.CodeSize);
461 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
462 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
463 IO.mapRequired("BlockName", Symbol.Name);
464}
465
466template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
467 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
468 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
469 IO.mapRequired("Flags", Symbol.Flags);
470 IO.mapRequired("Flags", Symbol.Flags);
471 IO.mapRequired("DisplayName", Symbol.Name);
472}
473
474template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
475 IO.mapRequired("Signature", Symbol.Signature);
476 IO.mapRequired("ObjectName", Symbol.Name);
477}
478
479template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
480 IO.mapRequired("Flags", Symbol.Flags);
481 IO.mapRequired("Machine", Symbol.Machine);
482 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
483 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
484 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
485 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
486 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
487 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
488 IO.mapRequired("Version", Symbol.Version);
489}
490
491template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
492 IO.mapRequired("Flags", Symbol.Flags);
493 IO.mapRequired("Machine", Symbol.Machine);
494 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
495 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
496 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
497 IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
498 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
499 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
500 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
501 IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
502 IO.mapRequired("Version", Symbol.Version);
503}
504
505template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
506 IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
507 IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
508 IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
509 IO.mapRequired("BytesOfCalleeSavedRegisters",
510 Symbol.BytesOfCalleeSavedRegisters);
511 IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
512 IO.mapRequired("SectionIdOfExceptionHandler",
513 Symbol.SectionIdOfExceptionHandler);
514 IO.mapRequired("Flags", Symbol.Flags);
515}
516
518 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
519 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
520 IO.mapRequired("Type", Symbol.Type);
521}
522
523template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
524 IO.mapRequired("Index", Symbol.Index);
525 IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
526 IO.mapRequired("Flags", Symbol.Flags);
527 IO.mapRequired("Name", Symbol.Name);
528}
529
531 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
532 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
533 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
534 IO.mapRequired("Type", Symbol.Type);
535}
536
538 IO.mapRequired("Register", Symbol.Register);
539 IO.mapRequired("CookieKind", Symbol.CookieKind);
540 IO.mapRequired("Flags", Symbol.Flags);
541}
542
543template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
544 IO.mapRequired("FuncID", Symbol.Indices);
545}
546
547template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
548 IO.mapRequired("Type", Symbol.Type);
549 IO.mapRequired("UDTName", Symbol.Name);
550}
551
552template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
553 IO.mapRequired("BuildId", Symbol.BuildId);
554}
555
556template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
557 IO.mapRequired("Offset", Symbol.Offset);
558 IO.mapRequired("Type", Symbol.Type);
559 IO.mapRequired("VarName", Symbol.Name);
560}
561
563 IO.mapRequired("Offset", Symbol.Offset);
564 IO.mapRequired("Type", Symbol.Type);
565 IO.mapRequired("Register", Symbol.Register);
566 IO.mapRequired("VarName", Symbol.Name);
567}
568
569template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
570 IO.mapRequired("Type", Symbol.Type);
571 IO.mapRequired("Value", Symbol.Value);
572 IO.mapRequired("Name", Symbol.Name);
573}
574
575template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
576 IO.mapRequired("Type", Symbol.Type);
577 IO.mapOptional("Offset", Symbol.DataOffset, 0U);
578 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
579 IO.mapRequired("DisplayName", Symbol.Name);
580}
581
583 IO.mapRequired("Type", Symbol.Type);
584 IO.mapOptional("Offset", Symbol.DataOffset, 0U);
585 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
586 IO.mapRequired("DisplayName", Symbol.Name);
587}
588
590 IO.mapRequired("Namespace", Symbol.Name);
591}
592
593template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) {
594 IO.mapOptional("Offset", Symbol.CodeOffset, 0U);
595 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0));
596 IO.mapRequired("Strings", Symbol.Strings);
597}
598
599template <> void SymbolRecordImpl<JumpTableSym>::map(IO &IO) {
600 IO.mapRequired("BaseOffset", Symbol.BaseOffset);
601 IO.mapRequired("BaseSegment", Symbol.BaseSegment);
602 IO.mapRequired("SwitchType", Symbol.SwitchType);
603 IO.mapRequired("BranchOffset", Symbol.BranchOffset);
604 IO.mapRequired("TableOffset", Symbol.TableOffset);
605 IO.mapRequired("BranchSegment", Symbol.BranchSegment);
606 IO.mapRequired("TableSegment", Symbol.TableSegment);
607 IO.mapRequired("EntriesCount", Symbol.EntriesCount);
608}
609
610} // end namespace detail
611} // end namespace CodeViewYAML
612} // end namespace llvm
613
615 BumpPtrAllocator &Allocator, CodeViewContainer Container) const {
616 return Symbol->toCodeViewSymbol(Allocator, Container);
617}
618
619namespace llvm {
620namespace yaml {
621
622template <> struct MappingTraits<SymbolRecordBase> {
623 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
624};
625
626} // end namespace yaml
627} // end namespace llvm
628
629template <typename SymbolType>
633
634 auto Impl = std::make_shared<SymbolType>(Symbol.kind());
635 if (auto EC = Impl->fromCodeViewSymbol(Symbol))
636 return std::move(EC);
637 Result.Symbol = Impl;
638 return Result;
639}
640
643#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
644 case EnumName: \
645 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol);
646#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
647 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
648 switch (Symbol.kind()) {
649#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
650 default:
651 return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol);
652 }
653 return make_error<CodeViewError>(cv_error_code::corrupt_record);
654}
655
656template <typename ConcreteType>
657static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
659 if (!IO.outputting())
660 Obj.Symbol = std::make_shared<ConcreteType>(Kind);
661
662 IO.mapRequired(Class, *Obj.Symbol);
663}
664
666 IO &IO, CodeViewYAML::SymbolRecord &Obj) {
668 if (IO.outputting())
669 Kind = Obj.Symbol->Kind;
670 IO.mapRequired("Kind", Kind);
671
672#define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
673 case EnumName: \
674 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \
675 Obj); \
676 break;
677#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
678 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
679 switch (Kind) {
680#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
681 default:
682 mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj);
683 }
684}
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:204
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:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
Tagged union holding either a T or a Error.
Definition: Error.h:474
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:660
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:104
@ IMAGE_FILE_MACHINE_ARM64X
Definition: COFF.h:102
@ 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:443
LocalSymFlags
Corresponds to CV_LVARFLAGS bitfield.
Definition: CodeView.h:416
CompileSym2Flags
Corresponds to COMPILESYM2::Flags bitfield.
Definition: CodeView.h:457
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
Definition: CodeView.h:76
CompileSym3Flags
Corresponds to COMPILESYM3::Flags bitfield.
Definition: CodeView.h:473
ArrayRef< EnumEntry< uint32_t > > getCompileSym2FlagNames()
Definition: EnumTables.cpp:495
ArrayRef< EnumEntry< uint16_t > > getExportSymFlagNames()
Definition: EnumTables.cpp:515
ArrayRef< EnumEntry< uint16_t > > getJumpTableEntrySizeNames()
Definition: EnumTables.cpp:580
SymbolRecordKind
Distinguishes individual records in the Symbols subsection of a .debug$S section.
Definition: CodeView.h:41
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
Definition: EnumTables.cpp:458
ThunkOrdinal
These values correspond to the THUNK_ORDINAL enumeration.
Definition: CodeView.h:563
ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
Definition: EnumTables.cpp:483
ArrayRef< EnumEntry< uint16_t > > getRegisterNames(CPUType Cpu)
Definition: EnumTables.cpp:466
ArrayRef< EnumEntry< uint8_t > > getThunkOrdinalNames()
Definition: EnumTables.cpp:523
ArrayRef< EnumEntry< uint8_t > > getProcSymFlagNames()
Definition: EnumTables.cpp:479
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:48
ArrayRef< EnumEntry< unsigned > > getCPUTypeNames()
Definition: EnumTables.cpp:507
CVRecord< SymbolKind > CVSymbol
Definition: CVRecord.h:65
ArrayRef< EnumEntry< uint32_t > > getFrameProcSymFlagNames()
Definition: EnumTables.cpp:511
ArrayRef< EnumEntry< uint16_t > > getTrampolineNames()
Definition: EnumTables.cpp:527
PublicSymFlags
Corresponds to the CV_PUBSYMFLAGS bitfield.
Definition: CodeView.h:433
ArrayRef< EnumEntry< uint32_t > > getPublicSymFlagNames()
Definition: EnumTables.cpp:475
ArrayRef< EnumEntry< uint32_t > > getCompileSym3FlagNames()
Definition: EnumTables.cpp:499
ArrayRef< EnumEntry< uint8_t > > getFrameCookieKindNames()
Definition: EnumTables.cpp:487
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)