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 14 #include "llvm/ObjectYAML/CodeViewYAMLSymbols.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/ADT/StringRef.h" 17 #include "llvm/DebugInfo/CodeView/CodeView.h" 18 #include "llvm/DebugInfo/CodeView/CodeViewError.h" 19 #include "llvm/DebugInfo/CodeView/EnumTables.h" 20 #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 21 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 22 #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 23 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h" 24 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 25 #include "llvm/ObjectYAML/YAML.h" 26 #include "llvm/Support/Allocator.h" 27 #include "llvm/Support/Error.h" 28 #include "llvm/Support/ScopedPrinter.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 const auto *Header = static_cast<COFF::header *>(io.getContext()); 152 assert(Header && "The IO context is not initialized"); 153 154 Optional<CPUType> CpuType; 155 ArrayRef<EnumEntry<uint16_t>> RegNames; 156 157 switch (Header->Machine) { 158 case COFF::IMAGE_FILE_MACHINE_I386: 159 CpuType = CPUType::Pentium3; 160 break; 161 case COFF::IMAGE_FILE_MACHINE_AMD64: 162 CpuType = CPUType::X64; 163 break; 164 case COFF::IMAGE_FILE_MACHINE_ARMNT: 165 CpuType = CPUType::ARMNT; 166 break; 167 case COFF::IMAGE_FILE_MACHINE_ARM64: 168 CpuType = CPUType::ARM64; 169 break; 170 } 171 172 if (CpuType) 173 RegNames = getRegisterNames(*CpuType); 174 175 for (const auto &E : RegNames) { 176 io.enumCase(Reg, E.Name.str().c_str(), static_cast<RegisterId>(E.Value)); 177 } 178 io.enumFallback<Hex16>(Reg); 179 } 180 181 void ScalarEnumerationTraits<TrampolineType>::enumeration( 182 IO &io, TrampolineType &Tramp) { 183 auto TrampNames = getTrampolineNames(); 184 for (const auto &E : TrampNames) { 185 io.enumCase(Tramp, E.Name.str().c_str(), 186 static_cast<TrampolineType>(E.Value)); 187 } 188 } 189 190 void ScalarEnumerationTraits<ThunkOrdinal>::enumeration(IO &io, 191 ThunkOrdinal &Ord) { 192 auto ThunkNames = getThunkOrdinalNames(); 193 for (const auto &E : ThunkNames) { 194 io.enumCase(Ord, E.Name.str().c_str(), static_cast<ThunkOrdinal>(E.Value)); 195 } 196 } 197 198 void ScalarEnumerationTraits<FrameCookieKind>::enumeration( 199 IO &io, FrameCookieKind &FC) { 200 auto ThunkNames = getFrameCookieKindNames(); 201 for (const auto &E : ThunkNames) { 202 io.enumCase(FC, E.Name.str().c_str(), 203 static_cast<FrameCookieKind>(E.Value)); 204 } 205 } 206 207 namespace llvm { 208 namespace yaml { 209 template <> struct MappingTraits<LocalVariableAddrRange> { 210 static void mapping(IO &io, LocalVariableAddrRange &Range) { 211 io.mapRequired("OffsetStart", Range.OffsetStart); 212 io.mapRequired("ISectStart", Range.ISectStart); 213 io.mapRequired("Range", Range.Range); 214 } 215 }; 216 template <> struct MappingTraits<LocalVariableAddrGap> { 217 static void mapping(IO &io, LocalVariableAddrGap &Gap) { 218 io.mapRequired("GapStartOffset", Gap.GapStartOffset); 219 io.mapRequired("Range", Gap.Range); 220 } 221 }; 222 } // namespace yaml 223 } // namespace llvm 224 225 namespace llvm { 226 namespace CodeViewYAML { 227 namespace detail { 228 229 struct SymbolRecordBase { 230 codeview::SymbolKind Kind; 231 232 explicit SymbolRecordBase(codeview::SymbolKind K) : Kind(K) {} 233 virtual ~SymbolRecordBase() = default; 234 235 virtual void map(yaml::IO &io) = 0; 236 virtual codeview::CVSymbol 237 toCodeViewSymbol(BumpPtrAllocator &Allocator, 238 CodeViewContainer Container) const = 0; 239 virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0; 240 }; 241 242 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase { 243 explicit SymbolRecordImpl(codeview::SymbolKind K) 244 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {} 245 246 void map(yaml::IO &io) override; 247 248 codeview::CVSymbol 249 toCodeViewSymbol(BumpPtrAllocator &Allocator, 250 CodeViewContainer Container) const override { 251 return SymbolSerializer::writeOneSymbol(Symbol, Allocator, Container); 252 } 253 254 Error fromCodeViewSymbol(codeview::CVSymbol CVS) override { 255 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol); 256 } 257 258 mutable T Symbol; 259 }; 260 261 struct UnknownSymbolRecord : public SymbolRecordBase { 262 explicit UnknownSymbolRecord(codeview::SymbolKind K) : SymbolRecordBase(K) {} 263 264 void map(yaml::IO &io) override; 265 266 CVSymbol toCodeViewSymbol(BumpPtrAllocator &Allocator, 267 CodeViewContainer Container) const override { 268 RecordPrefix Prefix; 269 uint32_t TotalLen = sizeof(RecordPrefix) + Data.size(); 270 Prefix.RecordKind = Kind; 271 Prefix.RecordLen = TotalLen - 2; 272 uint8_t *Buffer = Allocator.Allocate<uint8_t>(TotalLen); 273 ::memcpy(Buffer, &Prefix, sizeof(RecordPrefix)); 274 ::memcpy(Buffer + sizeof(RecordPrefix), Data.data(), Data.size()); 275 return CVSymbol(ArrayRef<uint8_t>(Buffer, TotalLen)); 276 } 277 278 Error fromCodeViewSymbol(CVSymbol CVS) override { 279 this->Kind = CVS.kind(); 280 Data = CVS.RecordData.drop_front(sizeof(RecordPrefix)); 281 return Error::success(); 282 } 283 284 std::vector<uint8_t> Data; 285 }; 286 287 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {} 288 289 void UnknownSymbolRecord::map(yaml::IO &io) { 290 yaml::BinaryRef Binary; 291 if (io.outputting()) 292 Binary = yaml::BinaryRef(Data); 293 io.mapRequired("Data", Binary); 294 if (!io.outputting()) { 295 std::string Str; 296 raw_string_ostream OS(Str); 297 Binary.writeAsBinary(OS); 298 OS.flush(); 299 Data.assign(Str.begin(), Str.end()); 300 } 301 } 302 303 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) { 304 IO.mapRequired("Parent", Symbol.Parent); 305 IO.mapRequired("End", Symbol.End); 306 IO.mapRequired("Next", Symbol.Next); 307 IO.mapRequired("Off", Symbol.Offset); 308 IO.mapRequired("Seg", Symbol.Segment); 309 IO.mapRequired("Len", Symbol.Length); 310 IO.mapRequired("Ordinal", Symbol.Thunk); 311 } 312 313 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) { 314 IO.mapRequired("Type", Symbol.Type); 315 IO.mapRequired("Size", Symbol.Size); 316 IO.mapRequired("ThunkOff", Symbol.ThunkOffset); 317 IO.mapRequired("TargetOff", Symbol.TargetOffset); 318 IO.mapRequired("ThunkSection", Symbol.ThunkSection); 319 IO.mapRequired("TargetSection", Symbol.TargetSection); 320 } 321 322 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) { 323 IO.mapRequired("SectionNumber", Symbol.SectionNumber); 324 IO.mapRequired("Alignment", Symbol.Alignment); 325 IO.mapRequired("Rva", Symbol.Rva); 326 IO.mapRequired("Length", Symbol.Length); 327 IO.mapRequired("Characteristics", Symbol.Characteristics); 328 IO.mapRequired("Name", Symbol.Name); 329 } 330 331 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) { 332 IO.mapRequired("Size", Symbol.Size); 333 IO.mapRequired("Characteristics", Symbol.Characteristics); 334 IO.mapRequired("Offset", Symbol.Offset); 335 IO.mapRequired("Segment", Symbol.Segment); 336 IO.mapRequired("Name", Symbol.Name); 337 } 338 339 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) { 340 IO.mapRequired("Ordinal", Symbol.Ordinal); 341 IO.mapRequired("Flags", Symbol.Flags); 342 IO.mapRequired("Name", Symbol.Name); 343 } 344 345 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) { 346 IO.mapOptional("PtrParent", Symbol.Parent, 0U); 347 IO.mapOptional("PtrEnd", Symbol.End, 0U); 348 IO.mapOptional("PtrNext", Symbol.Next, 0U); 349 IO.mapRequired("CodeSize", Symbol.CodeSize); 350 IO.mapRequired("DbgStart", Symbol.DbgStart); 351 IO.mapRequired("DbgEnd", Symbol.DbgEnd); 352 IO.mapRequired("FunctionType", Symbol.FunctionType); 353 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 354 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 355 IO.mapRequired("Flags", Symbol.Flags); 356 IO.mapRequired("DisplayName", Symbol.Name); 357 } 358 359 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) { 360 IO.mapRequired("Type", Symbol.Index); 361 IO.mapRequired("Seg", Symbol.Register); 362 IO.mapRequired("Name", Symbol.Name); 363 } 364 365 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) { 366 IO.mapRequired("Flags", Symbol.Flags); 367 IO.mapOptional("Offset", Symbol.Offset, 0U); 368 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 369 IO.mapRequired("Name", Symbol.Name); 370 } 371 372 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) { 373 IO.mapRequired("SumName", Symbol.SumName); 374 IO.mapRequired("SymOffset", Symbol.SymOffset); 375 IO.mapRequired("Mod", Symbol.Module); 376 IO.mapRequired("Name", Symbol.Name); 377 } 378 379 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) { 380 IO.mapRequired("Entries", Symbol.Fields); 381 } 382 383 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) { 384 IO.mapOptional("PtrParent", Symbol.Parent, 0U); 385 IO.mapOptional("PtrEnd", Symbol.End, 0U); 386 IO.mapRequired("Inlinee", Symbol.Inlinee); 387 // TODO: The binary annotations 388 } 389 390 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) { 391 IO.mapRequired("Type", Symbol.Type); 392 IO.mapRequired("Flags", Symbol.Flags); 393 394 IO.mapRequired("VarName", Symbol.Name); 395 } 396 397 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) { 398 IO.mapRequired("Program", Symbol.Program); 399 IO.mapRequired("Range", Symbol.Range); 400 IO.mapRequired("Gaps", Symbol.Gaps); 401 } 402 403 template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) { 404 IO.mapRequired("Program", Symbol.Program); 405 IO.mapRequired("OffsetInParent", Symbol.OffsetInParent); 406 IO.mapRequired("Range", Symbol.Range); 407 IO.mapRequired("Gaps", Symbol.Gaps); 408 } 409 410 template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { 411 IO.mapRequired("Register", Symbol.Hdr.Register); 412 IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName); 413 IO.mapRequired("Range", Symbol.Range); 414 IO.mapRequired("Gaps", Symbol.Gaps); 415 } 416 417 template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { 418 IO.mapRequired("Offset", Symbol.Hdr.Offset); 419 IO.mapRequired("Range", Symbol.Range); 420 IO.mapRequired("Gaps", Symbol.Gaps); 421 } 422 423 template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) { 424 IO.mapRequired("Register", Symbol.Hdr.Register); 425 IO.mapRequired("MayHaveNoName", Symbol.Hdr.MayHaveNoName); 426 IO.mapRequired("OffsetInParent", Symbol.Hdr.OffsetInParent); 427 IO.mapRequired("Range", Symbol.Range); 428 IO.mapRequired("Gaps", Symbol.Gaps); 429 } 430 431 template <> 432 void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) { 433 IO.mapRequired("Register", Symbol.Offset); 434 } 435 436 template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) { 437 IO.mapRequired("Register", Symbol.Hdr.Register); 438 IO.mapRequired("Flags", Symbol.Hdr.Flags); 439 IO.mapRequired("BasePointerOffset", Symbol.Hdr.BasePointerOffset); 440 IO.mapRequired("Range", Symbol.Range); 441 IO.mapRequired("Gaps", Symbol.Gaps); 442 } 443 444 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) { 445 IO.mapOptional("PtrParent", Symbol.Parent, 0U); 446 IO.mapOptional("PtrEnd", Symbol.End, 0U); 447 IO.mapRequired("CodeSize", Symbol.CodeSize); 448 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 449 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 450 IO.mapRequired("BlockName", Symbol.Name); 451 } 452 453 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) { 454 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 455 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 456 IO.mapRequired("Flags", Symbol.Flags); 457 IO.mapRequired("Flags", Symbol.Flags); 458 IO.mapRequired("DisplayName", Symbol.Name); 459 } 460 461 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) { 462 IO.mapRequired("Signature", Symbol.Signature); 463 IO.mapRequired("ObjectName", Symbol.Name); 464 } 465 466 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) { 467 IO.mapRequired("Flags", Symbol.Flags); 468 IO.mapRequired("Machine", Symbol.Machine); 469 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 470 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 471 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 472 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 473 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 474 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 475 IO.mapRequired("Version", Symbol.Version); 476 } 477 478 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) { 479 IO.mapRequired("Flags", Symbol.Flags); 480 IO.mapRequired("Machine", Symbol.Machine); 481 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 482 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 483 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 484 IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE); 485 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 486 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 487 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 488 IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE); 489 IO.mapRequired("Version", Symbol.Version); 490 } 491 492 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) { 493 IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes); 494 IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes); 495 IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding); 496 IO.mapRequired("BytesOfCalleeSavedRegisters", 497 Symbol.BytesOfCalleeSavedRegisters); 498 IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler); 499 IO.mapRequired("SectionIdOfExceptionHandler", 500 Symbol.SectionIdOfExceptionHandler); 501 IO.mapRequired("Flags", Symbol.Flags); 502 } 503 504 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) { 505 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 506 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 507 IO.mapRequired("Type", Symbol.Type); 508 } 509 510 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) { 511 IO.mapRequired("Index", Symbol.Index); 512 IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset); 513 IO.mapRequired("Flags", Symbol.Flags); 514 IO.mapRequired("Name", Symbol.Name); 515 } 516 517 template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) { 518 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 519 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 520 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize); 521 IO.mapRequired("Type", Symbol.Type); 522 } 523 524 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) { 525 IO.mapRequired("Register", Symbol.Register); 526 IO.mapRequired("CookieKind", Symbol.CookieKind); 527 IO.mapRequired("Flags", Symbol.Flags); 528 } 529 530 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) { 531 IO.mapRequired("FuncID", Symbol.Indices); 532 } 533 534 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) { 535 IO.mapRequired("Type", Symbol.Type); 536 IO.mapRequired("UDTName", Symbol.Name); 537 } 538 539 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) { 540 IO.mapRequired("BuildId", Symbol.BuildId); 541 } 542 543 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) { 544 IO.mapRequired("Offset", Symbol.Offset); 545 IO.mapRequired("Type", Symbol.Type); 546 IO.mapRequired("VarName", Symbol.Name); 547 } 548 549 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) { 550 IO.mapRequired("Offset", Symbol.Offset); 551 IO.mapRequired("Type", Symbol.Type); 552 IO.mapRequired("Register", Symbol.Register); 553 IO.mapRequired("VarName", Symbol.Name); 554 } 555 556 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) { 557 IO.mapRequired("Type", Symbol.Type); 558 IO.mapRequired("Value", Symbol.Value); 559 IO.mapRequired("Name", Symbol.Name); 560 } 561 562 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) { 563 IO.mapRequired("Type", Symbol.Type); 564 IO.mapOptional("Offset", Symbol.DataOffset, 0U); 565 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 566 IO.mapRequired("DisplayName", Symbol.Name); 567 } 568 569 template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) { 570 IO.mapRequired("Type", Symbol.Type); 571 IO.mapOptional("Offset", Symbol.DataOffset, 0U); 572 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 573 IO.mapRequired("DisplayName", Symbol.Name); 574 } 575 576 template <> void SymbolRecordImpl<UsingNamespaceSym>::map(IO &IO) { 577 IO.mapRequired("Namespace", Symbol.Name); 578 } 579 580 template <> void SymbolRecordImpl<AnnotationSym>::map(IO &IO) { 581 IO.mapOptional("Offset", Symbol.CodeOffset, 0U); 582 IO.mapOptional("Segment", Symbol.Segment, uint16_t(0)); 583 IO.mapRequired("Strings", Symbol.Strings); 584 } 585 586 } // end namespace detail 587 } // end namespace CodeViewYAML 588 } // end namespace llvm 589 590 CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol( 591 BumpPtrAllocator &Allocator, CodeViewContainer Container) const { 592 return Symbol->toCodeViewSymbol(Allocator, Container); 593 } 594 595 namespace llvm { 596 namespace yaml { 597 598 template <> struct MappingTraits<SymbolRecordBase> { 599 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); } 600 }; 601 602 } // end namespace yaml 603 } // end namespace llvm 604 605 template <typename SymbolType> 606 static inline Expected<CodeViewYAML::SymbolRecord> 607 fromCodeViewSymbolImpl(CVSymbol Symbol) { 608 CodeViewYAML::SymbolRecord Result; 609 610 auto Impl = std::make_shared<SymbolType>(Symbol.kind()); 611 if (auto EC = Impl->fromCodeViewSymbol(Symbol)) 612 return std::move(EC); 613 Result.Symbol = Impl; 614 return Result; 615 } 616 617 Expected<CodeViewYAML::SymbolRecord> 618 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { 619 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 620 case EnumName: \ 621 return fromCodeViewSymbolImpl<SymbolRecordImpl<ClassName>>(Symbol); 622 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 623 SYMBOL_RECORD(EnumName, EnumVal, ClassName) 624 switch (Symbol.kind()) { 625 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 626 default: 627 return fromCodeViewSymbolImpl<UnknownSymbolRecord>(Symbol); 628 } 629 return make_error<CodeViewError>(cv_error_code::corrupt_record); 630 } 631 632 template <typename ConcreteType> 633 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, 634 CodeViewYAML::SymbolRecord &Obj) { 635 if (!IO.outputting()) 636 Obj.Symbol = std::make_shared<ConcreteType>(Kind); 637 638 IO.mapRequired(Class, *Obj.Symbol); 639 } 640 641 void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( 642 IO &IO, CodeViewYAML::SymbolRecord &Obj) { 643 SymbolKind Kind; 644 if (IO.outputting()) 645 Kind = Obj.Symbol->Kind; 646 IO.mapRequired("Kind", Kind); 647 648 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 649 case EnumName: \ 650 mapSymbolRecordImpl<SymbolRecordImpl<ClassName>>(IO, #ClassName, Kind, \ 651 Obj); \ 652 break; 653 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 654 SYMBOL_RECORD(EnumName, EnumVal, ClassName) 655 switch (Kind) { 656 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 657 default: 658 mapSymbolRecordImpl<UnknownSymbolRecord>(IO, "UnknownSym", Kind, Obj); 659 } 660 } 661