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) const = 0; 152 virtual Error fromCodeViewSymbol(codeview::CVSymbol Type) = 0; 153 }; 154 155 template <typename T> struct SymbolRecordImpl : public SymbolRecordBase { 156 explicit SymbolRecordImpl(codeview::SymbolKind K) 157 : SymbolRecordBase(K), Symbol(static_cast<SymbolRecordKind>(K)) {} 158 159 void map(yaml::IO &io) override; 160 161 codeview::CVSymbol 162 toCodeViewSymbol(BumpPtrAllocator &Allocator) const override { 163 return SymbolSerializer::writeOneSymbol(Symbol, Allocator); 164 } 165 Error fromCodeViewSymbol(codeview::CVSymbol CVS) override { 166 return SymbolDeserializer::deserializeAs<T>(CVS, Symbol); 167 } 168 169 mutable T Symbol; 170 }; 171 172 template <> void SymbolRecordImpl<ScopeEndSym>::map(IO &IO) {} 173 174 template <> void SymbolRecordImpl<Thunk32Sym>::map(IO &IO) { 175 IO.mapRequired("Parent", Symbol.Parent); 176 IO.mapRequired("End", Symbol.End); 177 IO.mapRequired("Next", Symbol.Next); 178 IO.mapRequired("Off", Symbol.Offset); 179 IO.mapRequired("Seg", Symbol.Segment); 180 IO.mapRequired("Len", Symbol.Length); 181 IO.mapRequired("Ordinal", Symbol.Thunk); 182 } 183 184 template <> void SymbolRecordImpl<TrampolineSym>::map(IO &IO) { 185 IO.mapRequired("Type", Symbol.Type); 186 IO.mapRequired("Size", Symbol.Size); 187 IO.mapRequired("ThunkOff", Symbol.ThunkOffset); 188 IO.mapRequired("TargetOff", Symbol.TargetOffset); 189 IO.mapRequired("ThunkSection", Symbol.ThunkSection); 190 IO.mapRequired("TargetSection", Symbol.TargetSection); 191 } 192 193 template <> void SymbolRecordImpl<SectionSym>::map(IO &IO) { 194 IO.mapRequired("SectionNumber", Symbol.SectionNumber); 195 IO.mapRequired("Alignment", Symbol.Alignment); 196 IO.mapRequired("Rva", Symbol.Rva); 197 IO.mapRequired("Length", Symbol.Length); 198 IO.mapRequired("Characteristics", Symbol.Characteristics); 199 IO.mapRequired("Name", Symbol.Name); 200 } 201 202 template <> void SymbolRecordImpl<CoffGroupSym>::map(IO &IO) { 203 IO.mapRequired("Size", Symbol.Size); 204 IO.mapRequired("Characteristics", Symbol.Characteristics); 205 IO.mapRequired("Offset", Symbol.Offset); 206 IO.mapRequired("Segment", Symbol.Segment); 207 IO.mapRequired("Name", Symbol.Name); 208 } 209 210 template <> void SymbolRecordImpl<ExportSym>::map(IO &IO) { 211 IO.mapRequired("Ordinal", Symbol.Ordinal); 212 IO.mapRequired("Flags", Symbol.Flags); 213 IO.mapRequired("Name", Symbol.Name); 214 } 215 216 template <> void SymbolRecordImpl<ProcSym>::map(IO &IO) { 217 // TODO: Print the linkage name 218 219 IO.mapRequired("PtrParent", Symbol.Parent); 220 IO.mapRequired("PtrEnd", Symbol.End); 221 IO.mapRequired("PtrNext", Symbol.Next); 222 IO.mapRequired("CodeSize", Symbol.CodeSize); 223 IO.mapRequired("DbgStart", Symbol.DbgStart); 224 IO.mapRequired("DbgEnd", Symbol.DbgEnd); 225 IO.mapRequired("FunctionType", Symbol.FunctionType); 226 IO.mapRequired("Segment", Symbol.Segment); 227 IO.mapRequired("Flags", Symbol.Flags); 228 IO.mapRequired("DisplayName", Symbol.Name); 229 } 230 231 template <> void SymbolRecordImpl<RegisterSym>::map(IO &IO) { 232 IO.mapRequired("Type", Symbol.Index); 233 IO.mapRequired("Seg", Symbol.Register); 234 IO.mapRequired("Name", Symbol.Name); 235 } 236 237 template <> void SymbolRecordImpl<PublicSym32>::map(IO &IO) { 238 IO.mapRequired("Type", Symbol.Index); 239 IO.mapRequired("Seg", Symbol.Segment); 240 IO.mapRequired("Off", Symbol.Offset); 241 IO.mapRequired("Name", Symbol.Name); 242 } 243 244 template <> void SymbolRecordImpl<ProcRefSym>::map(IO &IO) { 245 IO.mapRequired("SumName", Symbol.SumName); 246 IO.mapRequired("SymOffset", Symbol.SymOffset); 247 IO.mapRequired("Mod", Symbol.Module); 248 IO.mapRequired("Name", Symbol.Name); 249 } 250 251 template <> void SymbolRecordImpl<EnvBlockSym>::map(IO &IO) { 252 IO.mapRequired("Entries", Symbol.Fields); 253 } 254 255 template <> void SymbolRecordImpl<InlineSiteSym>::map(IO &IO) { 256 IO.mapRequired("PtrParent", Symbol.Parent); 257 IO.mapRequired("PtrEnd", Symbol.End); 258 IO.mapRequired("Inlinee", Symbol.Inlinee); 259 // TODO: The binary annotations 260 } 261 262 template <> void SymbolRecordImpl<LocalSym>::map(IO &IO) { 263 IO.mapRequired("Type", Symbol.Type); 264 IO.mapRequired("Flags", Symbol.Flags); 265 IO.mapRequired("VarName", Symbol.Name); 266 } 267 268 template <> void SymbolRecordImpl<DefRangeSym>::map(IO &IO) { 269 // TODO: Print the subfields 270 } 271 272 template <> void SymbolRecordImpl<DefRangeSubfieldSym>::map(IO &IO) { 273 // TODO: Print the subfields 274 } 275 276 template <> void SymbolRecordImpl<DefRangeRegisterSym>::map(IO &IO) { 277 // TODO: Print the subfields 278 } 279 280 template <> void SymbolRecordImpl<DefRangeFramePointerRelSym>::map(IO &IO) { 281 // TODO: Print the subfields 282 } 283 284 template <> void SymbolRecordImpl<DefRangeSubfieldRegisterSym>::map(IO &IO) { 285 // TODO: Print the subfields 286 } 287 288 template <> 289 void SymbolRecordImpl<DefRangeFramePointerRelFullScopeSym>::map(IO &IO) { 290 // TODO: Print the subfields 291 } 292 293 template <> void SymbolRecordImpl<DefRangeRegisterRelSym>::map(IO &IO) { 294 // TODO: Print the subfields 295 } 296 297 template <> void SymbolRecordImpl<BlockSym>::map(IO &IO) { 298 // TODO: Print the linkage name 299 IO.mapRequired("PtrParent", Symbol.Parent); 300 IO.mapRequired("PtrEnd", Symbol.End); 301 IO.mapRequired("CodeSize", Symbol.CodeSize); 302 IO.mapRequired("Segment", Symbol.Segment); 303 IO.mapRequired("BlockName", Symbol.Name); 304 } 305 306 template <> void SymbolRecordImpl<LabelSym>::map(IO &IO) { 307 // TODO: Print the linkage name 308 IO.mapRequired("Segment", Symbol.Segment); 309 IO.mapRequired("Flags", Symbol.Flags); 310 IO.mapRequired("Flags", Symbol.Flags); 311 IO.mapRequired("DisplayName", Symbol.Name); 312 } 313 314 template <> void SymbolRecordImpl<ObjNameSym>::map(IO &IO) { 315 IO.mapRequired("Signature", Symbol.Signature); 316 IO.mapRequired("ObjectName", Symbol.Name); 317 } 318 319 template <> void SymbolRecordImpl<Compile2Sym>::map(IO &IO) { 320 IO.mapRequired("Flags", Symbol.Flags); 321 IO.mapRequired("Machine", Symbol.Machine); 322 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 323 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 324 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 325 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 326 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 327 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 328 IO.mapRequired("Version", Symbol.Version); 329 } 330 331 template <> void SymbolRecordImpl<Compile3Sym>::map(IO &IO) { 332 IO.mapRequired("Flags", Symbol.Flags); 333 IO.mapRequired("Machine", Symbol.Machine); 334 IO.mapRequired("FrontendMajor", Symbol.VersionFrontendMajor); 335 IO.mapRequired("FrontendMinor", Symbol.VersionFrontendMinor); 336 IO.mapRequired("FrontendBuild", Symbol.VersionFrontendBuild); 337 IO.mapRequired("FrontendQFE", Symbol.VersionFrontendQFE); 338 IO.mapRequired("BackendMajor", Symbol.VersionBackendMajor); 339 IO.mapRequired("BackendMinor", Symbol.VersionBackendMinor); 340 IO.mapRequired("BackendBuild", Symbol.VersionBackendBuild); 341 IO.mapRequired("BackendQFE", Symbol.VersionBackendQFE); 342 IO.mapRequired("Version", Symbol.Version); 343 } 344 345 template <> void SymbolRecordImpl<FrameProcSym>::map(IO &IO) { 346 IO.mapRequired("TotalFrameBytes", Symbol.TotalFrameBytes); 347 IO.mapRequired("PaddingFrameBytes", Symbol.PaddingFrameBytes); 348 IO.mapRequired("OffsetToPadding", Symbol.OffsetToPadding); 349 IO.mapRequired("BytesOfCalleeSavedRegisters", 350 Symbol.BytesOfCalleeSavedRegisters); 351 IO.mapRequired("OffsetOfExceptionHandler", Symbol.OffsetOfExceptionHandler); 352 IO.mapRequired("SectionIdOfExceptionHandler", 353 Symbol.SectionIdOfExceptionHandler); 354 IO.mapRequired("Flags", Symbol.Flags); 355 } 356 357 template <> void SymbolRecordImpl<CallSiteInfoSym>::map(IO &IO) { 358 // TODO: Map Linkage Name 359 IO.mapRequired("Segment", Symbol.Segment); 360 IO.mapRequired("Type", Symbol.Type); 361 } 362 363 template <> void SymbolRecordImpl<FileStaticSym>::map(IO &IO) { 364 IO.mapRequired("Index", Symbol.Index); 365 IO.mapRequired("ModFilenameOffset", Symbol.ModFilenameOffset); 366 IO.mapRequired("Flags", Symbol.Flags); 367 IO.mapRequired("Name", Symbol.Name); 368 } 369 370 template <> void SymbolRecordImpl<HeapAllocationSiteSym>::map(IO &IO) { 371 // TODO: Map Linkage Name 372 IO.mapRequired("Segment", Symbol.Segment); 373 IO.mapRequired("CallInstructionSize", Symbol.CallInstructionSize); 374 IO.mapRequired("Type", Symbol.Type); 375 } 376 377 template <> void SymbolRecordImpl<FrameCookieSym>::map(IO &IO) { 378 // TODO: Map Linkage Name 379 IO.mapRequired("Register", Symbol.Register); 380 IO.mapRequired("CookieKind", Symbol.CookieKind); 381 IO.mapRequired("Flags", Symbol.Flags); 382 } 383 384 template <> void SymbolRecordImpl<CallerSym>::map(IO &IO) { 385 IO.mapRequired("FuncID", Symbol.Indices); 386 } 387 388 template <> void SymbolRecordImpl<UDTSym>::map(IO &IO) { 389 IO.mapRequired("Type", Symbol.Type); 390 IO.mapRequired("UDTName", Symbol.Name); 391 } 392 393 template <> void SymbolRecordImpl<BuildInfoSym>::map(IO &IO) { 394 IO.mapRequired("BuildId", Symbol.BuildId); 395 } 396 397 template <> void SymbolRecordImpl<BPRelativeSym>::map(IO &IO) { 398 IO.mapRequired("Offset", Symbol.Offset); 399 IO.mapRequired("Type", Symbol.Type); 400 IO.mapRequired("VarName", Symbol.Name); 401 } 402 403 template <> void SymbolRecordImpl<RegRelativeSym>::map(IO &IO) { 404 IO.mapRequired("Offset", Symbol.Offset); 405 IO.mapRequired("Type", Symbol.Type); 406 IO.mapRequired("Register", Symbol.Register); 407 IO.mapRequired("VarName", Symbol.Name); 408 } 409 410 template <> void SymbolRecordImpl<ConstantSym>::map(IO &IO) { 411 IO.mapRequired("Type", Symbol.Type); 412 IO.mapRequired("Value", Symbol.Value); 413 IO.mapRequired("Name", Symbol.Name); 414 } 415 416 template <> void SymbolRecordImpl<DataSym>::map(IO &IO) { 417 // TODO: Map linkage name 418 IO.mapRequired("Type", Symbol.Type); 419 IO.mapRequired("DisplayName", Symbol.Name); 420 } 421 422 template <> void SymbolRecordImpl<ThreadLocalDataSym>::map(IO &IO) { 423 // TODO: Map linkage name 424 IO.mapRequired("Type", Symbol.Type); 425 IO.mapRequired("DisplayName", Symbol.Name); 426 } 427 } 428 } 429 } 430 431 CVSymbol CodeViewYAML::SymbolRecord::toCodeViewSymbol( 432 BumpPtrAllocator &Allocator) const { 433 return Symbol->toCodeViewSymbol(Allocator); 434 } 435 436 namespace llvm { 437 namespace yaml { 438 template <> struct MappingTraits<SymbolRecordBase> { 439 static void mapping(IO &io, SymbolRecordBase &Record) { Record.map(io); } 440 }; 441 } 442 } 443 444 template <typename SymbolType> 445 static inline Expected<CodeViewYAML::SymbolRecord> 446 fromCodeViewSymbolImpl(CVSymbol Symbol) { 447 CodeViewYAML::SymbolRecord Result; 448 449 auto Impl = std::make_shared<SymbolRecordImpl<SymbolType>>(Symbol.kind()); 450 if (auto EC = Impl->fromCodeViewSymbol(Symbol)) 451 return std::move(EC); 452 Result.Symbol = Impl; 453 return Result; 454 } 455 456 Expected<CodeViewYAML::SymbolRecord> 457 CodeViewYAML::SymbolRecord::fromCodeViewSymbol(CVSymbol Symbol) { 458 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 459 case EnumName: \ 460 return fromCodeViewSymbolImpl<ClassName>(Symbol); 461 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 462 SYMBOL_RECORD(EnumName, EnumVal, ClassName) 463 switch (Symbol.kind()) { 464 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 465 default: { llvm_unreachable("Unknown symbol kind!"); } 466 } 467 return make_error<CodeViewError>(cv_error_code::corrupt_record); 468 } 469 470 template <typename ConcreteType> 471 static void mapSymbolRecordImpl(IO &IO, const char *Class, SymbolKind Kind, 472 CodeViewYAML::SymbolRecord &Obj) { 473 if (!IO.outputting()) 474 Obj.Symbol = std::make_shared<SymbolRecordImpl<ConcreteType>>(Kind); 475 476 IO.mapRequired(Class, *Obj.Symbol); 477 } 478 479 void MappingTraits<CodeViewYAML::SymbolRecord>::mapping( 480 IO &IO, CodeViewYAML::SymbolRecord &Obj) { 481 SymbolKind Kind; 482 if (IO.outputting()) 483 Kind = Obj.Symbol->Kind; 484 IO.mapRequired("Kind", Kind); 485 486 #define SYMBOL_RECORD(EnumName, EnumVal, ClassName) \ 487 case EnumName: \ 488 mapSymbolRecordImpl<ClassName>(IO, #ClassName, Kind, Obj); \ 489 break; 490 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, AliasName, ClassName) \ 491 SYMBOL_RECORD(EnumName, EnumVal, ClassName) 492 switch (Kind) { 493 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 494 default: { llvm_unreachable("Unknown symbol kind!"); } 495 } 496 } 497