1 //===- SymbolRecord.h -------------------------------------------*- C++ -*-===// 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 #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H 11 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H 12 13 #include "llvm/ADT/APSInt.h" 14 #include "llvm/ADT/Optional.h" 15 #include "llvm/DebugInfo/CodeView/CVRecord.h" 16 #include "llvm/DebugInfo/CodeView/CodeView.h" 17 #include "llvm/DebugInfo/CodeView/RecordSerialization.h" 18 #include "llvm/DebugInfo/CodeView/StreamArray.h" 19 #include "llvm/DebugInfo/CodeView/StreamInterface.h" 20 #include "llvm/DebugInfo/CodeView/TypeIndex.h" 21 #include "llvm/Support/Endian.h" 22 #include "llvm/Support/Error.h" 23 24 namespace llvm { 25 namespace codeview { 26 27 using llvm::support::ulittle16_t; 28 using llvm::support::ulittle32_t; 29 using llvm::support::little32_t; 30 31 class SymbolRecord { 32 protected: SymbolRecord(SymbolRecordKind Kind)33 explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {} 34 35 public: getKind()36 SymbolRecordKind getKind() const { return Kind; } 37 38 private: 39 SymbolRecordKind Kind; 40 }; 41 42 // S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or 43 // S_LPROC32_DPC_ID 44 class ProcSym : public SymbolRecord { 45 public: 46 struct Hdr { 47 ulittle32_t PtrParent; 48 ulittle32_t PtrEnd; 49 ulittle32_t PtrNext; 50 ulittle32_t CodeSize; 51 ulittle32_t DbgStart; 52 ulittle32_t DbgEnd; 53 TypeIndex FunctionType; 54 ulittle32_t CodeOffset; 55 ulittle16_t Segment; 56 uint8_t Flags; // ProcSymFlags enum 57 // Name: The null-terminated name follows. 58 }; 59 ProcSym(SymbolRecordKind Kind,uint32_t RecordOffset,const Hdr * H,StringRef Name)60 ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H, 61 StringRef Name) 62 : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) { 63 } 64 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)65 static ErrorOr<ProcSym> deserialize(SymbolRecordKind Kind, 66 uint32_t RecordOffset, 67 ArrayRef<uint8_t> &Data) { 68 const Hdr *H = nullptr; 69 StringRef Name; 70 CV_DESERIALIZE(Data, H, Name); 71 72 return ProcSym(Kind, RecordOffset, H, Name); 73 } 74 getRelocationOffset()75 uint32_t getRelocationOffset() const { 76 return RecordOffset + offsetof(Hdr, CodeOffset); 77 } 78 79 uint32_t RecordOffset; 80 Hdr Header; 81 StringRef Name; 82 }; 83 84 // S_THUNK32 85 class Thunk32Sym : public SymbolRecord { 86 public: 87 struct Hdr { 88 ulittle32_t Parent; 89 ulittle32_t End; 90 ulittle32_t Next; 91 ulittle32_t Off; 92 ulittle16_t Seg; 93 ulittle16_t Len; 94 uint8_t Ord; // ThunkOrdinal enumeration 95 // Name: The null-terminated name follows. 96 // Variant portion of thunk 97 }; 98 Thunk32Sym(SymbolRecordKind Kind,uint32_t RecordOffset,const Hdr * H,StringRef Name,ArrayRef<uint8_t> VariantData)99 Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H, 100 StringRef Name, ArrayRef<uint8_t> VariantData) 101 : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name), 102 VariantData(VariantData) {} 103 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)104 static ErrorOr<Thunk32Sym> deserialize(SymbolRecordKind Kind, 105 uint32_t RecordOffset, 106 ArrayRef<uint8_t> &Data) { 107 const Hdr *H = nullptr; 108 StringRef Name; 109 ArrayRef<uint8_t> VariantData; 110 111 CV_DESERIALIZE(Data, H, Name, CV_ARRAY_FIELD_TAIL(VariantData)); 112 113 return Thunk32Sym(Kind, RecordOffset, H, Name, VariantData); 114 } 115 116 uint32_t RecordOffset; 117 Hdr Header; 118 StringRef Name; 119 ArrayRef<uint8_t> VariantData; 120 }; 121 122 // S_TRAMPOLINE 123 class TrampolineSym : public SymbolRecord { 124 public: 125 struct Hdr { 126 ulittle16_t Type; // TrampolineType enum 127 ulittle16_t Size; 128 ulittle32_t ThunkOff; 129 ulittle32_t TargetOff; 130 ulittle16_t ThunkSection; 131 ulittle16_t TargetSection; 132 }; 133 TrampolineSym(SymbolRecordKind Kind,uint32_t RecordOffset,const Hdr * H)134 TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H) 135 : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H) {} 136 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)137 static ErrorOr<TrampolineSym> deserialize(SymbolRecordKind Kind, 138 uint32_t RecordOffset, 139 ArrayRef<uint8_t> &Data) { 140 const Hdr *H = nullptr; 141 142 CV_DESERIALIZE(Data, H); 143 144 return TrampolineSym(Kind, RecordOffset, H); 145 } 146 147 uint32_t RecordOffset; 148 Hdr Header; 149 }; 150 151 // S_SECTION 152 class SectionSym : public SymbolRecord { 153 public: 154 struct Hdr { 155 ulittle16_t SectionNumber; 156 uint8_t Alignment; 157 uint8_t Reserved; // Must be 0 158 ulittle32_t Rva; 159 ulittle32_t Length; 160 ulittle32_t Characteristics; 161 // Name: The null-terminated name follows. 162 }; 163 SectionSym(SymbolRecordKind Kind,uint32_t RecordOffset,const Hdr * H,StringRef Name)164 SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H, 165 StringRef Name) 166 : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) { 167 } 168 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)169 static ErrorOr<SectionSym> deserialize(SymbolRecordKind Kind, 170 uint32_t RecordOffset, 171 ArrayRef<uint8_t> &Data) { 172 const Hdr *H = nullptr; 173 StringRef Name; 174 175 CV_DESERIALIZE(Data, H, Name); 176 177 return SectionSym(Kind, RecordOffset, H, Name); 178 } 179 180 uint32_t RecordOffset; 181 Hdr Header; 182 StringRef Name; 183 }; 184 185 // S_COFFGROUP 186 class CoffGroupSym : public SymbolRecord { 187 public: 188 struct Hdr { 189 ulittle32_t Size; 190 ulittle32_t Characteristics; 191 ulittle32_t Offset; 192 ulittle16_t Segment; 193 // Name: The null-terminated name follows. 194 }; 195 CoffGroupSym(SymbolRecordKind Kind,uint32_t RecordOffset,const Hdr * H,StringRef Name)196 CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *H, 197 StringRef Name) 198 : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*H), Name(Name) { 199 } 200 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)201 static ErrorOr<CoffGroupSym> deserialize(SymbolRecordKind Kind, 202 uint32_t RecordOffset, 203 ArrayRef<uint8_t> &Data) { 204 const Hdr *H = nullptr; 205 StringRef Name; 206 207 CV_DESERIALIZE(Data, H, Name); 208 209 return CoffGroupSym(Kind, RecordOffset, H, Name); 210 } 211 212 uint32_t RecordOffset; 213 Hdr Header; 214 StringRef Name; 215 }; 216 217 class ScopeEndSym : public SymbolRecord { 218 public: ScopeEndSym(SymbolRecordKind Kind,uint32_t RecordOffset)219 ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset) 220 : SymbolRecord(Kind), RecordOffset(RecordOffset) {} 221 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)222 static ErrorOr<ScopeEndSym> deserialize(SymbolRecordKind Kind, 223 uint32_t RecordOffset, 224 ArrayRef<uint8_t> &Data) { 225 return ScopeEndSym(Kind, RecordOffset); 226 } 227 uint32_t RecordOffset; 228 }; 229 230 class CallerSym : public SymbolRecord { 231 public: 232 struct Hdr { 233 ulittle32_t Count; 234 }; 235 CallerSym(SymbolRecordKind Kind,uint32_t RecordOffset,const Hdr * Header,ArrayRef<TypeIndex> Indices)236 CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset, const Hdr *Header, 237 ArrayRef<TypeIndex> Indices) 238 : SymbolRecord(Kind), RecordOffset(RecordOffset), Header(*Header), 239 Indices(Indices) {} 240 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)241 static ErrorOr<CallerSym> deserialize(SymbolRecordKind Kind, 242 uint32_t RecordOffset, 243 ArrayRef<uint8_t> &Data) { 244 const Hdr *Header; 245 ArrayRef<TypeIndex> Indices; 246 247 CV_DESERIALIZE(Data, Header, CV_ARRAY_FIELD_N(Indices, Header->Count)); 248 249 return CallerSym(Kind, RecordOffset, Header, Indices); 250 } 251 252 uint32_t RecordOffset; 253 Hdr Header; 254 ArrayRef<TypeIndex> Indices; 255 }; 256 257 struct BinaryAnnotationIterator { 258 struct AnnotationData { 259 BinaryAnnotationsOpCode OpCode; 260 StringRef Name; 261 uint32_t U1; 262 uint32_t U2; 263 int32_t S1; 264 }; 265 BinaryAnnotationIteratorBinaryAnnotationIterator266 BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {} BinaryAnnotationIteratorBinaryAnnotationIterator267 BinaryAnnotationIterator() {} BinaryAnnotationIteratorBinaryAnnotationIterator268 BinaryAnnotationIterator(const BinaryAnnotationIterator &Other) 269 : Data(Other.Data) {} 270 271 bool operator==(BinaryAnnotationIterator Other) const { 272 return Data == Other.Data; 273 } 274 275 bool operator!=(BinaryAnnotationIterator Other) const { 276 return !(*this == Other); 277 } 278 279 BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) { 280 Data = Other.Data; 281 return *this; 282 } 283 284 BinaryAnnotationIterator &operator++() { 285 if (!ParseCurrentAnnotation()) { 286 *this = BinaryAnnotationIterator(); 287 return *this; 288 } 289 Data = Next; 290 Next = ArrayRef<uint8_t>(); 291 Current.reset(); 292 return *this; 293 } 294 295 BinaryAnnotationIterator operator++(int) { 296 BinaryAnnotationIterator Orig(*this); 297 ++(*this); 298 return Orig; 299 } 300 301 const AnnotationData &operator*() { 302 ParseCurrentAnnotation(); 303 return Current.getValue(); 304 } 305 306 private: GetCompressedAnnotationBinaryAnnotationIterator307 static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) { 308 if (Annotations.empty()) 309 return -1; 310 311 uint8_t FirstByte = Annotations.front(); 312 Annotations = Annotations.drop_front(); 313 314 if ((FirstByte & 0x80) == 0x00) 315 return FirstByte; 316 317 if (Annotations.empty()) 318 return -1; 319 320 uint8_t SecondByte = Annotations.front(); 321 Annotations = Annotations.drop_front(); 322 323 if ((FirstByte & 0xC0) == 0x80) 324 return ((FirstByte & 0x3F) << 8) | SecondByte; 325 326 if (Annotations.empty()) 327 return -1; 328 329 uint8_t ThirdByte = Annotations.front(); 330 Annotations = Annotations.drop_front(); 331 332 if (Annotations.empty()) 333 return -1; 334 335 uint8_t FourthByte = Annotations.front(); 336 Annotations = Annotations.drop_front(); 337 338 if ((FirstByte & 0xE0) == 0xC0) 339 return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) | 340 (ThirdByte << 8) | FourthByte; 341 342 return -1; 343 }; 344 DecodeSignedOperandBinaryAnnotationIterator345 static int32_t DecodeSignedOperand(uint32_t Operand) { 346 if (Operand & 1) 347 return -(Operand >> 1); 348 return Operand >> 1; 349 }; 350 DecodeSignedOperandBinaryAnnotationIterator351 static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) { 352 return DecodeSignedOperand(GetCompressedAnnotation(Annotations)); 353 }; 354 ParseCurrentAnnotationBinaryAnnotationIterator355 bool ParseCurrentAnnotation() { 356 if (Current.hasValue()) 357 return true; 358 359 Next = Data; 360 uint32_t Op = GetCompressedAnnotation(Next); 361 AnnotationData Result; 362 Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op); 363 switch (Result.OpCode) { 364 case BinaryAnnotationsOpCode::Invalid: 365 Result.Name = "Invalid"; 366 Next = ArrayRef<uint8_t>(); 367 break; 368 case BinaryAnnotationsOpCode::CodeOffset: 369 Result.Name = "CodeOffset"; 370 Result.U1 = GetCompressedAnnotation(Next); 371 break; 372 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: 373 Result.Name = "ChangeCodeOffsetBase"; 374 Result.U1 = GetCompressedAnnotation(Next); 375 break; 376 case BinaryAnnotationsOpCode::ChangeCodeOffset: 377 Result.Name = "ChangeCodeOffset"; 378 Result.U1 = GetCompressedAnnotation(Next); 379 break; 380 case BinaryAnnotationsOpCode::ChangeCodeLength: 381 Result.Name = "ChangeCodeLength"; 382 Result.U1 = GetCompressedAnnotation(Next); 383 break; 384 case BinaryAnnotationsOpCode::ChangeFile: 385 Result.Name = "ChangeFile"; 386 Result.U1 = GetCompressedAnnotation(Next); 387 break; 388 case BinaryAnnotationsOpCode::ChangeLineEndDelta: 389 Result.Name = "ChangeLineEndDelta"; 390 Result.U1 = GetCompressedAnnotation(Next); 391 break; 392 case BinaryAnnotationsOpCode::ChangeRangeKind: 393 Result.Name = "ChangeRangeKind"; 394 Result.U1 = GetCompressedAnnotation(Next); 395 break; 396 case BinaryAnnotationsOpCode::ChangeColumnStart: 397 Result.Name = "ChangeColumnStart"; 398 Result.U1 = GetCompressedAnnotation(Next); 399 break; 400 case BinaryAnnotationsOpCode::ChangeColumnEnd: 401 Result.Name = "ChangeColumnEnd"; 402 Result.U1 = GetCompressedAnnotation(Next); 403 break; 404 case BinaryAnnotationsOpCode::ChangeLineOffset: 405 Result.Name = "ChangeLineOffset"; 406 Result.S1 = DecodeSignedOperand(Next); 407 break; 408 case BinaryAnnotationsOpCode::ChangeColumnEndDelta: 409 Result.Name = "ChangeColumnEndDelta"; 410 Result.S1 = DecodeSignedOperand(Next); 411 break; 412 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: { 413 Result.Name = "ChangeCodeOffsetAndLineOffset"; 414 uint32_t Annotation = GetCompressedAnnotation(Next); 415 Result.S1 = DecodeSignedOperand(Annotation >> 4); 416 Result.U1 = Annotation & 0xf; 417 break; 418 } 419 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: { 420 Result.Name = "ChangeCodeLengthAndCodeOffset"; 421 Result.U1 = GetCompressedAnnotation(Next); 422 Result.U2 = GetCompressedAnnotation(Next); 423 break; 424 } 425 } 426 Current = Result; 427 return true; 428 } 429 430 Optional<AnnotationData> Current; 431 ArrayRef<uint8_t> Data; 432 ArrayRef<uint8_t> Next; 433 }; 434 435 // S_INLINESITE 436 class InlineSiteSym : public SymbolRecord { 437 public: 438 struct Hdr { 439 ulittle32_t PtrParent; 440 ulittle32_t PtrEnd; 441 TypeIndex Inlinee; 442 // BinaryAnnotations 443 }; 444 InlineSiteSym(uint32_t RecordOffset,const Hdr * H,ArrayRef<uint8_t> Annotations)445 InlineSiteSym(uint32_t RecordOffset, const Hdr *H, 446 ArrayRef<uint8_t> Annotations) 447 : SymbolRecord(SymbolRecordKind::InlineSiteSym), 448 RecordOffset(RecordOffset), Header(*H), Annotations(Annotations) {} 449 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)450 static ErrorOr<InlineSiteSym> deserialize(SymbolRecordKind Kind, 451 uint32_t RecordOffset, 452 ArrayRef<uint8_t> &Data) { 453 const Hdr *H = nullptr; 454 ArrayRef<uint8_t> Annotations; 455 CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Annotations)); 456 457 return InlineSiteSym(RecordOffset, H, Annotations); 458 } 459 annotations()460 llvm::iterator_range<BinaryAnnotationIterator> annotations() const { 461 return llvm::make_range(BinaryAnnotationIterator(Annotations), 462 BinaryAnnotationIterator()); 463 } 464 465 uint32_t RecordOffset; 466 Hdr Header; 467 468 private: 469 ArrayRef<uint8_t> Annotations; 470 }; 471 472 // S_PUB32 473 class PublicSym32 : public SymbolRecord { 474 public: 475 struct Hdr { 476 ulittle32_t Index; // Type index, or Metadata token if a managed symbol 477 ulittle32_t Off; 478 ulittle16_t Seg; 479 // Name: The null-terminated name follows. 480 }; 481 PublicSym32(uint32_t RecordOffset,const Hdr * H,StringRef Name)482 PublicSym32(uint32_t RecordOffset, const Hdr *H, StringRef Name) 483 : SymbolRecord(SymbolRecordKind::PublicSym32), RecordOffset(RecordOffset), 484 Header(*H), Name(Name) {} 485 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)486 static ErrorOr<PublicSym32> deserialize(SymbolRecordKind Kind, 487 uint32_t RecordOffset, 488 ArrayRef<uint8_t> &Data) { 489 const Hdr *H = nullptr; 490 StringRef Name; 491 CV_DESERIALIZE(Data, H, Name); 492 493 return PublicSym32(RecordOffset, H, Name); 494 } 495 496 uint32_t RecordOffset; 497 Hdr Header; 498 StringRef Name; 499 }; 500 501 // S_REGISTER 502 class RegisterSym : public SymbolRecord { 503 public: 504 struct Hdr { 505 ulittle32_t Index; // Type index or Metadata token 506 ulittle16_t Register; // RegisterId enumeration 507 // Name: The null-terminated name follows. 508 }; 509 RegisterSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)510 RegisterSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 511 : SymbolRecord(SymbolRecordKind::RegisterSym), RecordOffset(RecordOffset), 512 Header(*H), Name(Name) {} 513 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)514 static ErrorOr<RegisterSym> deserialize(SymbolRecordKind Kind, 515 uint32_t RecordOffset, 516 ArrayRef<uint8_t> &Data) { 517 const Hdr *H = nullptr; 518 StringRef Name; 519 CV_DESERIALIZE(Data, H, Name); 520 521 return RegisterSym(RecordOffset, H, Name); 522 } 523 524 uint32_t RecordOffset; 525 Hdr Header; 526 StringRef Name; 527 }; 528 529 // S_PROCREF, S_LPROCREF 530 class ProcRefSym : public SymbolRecord { 531 public: 532 struct Hdr { 533 ulittle32_t SumName; // SUC of the name (?) 534 ulittle32_t SymOffset; // Offset of actual symbol in $$Symbols 535 ulittle16_t Mod; // Module containing the actual symbol 536 // Name: The null-terminated name follows. 537 }; 538 ProcRefSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)539 ProcRefSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 540 : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset), 541 Header(*H), Name(Name) {} 542 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)543 static ErrorOr<ProcRefSym> deserialize(SymbolRecordKind Kind, 544 uint32_t RecordOffset, 545 ArrayRef<uint8_t> &Data) { 546 const Hdr *H = nullptr; 547 StringRef Name; 548 CV_DESERIALIZE(Data, H, Name); 549 550 return ProcRefSym(RecordOffset, H, Name); 551 } 552 553 uint32_t RecordOffset; 554 Hdr Header; 555 StringRef Name; 556 }; 557 558 // S_LOCAL 559 class LocalSym : public SymbolRecord { 560 public: 561 struct Hdr { 562 TypeIndex Type; 563 ulittle16_t Flags; // LocalSymFlags enum 564 // Name: The null-terminated name follows. 565 }; 566 LocalSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)567 LocalSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 568 : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset), 569 Header(*H), Name(Name) {} 570 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)571 static ErrorOr<LocalSym> deserialize(SymbolRecordKind Kind, 572 uint32_t RecordOffset, 573 ArrayRef<uint8_t> &Data) { 574 const Hdr *H = nullptr; 575 StringRef Name; 576 CV_DESERIALIZE(Data, H, Name); 577 578 return LocalSym(RecordOffset, H, Name); 579 } 580 581 uint32_t RecordOffset; 582 Hdr Header; 583 StringRef Name; 584 }; 585 586 struct LocalVariableAddrRange { 587 ulittle32_t OffsetStart; 588 ulittle16_t ISectStart; 589 ulittle16_t Range; 590 }; 591 592 struct LocalVariableAddrGap { 593 ulittle16_t GapStartOffset; 594 ulittle16_t Range; 595 }; 596 597 enum : uint16_t { MaxDefRange = 0xf000 }; 598 599 // S_DEFRANGE 600 class DefRangeSym : public SymbolRecord { 601 public: 602 struct Hdr { 603 ulittle32_t Program; 604 LocalVariableAddrRange Range; 605 // LocalVariableAddrGap Gaps[]; 606 }; 607 DefRangeSym(uint32_t RecordOffset,const Hdr * H,ArrayRef<LocalVariableAddrGap> Gaps)608 DefRangeSym(uint32_t RecordOffset, const Hdr *H, 609 ArrayRef<LocalVariableAddrGap> Gaps) 610 : SymbolRecord(SymbolRecordKind::DefRangeSym), RecordOffset(RecordOffset), 611 Header(*H), Gaps(Gaps) {} 612 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)613 static ErrorOr<DefRangeSym> deserialize(SymbolRecordKind Kind, 614 uint32_t RecordOffset, 615 ArrayRef<uint8_t> &Data) { 616 const Hdr *H = nullptr; 617 ArrayRef<LocalVariableAddrGap> Gaps; 618 CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); 619 620 return DefRangeSym(RecordOffset, H, Gaps); 621 } 622 getRelocationOffset()623 uint32_t getRelocationOffset() const { 624 return RecordOffset + offsetof(Hdr, Range); 625 } 626 627 uint32_t RecordOffset; 628 Hdr Header; 629 ArrayRef<LocalVariableAddrGap> Gaps; 630 }; 631 632 // S_DEFRANGE_SUBFIELD 633 class DefRangeSubfieldSym : public SymbolRecord { 634 public: 635 struct Hdr { 636 ulittle32_t Program; 637 ulittle16_t OffsetInParent; 638 LocalVariableAddrRange Range; 639 // LocalVariableAddrGap Gaps[]; 640 }; DefRangeSubfieldSym(uint32_t RecordOffset,const Hdr * H,ArrayRef<LocalVariableAddrGap> Gaps)641 DefRangeSubfieldSym(uint32_t RecordOffset, const Hdr *H, 642 ArrayRef<LocalVariableAddrGap> Gaps) 643 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym), 644 RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {} 645 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)646 static ErrorOr<DefRangeSubfieldSym> deserialize(SymbolRecordKind Kind, 647 uint32_t RecordOffset, 648 ArrayRef<uint8_t> &Data) { 649 const Hdr *H = nullptr; 650 ArrayRef<LocalVariableAddrGap> Gaps; 651 CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); 652 653 return DefRangeSubfieldSym(RecordOffset, H, Gaps); 654 } 655 getRelocationOffset()656 uint32_t getRelocationOffset() const { 657 return RecordOffset + offsetof(Hdr, Range); 658 } 659 660 uint32_t RecordOffset; 661 Hdr Header; 662 ArrayRef<LocalVariableAddrGap> Gaps; 663 }; 664 665 // S_DEFRANGE_REGISTER 666 class DefRangeRegisterSym : public SymbolRecord { 667 public: 668 struct Hdr { 669 ulittle16_t Register; 670 ulittle16_t MayHaveNoName; 671 LocalVariableAddrRange Range; 672 // LocalVariableAddrGap Gaps[]; 673 }; 674 DefRangeRegisterSym(uint32_t RecordOffset,const Hdr * H,ArrayRef<LocalVariableAddrGap> Gaps)675 DefRangeRegisterSym(uint32_t RecordOffset, const Hdr *H, 676 ArrayRef<LocalVariableAddrGap> Gaps) 677 : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym), 678 RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {} 679 DefRangeRegisterSym(uint16_t Register,uint16_t MayHaveNoName,uint32_t OffsetStart,uint16_t ISectStart,uint16_t Range,ArrayRef<LocalVariableAddrGap> Gaps)680 DefRangeRegisterSym(uint16_t Register, uint16_t MayHaveNoName, 681 uint32_t OffsetStart, uint16_t ISectStart, uint16_t Range, 682 ArrayRef<LocalVariableAddrGap> Gaps) 683 : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym), RecordOffset(0), 684 Gaps(Gaps) { 685 Header.Register = Register; 686 Header.MayHaveNoName = MayHaveNoName; 687 Header.Range.OffsetStart = OffsetStart; 688 Header.Range.ISectStart = ISectStart; 689 Header.Range.Range = Range; 690 } 691 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)692 static ErrorOr<DefRangeRegisterSym> deserialize(SymbolRecordKind Kind, 693 uint32_t RecordOffset, 694 ArrayRef<uint8_t> &Data) { 695 const Hdr *H = nullptr; 696 ArrayRef<LocalVariableAddrGap> Gaps; 697 CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); 698 699 return DefRangeRegisterSym(RecordOffset, H, Gaps); 700 } 701 getRelocationOffset()702 uint32_t getRelocationOffset() const { 703 return RecordOffset + offsetof(Hdr, Range); 704 } 705 706 uint32_t RecordOffset; 707 Hdr Header; 708 ArrayRef<LocalVariableAddrGap> Gaps; 709 }; 710 711 // S_DEFRANGE_SUBFIELD_REGISTER 712 class DefRangeSubfieldRegisterSym : public SymbolRecord { 713 public: 714 struct Hdr { 715 ulittle16_t Register; // Register to which the variable is relative 716 ulittle16_t MayHaveNoName; 717 ulittle32_t OffsetInParent; 718 LocalVariableAddrRange Range; 719 // LocalVariableAddrGap Gaps[]; 720 }; 721 DefRangeSubfieldRegisterSym(uint32_t RecordOffset,const Hdr * H,ArrayRef<LocalVariableAddrGap> Gaps)722 DefRangeSubfieldRegisterSym(uint32_t RecordOffset, const Hdr *H, 723 ArrayRef<LocalVariableAddrGap> Gaps) 724 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym), 725 RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {} 726 DefRangeSubfieldRegisterSym(uint16_t Register,uint16_t MayHaveNoName,uint32_t OffsetInParent,ArrayRef<LocalVariableAddrGap> Gaps)727 DefRangeSubfieldRegisterSym(uint16_t Register, uint16_t MayHaveNoName, 728 uint32_t OffsetInParent, 729 ArrayRef<LocalVariableAddrGap> Gaps) 730 : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym), 731 RecordOffset(0), Gaps(Gaps) { 732 Header.Register = Register; 733 Header.MayHaveNoName = MayHaveNoName; 734 Header.OffsetInParent = OffsetInParent; 735 } 736 737 static ErrorOr<DefRangeSubfieldRegisterSym> deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)738 deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, 739 ArrayRef<uint8_t> &Data) { 740 const Hdr *H = nullptr; 741 ArrayRef<LocalVariableAddrGap> Gaps; 742 CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); 743 744 return DefRangeSubfieldRegisterSym(RecordOffset, H, Gaps); 745 } 746 getRelocationOffset()747 uint32_t getRelocationOffset() const { 748 return RecordOffset + offsetof(Hdr, Range); 749 } 750 751 uint32_t RecordOffset; 752 Hdr Header; 753 ArrayRef<LocalVariableAddrGap> Gaps; 754 }; 755 756 // S_DEFRANGE_FRAMEPOINTER_REL 757 class DefRangeFramePointerRelSym : public SymbolRecord { 758 public: 759 struct Hdr { 760 little32_t Offset; // Offset from the frame pointer register 761 LocalVariableAddrRange Range; 762 // LocalVariableAddrGap Gaps[]; 763 }; 764 DefRangeFramePointerRelSym(uint32_t RecordOffset,const Hdr * H,ArrayRef<LocalVariableAddrGap> Gaps)765 DefRangeFramePointerRelSym(uint32_t RecordOffset, const Hdr *H, 766 ArrayRef<LocalVariableAddrGap> Gaps) 767 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym), 768 RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {} 769 770 static ErrorOr<DefRangeFramePointerRelSym> deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)771 deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, 772 ArrayRef<uint8_t> &Data) { 773 const Hdr *H = nullptr; 774 ArrayRef<LocalVariableAddrGap> Gaps; 775 CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); 776 777 return DefRangeFramePointerRelSym(RecordOffset, H, Gaps); 778 } 779 getRelocationOffset()780 uint32_t getRelocationOffset() const { 781 return RecordOffset + offsetof(Hdr, Range); 782 } 783 784 uint32_t RecordOffset; 785 Hdr Header; 786 ArrayRef<LocalVariableAddrGap> Gaps; 787 }; 788 789 // S_DEFRANGE_REGISTER_REL 790 class DefRangeRegisterRelSym : public SymbolRecord { 791 public: 792 struct Hdr { 793 ulittle16_t BaseRegister; 794 ulittle16_t Flags; 795 little32_t BasePointerOffset; 796 LocalVariableAddrRange Range; 797 // LocalVariableAddrGap Gaps[]; 798 }; 799 DefRangeRegisterRelSym(uint32_t RecordOffset,const Hdr * H,ArrayRef<LocalVariableAddrGap> Gaps)800 DefRangeRegisterRelSym(uint32_t RecordOffset, const Hdr *H, 801 ArrayRef<LocalVariableAddrGap> Gaps) 802 : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym), 803 RecordOffset(RecordOffset), Header(*H), Gaps(Gaps) {} 804 DefRangeRegisterRelSym(uint16_t BaseRegister,uint16_t Flags,int32_t BasePointerOffset,uint32_t OffsetStart,uint16_t ISectStart,uint16_t Range,ArrayRef<LocalVariableAddrGap> Gaps)805 DefRangeRegisterRelSym(uint16_t BaseRegister, uint16_t Flags, 806 int32_t BasePointerOffset, uint32_t OffsetStart, 807 uint16_t ISectStart, uint16_t Range, 808 ArrayRef<LocalVariableAddrGap> Gaps) 809 : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym), RecordOffset(0), 810 Gaps(Gaps) { 811 Header.BaseRegister = BaseRegister; 812 Header.Flags = Flags; 813 Header.BasePointerOffset = BasePointerOffset; 814 Header.Range.OffsetStart = OffsetStart; 815 Header.Range.ISectStart = ISectStart; 816 Header.Range.Range = Range; 817 } 818 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)819 static ErrorOr<DefRangeRegisterRelSym> deserialize(SymbolRecordKind Kind, 820 uint32_t RecordOffset, 821 ArrayRef<uint8_t> &Data) { 822 const Hdr *H = nullptr; 823 ArrayRef<LocalVariableAddrGap> Gaps; 824 CV_DESERIALIZE(Data, H, CV_ARRAY_FIELD_TAIL(Gaps)); 825 826 return DefRangeRegisterRelSym(RecordOffset, H, Gaps); 827 } 828 hasSpilledUDTMember()829 bool hasSpilledUDTMember() const { return Header.Flags & 1; } offsetInParent()830 uint16_t offsetInParent() const { return Header.Flags >> 4; } 831 getRelocationOffset()832 uint32_t getRelocationOffset() const { 833 return RecordOffset + offsetof(Hdr, Range); 834 } 835 836 uint32_t RecordOffset; 837 Hdr Header; 838 ArrayRef<LocalVariableAddrGap> Gaps; 839 }; 840 841 // S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE 842 class DefRangeFramePointerRelFullScopeSym : public SymbolRecord { 843 public: 844 struct Hdr { 845 little32_t Offset; // Offset from the frame pointer register 846 }; 847 DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset,const Hdr * H)848 DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset, const Hdr *H) 849 : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym), 850 RecordOffset(RecordOffset), Header(*H) {} 851 852 static ErrorOr<DefRangeFramePointerRelFullScopeSym> deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)853 deserialize(SymbolRecordKind Kind, uint32_t RecordOffset, 854 ArrayRef<uint8_t> &Data) { 855 const Hdr *H = nullptr; 856 CV_DESERIALIZE(Data, H); 857 858 return DefRangeFramePointerRelFullScopeSym(RecordOffset, H); 859 } 860 861 uint32_t RecordOffset; 862 Hdr Header; 863 }; 864 865 // S_BLOCK32 866 class BlockSym : public SymbolRecord { 867 public: 868 struct Hdr { 869 ulittle32_t PtrParent; 870 ulittle32_t PtrEnd; 871 ulittle32_t CodeSize; 872 ulittle32_t CodeOffset; 873 ulittle16_t Segment; 874 // Name: The null-terminated name follows. 875 }; 876 BlockSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)877 BlockSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 878 : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset), 879 Header(*H), Name(Name) {} 880 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)881 static ErrorOr<BlockSym> deserialize(SymbolRecordKind Kind, 882 uint32_t RecordOffset, 883 ArrayRef<uint8_t> &Data) { 884 const Hdr *H = nullptr; 885 StringRef Name; 886 CV_DESERIALIZE(Data, H, Name); 887 888 return BlockSym(RecordOffset, H, Name); 889 } 890 getRelocationOffset()891 uint32_t getRelocationOffset() const { 892 return RecordOffset + offsetof(Hdr, CodeOffset); 893 } 894 895 uint32_t RecordOffset; 896 Hdr Header; 897 StringRef Name; 898 }; 899 900 // S_LABEL32 901 class LabelSym : public SymbolRecord { 902 public: 903 struct Hdr { 904 ulittle32_t CodeOffset; 905 ulittle16_t Segment; 906 uint8_t Flags; // CV_PROCFLAGS 907 // Name: The null-terminated name follows. 908 }; 909 LabelSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)910 LabelSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 911 : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset), 912 Header(*H), Name(Name) {} 913 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)914 static ErrorOr<LabelSym> deserialize(SymbolRecordKind Kind, 915 uint32_t RecordOffset, 916 ArrayRef<uint8_t> &Data) { 917 const Hdr *H = nullptr; 918 StringRef Name; 919 CV_DESERIALIZE(Data, H, Name); 920 921 return LabelSym(RecordOffset, H, Name); 922 } 923 getRelocationOffset()924 uint32_t getRelocationOffset() const { 925 return RecordOffset + offsetof(Hdr, CodeOffset); 926 } 927 928 uint32_t RecordOffset; 929 Hdr Header; 930 StringRef Name; 931 }; 932 933 // S_OBJNAME 934 class ObjNameSym : public SymbolRecord { 935 public: 936 struct Hdr { 937 ulittle32_t Signature; 938 // Name: The null-terminated name follows. 939 }; 940 ObjNameSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)941 ObjNameSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 942 : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset), 943 Header(*H), Name(Name) {} 944 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)945 static ErrorOr<ObjNameSym> deserialize(SymbolRecordKind Kind, 946 uint32_t RecordOffset, 947 ArrayRef<uint8_t> &Data) { 948 const Hdr *H = nullptr; 949 StringRef Name; 950 CV_DESERIALIZE(Data, H, Name); 951 952 return ObjNameSym(RecordOffset, H, Name); 953 } 954 955 uint32_t RecordOffset; 956 Hdr Header; 957 StringRef Name; 958 }; 959 960 // S_ENVBLOCK 961 class EnvBlockSym : public SymbolRecord { 962 public: 963 struct Hdr { 964 uint8_t Reserved; 965 // Sequence of zero terminated strings. 966 }; 967 EnvBlockSym(uint32_t RecordOffset,const Hdr * H,const std::vector<StringRef> & Fields)968 EnvBlockSym(uint32_t RecordOffset, const Hdr *H, 969 const std::vector<StringRef> &Fields) 970 : SymbolRecord(SymbolRecordKind::EnvBlockSym), RecordOffset(RecordOffset), 971 Header(*H), Fields(Fields) {} 972 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)973 static ErrorOr<EnvBlockSym> deserialize(SymbolRecordKind Kind, 974 uint32_t RecordOffset, 975 ArrayRef<uint8_t> &Data) { 976 const Hdr *H = nullptr; 977 std::vector<StringRef> Fields; 978 CV_DESERIALIZE(Data, H, CV_STRING_ARRAY_NULL_TERM(Fields)); 979 980 return EnvBlockSym(RecordOffset, H, Fields); 981 } 982 983 uint32_t RecordOffset; 984 Hdr Header; 985 std::vector<StringRef> Fields; 986 }; 987 988 // S_EXPORT 989 class ExportSym : public SymbolRecord { 990 public: 991 struct Hdr { 992 ulittle16_t Ordinal; 993 ulittle16_t Flags; // ExportFlags 994 // Name: The null-terminated name follows. 995 }; 996 ExportSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)997 ExportSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 998 : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset), 999 Header(*H), Name(Name) {} 1000 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1001 static ErrorOr<ExportSym> deserialize(SymbolRecordKind Kind, 1002 uint32_t RecordOffset, 1003 ArrayRef<uint8_t> &Data) { 1004 const Hdr *H = nullptr; 1005 StringRef Name; 1006 CV_DESERIALIZE(Data, H, Name); 1007 1008 return ExportSym(RecordOffset, H, Name); 1009 } 1010 1011 uint32_t RecordOffset; 1012 Hdr Header; 1013 StringRef Name; 1014 }; 1015 1016 // S_FILESTATIC 1017 class FileStaticSym : public SymbolRecord { 1018 public: 1019 struct Hdr { 1020 ulittle32_t Index; // Type Index 1021 ulittle32_t ModFilenameOffset; // Index of mod filename in string table 1022 ulittle16_t Flags; // LocalSymFlags enum 1023 // Name: The null-terminated name follows. 1024 }; 1025 FileStaticSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)1026 FileStaticSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 1027 : SymbolRecord(SymbolRecordKind::FileStaticSym), 1028 RecordOffset(RecordOffset), Header(*H), Name(Name) {} 1029 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1030 static ErrorOr<FileStaticSym> deserialize(SymbolRecordKind Kind, 1031 uint32_t RecordOffset, 1032 ArrayRef<uint8_t> &Data) { 1033 const Hdr *H = nullptr; 1034 StringRef Name; 1035 CV_DESERIALIZE(Data, H, Name); 1036 1037 return FileStaticSym(RecordOffset, H, Name); 1038 } 1039 1040 uint32_t RecordOffset; 1041 Hdr Header; 1042 StringRef Name; 1043 }; 1044 1045 // S_COMPILE2 1046 class Compile2Sym : public SymbolRecord { 1047 public: 1048 struct Hdr { 1049 ulittle32_t flags; // CompileSym2Flags enum getLanguageHdr1050 uint8_t getLanguage() const { return flags & 0xFF; } 1051 unsigned short Machine; // CPUType enum 1052 unsigned short VersionFrontendMajor; 1053 unsigned short VersionFrontendMinor; 1054 unsigned short VersionFrontendBuild; 1055 unsigned short VersionBackendMajor; 1056 unsigned short VersionBackendMinor; 1057 unsigned short VersionBackendBuild; 1058 // Version: The null-terminated version string follows. 1059 // Optional block of zero terminated strings terminated with a double zero. 1060 }; 1061 Compile2Sym(uint32_t RecordOffset,const Hdr * H,StringRef Version)1062 Compile2Sym(uint32_t RecordOffset, const Hdr *H, StringRef Version) 1063 : SymbolRecord(SymbolRecordKind::Compile2Sym), RecordOffset(RecordOffset), 1064 Header(*H), Version(Version) {} 1065 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1066 static ErrorOr<Compile2Sym> deserialize(SymbolRecordKind Kind, 1067 uint32_t RecordOffset, 1068 ArrayRef<uint8_t> &Data) { 1069 const Hdr *H = nullptr; 1070 StringRef Version; 1071 CV_DESERIALIZE(Data, H, Version); 1072 1073 return Compile2Sym(RecordOffset, H, Version); 1074 } 1075 1076 uint32_t RecordOffset; 1077 Hdr Header; 1078 StringRef Version; 1079 }; 1080 1081 // S_COMPILE3 1082 class Compile3Sym : public SymbolRecord { 1083 public: 1084 struct Hdr { 1085 ulittle32_t flags; // CompileSym3Flags enum getLanguageHdr1086 uint8_t getLanguage() const { return flags & 0xff; } 1087 ulittle16_t Machine; // CPUType enum 1088 ulittle16_t VersionFrontendMajor; 1089 ulittle16_t VersionFrontendMinor; 1090 ulittle16_t VersionFrontendBuild; 1091 ulittle16_t VersionFrontendQFE; 1092 ulittle16_t VersionBackendMajor; 1093 ulittle16_t VersionBackendMinor; 1094 ulittle16_t VersionBackendBuild; 1095 ulittle16_t VersionBackendQFE; 1096 // VersionString: The null-terminated version string follows. 1097 }; 1098 Compile3Sym(uint32_t RecordOffset,const Hdr * H,StringRef Version)1099 Compile3Sym(uint32_t RecordOffset, const Hdr *H, StringRef Version) 1100 : SymbolRecord(SymbolRecordKind::Compile3Sym), RecordOffset(RecordOffset), 1101 Header(*H), Version(Version) {} 1102 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1103 static ErrorOr<Compile3Sym> deserialize(SymbolRecordKind Kind, 1104 uint32_t RecordOffset, 1105 ArrayRef<uint8_t> &Data) { 1106 const Hdr *H = nullptr; 1107 StringRef Version; 1108 CV_DESERIALIZE(Data, H, Version); 1109 1110 return Compile3Sym(RecordOffset, H, Version); 1111 } 1112 1113 uint32_t RecordOffset; 1114 Hdr Header; 1115 StringRef Version; 1116 }; 1117 1118 // S_FRAMEPROC 1119 class FrameProcSym : public SymbolRecord { 1120 public: 1121 struct Hdr { 1122 ulittle32_t TotalFrameBytes; 1123 ulittle32_t PaddingFrameBytes; 1124 ulittle32_t OffsetToPadding; 1125 ulittle32_t BytesOfCalleeSavedRegisters; 1126 ulittle32_t OffsetOfExceptionHandler; 1127 ulittle16_t SectionIdOfExceptionHandler; 1128 ulittle32_t Flags; 1129 }; 1130 FrameProcSym(uint32_t RecordOffset,const Hdr * H)1131 FrameProcSym(uint32_t RecordOffset, const Hdr *H) 1132 : SymbolRecord(SymbolRecordKind::FrameProcSym), 1133 RecordOffset(RecordOffset), Header(*H) {} 1134 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1135 static ErrorOr<FrameProcSym> deserialize(SymbolRecordKind Kind, 1136 uint32_t RecordOffset, 1137 ArrayRef<uint8_t> &Data) { 1138 const Hdr *H = nullptr; 1139 CV_DESERIALIZE(Data, H); 1140 1141 return FrameProcSym(RecordOffset, H); 1142 } 1143 1144 uint32_t RecordOffset; 1145 Hdr Header; 1146 }; 1147 1148 // S_CALLSITEINFO 1149 class CallSiteInfoSym : public SymbolRecord { 1150 public: 1151 struct Hdr { 1152 ulittle32_t CodeOffset; 1153 ulittle16_t Segment; 1154 ulittle16_t Reserved; 1155 TypeIndex Type; 1156 }; 1157 CallSiteInfoSym(uint32_t RecordOffset,const Hdr * H)1158 CallSiteInfoSym(uint32_t RecordOffset, const Hdr *H) 1159 : SymbolRecord(SymbolRecordKind::CallSiteInfoSym), 1160 RecordOffset(RecordOffset), Header(*H) {} 1161 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1162 static ErrorOr<CallSiteInfoSym> deserialize(SymbolRecordKind Kind, 1163 uint32_t RecordOffset, 1164 ArrayRef<uint8_t> &Data) { 1165 const Hdr *H = nullptr; 1166 CV_DESERIALIZE(Data, H); 1167 1168 return CallSiteInfoSym(RecordOffset, H); 1169 } 1170 getRelocationOffset()1171 uint32_t getRelocationOffset() const { 1172 return RecordOffset + offsetof(Hdr, CodeOffset); 1173 } 1174 1175 uint32_t RecordOffset; 1176 Hdr Header; 1177 }; 1178 1179 // S_HEAPALLOCSITE 1180 class HeapAllocationSiteSym : public SymbolRecord { 1181 public: 1182 struct Hdr { 1183 ulittle32_t CodeOffset; 1184 ulittle16_t Segment; 1185 ulittle16_t CallInstructionSize; 1186 TypeIndex Type; 1187 }; 1188 HeapAllocationSiteSym(uint32_t RecordOffset,const Hdr * H)1189 HeapAllocationSiteSym(uint32_t RecordOffset, const Hdr *H) 1190 : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym), 1191 RecordOffset(RecordOffset), Header(*H) {} 1192 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1193 static ErrorOr<HeapAllocationSiteSym> deserialize(SymbolRecordKind Kind, 1194 uint32_t RecordOffset, 1195 ArrayRef<uint8_t> &Data) { 1196 const Hdr *H = nullptr; 1197 CV_DESERIALIZE(Data, H); 1198 1199 return HeapAllocationSiteSym(RecordOffset, H); 1200 } 1201 getRelocationOffset()1202 uint32_t getRelocationOffset() const { 1203 return RecordOffset + offsetof(Hdr, CodeOffset); 1204 } 1205 1206 uint32_t RecordOffset; 1207 Hdr Header; 1208 }; 1209 1210 // S_FRAMECOOKIE 1211 class FrameCookieSym : public SymbolRecord { 1212 public: 1213 struct Hdr { 1214 ulittle32_t CodeOffset; 1215 ulittle16_t Register; 1216 uint8_t CookieKind; 1217 uint8_t Flags; 1218 }; 1219 FrameCookieSym(uint32_t RecordOffset,const Hdr * H)1220 FrameCookieSym(uint32_t RecordOffset, const Hdr *H) 1221 : SymbolRecord(SymbolRecordKind::FrameCookieSym), 1222 RecordOffset(RecordOffset), Header(*H) {} 1223 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1224 static ErrorOr<FrameCookieSym> deserialize(SymbolRecordKind Kind, 1225 uint32_t RecordOffset, 1226 ArrayRef<uint8_t> &Data) { 1227 const Hdr *H = nullptr; 1228 CV_DESERIALIZE(Data, H); 1229 1230 return FrameCookieSym(RecordOffset, H); 1231 } 1232 getRelocationOffset()1233 uint32_t getRelocationOffset() const { 1234 return RecordOffset + offsetof(Hdr, CodeOffset); 1235 } 1236 1237 uint32_t RecordOffset; 1238 Hdr Header; 1239 }; 1240 1241 // S_UDT, S_COBOLUDT 1242 class UDTSym : public SymbolRecord { 1243 public: 1244 struct Hdr { 1245 TypeIndex Type; // Type of the UDT 1246 // Name: The null-terminated name follows. 1247 }; 1248 UDTSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)1249 UDTSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 1250 : SymbolRecord(SymbolRecordKind::UDTSym), RecordOffset(RecordOffset), 1251 Header(*H), Name(Name) {} 1252 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1253 static ErrorOr<UDTSym> deserialize(SymbolRecordKind Kind, 1254 uint32_t RecordOffset, 1255 ArrayRef<uint8_t> &Data) { 1256 const Hdr *H = nullptr; 1257 StringRef Name; 1258 CV_DESERIALIZE(Data, H, Name); 1259 1260 return UDTSym(RecordOffset, H, Name); 1261 } 1262 1263 uint32_t RecordOffset; 1264 Hdr Header; 1265 StringRef Name; 1266 }; 1267 1268 // S_BUILDINFO 1269 class BuildInfoSym : public SymbolRecord { 1270 public: 1271 struct Hdr { 1272 ulittle32_t BuildId; 1273 }; 1274 BuildInfoSym(uint32_t RecordOffset,const Hdr * H)1275 BuildInfoSym(uint32_t RecordOffset, const Hdr *H) 1276 : SymbolRecord(SymbolRecordKind::BuildInfoSym), 1277 RecordOffset(RecordOffset), Header(*H) {} 1278 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1279 static ErrorOr<BuildInfoSym> deserialize(SymbolRecordKind Kind, 1280 uint32_t RecordOffset, 1281 ArrayRef<uint8_t> &Data) { 1282 const Hdr *H = nullptr; 1283 CV_DESERIALIZE(Data, H); 1284 1285 return BuildInfoSym(RecordOffset, H); 1286 } 1287 1288 uint32_t RecordOffset; 1289 Hdr Header; 1290 }; 1291 1292 // S_BPREL32 1293 class BPRelativeSym : public SymbolRecord { 1294 public: 1295 struct Hdr { 1296 little32_t Offset; // Offset from the base pointer register 1297 TypeIndex Type; // Type of the variable 1298 // Name: The null-terminated name follows. 1299 }; 1300 BPRelativeSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)1301 BPRelativeSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 1302 : SymbolRecord(SymbolRecordKind::BPRelativeSym), 1303 RecordOffset(RecordOffset), Header(*H), Name(Name) {} 1304 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1305 static ErrorOr<BPRelativeSym> deserialize(SymbolRecordKind Kind, 1306 uint32_t RecordOffset, 1307 ArrayRef<uint8_t> &Data) { 1308 const Hdr *H = nullptr; 1309 StringRef Name; 1310 CV_DESERIALIZE(Data, H, Name); 1311 1312 return BPRelativeSym(RecordOffset, H, Name); 1313 } 1314 1315 uint32_t RecordOffset; 1316 Hdr Header; 1317 StringRef Name; 1318 }; 1319 1320 // S_REGREL32 1321 class RegRelativeSym : public SymbolRecord { 1322 public: 1323 struct Hdr { 1324 ulittle32_t Offset; // Offset from the register 1325 TypeIndex Type; // Type of the variable 1326 ulittle16_t Register; // Register to which the variable is relative 1327 // Name: The null-terminated name follows. 1328 }; 1329 RegRelativeSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)1330 RegRelativeSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 1331 : SymbolRecord(SymbolRecordKind::RegRelativeSym), 1332 RecordOffset(RecordOffset), Header(*H), Name(Name) {} 1333 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1334 static ErrorOr<RegRelativeSym> deserialize(SymbolRecordKind Kind, 1335 uint32_t RecordOffset, 1336 ArrayRef<uint8_t> &Data) { 1337 const Hdr *H = nullptr; 1338 StringRef Name; 1339 CV_DESERIALIZE(Data, H, Name); 1340 1341 return RegRelativeSym(RecordOffset, H, Name); 1342 } 1343 1344 uint32_t RecordOffset; 1345 Hdr Header; 1346 StringRef Name; 1347 }; 1348 1349 // S_CONSTANT, S_MANCONSTANT 1350 class ConstantSym : public SymbolRecord { 1351 public: 1352 struct Hdr { 1353 TypeIndex Type; 1354 // Value: The value of the constant. 1355 // Name: The null-terminated name follows. 1356 }; 1357 ConstantSym(uint32_t RecordOffset,const Hdr * H,const APSInt & Value,StringRef Name)1358 ConstantSym(uint32_t RecordOffset, const Hdr *H, const APSInt &Value, 1359 StringRef Name) 1360 : SymbolRecord(SymbolRecordKind::ConstantSym), RecordOffset(RecordOffset), 1361 Header(*H), Value(Value), Name(Name) {} 1362 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1363 static ErrorOr<ConstantSym> deserialize(SymbolRecordKind Kind, 1364 uint32_t RecordOffset, 1365 ArrayRef<uint8_t> &Data) { 1366 const Hdr *H = nullptr; 1367 APSInt Value; 1368 StringRef Name; 1369 CV_DESERIALIZE(Data, H, Value, Name); 1370 1371 return ConstantSym(RecordOffset, H, Value, Name); 1372 } 1373 1374 uint32_t RecordOffset; 1375 Hdr Header; 1376 APSInt Value; 1377 StringRef Name; 1378 }; 1379 1380 // S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA 1381 class DataSym : public SymbolRecord { 1382 public: 1383 struct Hdr { 1384 TypeIndex Type; 1385 ulittle32_t DataOffset; 1386 ulittle16_t Segment; 1387 // Name: The null-terminated name follows. 1388 }; 1389 DataSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)1390 DataSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 1391 : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset), 1392 Header(*H), Name(Name) {} 1393 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1394 static ErrorOr<DataSym> deserialize(SymbolRecordKind Kind, 1395 uint32_t RecordOffset, 1396 ArrayRef<uint8_t> &Data) { 1397 const Hdr *H = nullptr; 1398 StringRef Name; 1399 CV_DESERIALIZE(Data, H, Name); 1400 1401 return DataSym(RecordOffset, H, Name); 1402 } 1403 getRelocationOffset()1404 uint32_t getRelocationOffset() const { 1405 return RecordOffset + offsetof(Hdr, DataOffset); 1406 } 1407 1408 uint32_t RecordOffset; 1409 Hdr Header; 1410 StringRef Name; 1411 }; 1412 1413 // S_LTHREAD32, S_GTHREAD32 1414 class ThreadLocalDataSym : public SymbolRecord { 1415 public: 1416 struct Hdr { 1417 TypeIndex Type; 1418 ulittle32_t DataOffset; 1419 ulittle16_t Segment; 1420 // Name: The null-terminated name follows. 1421 }; 1422 ThreadLocalDataSym(uint32_t RecordOffset,const Hdr * H,StringRef Name)1423 ThreadLocalDataSym(uint32_t RecordOffset, const Hdr *H, StringRef Name) 1424 : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym), 1425 RecordOffset(RecordOffset), Header(*H), Name(Name) {} 1426 deserialize(SymbolRecordKind Kind,uint32_t RecordOffset,ArrayRef<uint8_t> & Data)1427 static ErrorOr<ThreadLocalDataSym> deserialize(SymbolRecordKind Kind, 1428 uint32_t RecordOffset, 1429 ArrayRef<uint8_t> &Data) { 1430 const Hdr *H = nullptr; 1431 StringRef Name; 1432 CV_DESERIALIZE(Data, H, Name); 1433 1434 return ThreadLocalDataSym(RecordOffset, H, Name); 1435 } 1436 getRelocationOffset()1437 uint32_t getRelocationOffset() const { 1438 return RecordOffset + offsetof(Hdr, DataOffset); 1439 } 1440 1441 uint32_t RecordOffset; 1442 Hdr Header; 1443 StringRef Name; 1444 }; 1445 1446 typedef CVRecord<SymbolKind> CVSymbol; 1447 typedef VarStreamArray<CVSymbol> CVSymbolArray; 1448 1449 } // namespace codeview 1450 } // namespace llvm 1451 1452 #endif 1453