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