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