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/ArrayRef.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/DebugInfo/CodeView/CodeView.h" 19 #include "llvm/DebugInfo/CodeView/CodeViewError.h" 20 #include "llvm/DebugInfo/CodeView/EnumTables.h" 21 #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 22 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 23 #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 24 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" 25 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 26 #include "llvm/ObjectYAML/YAML.h" 27 #include "llvm/Support/Allocator.h" 28 #include "llvm/Support/Error.h" 29 #include "llvm/Support/YAMLTraits.h" 30 #include <algorithm> 31 #include <cstdint> 32 #include <cstring> 33 #include <string> 34 #include <vector> 35 36 using namespace llvm; 37 using namespace llvm::codeview; 38 using namespace llvm::CodeViewYAML; 39 using namespace llvm::CodeViewYAML::detail; 40 using namespace llvm::yaml; 41 42 LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(TypeIndex) 43 44 // We only need to declare these, the definitions are in CodeViewYAMLTypes.cpp 45 LLVM_YAML_DECLARE_SCALAR_TRAITS(APSInt, QuotingType::None) 46 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeIndex, QuotingType::None) 47 48 LLVM_YAML_DECLARE_ENUM_TRAITS(SymbolKind) 49 LLVM_YAML_DECLARE_ENUM_TRAITS(FrameCookieKind) 50 51 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym2Flags) 52 LLVM_YAML_DECLARE_BITSET_TRAITS(CompileSym3Flags) 53 LLVM_YAML_DECLARE_BITSET_TRAITS(ExportFlags) 54 LLVM_YAML_DECLARE_BITSET_TRAITS(PublicSymFlags) 55 LLVM_YAML_DECLARE_BITSET_TRAITS(LocalSymFlags) 56 LLVM_YAML_DECLARE_BITSET_TRAITS(ProcSymFlags) 57 LLVM_YAML_DECLARE_BITSET_TRAITS(FrameProcedureOptions) 58 LLVM_YAML_DECLARE_ENUM_TRAITS(CPUType) 59 LLVM_YAML_DECLARE_ENUM_TRAITS(RegisterId) 60 LLVM_YAML_DECLARE_ENUM_TRAITS(TrampolineType) 61 LLVM_YAML_DECLARE_ENUM_TRAITS(ThunkOrdinal) 62 63 LLVM_YAML_STRONG_TYPEDEF(StringRef, TypeName) 64 65 LLVM_YAML_DECLARE_SCALAR_TRAITS(TypeName, QuotingType::Single) 66 67 StringRef ScalarTraits<TypeName>::input(StringRef S, void *V, TypeName &T) { 68 return ScalarTraits<StringRef>::input(S, V, T.value); 69 } 70 71 void ScalarTraits<TypeName>::output(const TypeName &T, void *V, 72 raw_ostream &R) { 73 ScalarTraits<StringRef>::output(T.value, V, R); 74 } 75 76 void ScalarEnumerationTraits<SymbolKind>::enumeration(IO &io, 77 SymbolKind &Value) { 78 auto SymbolNames = getSymbolTypeNames(); 79 for (const auto &E : SymbolNames) 80 io.enumCase(Value, E.Name.str().c_str(), E.Value); 81 } 82 83 void ScalarBitSetTraits<CompileSym2Flags>::bitset(IO &io, 84 CompileSym2Flags &Flags) { 85 auto FlagNames = getCompileSym2FlagNames(); 86 for (const auto &E : FlagNames) { 87 io.bitSetCase(Flags, E.Name.str().c_str(), 88 static_cast<CompileSym2Flags>(E.Value)); 89 } 90 } 91 92 void ScalarBitSetTraits<CompileSym3Flags>::bitset(IO &io, 93 CompileSym3Flags &Flags) { 94 auto FlagNames = getCompileSym3FlagNames(); 95 for (const auto &E : FlagNames) { 96 io.bitSetCase(Flags, E.Name.str().c_str(), 97 static_cast<CompileSym3Flags>(E.Value)); 98 } 99 } 100 101 void ScalarBitSetTraits<ExportFlags>::bitset(IO &io, ExportFlags &Flags) { 102 auto FlagNames = getExportSymFlagNames(); 103 for (const auto &E : FlagNames) { 104 io.bitSetCase(Flags, E.Name.str().c_str(), 105 static_cast<ExportFlags>(E.Value)); 106 } 107 } 108 109 void ScalarBitSetTraits<PublicSymFlags>::bitset(IO &io, PublicSymFlags &Flags) { 110 auto FlagNames = getProcSymFlagNames(); 111 for (const auto &E : FlagNames) { 112 io.bitSetCase(Flags, E.Name.str().c_str(), 113 static_cast<PublicSymFlags>(E.Value)); 114 } 115 } 116 117 void ScalarBitSetTraits<LocalSymFlags>::bitset(IO &io, LocalSymFlags &Flags) { 118 auto FlagNames = getLocalFlagNames(); 119 for (const auto &E : FlagNames) { 120 io.bitSetCase(Flags, E.Name.str().c_str(), 121 static_cast<LocalSymFlags>(E.Value)); 122 } 123 } 124 125 void ScalarBitSetTraits<ProcSymFlags>::bitset(IO &io, ProcSymFlags &Flags) { 126 auto FlagNames = getProcSymFlagNames(); 127 for (const auto &E : FlagNames) { 128 io.bitSetCase(Flags, E.Name.str().c_str(), 129 static_cast<ProcSymFlags>(E.Value)); 130 } 131 } 132 133 void ScalarBitSetTraits<FrameProcedureOptions>::bitset( 134 IO &io, FrameProcedureOptions &Flags) { 135 auto FlagNames = getFrameProcSymFlagNames(); 136 for (const auto &E : FlagNames) { 137 io.bitSetCase(Flags, E.Name.str().c_str(), 138 static_cast<FrameProcedureOptions>(E.Value)); 139 } 140 } 141 142 void ScalarEnumerationTraits<CPUType>::enumeration(IO &io, CPUType &Cpu) { 143 auto CpuNames = getCPUTypeNames(); 144 for (const auto &E : CpuNames) { 145 io.enumCase(Cpu, E.Name.str().c_str(), static_cast<CPUType>(E.Value)); 146 } 147 } 148 149 void ScalarEnumerationTraits<RegisterId>::enumeration(IO &io, RegisterId &Reg) { 150 auto RegNames = getRegisterNames(); 151 for (const auto &E : RegNames) { 152 io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value)); 153 } 154 io.enumFallback<Hex16>(Reg); 155 } 156 157 void ScalarEnumerationTraits<TrampolineType>::enumeration( 158 IO &io, TrampolineType &Tramp) { 159 auto TrampNames = getTrampolineNames(); 160 for (const auto &E : TrampNames) { 161 io.enumCase(Tramp, E.Name.str().c_str(), 162 static_cast<TrampolineType>(E.Value)); 163 } 164 } 165 166 void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io, 167 ThunkOrdinal &Ord) { 168 auto ThunkNames = getThunkOrdinalNames(); 169 for (const auto &E : ThunkNames) { 170 io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value)); 171 } 172 } 173 174 void ScalarEnumerationTraits<FrameCookieKind>::enumeration( 175 IO &io, FrameCookieKind &FC) { 176 auto ThunkNames = getFrameCookieKindNames(); 177 for (const auto &E : ThunkNames) { 178 io.enumCase(FC, E.Name.str().c_str(), 179 static_cast<FrameCookieKind>(E.Value)); 180 } 181 } 182 183 namespace llvm { 184 namespace CodeViewYAML { 185 namespace detail { 186 187 struct SymbolRecordBase { 188 codeview::SymbolKind Kind; 189 190 explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {} 191 virtual ~SymbolRecordBase() = default; 192 193 virtual void map(yaml::IO &io) = 0; 194 virtual codeview::CVSymbol 195 toCodeViewSymbol(BumpPtrAllocator &Allocator, 196 CodeViewContainer Container) const = 0; 197 virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0; 198 }; 199 200 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase { 201 explicit SymbolRecordImpl(codeview::SymbolKind K) 202 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {} 203 204 void map(yaml::IO &io) override; 205 206 codeview::CVSymbol 207 toCodeViewSymbol(BumpPtrAllocator &Allocator, 208 CodeViewContainer Container) const override { 209 return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container); 210 } 211 212 Error fromCodeViewSymbol(codeview::CVSymbol CVS) override { 213 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol); 214 } 215 216 mutable T Symbol; 217 }; 218 219 struct UnknownSymbolRecord : public SymbolRecordBase { 220 explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {} 221 222 void map(yaml::IO &io) override; 223 224 CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, 225 CodeViewContainer Container) const override { 226 RecordPrefix Prefix; 227 uint32_t TotalLen = sizeof(RecordPrefix) + Data.size(); 228 Prefix.RecordKind = Kind; 229 Prefix.RecordLen = TotalLen - 2; 230 uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen); 231 ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix)); 232 ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size()); 233 return CVSymbol(Kind, ArrayRef<uint8_t>(Buffer, TotalLen)); 234 } 235 236 Error fromCodeViewSymbol(CVSymbol CVS) override { 237 this->Kind = CVS.kind(); 238 Data = CVS.RecordData.drop_front(sizeof(RecordPrefix)); 239 return Error::success(); 240 } 241 242 std::vector<uint8_t> Data; 243 }; 244 245 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {} 246 247 void UnknownSymbolRecord::map(yaml::IO &io) { 248 yaml::BinaryRef Binary; 249 if (io.outputting()) 250 Binary = yaml::BinaryRef(Data); 251 io.mapRequired("Data", Binary); 252 if (!io.outputting()) { 253 std::string Str; 254 raw_string_ostream OS(Str); 255 Binary.writeAsBinary(OS); 256 OS.flush(); 257 Data.assign(Str.begin(), Str.end()); 258 } 259 } 260 261 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) { 262 IO.mapRequired("Parent", Symbol.Parent); 263 IO.mapRequired("End", Symbol.End); 264 IO.mapRequired("Next", Symbol.Next); 265 IO.mapRequired("Off", Symbol.Offset); 266 IO.mapRequired("Seg", Symbol.Segment); 267 IO.mapRequired("Len", Symbol.Length); 268 IO.mapRequired("Ordinal", Symbol.Thunk); 269 } 270 271 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) { 272 IO.mapRequired("Type", Symbol.Type); 273 IO.mapRequired("Size", Symbol.Size); 274 IO.mapRequired("ThunkOff", Symbol.ThunkOffset); 275 IO.mapRequired("TargetOff", Symbol.TargetOffset); 276 IO.mapRequired("ThunkSection", Symbol.ThunkSection); 277 IO.mapRequired("TargetSection", Symbol.TargetSection); 278 } 279 280 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) { 281 IO.mapRequired("SectionNumber", Symbol.SectionNumber); 282 IO.mapRequired("Alignment", Symbol.Alignment); 283 IO.mapRequired("Rva", Symbol.Rva); 284 IO.mapRequired("Length", Symbol.Length); 285 IO.mapRequired("Characteristics", Symbol.Characteristics); 286 IO.mapRequired("Name", Symbol.Name); 287 } 288 289 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) { 290 IO.mapRequired("Size", Symbol.Size); 291 IO.mapRequired("Characteristics", Symbol.Characteristics); 292 IO.mapRequired("Offset", Symbol.Offset); 293 IO.mapRequired("Segment", Symbol.Segment); 294 IO.mapRequired("Name", Symbol.Name); 295 } 296 297 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) { 298 IO.mapRequired("Ordinal", Symbol.Ordinal); 299 IO.mapRequired("Flags", Symbol.Flags); 300 IO.mapRequired("Name", Symbol.Name); 301 } 302 303 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) { 304 IO.mapOptional("PtrParent", Symbol.Parent, 0U); 305 IO.mapOptional("PtrEnd", Symbol.End, 0U); 306 IO.mapOptional("PtrNext", Symbol.Next, 0U); 307 IO.mapRequired("CodeSize", Symbol.CodeSize); 308 IO.mapRequired("DbgStart", Symbol.DbgStart); 309 IO.mapRequired("DbgEnd", Symbol.DbgEnd); 310 IO.mapRequired("FunctionType", Symbol.FunctionType); 311 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 312 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 313 IO.mapRequired("Flags", Symbol.Flags); 314 IO.mapRequired("DisplayName", Symbol.Name); 315 } 316 317 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) { 318 IO.mapRequired("Type", Symbol.Index); 319 IO.mapRequired("Seg", Symbol.Register); 320 IO.mapRequired("Name", Symbol.Name); 321 } 322 323 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) { 324 IO.mapRequired("Flags", Symbol.Flags); 325 IO.mapOptional("Offset", Symbol.Offset, 0U); 326 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 327 IO.mapRequired("Name", Symbol.Name); 328 } 329 330 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) { 331 IO.mapRequired("SumName", Symbol.SumName); 332 IO.mapRequired("SymOffset", Symbol.SymOffset); 333 IO.mapRequired("Mod", Symbol.Module); 334 IO.mapRequired("Name", Symbol.Name); 335 } 336 337 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) { 338 IO.mapRequired("Entries", Symbol.Fields); 339 } 340 341 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) { 342 IO.mapOptional("PtrParent", Symbol.Parent, 0U); 343 IO.mapOptional("PtrEnd", Symbol.End, 0U); 344 IO.mapRequired("Inlinee", Symbol.Inlinee); 345 // TODO: The binary annotations 346 } 347 348 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) { 349 IO.mapRequired("Type", Symbol.Type); 350 IO.mapRequired("Flags", Symbol.Flags); 351 352 IO.mapRequired("VarName", Symbol.Name); 353 } 354 355 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) { 356 // TODO: Print the subfields 357 } 358 359 template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) { 360 // TODO: Print the subfields 361 } 362 363 template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { 364 // TODO: Print the subfields 365 } 366 367 template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { 368 // TODO: Print the subfields 369 } 370 371 template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) { 372 // TODO: Print the subfields 373 } 374 375 template <> 376 void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) { 377 // TODO: Print the subfields 378 } 379 380 template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) { 381 // TODO: Print the subfields 382 } 383 384 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) { 385 IO.mapOptional("PtrParent", Symbol.Parent, 0U); 386 IO.mapOptional("PtrEnd", Symbol.End, 0U); 387 IO.mapRequired("CodeSize", Symbol.CodeSize); 388 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 389 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 390 IO.mapRequired("BlockName", Symbol.Name); 391 } 392 393 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) { 394 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 395 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 396 IO.mapRequired("Flags", Symbol.Flags); 397 IO.mapRequired("Flags", Symbol.Flags); 398 IO.mapRequired("DisplayName", Symbol.Name); 399 } 400 401 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) { 402 IO.mapRequired("Signature", Symbol.Signature); 403 IO.mapRequired("ObjectName", Symbol.Name); 404 } 405 406 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) { 407 IO.mapRequired("Flags", Symbol.Flags); 408 IO.mapRequired("Machine", Symbol.Machine); 409 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 410 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 411 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 412 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 413 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 414 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 415 IO.mapRequired("Version", Symbol.Version); 416 } 417 418 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) { 419 IO.mapRequired("Flags", Symbol.Flags); 420 IO.mapRequired("Machine", Symbol.Machine); 421 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 422 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 423 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 424 IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE); 425 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 426 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 427 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 428 IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE); 429 IO.mapRequired("Version", Symbol.Version); 430 } 431 432 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) { 433 IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes); 434 IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes); 435 IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding); 436 IO.mapRequired("BytesOfCalleeSavedRegisters", 437 Symbol.BytesOfCalleeSavedRegisters); 438 IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler); 439 IO.mapRequired("SectionIdOfExceptionHandler", 440 Symbol.SectionIdOfExceptionHandler); 441 IO.mapRequired("Flags", Symbol.Flags); 442 } 443 444 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) { 445 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 446 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 447 IO.mapRequired("Type", Symbol.Type); 448 } 449 450 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) { 451 IO.mapRequired("Index", Symbol.Index); 452 IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset); 453 IO.mapRequired("Flags", Symbol.Flags); 454 IO.mapRequired("Name", Symbol.Name); 455 } 456 457 template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) { 458 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 459 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 460 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize); 461 IO.mapRequired("Type", Symbol.Type); 462 } 463 464 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) { 465 IO.mapRequired("Register", Symbol.Register); 466 IO.mapRequired("CookieKind", Symbol.CookieKind); 467 IO.mapRequired("Flags", Symbol.Flags); 468 } 469 470 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) { 471 IO.mapRequired("FuncID", Symbol.Indices); 472 } 473 474 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) { 475 IO.mapRequired("Type", Symbol.Type); 476 IO.mapRequired("UDTName", Symbol.Name); 477 } 478 479 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) { 480 IO.mapRequired("BuildId", Symbol.BuildId); 481 } 482 483 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) { 484 IO.mapRequired("Offset", Symbol.Offset); 485 IO.mapRequired("Type", Symbol.Type); 486 IO.mapRequired("VarName", Symbol.Name); 487 } 488 489 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) { 490 IO.mapRequired("Offset", Symbol.Offset); 491 IO.mapRequired("Type", Symbol.Type); 492 IO.mapRequired("Register", Symbol.Register); 493 IO.mapRequired("VarName", Symbol.Name); 494 } 495 496 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) { 497 IO.mapRequired("Type", Symbol.Type); 498 IO.mapRequired("Value", Symbol.Value); 499 IO.mapRequired("Name", Symbol.Name); 500 } 501 502 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) { 503 IO.mapRequired("Type", Symbol.Type); 504 IO.mapOptional("Offset", Symbol.DataOffset, 0U); 505 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 506 IO.mapRequired("DisplayName", Symbol.Name); 507 } 508 509 template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) { 510 IO.mapRequired("Type", Symbol.Type); 511 IO.mapOptional("Offset", Symbol.DataOffset, 0U); 512 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 513 IO.mapRequired("DisplayName", Symbol.Name); 514 } 515 516 } // end namespace detail 517 } // end namespace CodeViewYAML 518 } // end namespace llvm 519 520 CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol( 521 BumpPtrAllocator &Allocator, CodeViewContainer Container) const { 522 return Symbol->toCodeViewSymbol(Allocator, Container); 523 } 524 525 namespace llvm { 526 namespace yaml { 527 528 template <> struct MappingTraits<SymbolRecordBase> { 529 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); } 530 }; 531 532 } // end namespace yaml 533 } // end namespace llvm 534 535 template <typename SymbolType> 536 static inline Expected<CodeViewYAML::SymbolRecord> 537 fromCodeViewSymbolImpl(CVSymbol Symbol) { 538 CodeViewYAML::SymbolRecord Result; 539 540 auto Impl = std::make_shared<SymbolType>(Symbol.kind()); 541 if (auto EC = Impl->fromCodeViewSymbol(Symbol)) 542 return std::move(EC); 543 Result.Symbol = Impl; 544 return Result; 545 } 546 547 Expected<CodeViewYAML::SymbolRecord> 548 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { 549 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 550 case EnumName: \ 551 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol); 552 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 553 SYMBOL_RECORD(EnumName, EnumVal, ClassName) 554 switch (Symbol.kind()) { 555 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 556 default: 557 return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol); 558 } 559 return make_error<CodeViewError>(cv_error_code::corrupt_record); 560 } 561 562 template <typename ConcreteType> 563 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, 564 CodeViewYAML::SymbolRecord &Obj) { 565 if (!IO.outputting()) 566 Obj.Symbol = std::make_shared<ConcreteType>(Kind); 567 568 IO.mapRequired(Class, *Obj.Symbol); 569 } 570 571 void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( 572 IO &IO, CodeViewYAML::SymbolRecord &Obj) { 573 SymbolKind Kind; 574 if (IO.outputting()) 575 Kind = Obj.Symbol->Kind; 576 IO.mapRequired("Kind", Kind); 577 578 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 579 case EnumName: \ 580 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \ 581 Obj); \ 582 break; 583 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 584 SYMBOL_RECORD(EnumName, EnumVal, ClassName) 585 switch (Kind) { 586 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 587 default: 588 mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj); 589 } 590 } 591