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 auto strings = index.pdb().getStringTable(); 707 if (!strings) { 708 consumeError(strings.takeError()); 709 return false; 710 } 711 out_program = cantFail(strings->getStringForID(frame_data_it->FrameFunc)); 712 return true; 713 } 714 715 static RegisterId GetBaseFrameRegister(PdbIndex &index, 716 PdbCompilandSymId frame_proc_id, 717 bool is_parameter) { 718 CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id); 719 if (frame_proc_cvs.kind() != S_FRAMEPROC) 720 return RegisterId::NONE; 721 722 FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym); 723 cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs, 724 frame_proc)); 725 726 CPUType cpu_type = index.compilands() 727 .GetCompiland(frame_proc_id.modi) 728 ->m_compile_opts->Machine; 729 730 return is_parameter ? frame_proc.getParamFramePtrReg(cpu_type) 731 : frame_proc.getLocalFramePtrReg(cpu_type); 732 } 733 734 VariableInfo lldb_private::npdb::GetVariableLocationInfo( 735 PdbIndex &index, PdbCompilandSymId var_id, Block &func_block, 736 lldb::ModuleSP module) { 737 738 CVSymbol sym = index.ReadSymbolRecord(var_id); 739 740 VariableInfo result = GetVariableNameInfo(sym); 741 742 if (sym.kind() == S_REGREL32) { 743 RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); 744 cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg)); 745 result.location = DWARFExpressionList( 746 module, MakeRegRelLocationExpression(reg.Register, reg.Offset, module), 747 nullptr); 748 return result; 749 } 750 751 if (sym.kind() == S_REGISTER) { 752 RegisterSym reg(SymbolRecordKind::RegisterSym); 753 cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg)); 754 result.location = DWARFExpressionList( 755 module, MakeEnregisteredLocationExpression(reg.Register, module), 756 nullptr); 757 return result; 758 } 759 760 if (sym.kind() == S_LOCAL) { 761 LocalSym local(SymbolRecordKind::LocalSym); 762 if (llvm::Error error = 763 SymbolDeserializer::deserializeAs<LocalSym>(sym, local)) { 764 llvm::consumeError(std::move(error)); 765 return result; 766 } 767 768 PdbCompilandSymId loc_specifier_id(var_id.modi, 769 var_id.offset + sym.RecordData.size()); 770 CVSymbol loc_specifier_cvs; 771 // Only used for S_DEFRANGE_FRAMEPOINTER_REL. 772 RegisterId base_reg = RegisterId::NONE; 773 size_t type_size = GetSizeOfType(result.type, index.tpi()); 774 // A map from offset of a field in parent to size of the field. 775 std::map<uint64_t, size_t> offset_to_size; 776 777 // When overlaps happens, always prefer the one that doesn't split the value 778 // into multiple locations and the location parsed first is perfered. 779 RangeMap location_map; 780 781 // Iterate through all location records after S_LOCAL. They describe the 782 // value of this variable at different locations. 783 bool finished = false; 784 while (!finished) { 785 loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); 786 switch (loc_specifier_cvs.kind()) { 787 case S_DEFRANGE_FRAMEPOINTER_REL: { 788 DefRangeFramePointerRelSym loc( 789 SymbolRecordKind::DefRangeFramePointerRelSym); 790 if (llvm::Error error = 791 SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>( 792 loc_specifier_cvs, loc)) { 793 llvm::consumeError(std::move(error)); 794 return result; 795 } 796 Variable::RangeList raw_ranges = 797 MakeRangeList(index, loc.Range, loc.Gaps); 798 if (base_reg == RegisterId::NONE) { 799 PdbCompilandSymId func_scope_id = 800 PdbSymUid(func_block.GetID()).asCompilandSym(); 801 CVSymbol func_block_cvs = index.ReadSymbolRecord(func_scope_id); 802 lldbassert(func_block_cvs.kind() == S_GPROC32 || 803 func_block_cvs.kind() == S_LPROC32); 804 PdbCompilandSymId frame_proc_id(func_scope_id.modi, 805 func_scope_id.offset + 806 func_block_cvs.length()); 807 base_reg = 808 GetBaseFrameRegister(index, frame_proc_id, result.is_param); 809 if (base_reg == RegisterId::NONE) 810 break; 811 } 812 DWARFExpression expr; 813 if (base_reg == RegisterId::VFRAME) { 814 llvm::StringRef program; 815 if (GetFrameDataProgram(index, raw_ranges, program)) 816 expr = MakeVFrameRelLocationExpression(program, loc.Hdr.Offset, 817 module); 818 else { 819 // invalid variable 820 } 821 } else 822 expr = MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module); 823 AddDwarfRange(location_map, expr, raw_ranges); 824 break; 825 } 826 case S_DEFRANGE_REGISTER: { 827 DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym); 828 if (llvm::Error error = 829 SymbolDeserializer::deserializeAs<DefRangeRegisterSym>( 830 loc_specifier_cvs, loc)) { 831 llvm::consumeError(std::move(error)); 832 return result; 833 } 834 RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register; 835 Variable::RangeList raw_ranges = 836 MakeRangeList(index, loc.Range, loc.Gaps); 837 DWARFExpression expr = 838 MakeEnregisteredLocationExpression(reg_id, module); 839 AddDwarfRange(location_map, expr, raw_ranges); 840 break; 841 } 842 case S_DEFRANGE_REGISTER_REL: { 843 DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym); 844 if (llvm::Error error = 845 SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>( 846 loc_specifier_cvs, loc)) { 847 llvm::consumeError(std::move(error)); 848 return result; 849 } 850 Variable::RangeList raw_ranges = 851 MakeRangeList(index, loc.Range, loc.Gaps); 852 RegisterId reg_id = (RegisterId)(uint16_t)loc.Hdr.Register; 853 DWARFExpression expr; 854 if (reg_id == RegisterId::VFRAME) { 855 llvm::StringRef program; 856 if (GetFrameDataProgram(index, raw_ranges, program)) 857 expr = MakeVFrameRelLocationExpression( 858 program, loc.Hdr.BasePointerOffset, module); 859 else { 860 // invalid variable 861 } 862 } else { 863 expr = MakeRegRelLocationExpression(reg_id, loc.Hdr.BasePointerOffset, 864 module); 865 } 866 // FIXME: If it's UDT, we need to know the size of the value in byte. 867 if (!loc.hasSpilledUDTMember()) 868 AddDwarfRange(location_map, expr, raw_ranges); 869 break; 870 } 871 case S_DEFRANGE_SUBFIELD_REGISTER: { 872 DefRangeSubfieldRegisterSym loc( 873 SymbolRecordKind::DefRangeSubfieldRegisterSym); 874 if (llvm::Error error = 875 SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>( 876 loc_specifier_cvs, loc)) { 877 llvm::consumeError(std::move(error)); 878 return result; 879 } 880 881 Variable::RangeList ranges = MakeRangeList(index, loc.Range, loc.Gaps); 882 uint32_t reg_size = 883 GetRegisterSize((RegisterId)(uint16_t)loc.Hdr.Register); 884 if (reg_size == 0) 885 break; 886 offset_to_size[loc.Hdr.OffsetInParent] = reg_size; 887 AddMemberLocationRanges(location_map, loc.Hdr.OffsetInParent, 888 {loc.Hdr.Register, 0, true}, ranges); 889 break; 890 } 891 // FIXME: Handle other kinds. LLVM only generates the 4 types of records 892 // above. MSVC generates other location types. 893 case S_DEFRANGE: 894 case S_DEFRANGE_SUBFIELD: 895 case S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE: 896 break; 897 default: 898 finished = true; 899 break; 900 } 901 loc_specifier_id = PdbCompilandSymId( 902 loc_specifier_id.modi, 903 loc_specifier_id.offset + loc_specifier_cvs.RecordData.size()); 904 } 905 for (const auto &entry : location_map) { 906 DWARFExpression dwarf_expr = 907 entry.data.is_dwarf ? entry.data.expr 908 : MakeEnregisteredLocationExpressionForComposite( 909 entry.data.offset_to_location, 910 offset_to_size, type_size, module); 911 912 result.location.AddExpression(entry.GetRangeBase(), entry.GetRangeEnd(), 913 dwarf_expr); 914 } 915 return result; 916 } 917 llvm_unreachable("Symbol is not a local variable!"); 918 return result; 919 } 920 921 lldb::BasicType 922 lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) { 923 switch (kind) { 924 case SimpleTypeKind::Boolean128: 925 case SimpleTypeKind::Boolean16: 926 case SimpleTypeKind::Boolean32: 927 case SimpleTypeKind::Boolean64: 928 case SimpleTypeKind::Boolean8: 929 return lldb::eBasicTypeBool; 930 case SimpleTypeKind::Byte: 931 case SimpleTypeKind::UnsignedCharacter: 932 return lldb::eBasicTypeUnsignedChar; 933 case SimpleTypeKind::NarrowCharacter: 934 return lldb::eBasicTypeChar; 935 case SimpleTypeKind::SignedCharacter: 936 case SimpleTypeKind::SByte: 937 return lldb::eBasicTypeSignedChar; 938 case SimpleTypeKind::Character16: 939 return lldb::eBasicTypeChar16; 940 case SimpleTypeKind::Character32: 941 return lldb::eBasicTypeChar32; 942 case SimpleTypeKind::Character8: 943 return lldb::eBasicTypeChar8; 944 case SimpleTypeKind::Complex80: 945 return lldb::eBasicTypeLongDoubleComplex; 946 case SimpleTypeKind::Complex64: 947 return lldb::eBasicTypeDoubleComplex; 948 case SimpleTypeKind::Complex32: 949 return lldb::eBasicTypeFloatComplex; 950 case SimpleTypeKind::Float128: 951 case SimpleTypeKind::Float80: 952 return lldb::eBasicTypeLongDouble; 953 case SimpleTypeKind::Float64: 954 return lldb::eBasicTypeDouble; 955 case SimpleTypeKind::Float32: 956 return lldb::eBasicTypeFloat; 957 case SimpleTypeKind::Float16: 958 return lldb::eBasicTypeHalf; 959 case SimpleTypeKind::Int128: 960 return lldb::eBasicTypeInt128; 961 case SimpleTypeKind::Int64: 962 case SimpleTypeKind::Int64Quad: 963 return lldb::eBasicTypeLongLong; 964 case SimpleTypeKind::Int32: 965 return lldb::eBasicTypeInt; 966 case SimpleTypeKind::Int16: 967 case SimpleTypeKind::Int16Short: 968 return lldb::eBasicTypeShort; 969 case SimpleTypeKind::UInt128: 970 return lldb::eBasicTypeUnsignedInt128; 971 case SimpleTypeKind::UInt64: 972 case SimpleTypeKind::UInt64Quad: 973 return lldb::eBasicTypeUnsignedLongLong; 974 case SimpleTypeKind::HResult: 975 case SimpleTypeKind::UInt32: 976 return lldb::eBasicTypeUnsignedInt; 977 case SimpleTypeKind::UInt16: 978 case SimpleTypeKind::UInt16Short: 979 return lldb::eBasicTypeUnsignedShort; 980 case SimpleTypeKind::Int32Long: 981 return lldb::eBasicTypeLong; 982 case SimpleTypeKind::UInt32Long: 983 return lldb::eBasicTypeUnsignedLong; 984 case SimpleTypeKind::Void: 985 return lldb::eBasicTypeVoid; 986 case SimpleTypeKind::WideCharacter: 987 return lldb::eBasicTypeWChar; 988 default: 989 return lldb::eBasicTypeInvalid; 990 } 991 } 992 993 size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) { 994 switch (kind) { 995 case SimpleTypeKind::Boolean128: 996 case SimpleTypeKind::Int128: 997 case SimpleTypeKind::UInt128: 998 case SimpleTypeKind::Float128: 999 return 16; 1000 case SimpleTypeKind::Complex80: 1001 case SimpleTypeKind::Float80: 1002 return 10; 1003 case SimpleTypeKind::Boolean64: 1004 case SimpleTypeKind::Complex64: 1005 case SimpleTypeKind::UInt64: 1006 case SimpleTypeKind::UInt64Quad: 1007 case SimpleTypeKind::Float64: 1008 case SimpleTypeKind::Int64: 1009 case SimpleTypeKind::Int64Quad: 1010 return 8; 1011 case SimpleTypeKind::Boolean32: 1012 case SimpleTypeKind::Character32: 1013 case SimpleTypeKind::Complex32: 1014 case SimpleTypeKind::Float32: 1015 case SimpleTypeKind::Int32: 1016 case SimpleTypeKind::Int32Long: 1017 case SimpleTypeKind::UInt32Long: 1018 case SimpleTypeKind::HResult: 1019 case SimpleTypeKind::UInt32: 1020 return 4; 1021 case SimpleTypeKind::Boolean16: 1022 case SimpleTypeKind::Character16: 1023 case SimpleTypeKind::Float16: 1024 case SimpleTypeKind::Int16: 1025 case SimpleTypeKind::Int16Short: 1026 case SimpleTypeKind::UInt16: 1027 case SimpleTypeKind::UInt16Short: 1028 case SimpleTypeKind::WideCharacter: 1029 return 2; 1030 case SimpleTypeKind::Boolean8: 1031 case SimpleTypeKind::Byte: 1032 case SimpleTypeKind::UnsignedCharacter: 1033 case SimpleTypeKind::NarrowCharacter: 1034 case SimpleTypeKind::SignedCharacter: 1035 case SimpleTypeKind::SByte: 1036 case SimpleTypeKind::Character8: 1037 return 1; 1038 case SimpleTypeKind::Void: 1039 default: 1040 return 0; 1041 } 1042 } 1043 1044 PdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id, 1045 TpiStream &tpi) { 1046 if (id.index.isSimple()) 1047 return id; 1048 1049 CVType cvt = tpi.getType(id.index); 1050 1051 // Only tag records have a best and a worst record. 1052 if (!IsTagRecord(cvt)) 1053 return id; 1054 1055 // Tag records that are not forward decls are full decls, hence they are the 1056 // best. 1057 if (!IsForwardRefUdt(cvt)) 1058 return id; 1059 1060 return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index)); 1061 } 1062 1063 template <typename RecordType> static size_t GetSizeOfTypeInternal(CVType cvt) { 1064 RecordType record; 1065 llvm::cantFail(TypeDeserializer::deserializeAs<RecordType>(cvt, record)); 1066 return record.getSize(); 1067 } 1068 1069 size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id, 1070 llvm::pdb::TpiStream &tpi) { 1071 if (id.index.isSimple()) { 1072 switch (id.index.getSimpleMode()) { 1073 case SimpleTypeMode::Direct: 1074 return GetTypeSizeForSimpleKind(id.index.getSimpleKind()); 1075 case SimpleTypeMode::NearPointer32: 1076 case SimpleTypeMode::FarPointer32: 1077 return 4; 1078 case SimpleTypeMode::NearPointer64: 1079 return 8; 1080 case SimpleTypeMode::NearPointer128: 1081 return 16; 1082 default: 1083 break; 1084 } 1085 return 0; 1086 } 1087 1088 TypeIndex index = id.index; 1089 if (IsForwardRefUdt(index, tpi)) 1090 index = llvm::cantFail(tpi.findFullDeclForForwardRef(index)); 1091 1092 CVType cvt = tpi.getType(index); 1093 switch (cvt.kind()) { 1094 case LF_MODIFIER: 1095 return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi); 1096 case LF_ENUM: { 1097 EnumRecord record; 1098 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, record)); 1099 return GetSizeOfType({record.UnderlyingType}, tpi); 1100 } 1101 case LF_POINTER: 1102 return GetSizeOfTypeInternal<PointerRecord>(cvt); 1103 case LF_ARRAY: 1104 return GetSizeOfTypeInternal<ArrayRecord>(cvt); 1105 case LF_CLASS: 1106 case LF_STRUCTURE: 1107 case LF_INTERFACE: 1108 return GetSizeOfTypeInternal<ClassRecord>(cvt); 1109 case LF_UNION: 1110 return GetSizeOfTypeInternal<UnionRecord>(cvt); 1111 case LF_BITFIELD: { 1112 BitFieldRecord record; 1113 llvm::cantFail(TypeDeserializer::deserializeAs<BitFieldRecord>(cvt, record)); 1114 return GetSizeOfType({record.Type}, tpi); 1115 } 1116 default: 1117 break; 1118 } 1119 return 0; 1120 } 1121