1 //===-- PdbUtil.cpp -------------------------------------------------------===// 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 "PdbUtil.h" 10 11 #include "DWARFLocationExpression.h" 12 #include "PdbIndex.h" 13 #include "PdbSymUid.h" 14 15 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" 16 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 17 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 18 #include "llvm/DebugInfo/PDB/Native/DbiStream.h" 19 #include "llvm/DebugInfo/PDB/Native/TpiStream.h" 20 21 #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" 22 #include "lldb/Symbol/Block.h" 23 #include "lldb/Utility/LLDBAssert.h" 24 #include "lldb/Utility/LLDBLog.h" 25 #include "lldb/lldb-enumerations.h" 26 27 using namespace lldb_private; 28 using namespace lldb_private::npdb; 29 using namespace llvm::codeview; 30 using namespace llvm::pdb; 31 32 static Variable::RangeList 33 MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, 34 llvm::ArrayRef<LocalVariableAddrGap> gaps) { 35 lldb::addr_t start = 36 index.MakeVirtualAddress(range.ISectStart, range.OffsetStart); 37 if (start == LLDB_INVALID_ADDRESS) 38 return {}; 39 lldb::addr_t end = start + range.Range; 40 41 Variable::RangeList result; 42 while (!gaps.empty()) { 43 const LocalVariableAddrGap &gap = gaps.front(); 44 lldb::addr_t gap_start = start + gap.GapStartOffset; 45 result.Append(start, gap_start - start); 46 start = gap_start + gap.Range; 47 gaps = gaps.drop_front(); 48 } 49 50 result.Append(start, end - start); 51 return result; 52 } 53 54 namespace { 55 struct FindMembersSize : public TypeVisitorCallbacks { 56 FindMembersSize( 57 std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info, 58 TpiStream &tpi) 59 : members_info(members_info), tpi(tpi) {} 60 std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info; 61 TpiStream &tpi; 62 llvm::Error visitKnownMember(CVMemberRecord &cvr, 63 DataMemberRecord &member) override { 64 members_info.insert( 65 {member.getFieldOffset(), 66 {llvm::codeview::RegisterId::NONE, GetSizeOfType(member.Type, tpi)}}); 67 return llvm::Error::success(); 68 } 69 }; 70 } // namespace 71 72 CVTagRecord CVTagRecord::create(CVType type) { 73 assert(IsTagRecord(type) && "type is not a tag record!"); 74 switch (type.kind()) { 75 case LF_CLASS: 76 case LF_STRUCTURE: 77 case LF_INTERFACE: { 78 ClassRecord cr; 79 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(type, cr)); 80 return CVTagRecord(std::move(cr)); 81 } 82 case LF_UNION: { 83 UnionRecord ur; 84 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(type, ur)); 85 return CVTagRecord(std::move(ur)); 86 } 87 case LF_ENUM: { 88 EnumRecord er; 89 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(type, er)); 90 return CVTagRecord(std::move(er)); 91 } 92 default: 93 llvm_unreachable("Unreachable!"); 94 } 95 } 96 97 CVTagRecord::CVTagRecord(ClassRecord &&c) 98 : cvclass(std::move(c)), 99 m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {} 100 CVTagRecord::CVTagRecord(UnionRecord &&u) 101 : cvunion(std::move(u)), m_kind(Union) {} 102 CVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {} 103 104 PDB_SymType lldb_private::npdb::CVSymToPDBSym(SymbolKind kind) { 105 switch (kind) { 106 case S_COMPILE3: 107 case S_OBJNAME: 108 return PDB_SymType::CompilandDetails; 109 case S_ENVBLOCK: 110 return PDB_SymType::CompilandEnv; 111 case S_THUNK32: 112 case S_TRAMPOLINE: 113 return PDB_SymType::Thunk; 114 case S_COFFGROUP: 115 return PDB_SymType::CoffGroup; 116 case S_EXPORT: 117 return PDB_SymType::Export; 118 case S_LPROC32: 119 case S_GPROC32: 120 case S_LPROC32_DPC: 121 return PDB_SymType::Function; 122 case S_PUB32: 123 return PDB_SymType::PublicSymbol; 124 case S_INLINESITE: 125 return PDB_SymType::InlineSite; 126 case S_LOCAL: 127 case S_BPREL32: 128 case S_REGREL32: 129 case S_MANCONSTANT: 130 case S_CONSTANT: 131 case S_LDATA32: 132 case S_GDATA32: 133 case S_LMANDATA: 134 case S_GMANDATA: 135 case S_LTHREAD32: 136 case S_GTHREAD32: 137 return PDB_SymType::Data; 138 case S_BLOCK32: 139 return PDB_SymType::Block; 140 case S_LABEL32: 141 return PDB_SymType::Label; 142 case S_CALLSITEINFO: 143 return PDB_SymType::CallSite; 144 case S_HEAPALLOCSITE: 145 return PDB_SymType::HeapAllocationSite; 146 case S_CALLEES: 147 return PDB_SymType::Callee; 148 case S_CALLERS: 149 return PDB_SymType::Caller; 150 default: 151 lldbassert(false && "Invalid symbol record kind!"); 152 } 153 return PDB_SymType::None; 154 } 155 156 PDB_SymType lldb_private::npdb::CVTypeToPDBType(TypeLeafKind kind) { 157 switch (kind) { 158 case LF_ARRAY: 159 return PDB_SymType::ArrayType; 160 case LF_ARGLIST: 161 return PDB_SymType::FunctionSig; 162 case LF_BCLASS: 163 return PDB_SymType::BaseClass; 164 case LF_BINTERFACE: 165 return PDB_SymType::BaseInterface; 166 case LF_CLASS: 167 case LF_STRUCTURE: 168 case LF_INTERFACE: 169 case LF_UNION: 170 return PDB_SymType::UDT; 171 case LF_POINTER: 172 return PDB_SymType::PointerType; 173 case LF_ENUM: 174 return PDB_SymType::Enum; 175 case LF_PROCEDURE: 176 return PDB_SymType::FunctionSig; 177 case LF_BITFIELD: 178 return PDB_SymType::BuiltinType; 179 default: 180 lldbassert(false && "Invalid type record kind!"); 181 } 182 return PDB_SymType::None; 183 } 184 185 bool lldb_private::npdb::SymbolHasAddress(const CVSymbol &sym) { 186 switch (sym.kind()) { 187 case S_GPROC32: 188 case S_LPROC32: 189 case S_GPROC32_ID: 190 case S_LPROC32_ID: 191 case S_LPROC32_DPC: 192 case S_LPROC32_DPC_ID: 193 case S_THUNK32: 194 case S_TRAMPOLINE: 195 case S_COFFGROUP: 196 case S_BLOCK32: 197 case S_LABEL32: 198 case S_CALLSITEINFO: 199 case S_HEAPALLOCSITE: 200 case S_LDATA32: 201 case S_GDATA32: 202 case S_LMANDATA: 203 case S_GMANDATA: 204 case S_LTHREAD32: 205 case S_GTHREAD32: 206 return true; 207 default: 208 return false; 209 } 210 } 211 212 bool lldb_private::npdb::SymbolIsCode(const CVSymbol &sym) { 213 switch (sym.kind()) { 214 case S_GPROC32: 215 case S_LPROC32: 216 case S_GPROC32_ID: 217 case S_LPROC32_ID: 218 case S_LPROC32_DPC: 219 case S_LPROC32_DPC_ID: 220 case S_THUNK32: 221 case S_TRAMPOLINE: 222 case S_COFFGROUP: 223 case S_BLOCK32: 224 return true; 225 default: 226 return false; 227 } 228 } 229 230 template <typename RecordT> RecordT createRecord(const CVSymbol &sym) { 231 RecordT record(static_cast<SymbolRecordKind>(sym.kind())); 232 cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record)); 233 return record; 234 } 235 236 template <typename RecordT> 237 static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { 238 RecordT record = createRecord<RecordT>(sym); 239 return {record.Segment, record.CodeOffset}; 240 } 241 242 template <> 243 SegmentOffset GetSegmentAndOffset<TrampolineSym>(const CVSymbol &sym) { 244 TrampolineSym record = createRecord<TrampolineSym>(sym); 245 return {record.ThunkSection, record.ThunkOffset}; 246 } 247 248 template <> SegmentOffset GetSegmentAndOffset<Thunk32Sym>(const CVSymbol &sym) { 249 Thunk32Sym record = createRecord<Thunk32Sym>(sym); 250 return {record.Segment, record.Offset}; 251 } 252 253 template <> 254 SegmentOffset GetSegmentAndOffset<CoffGroupSym>(const CVSymbol &sym) { 255 CoffGroupSym record = createRecord<CoffGroupSym>(sym); 256 return {record.Segment, record.Offset}; 257 } 258 259 template <> SegmentOffset GetSegmentAndOffset<DataSym>(const CVSymbol &sym) { 260 DataSym record = createRecord<DataSym>(sym); 261 return {record.Segment, record.DataOffset}; 262 } 263 264 template <> 265 SegmentOffset GetSegmentAndOffset<ThreadLocalDataSym>(const CVSymbol &sym) { 266 ThreadLocalDataSym record = createRecord<ThreadLocalDataSym>(sym); 267 return {record.Segment, record.DataOffset}; 268 } 269 270 SegmentOffset lldb_private::npdb::GetSegmentAndOffset(const CVSymbol &sym) { 271 switch (sym.kind()) { 272 case S_GPROC32: 273 case S_LPROC32: 274 case S_GPROC32_ID: 275 case S_LPROC32_ID: 276 case S_LPROC32_DPC: 277 case S_LPROC32_DPC_ID: 278 return ::GetSegmentAndOffset<ProcSym>(sym); 279 case S_THUNK32: 280 return ::GetSegmentAndOffset<Thunk32Sym>(sym); 281 break; 282 case S_TRAMPOLINE: 283 return ::GetSegmentAndOffset<TrampolineSym>(sym); 284 break; 285 case S_COFFGROUP: 286 return ::GetSegmentAndOffset<CoffGroupSym>(sym); 287 break; 288 case S_BLOCK32: 289 return ::GetSegmentAndOffset<BlockSym>(sym); 290 break; 291 case S_LABEL32: 292 return ::GetSegmentAndOffset<LabelSym>(sym); 293 break; 294 case S_CALLSITEINFO: 295 return ::GetSegmentAndOffset<CallSiteInfoSym>(sym); 296 break; 297 case S_HEAPALLOCSITE: 298 return ::GetSegmentAndOffset<HeapAllocationSiteSym>(sym); 299 break; 300 case S_LDATA32: 301 case S_GDATA32: 302 case S_LMANDATA: 303 case S_GMANDATA: 304 return ::GetSegmentAndOffset<DataSym>(sym); 305 break; 306 case S_LTHREAD32: 307 case S_GTHREAD32: 308 return ::GetSegmentAndOffset<ThreadLocalDataSym>(sym); 309 break; 310 default: 311 lldbassert(false && "Record does not have a segment/offset!"); 312 } 313 return {0, 0}; 314 } 315 316 template <typename RecordT> 317 SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) { 318 RecordT record = createRecord<RecordT>(sym); 319 return {record.Segment, record.CodeOffset, record.CodeSize}; 320 } 321 322 template <> 323 SegmentOffsetLength 324 GetSegmentOffsetAndLength<TrampolineSym>(const CVSymbol &sym) { 325 TrampolineSym record = createRecord<TrampolineSym>(sym); 326 return {record.ThunkSection, record.ThunkOffset, record.Size}; 327 } 328 329 template <> 330 SegmentOffsetLength GetSegmentOffsetAndLength<Thunk32Sym>(const CVSymbol &sym) { 331 Thunk32Sym record = createRecord<Thunk32Sym>(sym); 332 return SegmentOffsetLength{record.Segment, record.Offset, record.Length}; 333 } 334 335 template <> 336 SegmentOffsetLength 337 GetSegmentOffsetAndLength<CoffGroupSym>(const CVSymbol &sym) { 338 CoffGroupSym record = createRecord<CoffGroupSym>(sym); 339 return SegmentOffsetLength{record.Segment, record.Offset, record.Size}; 340 } 341 342 SegmentOffsetLength 343 lldb_private::npdb::GetSegmentOffsetAndLength(const CVSymbol &sym) { 344 switch (sym.kind()) { 345 case S_GPROC32: 346 case S_LPROC32: 347 case S_GPROC32_ID: 348 case S_LPROC32_ID: 349 case S_LPROC32_DPC: 350 case S_LPROC32_DPC_ID: 351 return ::GetSegmentOffsetAndLength<ProcSym>(sym); 352 case S_THUNK32: 353 return ::GetSegmentOffsetAndLength<Thunk32Sym>(sym); 354 break; 355 case S_TRAMPOLINE: 356 return ::GetSegmentOffsetAndLength<TrampolineSym>(sym); 357 break; 358 case S_COFFGROUP: 359 return ::GetSegmentOffsetAndLength<CoffGroupSym>(sym); 360 break; 361 case S_BLOCK32: 362 return ::GetSegmentOffsetAndLength<BlockSym>(sym); 363 break; 364 default: 365 lldbassert(false && "Record does not have a segment/offset/length triple!"); 366 } 367 return {0, 0, 0}; 368 } 369 370 bool lldb_private::npdb::IsForwardRefUdt(CVType cvt) { 371 ClassRecord cr; 372 UnionRecord ur; 373 EnumRecord er; 374 switch (cvt.kind()) { 375 case LF_CLASS: 376 case LF_STRUCTURE: 377 case LF_INTERFACE: 378 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); 379 return cr.isForwardRef(); 380 case LF_UNION: 381 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); 382 return ur.isForwardRef(); 383 case LF_ENUM: 384 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); 385 return er.isForwardRef(); 386 default: 387 return false; 388 } 389 } 390 391 bool lldb_private::npdb::IsTagRecord(llvm::codeview::CVType cvt) { 392 switch (cvt.kind()) { 393 case LF_CLASS: 394 case LF_STRUCTURE: 395 case LF_UNION: 396 case LF_ENUM: 397 return true; 398 default: 399 return false; 400 } 401 } 402 403 bool lldb_private::npdb::IsClassStructUnion(llvm::codeview::CVType cvt) { 404 switch (cvt.kind()) { 405 case LF_CLASS: 406 case LF_STRUCTURE: 407 case LF_UNION: 408 return true; 409 default: 410 return false; 411 } 412 } 413 414 bool lldb_private::npdb::IsForwardRefUdt(const PdbTypeSymId &id, 415 TpiStream &tpi) { 416 if (id.is_ipi || id.index.isSimple()) 417 return false; 418 return IsForwardRefUdt(tpi.getType(id.index)); 419 } 420 421 bool lldb_private::npdb::IsTagRecord(const PdbTypeSymId &id, TpiStream &tpi) { 422 if (id.is_ipi || id.index.isSimple()) 423 return false; 424 return IsTagRecord(tpi.getType(id.index)); 425 } 426 427 lldb::AccessType 428 lldb_private::npdb::TranslateMemberAccess(MemberAccess access) { 429 switch (access) { 430 case MemberAccess::Private: 431 return lldb::eAccessPrivate; 432 case MemberAccess::Protected: 433 return lldb::eAccessProtected; 434 case MemberAccess::Public: 435 return lldb::eAccessPublic; 436 case MemberAccess::None: 437 return lldb::eAccessNone; 438 } 439 llvm_unreachable("unreachable"); 440 } 441 442 TypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) { 443 switch (cvt.kind()) { 444 case LF_CLASS: 445 case LF_STRUCTURE: 446 case LF_INTERFACE: { 447 ClassRecord cr; 448 cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); 449 return cr.FieldList; 450 } 451 case LF_UNION: { 452 UnionRecord ur; 453 cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); 454 return ur.FieldList; 455 } 456 case LF_ENUM: { 457 EnumRecord er; 458 cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); 459 return er.FieldList; 460 } 461 default: 462 llvm_unreachable("Unreachable!"); 463 } 464 } 465 466 TypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) { 467 lldbassert(modifier.kind() == LF_MODIFIER); 468 ModifierRecord mr; 469 llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(modifier, mr)); 470 return mr.ModifiedType; 471 } 472 473 llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) { 474 return MSVCUndecoratedNameParser::DropScope(name); 475 } 476 477 VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) { 478 VariableInfo result = {}; 479 480 if (sym.kind() == S_REGREL32) { 481 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); 482 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg)); 483 result.type = reg.Type; 484 result.name = reg.Name; 485 return result; 486 } 487 488 if (sym.kind() == S_REGISTER) { 489 RegisterSym reg(SymbolRecordKind::RegisterSym); 490 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg)); 491 result.type = reg.Index; 492 result.name = reg.Name; 493 return result; 494 } 495 496 if (sym.kind() == S_LOCAL) { 497 LocalSym local(SymbolRecordKind::LocalSym); 498 cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local)); 499 result.type = local.Type; 500 result.name = local.Name; 501 result.is_param = 502 ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None); 503 return result; 504 } 505 506 if (sym.kind() == S_GDATA32 || sym.kind() == S_LDATA32) { 507 DataSym data(SymbolRecordKind::DataSym); 508 cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, data)); 509 result.type = data.Type; 510 result.name = data.Name; 511 return result; 512 } 513 514 if (sym.kind() == S_GTHREAD32 || sym.kind() == S_LTHREAD32) { 515 ThreadLocalDataSym data(SymbolRecordKind::ThreadLocalDataSym); 516 cantFail(SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, data)); 517 result.type = data.Type; 518 result.name = data.Name; 519 return result; 520 } 521 522 if (sym.kind() == S_CONSTANT) { 523 ConstantSym constant(SymbolRecordKind::ConstantSym); 524 cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym, constant)); 525 result.type = constant.Type; 526 result.name = constant.Name; 527 return result; 528 } 529 530 lldbassert(false && "Invalid variable record kind!"); 531 return {}; 532 } 533 534 static llvm::FixedStreamArray<FrameData>::Iterator 535 GetCorrespondingFrameData(lldb::addr_t load_addr, 536 const DebugFrameDataSubsectionRef &fpo_data, 537 const Variable::RangeList &ranges) { 538 lldbassert(!ranges.IsEmpty()); 539 540 // assume that all variable ranges correspond to one frame data 541 using RangeListEntry = Variable::RangeList::Entry; 542 const RangeListEntry &range = ranges.GetEntryRef(0); 543 544 auto it = fpo_data.begin(); 545 546 // start by searching first frame data range containing variable range 547 for (; it != fpo_data.end(); ++it) { 548 RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize); 549 550 if (fd_range.Contains(range)) { 551 break; 552 } 553 } 554 555 // then first most nested entry that still contains variable range 556 auto found = it; 557 for (; it != fpo_data.end(); ++it) { 558 RangeListEntry fd_range(load_addr + it->RvaStart, it->CodeSize); 559 560 if (!fd_range.Contains(range)) { 561 break; 562 } 563 found = it; 564 } 565 566 return found; 567 } 568 569 static bool GetFrameDataProgram(PdbIndex &index, 570 const Variable::RangeList &ranges, 571 llvm::StringRef &out_program) { 572 const DebugFrameDataSubsectionRef &new_fpo_data = 573 index.dbi().getNewFpoRecords(); 574 575 auto frame_data_it = 576 GetCorrespondingFrameData(index.GetLoadAddress(), new_fpo_data, ranges); 577 if (frame_data_it == new_fpo_data.end()) 578 return false; 579 580 PDBStringTable &strings = cantFail(index.pdb().getStringTable()); 581 out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc)); 582 return true; 583 } 584 585 static RegisterId GetBaseFrameRegister(PdbIndex &index, 586 PdbCompilandSymId frame_proc_id, 587 bool is_parameter) { 588 CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id); 589 if (frame_proc_cvs.kind() != S_FRAMEPROC) 590 return RegisterId::NONE; 591 592 FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym); 593 cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs, 594 frame_proc)); 595 596 CPUType cpu_type = index.compilands() 597 .GetCompiland(frame_proc_id.modi) 598 ->m_compile_opts->Machine; 599 600 return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type) 601 : frame_proc.getLocalFramePtrReg(cpu_type); 602 } 603 604 VariableInfo lldb_private::npdb::GetVariableLocationInfo( 605 PdbIndex &index, PdbCompilandSymId var_id, Block &func_block, 606 lldb::ModuleSP module) { 607 608 CVSymbol sym = index.ReadSymbolRecord(var_id); 609 610 VariableInfo result = GetVariableNameInfo(sym); 611 612 if (sym.kind() == S_REGREL32) { 613 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); 614 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg)); 615 result.location = 616 MakeRegRelLocationExpression(reg.Register, reg.Offset, module); 617 result.ranges.emplace(); 618 return result; 619 } 620 621 if (sym.kind() == S_REGISTER) { 622 RegisterSym reg(SymbolRecordKind::RegisterSym); 623 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg)); 624 result.location = MakeEnregisteredLocationExpression(reg.Register, module); 625 result.ranges.emplace(); 626 return result; 627 } 628 629 if (sym.kind() == S_LOCAL) { 630 LocalSym local(SymbolRecordKind::LocalSym); 631 cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local)); 632 633 PdbCompilandSymId loc_specifier_id(var_id.modi, 634 var_id.offset + sym.RecordData.size()); 635 CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); 636 switch(loc_specifier_cvs.kind()) { 637 case S_DEFRANGE_FRAMEPOINTER_REL: { 638 DefRangeFramePointerRelSym loc( 639 SymbolRecordKind::DefRangeFramePointerRelSym); 640 cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>( 641 loc_specifier_cvs, loc)); 642 643 Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps); 644 645 PdbCompilandSymId func_scope_id = 646 PdbSymUid(func_block.GetID()).asCompilandSym(); 647 CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id); 648 lldbassert(func_block_cvs.kind() == S_GPROC32 || 649 func_block_cvs.kind() == S_LPROC32); 650 651 PdbCompilandSymId frame_proc_id( 652 func_scope_id.modi, func_scope_id.offset + func_block_cvs.length()); 653 654 RegisterId base_reg = 655 GetBaseFrameRegister(index, frame_proc_id, result.is_param); 656 if (base_reg == RegisterId::NONE) 657 break; 658 if (base_reg == RegisterId::VFRAME) { 659 llvm::StringRef program; 660 if (GetFrameDataProgram(index, ranges, program)) { 661 result.location = 662 MakeVFrameRelLocationExpression(program, loc.Hdr.Offset, module); 663 result.ranges = std::move(ranges); 664 } else { 665 // invalid variable 666 } 667 } else { 668 result.location = 669 MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module); 670 result.ranges = std::move(ranges); 671 } 672 break; 673 } 674 case S_DEFRANGE_REGISTER_REL: { 675 DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym); 676 cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>( 677 loc_specifier_cvs, loc)); 678 679 Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps); 680 681 RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register; 682 683 if (base_reg == RegisterId::VFRAME) { 684 llvm::StringRef program; 685 if (GetFrameDataProgram(index, ranges, program)) { 686 result.location = MakeVFrameRelLocationExpression( 687 program, loc.Hdr.BasePointerOffset, module); 688 result.ranges = std::move(ranges); 689 } else { 690 // invalid variable 691 } 692 } else { 693 result.location = MakeRegRelLocationExpression( 694 base_reg, loc.Hdr.BasePointerOffset, module); 695 result.ranges = std::move(ranges); 696 } 697 break; 698 } 699 case S_DEFRANGE_REGISTER: { 700 DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym); 701 cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterSym>( 702 loc_specifier_cvs, loc)); 703 704 RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register; 705 result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); 706 result.location = MakeEnregisteredLocationExpression(base_reg, module); 707 break; 708 } 709 case S_DEFRANGE_SUBFIELD_REGISTER: { 710 // A map from offset in parent to pair of register id and size. If the 711 // variable is a simple type, then we don't know the number of subfields. 712 // Otherwise, the size of the map should be greater than or equal to the 713 // number of sub field record. 714 std::map<uint64_t, std::pair<RegisterId, uint32_t>> members_info; 715 bool is_simple_type = result.type.isSimple(); 716 if (!is_simple_type) { 717 CVType class_cvt = index.tpi().getType(result.type); 718 TypeIndex class_id = result.type; 719 if (class_cvt.kind() == LF_MODIFIER) 720 class_id = LookThroughModifierRecord(class_cvt); 721 if (IsForwardRefUdt(class_id, index.tpi())) { 722 auto expected_full_ti = 723 index.tpi().findFullDeclForForwardRef(class_id); 724 if (!expected_full_ti) { 725 llvm::consumeError(expected_full_ti.takeError()); 726 break; 727 } 728 class_cvt = index.tpi().getType(*expected_full_ti); 729 } 730 if (IsTagRecord(class_cvt)) { 731 TagRecord tag_record = CVTagRecord::create(class_cvt).asTag(); 732 CVType field_list_cvt = index.tpi().getType(tag_record.FieldList); 733 FieldListRecord field_list; 734 if (llvm::Error error = 735 TypeDeserializer::deserializeAs<FieldListRecord>( 736 field_list_cvt, field_list)) 737 llvm::consumeError(std::move(error)); 738 FindMembersSize find_members_size(members_info, index.tpi()); 739 if (llvm::Error err = visitMemberRecordStream(field_list.Data, 740 find_members_size)) { 741 llvm::consumeError(std::move(err)); 742 break; 743 } 744 } else { 745 // TODO: Handle poiner type. 746 break; 747 } 748 } 749 750 size_t member_idx = 0; 751 // Assuming S_DEFRANGE_SUBFIELD_REGISTER is followed only by 752 // S_DEFRANGE_SUBFIELD_REGISTER, need to verify. 753 while (loc_specifier_cvs.kind() == S_DEFRANGE_SUBFIELD_REGISTER) { 754 if (!is_simple_type && member_idx >= members_info.size()) 755 break; 756 757 DefRangeSubfieldRegisterSym loc( 758 SymbolRecordKind::DefRangeSubfieldRegisterSym); 759 cantFail(SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>( 760 loc_specifier_cvs, loc)); 761 762 if (result.ranges) { 763 result.ranges = Variable::RangeList::GetOverlaps( 764 *result.ranges, MakeRangeList(index, loc.Range, loc.Gaps)); 765 } else { 766 result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); 767 result.ranges->Sort(); 768 } 769 770 if (is_simple_type) { 771 if (members_info.count(loc.Hdr.OffsetInParent)) { 772 // Malformed record. 773 result.ranges->Clear(); 774 return result; 775 } 776 members_info[loc.Hdr.OffsetInParent] = { 777 (RegisterId)(uint16_t)loc.Hdr.Register, 0}; 778 } else { 779 if (!members_info.count(loc.Hdr.OffsetInParent)) { 780 // Malformed record. 781 result.ranges->Clear(); 782 return result; 783 } 784 members_info[loc.Hdr.OffsetInParent].first = 785 (RegisterId)(uint16_t)loc.Hdr.Register; 786 } 787 // Go to next S_DEFRANGE_SUBFIELD_REGISTER. 788 loc_specifier_id = PdbCompilandSymId( 789 loc_specifier_id.modi, 790 loc_specifier_id.offset + loc_specifier_cvs.RecordData.size()); 791 loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); 792 } 793 // Fix size for simple type. 794 if (is_simple_type) { 795 auto cur = members_info.begin(); 796 auto end = members_info.end(); 797 auto next = cur; 798 ++next; 799 uint32_t size = 0; 800 while (next != end) { 801 cur->second.second = next->first - cur->first; 802 size += cur->second.second; 803 cur = next++; 804 } 805 cur->second.second = 806 GetTypeSizeForSimpleKind(result.type.getSimpleKind()) - size; 807 } 808 result.location = 809 MakeEnregisteredLocationExpressionForClass(members_info, module); 810 break; 811 } 812 default: 813 // FIXME: Handle other kinds. LLVM only generates the 4 types of records 814 // above. 815 break; 816 } 817 return result; 818 } 819 llvm_unreachable("Symbol is not a local variable!"); 820 return result; 821 } 822 823 lldb::BasicType 824 lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) { 825 switch (kind) { 826 case SimpleTypeKind::Boolean128: 827 case SimpleTypeKind::Boolean16: 828 case SimpleTypeKind::Boolean32: 829 case SimpleTypeKind::Boolean64: 830 case SimpleTypeKind::Boolean8: 831 return lldb::eBasicTypeBool; 832 case SimpleTypeKind::Byte: 833 case SimpleTypeKind::UnsignedCharacter: 834 return lldb::eBasicTypeUnsignedChar; 835 case SimpleTypeKind::NarrowCharacter: 836 return lldb::eBasicTypeChar; 837 case SimpleTypeKind::SignedCharacter: 838 case SimpleTypeKind::SByte: 839 return lldb::eBasicTypeSignedChar; 840 case SimpleTypeKind::Character16: 841 return lldb::eBasicTypeChar16; 842 case SimpleTypeKind::Character32: 843 return lldb::eBasicTypeChar32; 844 case SimpleTypeKind::Character8: 845 return lldb::eBasicTypeChar8; 846 case SimpleTypeKind::Complex80: 847 return lldb::eBasicTypeLongDoubleComplex; 848 case SimpleTypeKind::Complex64: 849 return lldb::eBasicTypeDoubleComplex; 850 case SimpleTypeKind::Complex32: 851 return lldb::eBasicTypeFloatComplex; 852 case SimpleTypeKind::Float128: 853 case SimpleTypeKind::Float80: 854 return lldb::eBasicTypeLongDouble; 855 case SimpleTypeKind::Float64: 856 return lldb::eBasicTypeDouble; 857 case SimpleTypeKind::Float32: 858 return lldb::eBasicTypeFloat; 859 case SimpleTypeKind::Float16: 860 return lldb::eBasicTypeHalf; 861 case SimpleTypeKind::Int128: 862 return lldb::eBasicTypeInt128; 863 case SimpleTypeKind::Int64: 864 case SimpleTypeKind::Int64Quad: 865 return lldb::eBasicTypeLongLong; 866 case SimpleTypeKind::Int32: 867 return lldb::eBasicTypeInt; 868 case SimpleTypeKind::Int16: 869 case SimpleTypeKind::Int16Short: 870 return lldb::eBasicTypeShort; 871 case SimpleTypeKind::UInt128: 872 return lldb::eBasicTypeUnsignedInt128; 873 case SimpleTypeKind::UInt64: 874 case SimpleTypeKind::UInt64Quad: 875 return lldb::eBasicTypeUnsignedLongLong; 876 case SimpleTypeKind::HResult: 877 case SimpleTypeKind::UInt32: 878 return lldb::eBasicTypeUnsignedInt; 879 case SimpleTypeKind::UInt16: 880 case SimpleTypeKind::UInt16Short: 881 return lldb::eBasicTypeUnsignedShort; 882 case SimpleTypeKind::Int32Long: 883 return lldb::eBasicTypeLong; 884 case SimpleTypeKind::UInt32Long: 885 return lldb::eBasicTypeUnsignedLong; 886 case SimpleTypeKind::Void: 887 return lldb::eBasicTypeVoid; 888 case SimpleTypeKind::WideCharacter: 889 return lldb::eBasicTypeWChar; 890 default: 891 return lldb::eBasicTypeInvalid; 892 } 893 } 894 895 size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) { 896 switch (kind) { 897 case SimpleTypeKind::Boolean128: 898 case SimpleTypeKind::Int128: 899 case SimpleTypeKind::UInt128: 900 case SimpleTypeKind::Float128: 901 return 16; 902 case SimpleTypeKind::Complex80: 903 case SimpleTypeKind::Float80: 904 return 10; 905 case SimpleTypeKind::Boolean64: 906 case SimpleTypeKind::Complex64: 907 case SimpleTypeKind::UInt64: 908 case SimpleTypeKind::UInt64Quad: 909 case SimpleTypeKind::Float64: 910 case SimpleTypeKind::Int64: 911 case SimpleTypeKind::Int64Quad: 912 return 8; 913 case SimpleTypeKind::Boolean32: 914 case SimpleTypeKind::Character32: 915 case SimpleTypeKind::Complex32: 916 case SimpleTypeKind::Float32: 917 case SimpleTypeKind::Int32: 918 case SimpleTypeKind::Int32Long: 919 case SimpleTypeKind::UInt32Long: 920 case SimpleTypeKind::HResult: 921 case SimpleTypeKind::UInt32: 922 return 4; 923 case SimpleTypeKind::Boolean16: 924 case SimpleTypeKind::Character16: 925 case SimpleTypeKind::Float16: 926 case SimpleTypeKind::Int16: 927 case SimpleTypeKind::Int16Short: 928 case SimpleTypeKind::UInt16: 929 case SimpleTypeKind::UInt16Short: 930 case SimpleTypeKind::WideCharacter: 931 return 2; 932 case SimpleTypeKind::Boolean8: 933 case SimpleTypeKind::Byte: 934 case SimpleTypeKind::UnsignedCharacter: 935 case SimpleTypeKind::NarrowCharacter: 936 case SimpleTypeKind::SignedCharacter: 937 case SimpleTypeKind::SByte: 938 case SimpleTypeKind::Character8: 939 return 1; 940 case SimpleTypeKind::Void: 941 default: 942 return 0; 943 } 944 } 945 946 PdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id, 947 TpiStream &tpi) { 948 if (id.index.isSimple()) 949 return id; 950 951 CVType cvt = tpi.getType(id.index); 952 953 // Only tag records have a best and a worst record. 954 if (!IsTagRecord(cvt)) 955 return id; 956 957 // Tag records that are not forward decls are full decls, hence they are the 958 // best. 959 if (!IsForwardRefUdt(cvt)) 960 return id; 961 962 return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index)); 963 } 964 965 template <typename RecordType> static size_t GetSizeOfTypeInternal(CVType cvt) { 966 RecordType record; 967 llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record)); 968 return record.getSize(); 969 } 970 971 size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id, 972 llvm::pdb::TpiStream &tpi) { 973 if (id.index.isSimple()) { 974 switch (id.index.getSimpleMode()) { 975 case SimpleTypeMode::Direct: 976 return GetTypeSizeForSimpleKind(id.index.getSimpleKind()); 977 case SimpleTypeMode::NearPointer32: 978 case SimpleTypeMode::FarPointer32: 979 return 4; 980 case SimpleTypeMode::NearPointer64: 981 return 8; 982 case SimpleTypeMode::NearPointer128: 983 return 16; 984 default: 985 break; 986 } 987 return 0; 988 } 989 990 TypeIndex index = id.index; 991 if (IsForwardRefUdt(index, tpi)) 992 index = llvm::cantFail(tpi.findFullDeclForForwardRef(index)); 993 994 CVType cvt = tpi.getType(index); 995 switch (cvt.kind()) { 996 case LF_MODIFIER: 997 return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi); 998 case LF_ENUM: { 999 EnumRecord record; 1000 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record)); 1001 return GetSizeOfType({record.UnderlyingType}, tpi); 1002 } 1003 case LF_POINTER: 1004 return GetSizeOfTypeInternal<PointerRecord>(cvt); 1005 case LF_ARRAY: 1006 return GetSizeOfTypeInternal<ArrayRecord>(cvt); 1007 case LF_CLASS: 1008 case LF_STRUCTURE: 1009 case LF_INTERFACE: 1010 return GetSizeOfTypeInternal<ClassRecord>(cvt); 1011 case LF_UNION: 1012 return GetSizeOfTypeInternal<UnionRecord>(cvt); 1013 default: 1014 break; 1015 } 1016 return 0; 1017 } 1018