1 //===- SymbolRecordMapping.cpp -----------------------------------*- C++-*-===// 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 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" 10 11 using namespace llvm; 12 using namespace llvm::codeview; 13 14 #define error(X) \ 15 if (auto EC = X) \ 16 return EC; 17 18 namespace { 19 struct MapGap { 20 Error operator()(CodeViewRecordIO &IO, LocalVariableAddrGap &Gap) const { 21 error(IO.mapInteger(Gap.GapStartOffset)); 22 error(IO.mapInteger(Gap.Range)); 23 return Error::success(); 24 } 25 }; 26 } 27 28 static Error mapLocalVariableAddrRange(CodeViewRecordIO &IO, 29 LocalVariableAddrRange &Range) { 30 error(IO.mapInteger(Range.OffsetStart)); 31 error(IO.mapInteger(Range.ISectStart)); 32 error(IO.mapInteger(Range.Range)); 33 return Error::success(); 34 } 35 36 Error SymbolRecordMapping::visitSymbolBegin(CVSymbol &Record) { 37 error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix))); 38 return Error::success(); 39 } 40 41 Error SymbolRecordMapping::visitSymbolEnd(CVSymbol &Record) { 42 error(IO.padToAlignment(alignOf(Container))); 43 error(IO.endRecord()); 44 return Error::success(); 45 } 46 47 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) { 48 49 error(IO.mapInteger(Block.Parent)); 50 error(IO.mapInteger(Block.End)); 51 error(IO.mapInteger(Block.CodeSize)); 52 error(IO.mapInteger(Block.CodeOffset)); 53 error(IO.mapInteger(Block.Segment)); 54 error(IO.mapStringZ(Block.Name)); 55 56 return Error::success(); 57 } 58 59 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) { 60 61 error(IO.mapInteger(Thunk.Parent)); 62 error(IO.mapInteger(Thunk.End)); 63 error(IO.mapInteger(Thunk.Next)); 64 error(IO.mapInteger(Thunk.Offset)); 65 error(IO.mapInteger(Thunk.Segment)); 66 error(IO.mapInteger(Thunk.Length)); 67 error(IO.mapEnum(Thunk.Thunk)); 68 error(IO.mapStringZ(Thunk.Name)); 69 error(IO.mapByteVectorTail(Thunk.VariantData)); 70 71 return Error::success(); 72 } 73 74 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 75 TrampolineSym &Tramp) { 76 77 error(IO.mapEnum(Tramp.Type)); 78 error(IO.mapInteger(Tramp.Size)); 79 error(IO.mapInteger(Tramp.ThunkOffset)); 80 error(IO.mapInteger(Tramp.TargetOffset)); 81 error(IO.mapInteger(Tramp.ThunkSection)); 82 error(IO.mapInteger(Tramp.TargetSection)); 83 84 return Error::success(); 85 } 86 87 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 88 SectionSym &Section) { 89 uint8_t Padding = 0; 90 91 error(IO.mapInteger(Section.SectionNumber)); 92 error(IO.mapInteger(Section.Alignment)); 93 error(IO.mapInteger(Padding)); 94 error(IO.mapInteger(Section.Rva)); 95 error(IO.mapInteger(Section.Length)); 96 error(IO.mapInteger(Section.Characteristics)); 97 error(IO.mapStringZ(Section.Name)); 98 99 return Error::success(); 100 } 101 102 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 103 CoffGroupSym &CoffGroup) { 104 105 error(IO.mapInteger(CoffGroup.Size)); 106 error(IO.mapInteger(CoffGroup.Characteristics)); 107 error(IO.mapInteger(CoffGroup.Offset)); 108 error(IO.mapInteger(CoffGroup.Segment)); 109 error(IO.mapStringZ(CoffGroup.Name)); 110 111 return Error::success(); 112 } 113 114 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 115 BPRelativeSym &BPRel) { 116 117 error(IO.mapInteger(BPRel.Offset)); 118 error(IO.mapInteger(BPRel.Type)); 119 error(IO.mapStringZ(BPRel.Name)); 120 121 return Error::success(); 122 } 123 124 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 125 BuildInfoSym &BuildInfo) { 126 127 error(IO.mapInteger(BuildInfo.BuildId)); 128 129 return Error::success(); 130 } 131 132 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 133 CallSiteInfoSym &CallSiteInfo) { 134 uint16_t Padding = 0; 135 136 error(IO.mapInteger(CallSiteInfo.CodeOffset)); 137 error(IO.mapInteger(CallSiteInfo.Segment)); 138 error(IO.mapInteger(Padding)); 139 error(IO.mapInteger(CallSiteInfo.Type)); 140 141 return Error::success(); 142 } 143 144 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 145 EnvBlockSym &EnvBlock) { 146 147 uint8_t Reserved = 0; 148 error(IO.mapInteger(Reserved)); 149 error(IO.mapStringZVectorZ(EnvBlock.Fields)); 150 151 return Error::success(); 152 } 153 154 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 155 FileStaticSym &FileStatic) { 156 157 error(IO.mapInteger(FileStatic.Index)); 158 error(IO.mapInteger(FileStatic.ModFilenameOffset)); 159 error(IO.mapEnum(FileStatic.Flags)); 160 error(IO.mapStringZ(FileStatic.Name)); 161 162 return Error::success(); 163 } 164 165 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) { 166 167 error(IO.mapInteger(Export.Ordinal)); 168 error(IO.mapEnum(Export.Flags)); 169 error(IO.mapStringZ(Export.Name)); 170 171 return Error::success(); 172 } 173 174 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 175 Compile2Sym &Compile2) { 176 177 error(IO.mapEnum(Compile2.Flags)); 178 error(IO.mapEnum(Compile2.Machine)); 179 error(IO.mapInteger(Compile2.VersionFrontendMajor)); 180 error(IO.mapInteger(Compile2.VersionFrontendMinor)); 181 error(IO.mapInteger(Compile2.VersionFrontendBuild)); 182 error(IO.mapInteger(Compile2.VersionBackendMajor)); 183 error(IO.mapInteger(Compile2.VersionBackendMinor)); 184 error(IO.mapInteger(Compile2.VersionBackendBuild)); 185 error(IO.mapStringZ(Compile2.Version)); 186 error(IO.mapStringZVectorZ(Compile2.ExtraStrings)); 187 188 return Error::success(); 189 } 190 191 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 192 Compile3Sym &Compile3) { 193 194 error(IO.mapEnum(Compile3.Flags)); 195 error(IO.mapEnum(Compile3.Machine)); 196 error(IO.mapInteger(Compile3.VersionFrontendMajor)); 197 error(IO.mapInteger(Compile3.VersionFrontendMinor)); 198 error(IO.mapInteger(Compile3.VersionFrontendBuild)); 199 error(IO.mapInteger(Compile3.VersionFrontendQFE)); 200 error(IO.mapInteger(Compile3.VersionBackendMajor)); 201 error(IO.mapInteger(Compile3.VersionBackendMinor)); 202 error(IO.mapInteger(Compile3.VersionBackendBuild)); 203 error(IO.mapInteger(Compile3.VersionBackendQFE)); 204 error(IO.mapStringZ(Compile3.Version)); 205 206 return Error::success(); 207 } 208 209 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 210 ConstantSym &Constant) { 211 212 error(IO.mapInteger(Constant.Type)); 213 error(IO.mapEncodedInteger(Constant.Value)); 214 error(IO.mapStringZ(Constant.Name)); 215 216 return Error::success(); 217 } 218 219 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, DataSym &Data) { 220 221 error(IO.mapInteger(Data.Type)); 222 error(IO.mapInteger(Data.DataOffset)); 223 error(IO.mapInteger(Data.Segment)); 224 error(IO.mapStringZ(Data.Name)); 225 226 return Error::success(); 227 } 228 229 Error SymbolRecordMapping::visitKnownRecord( 230 CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) { 231 232 error(IO.mapObject(DefRangeFramePointerRel.Hdr.Offset)); 233 error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range)); 234 error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap())); 235 236 return Error::success(); 237 } 238 239 Error SymbolRecordMapping::visitKnownRecord( 240 CVSymbol &CVR, 241 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) { 242 243 error(IO.mapInteger(DefRangeFramePointerRelFullScope.Offset)); 244 245 return Error::success(); 246 } 247 248 Error SymbolRecordMapping::visitKnownRecord( 249 CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) { 250 251 error(IO.mapObject(DefRangeRegisterRel.Hdr.Register)); 252 error(IO.mapObject(DefRangeRegisterRel.Hdr.Flags)); 253 error(IO.mapObject(DefRangeRegisterRel.Hdr.BasePointerOffset)); 254 error(mapLocalVariableAddrRange(IO, DefRangeRegisterRel.Range)); 255 error(IO.mapVectorTail(DefRangeRegisterRel.Gaps, MapGap())); 256 257 return Error::success(); 258 } 259 260 Error SymbolRecordMapping::visitKnownRecord( 261 CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) { 262 263 error(IO.mapObject(DefRangeRegister.Hdr.Register)); 264 error(IO.mapObject(DefRangeRegister.Hdr.MayHaveNoName)); 265 error(mapLocalVariableAddrRange(IO, DefRangeRegister.Range)); 266 error(IO.mapVectorTail(DefRangeRegister.Gaps, MapGap())); 267 268 return Error::success(); 269 } 270 271 Error SymbolRecordMapping::visitKnownRecord( 272 CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) { 273 274 error(IO.mapObject(DefRangeSubfieldRegister.Hdr.Register)); 275 error(IO.mapObject(DefRangeSubfieldRegister.Hdr.MayHaveNoName)); 276 error(IO.mapObject(DefRangeSubfieldRegister.Hdr.OffsetInParent)); 277 error(mapLocalVariableAddrRange(IO, DefRangeSubfieldRegister.Range)); 278 error(IO.mapVectorTail(DefRangeSubfieldRegister.Gaps, MapGap())); 279 280 return Error::success(); 281 } 282 283 Error SymbolRecordMapping::visitKnownRecord( 284 CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) { 285 286 error(IO.mapInteger(DefRangeSubfield.Program)); 287 error(IO.mapInteger(DefRangeSubfield.OffsetInParent)); 288 error(mapLocalVariableAddrRange(IO, DefRangeSubfield.Range)); 289 error(IO.mapVectorTail(DefRangeSubfield.Gaps, MapGap())); 290 291 return Error::success(); 292 } 293 294 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 295 DefRangeSym &DefRange) { 296 297 error(IO.mapInteger(DefRange.Program)); 298 error(mapLocalVariableAddrRange(IO, DefRange.Range)); 299 error(IO.mapVectorTail(DefRange.Gaps, MapGap())); 300 301 return Error::success(); 302 } 303 304 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 305 FrameCookieSym &FrameCookie) { 306 307 error(IO.mapInteger(FrameCookie.CodeOffset)); 308 error(IO.mapInteger(FrameCookie.Register)); 309 error(IO.mapEnum(FrameCookie.CookieKind)); 310 error(IO.mapInteger(FrameCookie.Flags)); 311 312 return Error::success(); 313 } 314 315 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 316 FrameProcSym &FrameProc) { 317 error(IO.mapInteger(FrameProc.TotalFrameBytes)); 318 error(IO.mapInteger(FrameProc.PaddingFrameBytes)); 319 error(IO.mapInteger(FrameProc.OffsetToPadding)); 320 error(IO.mapInteger(FrameProc.BytesOfCalleeSavedRegisters)); 321 error(IO.mapInteger(FrameProc.OffsetOfExceptionHandler)); 322 error(IO.mapInteger(FrameProc.SectionIdOfExceptionHandler)); 323 error(IO.mapEnum(FrameProc.Flags)); 324 325 return Error::success(); 326 } 327 328 Error SymbolRecordMapping::visitKnownRecord( 329 CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) { 330 331 error(IO.mapInteger(HeapAllocSite.CodeOffset)); 332 error(IO.mapInteger(HeapAllocSite.Segment)); 333 error(IO.mapInteger(HeapAllocSite.CallInstructionSize)); 334 error(IO.mapInteger(HeapAllocSite.Type)); 335 336 return Error::success(); 337 } 338 339 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 340 InlineSiteSym &InlineSite) { 341 342 error(IO.mapInteger(InlineSite.Parent)); 343 error(IO.mapInteger(InlineSite.End)); 344 error(IO.mapInteger(InlineSite.Inlinee)); 345 error(IO.mapByteVectorTail(InlineSite.AnnotationData)); 346 347 return Error::success(); 348 } 349 350 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 351 RegisterSym &Register) { 352 353 error(IO.mapInteger(Register.Index)); 354 error(IO.mapEnum(Register.Register)); 355 error(IO.mapStringZ(Register.Name)); 356 357 return Error::success(); 358 } 359 360 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 361 PublicSym32 &Public) { 362 363 error(IO.mapEnum(Public.Flags)); 364 error(IO.mapInteger(Public.Offset)); 365 error(IO.mapInteger(Public.Segment)); 366 error(IO.mapStringZ(Public.Name)); 367 368 return Error::success(); 369 } 370 371 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 372 ProcRefSym &ProcRef) { 373 374 error(IO.mapInteger(ProcRef.SumName)); 375 error(IO.mapInteger(ProcRef.SymOffset)); 376 error(IO.mapInteger(ProcRef.Module)); 377 error(IO.mapStringZ(ProcRef.Name)); 378 379 return Error::success(); 380 } 381 382 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) { 383 384 error(IO.mapInteger(Label.CodeOffset)); 385 error(IO.mapInteger(Label.Segment)); 386 error(IO.mapEnum(Label.Flags)); 387 error(IO.mapStringZ(Label.Name)); 388 389 return Error::success(); 390 } 391 392 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) { 393 error(IO.mapInteger(Local.Type)); 394 error(IO.mapEnum(Local.Flags)); 395 error(IO.mapStringZ(Local.Name)); 396 397 return Error::success(); 398 } 399 400 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 401 ObjNameSym &ObjName) { 402 403 error(IO.mapInteger(ObjName.Signature)); 404 error(IO.mapStringZ(ObjName.Name)); 405 406 return Error::success(); 407 } 408 409 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) { 410 error(IO.mapInteger(Proc.Parent)); 411 error(IO.mapInteger(Proc.End)); 412 error(IO.mapInteger(Proc.Next)); 413 error(IO.mapInteger(Proc.CodeSize)); 414 error(IO.mapInteger(Proc.DbgStart)); 415 error(IO.mapInteger(Proc.DbgEnd)); 416 error(IO.mapInteger(Proc.FunctionType)); 417 error(IO.mapInteger(Proc.CodeOffset)); 418 error(IO.mapInteger(Proc.Segment)); 419 error(IO.mapEnum(Proc.Flags)); 420 error(IO.mapStringZ(Proc.Name)); 421 return Error::success(); 422 } 423 424 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 425 ScopeEndSym &ScopeEnd) { 426 return Error::success(); 427 } 428 429 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) { 430 error(IO.mapVectorN<uint32_t>( 431 Caller.Indices, 432 [](CodeViewRecordIO &IO, TypeIndex &N) { return IO.mapInteger(N); })); 433 return Error::success(); 434 } 435 436 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 437 RegRelativeSym &RegRel) { 438 439 error(IO.mapInteger(RegRel.Offset)); 440 error(IO.mapInteger(RegRel.Type)); 441 error(IO.mapEnum(RegRel.Register)); 442 error(IO.mapStringZ(RegRel.Name)); 443 444 return Error::success(); 445 } 446 447 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 448 ThreadLocalDataSym &Data) { 449 450 error(IO.mapInteger(Data.Type)); 451 error(IO.mapInteger(Data.DataOffset)); 452 error(IO.mapInteger(Data.Segment)); 453 error(IO.mapStringZ(Data.Name)); 454 455 return Error::success(); 456 } 457 458 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) { 459 460 error(IO.mapInteger(UDT.Type)); 461 error(IO.mapStringZ(UDT.Name)); 462 463 return Error::success(); 464 } 465 466 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 467 UsingNamespaceSym &UN) { 468 469 error(IO.mapStringZ(UN.Name)); 470 471 return Error::success(); 472 } 473 474 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 475 AnnotationSym &Annot) { 476 477 error(IO.mapInteger(Annot.CodeOffset)); 478 error(IO.mapInteger(Annot.Segment)); 479 error(IO.mapVectorN<uint16_t>( 480 Annot.Strings, 481 [](CodeViewRecordIO &IO, StringRef &S) { return IO.mapStringZ(S); })); 482 483 return Error::success(); 484 } 485 486 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, 487 JumpTableSym &JumpTable) { 488 error(IO.mapInteger(JumpTable.BaseOffset)); 489 error(IO.mapInteger(JumpTable.BaseSegment)); 490 error(IO.mapEnum(JumpTable.SwitchType)); 491 error(IO.mapInteger(JumpTable.BranchOffset)); 492 error(IO.mapInteger(JumpTable.TableOffset)); 493 error(IO.mapInteger(JumpTable.BranchSegment)); 494 error(IO.mapInteger(JumpTable.TableSegment)); 495 error(IO.mapInteger(JumpTable.EntriesCount)); 496 return Error::success(); 497 } 498 499 RegisterId codeview::decodeFramePtrReg(EncodedFramePtrReg EncodedReg, 500 CPUType CPU) { 501 assert(unsigned(EncodedReg) < 4); 502 switch (CPU) { 503 // FIXME: Add ARM and AArch64 variants here. 504 default: 505 break; 506 case CPUType::Intel8080: 507 case CPUType::Intel8086: 508 case CPUType::Intel80286: 509 case CPUType::Intel80386: 510 case CPUType::Intel80486: 511 case CPUType::Pentium: 512 case CPUType::PentiumPro: 513 case CPUType::Pentium3: 514 switch (EncodedReg) { 515 case EncodedFramePtrReg::None: return RegisterId::NONE; 516 case EncodedFramePtrReg::StackPtr: return RegisterId::VFRAME; 517 case EncodedFramePtrReg::FramePtr: return RegisterId::EBP; 518 case EncodedFramePtrReg::BasePtr: return RegisterId::EBX; 519 } 520 llvm_unreachable("bad encoding"); 521 case CPUType::X64: 522 switch (EncodedReg) { 523 case EncodedFramePtrReg::None: return RegisterId::NONE; 524 case EncodedFramePtrReg::StackPtr: return RegisterId::RSP; 525 case EncodedFramePtrReg::FramePtr: return RegisterId::RBP; 526 case EncodedFramePtrReg::BasePtr: return RegisterId::R13; 527 } 528 llvm_unreachable("bad encoding"); 529 } 530 return RegisterId::NONE; 531 } 532 533 EncodedFramePtrReg codeview::encodeFramePtrReg(RegisterId Reg, CPUType CPU) { 534 switch (CPU) { 535 // FIXME: Add ARM and AArch64 variants here. 536 default: 537 break; 538 case CPUType::Intel8080: 539 case CPUType::Intel8086: 540 case CPUType::Intel80286: 541 case CPUType::Intel80386: 542 case CPUType::Intel80486: 543 case CPUType::Pentium: 544 case CPUType::PentiumPro: 545 case CPUType::Pentium3: 546 switch (Reg) { 547 case RegisterId::VFRAME: 548 return EncodedFramePtrReg::StackPtr; 549 case RegisterId::EBP: 550 return EncodedFramePtrReg::FramePtr; 551 case RegisterId::EBX: 552 return EncodedFramePtrReg::BasePtr; 553 default: 554 break; 555 } 556 break; 557 case CPUType::X64: 558 switch (Reg) { 559 case RegisterId::RSP: 560 return EncodedFramePtrReg::StackPtr; 561 case RegisterId::RBP: 562 return EncodedFramePtrReg::FramePtr; 563 case RegisterId::R13: 564 return EncodedFramePtrReg::BasePtr; 565 default: 566 break; 567 } 568 break; 569 } 570 return EncodedFramePtrReg::None; 571 } 572