1 //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines classes for handling the YAML representation of CodeView
13 //===----------------------------------------------------------------------===//
15 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
19 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
20 #include "llvm/DebugInfo/CodeView/EnumTables.h"
21 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
22 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
25 using namespace llvm::codeview;
26 using namespace llvm::CodeViewYAML;
27 using namespace llvm::CodeViewYAML::detail;
28 using namespace llvm::yaml;
30 LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef)
31 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex)
33 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp
34 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, false)
35 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, false)
37 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind)
39 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags)
40 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags)
41 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags)
42 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags)
43 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags)
44 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions)
45 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType)
46 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId)
47 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType)
48 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal)
50 void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io,
52 auto SymbolNames = getSymbolTypeNames();
53 for (const auto &E : SymbolNames)
54 io.enumCase(Value, E.Name.str().c_str(), E.Value);
57 void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io,
58 CompileSym2Flags &Flags) {
59 auto FlagNames = getCompileSym2FlagNames();
60 for (const auto &E : FlagNames) {
61 io.bitSetCase(Flags, E.Name.str().c_str(),
62 static_cast<CompileSym2Flags>(E.Value));
66 void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io,
67 CompileSym3Flags &Flags) {
68 auto FlagNames = getCompileSym3FlagNames();
69 for (const auto &E : FlagNames) {
70 io.bitSetCase(Flags, E.Name.str().c_str(),
71 static_cast<CompileSym3Flags>(E.Value));
75 void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) {
76 auto FlagNames = getExportSymFlagNames();
77 for (const auto &E : FlagNames) {
78 io.bitSetCase(Flags, E.Name.str().c_str(),
79 static_cast<ExportFlags>(E.Value));
83 void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) {
84 auto FlagNames = getLocalFlagNames();
85 for (const auto &E : FlagNames) {
86 io.bitSetCase(Flags, E.Name.str().c_str(),
87 static_cast<LocalSymFlags>(E.Value));
91 void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) {
92 auto FlagNames = getProcSymFlagNames();
93 for (const auto &E : FlagNames) {
94 io.bitSetCase(Flags, E.Name.str().c_str(),
95 static_cast<ProcSymFlags>(E.Value));
99 void ScalarBitSetTraits<FrameProcedureOptions>::bitset(
100 IO &io, FrameProcedureOptions &Flags) {
101 auto FlagNames = getFrameProcSymFlagNames();
102 for (const auto &E : FlagNames) {
103 io.bitSetCase(Flags, E.Name.str().c_str(),
104 static_cast<FrameProcedureOptions>(E.Value));
108 void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) {
109 auto CpuNames = getCPUTypeNames();
110 for (const auto &E : CpuNames) {
111 io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value));
115 void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) {
116 auto RegNames = getRegisterNames();
117 for (const auto &E : RegNames) {
118 io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value));
120 io.enumFallback<Hex16>(Reg);
123 void ScalarEnumerationTraits<TrampolineType>::enumeration(
124 IO &io, TrampolineType &Tramp) {
125 auto TrampNames = getTrampolineNames();
126 for (const auto &E : TrampNames) {
127 io.enumCase(Tramp, E.Name.str().c_str(),
128 static_cast<TrampolineType>(E.Value));
132 void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io,
134 auto ThunkNames = getThunkOrdinalNames();
135 for (const auto &E : ThunkNames) {
136 io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value));
141 namespace CodeViewYAML {
144 struct SymbolRecordBase {
145 codeview::SymbolKind Kind;
146 explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {}
148 virtual ~SymbolRecordBase() {}
149 virtual void map(yaml::IO &io) = 0;
150 virtual codeview::CVSymbol
151 toCodeViewSymbol(BumpPtrAllocator &Allocator) const = 0;
152 virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0;
155 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase {
156 explicit SymbolRecordImpl(codeview::SymbolKind K)
157 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {}
159 void map(yaml::IO &io) override;
162 toCodeViewSymbol(BumpPtrAllocator &Allocator) const override {
163 return SymbolSerializer::writeOneSymbol(Symbol, Allocator);
165 Error fromCodeViewSymbol(codeview::CVSymbol CVS) override {
166 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol);
172 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {}
174 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) {
175 IO.mapRequired("Parent", Symbol.Parent);
176 IO.mapRequired("End", Symbol.End);
177 IO.mapRequired("Next", Symbol.Next);
178 IO.mapRequired("Off", Symbol.Offset);
179 IO.mapRequired("Seg", Symbol.Segment);
180 IO.mapRequired("Len", Symbol.Length);
181 IO.mapRequired("Ordinal", Symbol.Thunk);
184 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) {
185 IO.mapRequired("Type", Symbol.Type);
186 IO.mapRequired("Size", Symbol.Size);
187 IO.mapRequired("ThunkOff", Symbol.ThunkOffset);
188 IO.mapRequired("TargetOff", Symbol.TargetOffset);
189 IO.mapRequired("ThunkSection", Symbol.ThunkSection);
190 IO.mapRequired("TargetSection", Symbol.TargetSection);
193 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) {
194 IO.mapRequired("SectionNumber", Symbol.SectionNumber);
195 IO.mapRequired("Alignment", Symbol.Alignment);
196 IO.mapRequired("Rva", Symbol.Rva);
197 IO.mapRequired("Length", Symbol.Length);
198 IO.mapRequired("Characteristics", Symbol.Characteristics);
199 IO.mapRequired("Name", Symbol.Name);
202 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) {
203 IO.mapRequired("Size", Symbol.Size);
204 IO.mapRequired("Characteristics", Symbol.Characteristics);
205 IO.mapRequired("Offset", Symbol.Offset);
206 IO.mapRequired("Segment", Symbol.Segment);
207 IO.mapRequired("Name", Symbol.Name);
210 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) {
211 IO.mapRequired("Ordinal", Symbol.Ordinal);
212 IO.mapRequired("Flags", Symbol.Flags);
213 IO.mapRequired("Name", Symbol.Name);
216 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) {
217 // TODO: Print the linkage name
219 IO.mapRequired("PtrParent", Symbol.Parent);
220 IO.mapRequired("PtrEnd", Symbol.End);
221 IO.mapRequired("PtrNext", Symbol.Next);
222 IO.mapRequired("CodeSize", Symbol.CodeSize);
223 IO.mapRequired("DbgStart", Symbol.DbgStart);
224 IO.mapRequired("DbgEnd", Symbol.DbgEnd);
225 IO.mapRequired("FunctionType", Symbol.FunctionType);
226 IO.mapRequired("Segment", Symbol.Segment);
227 IO.mapRequired("Flags", Symbol.Flags);
228 IO.mapRequired("DisplayName", Symbol.Name);
231 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) {
232 IO.mapRequired("Type", Symbol.Index);
233 IO.mapRequired("Seg", Symbol.Register);
234 IO.mapRequired("Name", Symbol.Name);
237 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) {
238 IO.mapRequired("Type", Symbol.Index);
239 IO.mapRequired("Seg", Symbol.Segment);
240 IO.mapRequired("Off", Symbol.Offset);
241 IO.mapRequired("Name", Symbol.Name);
244 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) {
245 IO.mapRequired("SumName", Symbol.SumName);
246 IO.mapRequired("SymOffset", Symbol.SymOffset);
247 IO.mapRequired("Mod", Symbol.Module);
248 IO.mapRequired("Name", Symbol.Name);
251 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) {
252 IO.mapRequired("Entries", Symbol.Fields);
255 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) {
256 IO.mapRequired("PtrParent", Symbol.Parent);
257 IO.mapRequired("PtrEnd", Symbol.End);
258 IO.mapRequired("Inlinee", Symbol.Inlinee);
259 // TODO: The binary annotations
262 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) {
263 IO.mapRequired("Type", Symbol.Type);
264 IO.mapRequired("Flags", Symbol.Flags);
265 IO.mapRequired("VarName", Symbol.Name);
268 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) {
269 // TODO: Print the subfields
272 template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) {
273 // TODO: Print the subfields
276 template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) {
277 // TODO: Print the subfields
280 template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) {
281 // TODO: Print the subfields
284 template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) {
285 // TODO: Print the subfields
289 void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) {
290 // TODO: Print the subfields
293 template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) {
294 // TODO: Print the subfields
297 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) {
298 // TODO: Print the linkage name
299 IO.mapRequired("PtrParent", Symbol.Parent);
300 IO.mapRequired("PtrEnd", Symbol.End);
301 IO.mapRequired("CodeSize", Symbol.CodeSize);
302 IO.mapRequired("Segment", Symbol.Segment);
303 IO.mapRequired("BlockName", Symbol.Name);
306 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) {
307 // TODO: Print the linkage name
308 IO.mapRequired("Segment", Symbol.Segment);
309 IO.mapRequired("Flags", Symbol.Flags);
310 IO.mapRequired("Flags", Symbol.Flags);
311 IO.mapRequired("DisplayName", Symbol.Name);
314 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) {
315 IO.mapRequired("Signature", Symbol.Signature);
316 IO.mapRequired("ObjectName", Symbol.Name);
319 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) {
320 IO.mapRequired("Flags", Symbol.Flags);
321 IO.mapRequired("Machine", Symbol.Machine);
322 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
323 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
324 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
325 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
326 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
327 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
328 IO.mapRequired("Version", Symbol.Version);
331 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) {
332 IO.mapRequired("Flags", Symbol.Flags);
333 IO.mapRequired("Machine", Symbol.Machine);
334 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor);
335 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor);
336 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild);
337 IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE);
338 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor);
339 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor);
340 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild);
341 IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE);
342 IO.mapRequired("Version", Symbol.Version);
345 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) {
346 IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes);
347 IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes);
348 IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding);
349 IO.mapRequired("BytesOfCalleeSavedRegisters",
350 Symbol.BytesOfCalleeSavedRegisters);
351 IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler);
352 IO.mapRequired("SectionIdOfExceptionHandler",
353 Symbol.SectionIdOfExceptionHandler);
354 IO.mapRequired("Flags", Symbol.Flags);
357 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) {
358 // TODO: Map Linkage Name
359 IO.mapRequired("Segment", Symbol.Segment);
360 IO.mapRequired("Type", Symbol.Type);
363 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) {
364 IO.mapRequired("Index", Symbol.Index);
365 IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset);
366 IO.mapRequired("Flags", Symbol.Flags);
367 IO.mapRequired("Name", Symbol.Name);
370 template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) {
371 // TODO: Map Linkage Name
372 IO.mapRequired("Segment", Symbol.Segment);
373 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize);
374 IO.mapRequired("Type", Symbol.Type);
377 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) {
378 // TODO: Map Linkage Name
379 IO.mapRequired("Register", Symbol.Register);
380 IO.mapRequired("CookieKind", Symbol.CookieKind);
381 IO.mapRequired("Flags", Symbol.Flags);
384 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) {
385 IO.mapRequired("FuncID", Symbol.Indices);
388 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) {
389 IO.mapRequired("Type", Symbol.Type);
390 IO.mapRequired("UDTName", Symbol.Name);
393 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) {
394 IO.mapRequired("BuildId", Symbol.BuildId);
397 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) {
398 IO.mapRequired("Offset", Symbol.Offset);
399 IO.mapRequired("Type", Symbol.Type);
400 IO.mapRequired("VarName", Symbol.Name);
403 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) {
404 IO.mapRequired("Offset", Symbol.Offset);
405 IO.mapRequired("Type", Symbol.Type);
406 IO.mapRequired("Register", Symbol.Register);
407 IO.mapRequired("VarName", Symbol.Name);
410 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) {
411 IO.mapRequired("Type", Symbol.Type);
412 IO.mapRequired("Value", Symbol.Value);
413 IO.mapRequired("Name", Symbol.Name);
416 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) {
417 // TODO: Map linkage name
418 IO.mapRequired("Type", Symbol.Type);
419 IO.mapRequired("DisplayName", Symbol.Name);
422 template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) {
423 // TODO: Map linkage name
424 IO.mapRequired("Type", Symbol.Type);
425 IO.mapRequired("DisplayName", Symbol.Name);
431 CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol(
432 BumpPtrAllocator &Allocator) const {
433 return Symbol->toCodeViewSymbol(Allocator);
438 template <> struct MappingTraits<SymbolRecordBase> {
439 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); }
444 template <typename SymbolType>
445 static inline Expected<CodeViewYAML::SymbolRecord>
446 fromCodeViewSymbolImpl(CVSymbol Symbol) {
447 CodeViewYAML::SymbolRecord Result;
449 auto Impl = std::make_shared<SymbolRecordImpl<SymbolType>>(Symbol.kind());
450 if (auto EC = Impl->fromCodeViewSymbol(Symbol))
451 return std::move(EC);
452 Result.Symbol = Impl;
456 Expected<CodeViewYAML::SymbolRecord>
457 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) {
458 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
460 return fromCodeViewSymbolImpl<ClassName>(Symbol);
461 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
462 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
463 switch (Symbol.kind()) {
464 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
465 default: { llvm_unreachable("Unknown symbol kind!"); }
467 return make_error<CodeViewError>(cv_error_code::corrupt_record);
470 template <typename ConcreteType>
471 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind,
472 CodeViewYAML::SymbolRecord &Obj) {
473 if (!IO.outputting())
474 Obj.Symbol = std::make_shared<SymbolRecordImpl<ConcreteType>>(Kind);
476 IO.mapRequired(Class, *Obj.Symbol);
479 void MappingTraits<CodeViewYAML::SymbolRecord>::mapping(
480 IO &IO, CodeViewYAML::SymbolRecord &Obj) {
483 Kind = Obj.Symbol->Kind;
484 IO.mapRequired("Kind", Kind);
486 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \
488 mapSymbolRecordImpl<ClassName>(IO, #ClassName, Kind, Obj); \
490 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \
491 SYMBOL_RECORD(EnumName, EnumVal, ClassName)
493 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
494 default: { llvm_unreachable("Unknown symbol kind!"); }