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