1 //===- CodeViewYAMLSymbols.cpp - CodeView YAMLIO Symbol implementation ----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines classes for handling the YAML representation of CodeView 11 // Debug Info. 12 // 13 //===----------------------------------------------------------------------===// 14 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" 23 24 using namespace llvm; 25 using namespace llvm::codeview; 26 using namespace llvm::CodeViewYAML; 27 using namespace llvm::CodeViewYAML::detail; 28 using namespace llvm::yaml; 29 30 LLVM_YAML_IS_SEQUENCE_VECTOR(StringRef) 31 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) 32 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) 36 37 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind) 38 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) 49 50 LLVM_YAML_STRONG_TYPEDEF(llvm::StringRef, TypeName) 51 52 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, true) 53 54 StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) { 55 return ScalarTraits<StringRef>::input(S, V, T.value); 56 } 57 void ScalarTraits<TypeName>::output(const TypeName &T, void *V, 58 llvm::raw_ostream &R) { 59 ScalarTraits<StringRef>::output(T.value, V, R); 60 } 61 62 void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io, 63 SymbolKind &Value) { 64 auto SymbolNames = getSymbolTypeNames(); 65 for (const auto &E : SymbolNames) 66 io.enumCase(Value, E.Name.str().c_str(), E.Value); 67 } 68 69 void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io, 70 CompileSym2Flags &Flags) { 71 auto FlagNames = getCompileSym2FlagNames(); 72 for (const auto &E : FlagNames) { 73 io.bitSetCase(Flags, E.Name.str().c_str(), 74 static_cast<CompileSym2Flags>(E.Value)); 75 } 76 } 77 78 void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io, 79 CompileSym3Flags &Flags) { 80 auto FlagNames = getCompileSym3FlagNames(); 81 for (const auto &E : FlagNames) { 82 io.bitSetCase(Flags, E.Name.str().c_str(), 83 static_cast<CompileSym3Flags>(E.Value)); 84 } 85 } 86 87 void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) { 88 auto FlagNames = getExportSymFlagNames(); 89 for (const auto &E : FlagNames) { 90 io.bitSetCase(Flags, E.Name.str().c_str(), 91 static_cast<ExportFlags>(E.Value)); 92 } 93 } 94 95 void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) { 96 auto FlagNames = getLocalFlagNames(); 97 for (const auto &E : FlagNames) { 98 io.bitSetCase(Flags, E.Name.str().c_str(), 99 static_cast<LocalSymFlags>(E.Value)); 100 } 101 } 102 103 void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) { 104 auto FlagNames = getProcSymFlagNames(); 105 for (const auto &E : FlagNames) { 106 io.bitSetCase(Flags, E.Name.str().c_str(), 107 static_cast<ProcSymFlags>(E.Value)); 108 } 109 } 110 111 void ScalarBitSetTraits<FrameProcedureOptions>::bitset( 112 IO &io, FrameProcedureOptions &Flags) { 113 auto FlagNames = getFrameProcSymFlagNames(); 114 for (const auto &E : FlagNames) { 115 io.bitSetCase(Flags, E.Name.str().c_str(), 116 static_cast<FrameProcedureOptions>(E.Value)); 117 } 118 } 119 120 void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) { 121 auto CpuNames = getCPUTypeNames(); 122 for (const auto &E : CpuNames) { 123 io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value)); 124 } 125 } 126 127 void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) { 128 auto RegNames = getRegisterNames(); 129 for (const auto &E : RegNames) { 130 io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value)); 131 } 132 io.enumFallback<Hex16>(Reg); 133 } 134 135 void ScalarEnumerationTraits<TrampolineType>::enumeration( 136 IO &io, TrampolineType &Tramp) { 137 auto TrampNames = getTrampolineNames(); 138 for (const auto &E : TrampNames) { 139 io.enumCase(Tramp, E.Name.str().c_str(), 140 static_cast<TrampolineType>(E.Value)); 141 } 142 } 143 144 void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io, 145 ThunkOrdinal &Ord) { 146 auto ThunkNames = getThunkOrdinalNames(); 147 for (const auto &E : ThunkNames) { 148 io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value)); 149 } 150 } 151 152 namespace llvm { 153 namespace CodeViewYAML { 154 namespace detail { 155 156 struct SymbolRecordBase { 157 codeview::SymbolKind Kind; 158 explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {} 159 160 virtual ~SymbolRecordBase() {} 161 virtual void map(yaml::IO &io) = 0; 162 virtual codeview::CVSymbol 163 toCodeViewSymbol(BumpPtrAllocator &Allocator, 164 CodeViewContainer Container) const = 0; 165 virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0; 166 }; 167 168 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase { 169 explicit SymbolRecordImpl(codeview::SymbolKind K) 170 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {} 171 172 void map(yaml::IO &io) override; 173 174 codeview::CVSymbol 175 toCodeViewSymbol(BumpPtrAllocator &Allocator, 176 CodeViewContainer Container) const override { 177 return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container); 178 } 179 Error fromCodeViewSymbol(codeview::CVSymbol CVS) override { 180 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol); 181 } 182 183 mutable T Symbol; 184 }; 185 186 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {} 187 188 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) { 189 IO.mapRequired("Parent", Symbol.Parent); 190 IO.mapRequired("End", Symbol.End); 191 IO.mapRequired("Next", Symbol.Next); 192 IO.mapRequired("Off", Symbol.Offset); 193 IO.mapRequired("Seg", Symbol.Segment); 194 IO.mapRequired("Len", Symbol.Length); 195 IO.mapRequired("Ordinal", Symbol.Thunk); 196 } 197 198 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) { 199 IO.mapRequired("Type", Symbol.Type); 200 IO.mapRequired("Size", Symbol.Size); 201 IO.mapRequired("ThunkOff", Symbol.ThunkOffset); 202 IO.mapRequired("TargetOff", Symbol.TargetOffset); 203 IO.mapRequired("ThunkSection", Symbol.ThunkSection); 204 IO.mapRequired("TargetSection", Symbol.TargetSection); 205 } 206 207 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) { 208 IO.mapRequired("SectionNumber", Symbol.SectionNumber); 209 IO.mapRequired("Alignment", Symbol.Alignment); 210 IO.mapRequired("Rva", Symbol.Rva); 211 IO.mapRequired("Length", Symbol.Length); 212 IO.mapRequired("Characteristics", Symbol.Characteristics); 213 IO.mapRequired("Name", Symbol.Name); 214 } 215 216 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) { 217 IO.mapRequired("Size", Symbol.Size); 218 IO.mapRequired("Characteristics", Symbol.Characteristics); 219 IO.mapRequired("Offset", Symbol.Offset); 220 IO.mapRequired("Segment", Symbol.Segment); 221 IO.mapRequired("Name", Symbol.Name); 222 } 223 224 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) { 225 IO.mapRequired("Ordinal", Symbol.Ordinal); 226 IO.mapRequired("Flags", Symbol.Flags); 227 IO.mapRequired("Name", Symbol.Name); 228 } 229 230 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) { 231 // TODO: Print the linkage name 232 233 IO.mapRequired("PtrParent", Symbol.Parent); 234 IO.mapRequired("PtrEnd", Symbol.End); 235 IO.mapRequired("PtrNext", Symbol.Next); 236 IO.mapRequired("CodeSize", Symbol.CodeSize); 237 IO.mapRequired("DbgStart", Symbol.DbgStart); 238 IO.mapRequired("DbgEnd", Symbol.DbgEnd); 239 IO.mapRequired("FunctionType", Symbol.FunctionType); 240 IO.mapRequired("Segment", Symbol.Segment); 241 IO.mapRequired("Flags", Symbol.Flags); 242 IO.mapRequired("DisplayName", Symbol.Name); 243 } 244 245 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) { 246 IO.mapRequired("Type", Symbol.Index); 247 IO.mapRequired("Seg", Symbol.Register); 248 IO.mapRequired("Name", Symbol.Name); 249 } 250 251 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) { 252 IO.mapRequired("Type", Symbol.Index); 253 IO.mapRequired("Seg", Symbol.Segment); 254 IO.mapRequired("Off", Symbol.Offset); 255 IO.mapRequired("Name", Symbol.Name); 256 } 257 258 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) { 259 IO.mapRequired("SumName", Symbol.SumName); 260 IO.mapRequired("SymOffset", Symbol.SymOffset); 261 IO.mapRequired("Mod", Symbol.Module); 262 IO.mapRequired("Name", Symbol.Name); 263 } 264 265 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) { 266 IO.mapRequired("Entries", Symbol.Fields); 267 } 268 269 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) { 270 IO.mapRequired("PtrParent", Symbol.Parent); 271 IO.mapRequired("PtrEnd", Symbol.End); 272 IO.mapRequired("Inlinee", Symbol.Inlinee); 273 // TODO: The binary annotations 274 } 275 276 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) { 277 IO.mapRequired("Type", Symbol.Type); 278 IO.mapRequired("Flags", Symbol.Flags); 279 280 IO.mapRequired("VarName", Symbol.Name); 281 } 282 283 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) { 284 // TODO: Print the subfields 285 } 286 287 template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) { 288 // TODO: Print the subfields 289 } 290 291 template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { 292 // TODO: Print the subfields 293 } 294 295 template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { 296 // TODO: Print the subfields 297 } 298 299 template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) { 300 // TODO: Print the subfields 301 } 302 303 template <> 304 void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) { 305 // TODO: Print the subfields 306 } 307 308 template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) { 309 // TODO: Print the subfields 310 } 311 312 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) { 313 // TODO: Print the linkage name 314 IO.mapRequired("PtrParent", Symbol.Parent); 315 IO.mapRequired("PtrEnd", Symbol.End); 316 IO.mapRequired("CodeSize", Symbol.CodeSize); 317 IO.mapRequired("Segment", Symbol.Segment); 318 IO.mapRequired("BlockName", Symbol.Name); 319 } 320 321 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) { 322 // TODO: Print the linkage name 323 IO.mapRequired("Segment", Symbol.Segment); 324 IO.mapRequired("Flags", Symbol.Flags); 325 IO.mapRequired("Flags", Symbol.Flags); 326 IO.mapRequired("DisplayName", Symbol.Name); 327 } 328 329 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) { 330 IO.mapRequired("Signature", Symbol.Signature); 331 IO.mapRequired("ObjectName", Symbol.Name); 332 } 333 334 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) { 335 IO.mapRequired("Flags", Symbol.Flags); 336 IO.mapRequired("Machine", Symbol.Machine); 337 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 338 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 339 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 340 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 341 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 342 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 343 IO.mapRequired("Version", Symbol.Version); 344 } 345 346 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) { 347 IO.mapRequired("Flags", Symbol.Flags); 348 IO.mapRequired("Machine", Symbol.Machine); 349 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 350 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 351 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 352 IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE); 353 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 354 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 355 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 356 IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE); 357 IO.mapRequired("Version", Symbol.Version); 358 } 359 360 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) { 361 IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes); 362 IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes); 363 IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding); 364 IO.mapRequired("BytesOfCalleeSavedRegisters", 365 Symbol.BytesOfCalleeSavedRegisters); 366 IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler); 367 IO.mapRequired("SectionIdOfExceptionHandler", 368 Symbol.SectionIdOfExceptionHandler); 369 IO.mapRequired("Flags", Symbol.Flags); 370 } 371 372 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) { 373 // TODO: Map Linkage Name 374 IO.mapRequired("Segment", Symbol.Segment); 375 IO.mapRequired("Type", Symbol.Type); 376 } 377 378 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) { 379 IO.mapRequired("Index", Symbol.Index); 380 IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset); 381 IO.mapRequired("Flags", Symbol.Flags); 382 IO.mapRequired("Name", Symbol.Name); 383 } 384 385 template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) { 386 // TODO: Map Linkage Name 387 IO.mapRequired("Segment", Symbol.Segment); 388 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize); 389 IO.mapRequired("Type", Symbol.Type); 390 } 391 392 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) { 393 // TODO: Map Linkage Name 394 IO.mapRequired("Register", Symbol.Register); 395 IO.mapRequired("CookieKind", Symbol.CookieKind); 396 IO.mapRequired("Flags", Symbol.Flags); 397 } 398 399 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) { 400 IO.mapRequired("FuncID", Symbol.Indices); 401 } 402 403 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) { 404 IO.mapRequired("Type", Symbol.Type); 405 IO.mapRequired("UDTName", Symbol.Name); 406 } 407 408 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) { 409 IO.mapRequired("BuildId", Symbol.BuildId); 410 } 411 412 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) { 413 IO.mapRequired("Offset", Symbol.Offset); 414 IO.mapRequired("Type", Symbol.Type); 415 IO.mapRequired("VarName", Symbol.Name); 416 } 417 418 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) { 419 IO.mapRequired("Offset", Symbol.Offset); 420 IO.mapRequired("Type", Symbol.Type); 421 IO.mapRequired("Register", Symbol.Register); 422 IO.mapRequired("VarName", Symbol.Name); 423 } 424 425 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) { 426 IO.mapRequired("Type", Symbol.Type); 427 IO.mapRequired("Value", Symbol.Value); 428 IO.mapRequired("Name", Symbol.Name); 429 } 430 431 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) { 432 // TODO: Map linkage name 433 IO.mapRequired("Type", Symbol.Type); 434 IO.mapRequired("DisplayName", Symbol.Name); 435 } 436 437 template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) { 438 // TODO: Map linkage name 439 IO.mapRequired("Type", Symbol.Type); 440 IO.mapRequired("DisplayName", Symbol.Name); 441 } 442 } 443 } 444 } 445 446 CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol( 447 BumpPtrAllocator &Allocator, CodeViewContainer Container) const { 448 return Symbol->toCodeViewSymbol(Allocator, Container); 449 } 450 451 namespace llvm { 452 namespace yaml { 453 template <> struct MappingTraits<SymbolRecordBase> { 454 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); } 455 }; 456 } 457 } 458 459 template <typename SymbolType> 460 static inline Expected<CodeViewYAML::SymbolRecord> 461 fromCodeViewSymbolImpl(CVSymbol Symbol) { 462 CodeViewYAML::SymbolRecord Result; 463 464 auto Impl = std::make_shared<SymbolRecordImpl<SymbolType>>(Symbol.kind()); 465 if (auto EC = Impl->fromCodeViewSymbol(Symbol)) 466 return std::move(EC); 467 Result.Symbol = Impl; 468 return Result; 469 } 470 471 Expected<CodeViewYAML::SymbolRecord> 472 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { 473 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 474 case EnumName: \ 475 return fromCodeViewSymbolImpl<ClassName>(Symbol); 476 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 477 SYMBOL_RECORD(EnumName, EnumVal, ClassName) 478 switch (Symbol.kind()) { 479 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 480 default: { llvm_unreachable("Unknown symbol kind!"); } 481 } 482 return make_error<CodeViewError>(cv_error_code::corrupt_record); 483 } 484 485 template <typename ConcreteType> 486 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, 487 CodeViewYAML::SymbolRecord &Obj) { 488 if (!IO.outputting()) 489 Obj.Symbol = std::make_shared<SymbolRecordImpl<ConcreteType>>(Kind); 490 491 IO.mapRequired(Class, *Obj.Symbol); 492 } 493 494 void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( 495 IO &IO, CodeViewYAML::SymbolRecord &Obj) { 496 SymbolKind Kind; 497 if (IO.outputting()) 498 Kind = Obj.Symbol->Kind; 499 IO.mapRequired("Kind", Kind); 500 501 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 502 case EnumName: \ 503 mapSymbolRecordImpl<ClassName>(IO, #ClassName, Kind, Obj); \ 504 break; 505 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 506 SYMBOL_RECORD(EnumName, EnumVal, ClassName) 507 switch (Kind) { 508 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 509 default: { llvm_unreachable("Unknown symbol kind!"); } 510 } 511 } 512