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