1 //===-- SymbolFileNativePDB.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 "SymbolFileNativePDB.h" 10 11 #include "Plugins/ExpressionParser/Clang/ClangUtil.h" 12 #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" 13 #include "Plugins/ObjectFile/PDB/ObjectFilePDB.h" 14 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 15 #include "lldb/Core/Module.h" 16 #include "lldb/Core/PluginManager.h" 17 #include "lldb/Symbol/CompileUnit.h" 18 #include "lldb/Symbol/LineTable.h" 19 #include "lldb/Symbol/ObjectFile.h" 20 #include "lldb/Symbol/SymbolContext.h" 21 #include "lldb/Symbol/SymbolVendor.h" 22 #include "lldb/Symbol/Variable.h" 23 #include "lldb/Symbol/VariableList.h" 24 #include "lldb/Utility/LLDBLog.h" 25 #include "lldb/Utility/Log.h" 26 27 #include "llvm/DebugInfo/CodeView/CVRecord.h" 28 #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" 29 #include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" 30 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" 31 #include "llvm/DebugInfo/CodeView/RecordName.h" 32 #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 33 #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" 34 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" 35 #include "llvm/DebugInfo/PDB/Native/DbiStream.h" 36 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" 37 #include "llvm/DebugInfo/PDB/Native/InfoStream.h" 38 #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" 39 #include "llvm/DebugInfo/PDB/Native/NativeSession.h" 40 #include "llvm/DebugInfo/PDB/Native/PDBFile.h" 41 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h" 42 #include "llvm/DebugInfo/PDB/Native/TpiStream.h" 43 #include "llvm/DebugInfo/PDB/PDB.h" 44 #include "llvm/DebugInfo/PDB/PDBTypes.h" 45 #include "llvm/Demangle/MicrosoftDemangle.h" 46 #include "llvm/Object/COFF.h" 47 #include "llvm/Support/Allocator.h" 48 #include "llvm/Support/BinaryStreamReader.h" 49 #include "llvm/Support/Error.h" 50 #include "llvm/Support/ErrorOr.h" 51 #include "llvm/Support/MemoryBuffer.h" 52 53 #include "DWARFLocationExpression.h" 54 #include "PdbSymUid.h" 55 #include "PdbUtil.h" 56 #include "UdtRecordCompleter.h" 57 #include <optional> 58 #include <string_view> 59 60 using namespace lldb; 61 using namespace lldb_private; 62 using namespace npdb; 63 using namespace llvm::codeview; 64 using namespace llvm::pdb; 65 66 char SymbolFileNativePDB::ID; 67 68 static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { 69 switch (lang) { 70 case PDB_Lang::Cpp: 71 return lldb::LanguageType::eLanguageTypeC_plus_plus; 72 case PDB_Lang::C: 73 return lldb::LanguageType::eLanguageTypeC; 74 case PDB_Lang::Swift: 75 return lldb::LanguageType::eLanguageTypeSwift; 76 case PDB_Lang::Rust: 77 return lldb::LanguageType::eLanguageTypeRust; 78 case PDB_Lang::ObjC: 79 return lldb::LanguageType::eLanguageTypeObjC; 80 case PDB_Lang::ObjCpp: 81 return lldb::LanguageType::eLanguageTypeObjC_plus_plus; 82 default: 83 return lldb::LanguageType::eLanguageTypeUnknown; 84 } 85 } 86 87 static std::unique_ptr<PDBFile> 88 loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { 89 // Try to find a matching PDB for an EXE. 90 using namespace llvm::object; 91 auto expected_binary = createBinary(exe_path); 92 93 // If the file isn't a PE/COFF executable, fail. 94 if (!expected_binary) { 95 llvm::consumeError(expected_binary.takeError()); 96 return nullptr; 97 } 98 OwningBinary<Binary> binary = std::move(*expected_binary); 99 100 // TODO: Avoid opening the PE/COFF binary twice by reading this information 101 // directly from the lldb_private::ObjectFile. 102 auto *obj = llvm::dyn_cast<llvm::object::COFFObjectFile>(binary.getBinary()); 103 if (!obj) 104 return nullptr; 105 const llvm::codeview::DebugInfo *pdb_info = nullptr; 106 107 // If it doesn't have a debug directory, fail. 108 llvm::StringRef pdb_file; 109 if (llvm::Error e = obj->getDebugPDBInfo(pdb_info, pdb_file)) { 110 consumeError(std::move(e)); 111 return nullptr; 112 } 113 114 // If the file doesn't exist, perhaps the path specified at build time 115 // doesn't match the PDB's current location, so check the location of the 116 // executable. 117 if (!FileSystem::Instance().Exists(pdb_file)) { 118 const auto exe_dir = FileSpec(exe_path).CopyByRemovingLastPathComponent(); 119 const auto pdb_name = FileSpec(pdb_file).GetFilename().GetCString(); 120 pdb_file = exe_dir.CopyByAppendingPathComponent(pdb_name).GetPathAsConstString().GetStringRef(); 121 } 122 123 // If the file is not a PDB or if it doesn't have a matching GUID, fail. 124 auto pdb = ObjectFilePDB::loadPDBFile(std::string(pdb_file), allocator); 125 if (!pdb) 126 return nullptr; 127 128 auto expected_info = pdb->getPDBInfoStream(); 129 if (!expected_info) { 130 llvm::consumeError(expected_info.takeError()); 131 return nullptr; 132 } 133 llvm::codeview::GUID guid; 134 memcpy(&guid, pdb_info->PDB70.Signature, 16); 135 136 if (expected_info->getGuid() != guid) 137 return nullptr; 138 return pdb; 139 } 140 141 static bool IsFunctionPrologue(const CompilandIndexItem &cci, 142 lldb::addr_t addr) { 143 // FIXME: Implement this. 144 return false; 145 } 146 147 static bool IsFunctionEpilogue(const CompilandIndexItem &cci, 148 lldb::addr_t addr) { 149 // FIXME: Implement this. 150 return false; 151 } 152 153 static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) { 154 switch (kind) { 155 case SimpleTypeKind::Boolean128: 156 case SimpleTypeKind::Boolean16: 157 case SimpleTypeKind::Boolean32: 158 case SimpleTypeKind::Boolean64: 159 case SimpleTypeKind::Boolean8: 160 return "bool"; 161 case SimpleTypeKind::Byte: 162 case SimpleTypeKind::UnsignedCharacter: 163 return "unsigned char"; 164 case SimpleTypeKind::NarrowCharacter: 165 return "char"; 166 case SimpleTypeKind::SignedCharacter: 167 case SimpleTypeKind::SByte: 168 return "signed char"; 169 case SimpleTypeKind::Character16: 170 return "char16_t"; 171 case SimpleTypeKind::Character32: 172 return "char32_t"; 173 case SimpleTypeKind::Character8: 174 return "char8_t"; 175 case SimpleTypeKind::Complex80: 176 case SimpleTypeKind::Complex64: 177 case SimpleTypeKind::Complex32: 178 return "complex"; 179 case SimpleTypeKind::Float128: 180 case SimpleTypeKind::Float80: 181 return "long double"; 182 case SimpleTypeKind::Float64: 183 return "double"; 184 case SimpleTypeKind::Float32: 185 return "float"; 186 case SimpleTypeKind::Float16: 187 return "single"; 188 case SimpleTypeKind::Int128: 189 return "__int128"; 190 case SimpleTypeKind::Int64: 191 case SimpleTypeKind::Int64Quad: 192 return "int64_t"; 193 case SimpleTypeKind::Int32: 194 return "int"; 195 case SimpleTypeKind::Int16: 196 return "short"; 197 case SimpleTypeKind::UInt128: 198 return "unsigned __int128"; 199 case SimpleTypeKind::UInt64: 200 case SimpleTypeKind::UInt64Quad: 201 return "uint64_t"; 202 case SimpleTypeKind::HResult: 203 return "HRESULT"; 204 case SimpleTypeKind::UInt32: 205 return "unsigned"; 206 case SimpleTypeKind::UInt16: 207 case SimpleTypeKind::UInt16Short: 208 return "unsigned short"; 209 case SimpleTypeKind::Int32Long: 210 return "long"; 211 case SimpleTypeKind::UInt32Long: 212 return "unsigned long"; 213 case SimpleTypeKind::Void: 214 return "void"; 215 case SimpleTypeKind::WideCharacter: 216 return "wchar_t"; 217 default: 218 return ""; 219 } 220 } 221 222 static bool IsClassRecord(TypeLeafKind kind) { 223 switch (kind) { 224 case LF_STRUCTURE: 225 case LF_CLASS: 226 case LF_INTERFACE: 227 return true; 228 default: 229 return false; 230 } 231 } 232 233 static std::optional<CVTagRecord> 234 GetNestedTagDefinition(const NestedTypeRecord &Record, 235 const CVTagRecord &parent, TpiStream &tpi) { 236 // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it 237 // is also used to indicate the primary definition of a nested class. That is 238 // to say, if you have: 239 // struct A { 240 // struct B {}; 241 // using C = B; 242 // }; 243 // Then in the debug info, this will appear as: 244 // LF_STRUCTURE `A::B` [type index = N] 245 // LF_STRUCTURE `A` 246 // LF_NESTTYPE [name = `B`, index = N] 247 // LF_NESTTYPE [name = `C`, index = N] 248 // In order to accurately reconstruct the decl context hierarchy, we need to 249 // know which ones are actual definitions and which ones are just aliases. 250 251 // If it's a simple type, then this is something like `using foo = int`. 252 if (Record.Type.isSimple()) 253 return std::nullopt; 254 255 CVType cvt = tpi.getType(Record.Type); 256 257 if (!IsTagRecord(cvt)) 258 return std::nullopt; 259 260 // If it's an inner definition, then treat whatever name we have here as a 261 // single component of a mangled name. So we can inject it into the parent's 262 // mangled name to see if it matches. 263 CVTagRecord child = CVTagRecord::create(cvt); 264 std::string qname = std::string(parent.asTag().getUniqueName()); 265 if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4) 266 return std::nullopt; 267 268 // qname[3] is the tag type identifier (struct, class, union, etc). Since the 269 // inner tag type is not necessarily the same as the outer tag type, re-write 270 // it to match the inner tag type. 271 qname[3] = child.asTag().getUniqueName()[3]; 272 std::string piece; 273 if (qname[3] == 'W') 274 piece = "4"; 275 piece += Record.Name; 276 piece.push_back('@'); 277 qname.insert(4, std::move(piece)); 278 if (qname != child.asTag().UniqueName) 279 return std::nullopt; 280 281 return std::move(child); 282 } 283 284 void SymbolFileNativePDB::Initialize() { 285 PluginManager::RegisterPlugin(GetPluginNameStatic(), 286 GetPluginDescriptionStatic(), CreateInstance, 287 DebuggerInitialize); 288 } 289 290 void SymbolFileNativePDB::Terminate() { 291 PluginManager::UnregisterPlugin(CreateInstance); 292 } 293 294 void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {} 295 296 llvm::StringRef SymbolFileNativePDB::GetPluginDescriptionStatic() { 297 return "Microsoft PDB debug symbol cross-platform file reader."; 298 } 299 300 SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) { 301 return new SymbolFileNativePDB(std::move(objfile_sp)); 302 } 303 304 SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp) 305 : SymbolFileCommon(std::move(objfile_sp)) {} 306 307 SymbolFileNativePDB::~SymbolFileNativePDB() = default; 308 309 uint32_t SymbolFileNativePDB::CalculateAbilities() { 310 uint32_t abilities = 0; 311 if (!m_objfile_sp) 312 return 0; 313 314 if (!m_index) { 315 // Lazily load and match the PDB file, but only do this once. 316 PDBFile *pdb_file; 317 if (auto *pdb = llvm::dyn_cast<ObjectFilePDB>(m_objfile_sp.get())) { 318 pdb_file = &pdb->GetPDBFile(); 319 } else { 320 m_file_up = loadMatchingPDBFile(m_objfile_sp->GetFileSpec().GetPath(), 321 m_allocator); 322 pdb_file = m_file_up.get(); 323 } 324 325 if (!pdb_file) 326 return 0; 327 328 auto expected_index = PdbIndex::create(pdb_file); 329 if (!expected_index) { 330 llvm::consumeError(expected_index.takeError()); 331 return 0; 332 } 333 m_index = std::move(*expected_index); 334 } 335 if (!m_index) 336 return 0; 337 338 // We don't especially have to be precise here. We only distinguish between 339 // stripped and not stripped. 340 abilities = kAllAbilities; 341 342 if (m_index->dbi().isStripped()) 343 abilities &= ~(Blocks | LocalVariables); 344 return abilities; 345 } 346 347 void SymbolFileNativePDB::InitializeObject() { 348 m_obj_load_address = m_objfile_sp->GetModule() 349 ->GetObjectFile() 350 ->GetBaseAddress() 351 .GetFileAddress(); 352 m_index->SetLoadAddress(m_obj_load_address); 353 m_index->ParseSectionContribs(); 354 355 auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage( 356 lldb::eLanguageTypeC_plus_plus); 357 if (auto err = ts_or_err.takeError()) { 358 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), 359 "Failed to initialize: {0}"); 360 } else { 361 if (auto ts = *ts_or_err) 362 ts->SetSymbolFile(this); 363 BuildParentMap(); 364 } 365 } 366 367 uint32_t SymbolFileNativePDB::CalculateNumCompileUnits() { 368 const DbiModuleList &modules = m_index->dbi().modules(); 369 uint32_t count = modules.getModuleCount(); 370 if (count == 0) 371 return count; 372 373 // The linker can inject an additional "dummy" compilation unit into the 374 // PDB. Ignore this special compile unit for our purposes, if it is there. 375 // It is always the last one. 376 DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1); 377 if (last.getModuleName() == "* Linker *") 378 --count; 379 return count; 380 } 381 382 Block *SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) { 383 CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); 384 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); 385 CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); 386 lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id); 387 auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage()); 388 if (auto err = ts_or_err.takeError()) 389 return nullptr; 390 auto ts = *ts_or_err; 391 if (!ts) 392 return nullptr; 393 PdbAstBuilder* ast_builder = ts->GetNativePDBParser(); 394 395 switch (sym.kind()) { 396 case S_GPROC32: 397 case S_LPROC32: 398 // This is a function. It must be global. Creating the Function entry 399 // for it automatically creates a block for it. 400 if (FunctionSP func = GetOrCreateFunction(block_id, *comp_unit)) 401 return &func->GetBlock(false); 402 break; 403 case S_BLOCK32: { 404 // This is a block. Its parent is either a function or another block. In 405 // either case, its parent can be viewed as a block (e.g. a function 406 // contains 1 big block. So just get the parent block and add this block 407 // to it. 408 BlockSym block(static_cast<SymbolRecordKind>(sym.kind())); 409 cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block)); 410 lldbassert(block.Parent != 0); 411 PdbCompilandSymId parent_id(block_id.modi, block.Parent); 412 Block *parent_block = GetOrCreateBlock(parent_id); 413 if (!parent_block) 414 return nullptr; 415 Function *func = parent_block->CalculateSymbolContextFunction(); 416 lldbassert(func); 417 lldb::addr_t block_base = 418 m_index->MakeVirtualAddress(block.Segment, block.CodeOffset); 419 lldb::addr_t func_base = func->GetAddress().GetFileAddress(); 420 BlockSP child_block = parent_block->CreateChild(opaque_block_uid); 421 if (block_base >= func_base) 422 child_block->AddRange(Block::Range(block_base - func_base, block.CodeSize)); 423 else { 424 GetObjectFile()->GetModule()->ReportError( 425 "S_BLOCK32 at modi: {0:d} offset: {1:d}: adding range " 426 "[{2:x16}-{3:x16}) which has a base that is less than the " 427 "function's " 428 "low PC 0x%" PRIx64 ". Please file a bug and attach the file at the " 429 "start of this error message", 430 block_id.modi, block_id.offset, block_base, 431 block_base + block.CodeSize, func_base); 432 } 433 ast_builder->GetOrCreateBlockDecl(block_id); 434 m_blocks.insert({opaque_block_uid, child_block}); 435 break; 436 } 437 case S_INLINESITE: { 438 // This ensures line table is parsed first so we have inline sites info. 439 comp_unit->GetLineTable(); 440 441 std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid]; 442 Block *parent_block = GetOrCreateBlock(inline_site->parent_id); 443 if (!parent_block) 444 return nullptr; 445 BlockSP child_block = parent_block->CreateChild(opaque_block_uid); 446 ast_builder->GetOrCreateInlinedFunctionDecl(block_id); 447 // Copy ranges from InlineSite to Block. 448 for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) { 449 auto *entry = inline_site->ranges.GetEntryAtIndex(i); 450 child_block->AddRange( 451 Block::Range(entry->GetRangeBase(), entry->GetByteSize())); 452 } 453 child_block->FinalizeRanges(); 454 455 // Get the inlined function callsite info. 456 Declaration &decl = inline_site->inline_function_info->GetDeclaration(); 457 Declaration &callsite = inline_site->inline_function_info->GetCallSite(); 458 child_block->SetInlinedFunctionInfo( 459 inline_site->inline_function_info->GetName().GetCString(), nullptr, 460 &decl, &callsite); 461 m_blocks.insert({opaque_block_uid, child_block}); 462 break; 463 } 464 default: 465 lldbassert(false && "Symbol is not a block!"); 466 } 467 468 return nullptr; 469 } 470 471 lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, 472 CompileUnit &comp_unit) { 473 const CompilandIndexItem *cci = 474 m_index->compilands().GetCompiland(func_id.modi); 475 lldbassert(cci); 476 CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset); 477 478 lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); 479 SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); 480 481 auto file_vm_addr = 482 m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset); 483 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) 484 return nullptr; 485 486 Address func_addr(file_vm_addr, comp_unit.GetModule()->GetSectionList()); 487 if (!func_addr.IsValid()) 488 return nullptr; 489 490 ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind())); 491 cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)); 492 if (proc.FunctionType == TypeIndex::None()) 493 return nullptr; 494 TypeSP func_type = GetOrCreateType(proc.FunctionType); 495 if (!func_type) 496 return nullptr; 497 498 PdbTypeSymId sig_id(proc.FunctionType, false); 499 Mangled mangled(proc.Name); 500 FunctionSP func_sp = std::make_shared<Function>( 501 &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled, 502 func_type.get(), func_addr, 503 AddressRanges{AddressRange(func_addr, sol.length)}); 504 505 comp_unit.AddFunction(func_sp); 506 507 auto ts_or_err = GetTypeSystemForLanguage(comp_unit.GetLanguage()); 508 if (auto err = ts_or_err.takeError()) 509 return func_sp; 510 auto ts = *ts_or_err; 511 if (!ts) 512 return func_sp; 513 ts->GetNativePDBParser()->GetOrCreateFunctionDecl(func_id); 514 515 return func_sp; 516 } 517 518 CompUnitSP 519 SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { 520 lldb::LanguageType lang = 521 cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage()) 522 : lldb::eLanguageTypeUnknown; 523 524 LazyBool optimized = eLazyBoolNo; 525 if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations()) 526 optimized = eLazyBoolYes; 527 528 llvm::SmallString<64> source_file_name = 529 m_index->compilands().GetMainSourceFile(cci); 530 FileSpec fs(llvm::sys::path::convert_to_slash( 531 source_file_name, llvm::sys::path::Style::windows_backslash)); 532 533 CompUnitSP cu_sp = std::make_shared<CompileUnit>( 534 m_objfile_sp->GetModule(), nullptr, std::make_shared<SupportFile>(fs), 535 toOpaqueUid(cci.m_id), lang, optimized); 536 537 SetCompileUnitAtIndex(cci.m_id.modi, cu_sp); 538 return cu_sp; 539 } 540 541 lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id, 542 const ModifierRecord &mr, 543 CompilerType ct) { 544 TpiStream &stream = m_index->tpi(); 545 546 std::string name; 547 if (mr.ModifiedType.isSimple()) 548 name = std::string(GetSimpleTypeName(mr.ModifiedType.getSimpleKind())); 549 else 550 name = computeTypeName(stream.typeCollection(), mr.ModifiedType); 551 Declaration decl; 552 lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType); 553 554 return MakeType(toOpaqueUid(type_id), ConstString(name), 555 modified_type->GetByteSize(nullptr), nullptr, 556 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, 557 Type::ResolveState::Full); 558 } 559 560 lldb::TypeSP 561 SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id, 562 const llvm::codeview::PointerRecord &pr, 563 CompilerType ct) { 564 TypeSP pointee = GetOrCreateType(pr.ReferentType); 565 if (!pointee) 566 return nullptr; 567 568 if (pr.isPointerToMember()) { 569 MemberPointerInfo mpi = pr.getMemberInfo(); 570 GetOrCreateType(mpi.ContainingType); 571 } 572 573 Declaration decl; 574 return MakeType(toOpaqueUid(type_id), ConstString(), pr.getSize(), nullptr, 575 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, 576 Type::ResolveState::Full); 577 } 578 579 lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti, 580 CompilerType ct) { 581 uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false)); 582 if (ti == TypeIndex::NullptrT()) { 583 Declaration decl; 584 return MakeType(uid, ConstString("std::nullptr_t"), 0, nullptr, 585 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, 586 Type::ResolveState::Full); 587 } 588 589 if (ti.getSimpleMode() != SimpleTypeMode::Direct) { 590 TypeSP direct_sp = GetOrCreateType(ti.makeDirect()); 591 uint32_t pointer_size = 0; 592 switch (ti.getSimpleMode()) { 593 case SimpleTypeMode::FarPointer32: 594 case SimpleTypeMode::NearPointer32: 595 pointer_size = 4; 596 break; 597 case SimpleTypeMode::NearPointer64: 598 pointer_size = 8; 599 break; 600 default: 601 // 128-bit and 16-bit pointers unsupported. 602 return nullptr; 603 } 604 Declaration decl; 605 return MakeType(uid, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID, 606 Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full); 607 } 608 609 if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated) 610 return nullptr; 611 612 size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind()); 613 llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind()); 614 615 Declaration decl; 616 return MakeType(uid, ConstString(type_name), size, nullptr, LLDB_INVALID_UID, 617 Type::eEncodingIsUID, decl, ct, Type::ResolveState::Full); 618 } 619 620 static std::string GetUnqualifiedTypeName(const TagRecord &record) { 621 if (!record.hasUniqueName()) { 622 MSVCUndecoratedNameParser parser(record.Name); 623 llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); 624 625 return std::string(specs.back().GetBaseName()); 626 } 627 628 llvm::ms_demangle::Demangler demangler; 629 std::string_view sv(record.UniqueName.begin(), record.UniqueName.size()); 630 llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); 631 if (demangler.Error) 632 return std::string(record.Name); 633 634 llvm::ms_demangle::IdentifierNode *idn = 635 ttn->QualifiedName->getUnqualifiedIdentifier(); 636 return idn->toString(); 637 } 638 639 lldb::TypeSP 640 SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id, 641 const TagRecord &record, 642 size_t size, CompilerType ct) { 643 644 std::string uname = GetUnqualifiedTypeName(record); 645 646 // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE. 647 Declaration decl; 648 return MakeType(toOpaqueUid(type_id), ConstString(uname), size, nullptr, 649 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, ct, 650 Type::ResolveState::Forward); 651 } 652 653 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 654 const ClassRecord &cr, 655 CompilerType ct) { 656 return CreateClassStructUnion(type_id, cr, cr.getSize(), ct); 657 } 658 659 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 660 const UnionRecord &ur, 661 CompilerType ct) { 662 return CreateClassStructUnion(type_id, ur, ur.getSize(), ct); 663 } 664 665 lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, 666 const EnumRecord &er, 667 CompilerType ct) { 668 std::string uname = GetUnqualifiedTypeName(er); 669 670 Declaration decl; 671 TypeSP underlying_type = GetOrCreateType(er.UnderlyingType); 672 673 return MakeType(toOpaqueUid(type_id), ConstString(uname), 674 underlying_type->GetByteSize(nullptr), nullptr, 675 LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, 676 ct, lldb_private::Type::ResolveState::Forward); 677 } 678 679 TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id, 680 const ArrayRecord &ar, 681 CompilerType ct) { 682 TypeSP element_type = GetOrCreateType(ar.ElementType); 683 684 Declaration decl; 685 TypeSP array_sp = 686 MakeType(toOpaqueUid(type_id), ConstString(), ar.Size, nullptr, 687 LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct, 688 lldb_private::Type::ResolveState::Full); 689 array_sp->SetEncodingType(element_type.get()); 690 return array_sp; 691 } 692 693 TypeSP SymbolFileNativePDB::CreateFunctionType(PdbTypeSymId type_id, 694 const MemberFunctionRecord &mfr, 695 CompilerType ct) { 696 Declaration decl; 697 return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr, 698 LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, 699 ct, lldb_private::Type::ResolveState::Full); 700 } 701 702 TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, 703 const ProcedureRecord &pr, 704 CompilerType ct) { 705 Declaration decl; 706 return MakeType(toOpaqueUid(type_id), ConstString(), 0, nullptr, 707 LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, 708 ct, lldb_private::Type::ResolveState::Full); 709 } 710 711 TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { 712 if (type_id.index.isSimple()) 713 return CreateSimpleType(type_id.index, ct); 714 715 TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi(); 716 CVType cvt = stream.getType(type_id.index); 717 718 if (cvt.kind() == LF_MODIFIER) { 719 ModifierRecord modifier; 720 llvm::cantFail( 721 TypeDeserializer::deserializeAs<ModifierRecord>(cvt, modifier)); 722 return CreateModifierType(type_id, modifier, ct); 723 } 724 725 if (cvt.kind() == LF_POINTER) { 726 PointerRecord pointer; 727 llvm::cantFail( 728 TypeDeserializer::deserializeAs<PointerRecord>(cvt, pointer)); 729 return CreatePointerType(type_id, pointer, ct); 730 } 731 732 if (IsClassRecord(cvt.kind())) { 733 ClassRecord cr; 734 llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); 735 return CreateTagType(type_id, cr, ct); 736 } 737 738 if (cvt.kind() == LF_ENUM) { 739 EnumRecord er; 740 llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); 741 return CreateTagType(type_id, er, ct); 742 } 743 744 if (cvt.kind() == LF_UNION) { 745 UnionRecord ur; 746 llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); 747 return CreateTagType(type_id, ur, ct); 748 } 749 750 if (cvt.kind() == LF_ARRAY) { 751 ArrayRecord ar; 752 llvm::cantFail(TypeDeserializer::deserializeAs<ArrayRecord>(cvt, ar)); 753 return CreateArrayType(type_id, ar, ct); 754 } 755 756 if (cvt.kind() == LF_PROCEDURE) { 757 ProcedureRecord pr; 758 llvm::cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(cvt, pr)); 759 return CreateProcedureType(type_id, pr, ct); 760 } 761 if (cvt.kind() == LF_MFUNCTION) { 762 MemberFunctionRecord mfr; 763 llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>(cvt, mfr)); 764 return CreateFunctionType(type_id, mfr, ct); 765 } 766 767 return nullptr; 768 } 769 770 TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) { 771 // If they search for a UDT which is a forward ref, try and resolve the full 772 // decl and just map the forward ref uid to the full decl record. 773 std::optional<PdbTypeSymId> full_decl_uid; 774 if (IsForwardRefUdt(type_id, m_index->tpi())) { 775 auto expected_full_ti = 776 m_index->tpi().findFullDeclForForwardRef(type_id.index); 777 if (!expected_full_ti) 778 llvm::consumeError(expected_full_ti.takeError()); 779 else if (*expected_full_ti != type_id.index) { 780 full_decl_uid = PdbTypeSymId(*expected_full_ti, false); 781 782 // It's possible that a lookup would occur for the full decl causing it 783 // to be cached, then a second lookup would occur for the forward decl. 784 // We don't want to create a second full decl, so make sure the full 785 // decl hasn't already been cached. 786 auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid)); 787 if (full_iter != m_types.end()) { 788 TypeSP result = full_iter->second; 789 // Map the forward decl to the TypeSP for the full decl so we can take 790 // the fast path next time. 791 m_types[toOpaqueUid(type_id)] = result; 792 return result; 793 } 794 } 795 } 796 797 PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id; 798 auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 799 if (auto err = ts_or_err.takeError()) 800 return nullptr; 801 auto ts = *ts_or_err; 802 if (!ts) 803 return nullptr; 804 805 PdbAstBuilder* ast_builder = ts->GetNativePDBParser(); 806 clang::QualType qt = ast_builder->GetOrCreateType(best_decl_id); 807 if (qt.isNull()) 808 return nullptr; 809 810 TypeSP result = CreateType(best_decl_id, ast_builder->ToCompilerType(qt)); 811 if (!result) 812 return nullptr; 813 814 uint64_t best_uid = toOpaqueUid(best_decl_id); 815 m_types[best_uid] = result; 816 // If we had both a forward decl and a full decl, make both point to the new 817 // type. 818 if (full_decl_uid) 819 m_types[toOpaqueUid(type_id)] = result; 820 821 return result; 822 } 823 824 TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) { 825 // We can't use try_emplace / overwrite here because the process of creating 826 // a type could create nested types, which could invalidate iterators. So 827 // we have to do a 2-phase lookup / insert. 828 auto iter = m_types.find(toOpaqueUid(type_id)); 829 if (iter != m_types.end()) 830 return iter->second; 831 832 TypeSP type = CreateAndCacheType(type_id); 833 if (type) 834 GetTypeList().Insert(type); 835 return type; 836 } 837 838 VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { 839 CVSymbol sym = m_index->symrecords().readRecord(var_id.offset); 840 if (sym.kind() == S_CONSTANT) 841 return CreateConstantSymbol(var_id, sym); 842 843 lldb::ValueType scope = eValueTypeInvalid; 844 TypeIndex ti; 845 llvm::StringRef name; 846 lldb::addr_t addr = 0; 847 uint16_t section = 0; 848 uint32_t offset = 0; 849 bool is_external = false; 850 switch (sym.kind()) { 851 case S_GDATA32: 852 is_external = true; 853 [[fallthrough]]; 854 case S_LDATA32: { 855 DataSym ds(sym.kind()); 856 llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym, ds)); 857 ti = ds.Type; 858 scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal 859 : eValueTypeVariableStatic; 860 name = ds.Name; 861 section = ds.Segment; 862 offset = ds.DataOffset; 863 addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset); 864 break; 865 } 866 case S_GTHREAD32: 867 is_external = true; 868 [[fallthrough]]; 869 case S_LTHREAD32: { 870 ThreadLocalDataSym tlds(sym.kind()); 871 llvm::cantFail( 872 SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym, tlds)); 873 ti = tlds.Type; 874 name = tlds.Name; 875 section = tlds.Segment; 876 offset = tlds.DataOffset; 877 addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset); 878 scope = eValueTypeVariableThreadLocal; 879 break; 880 } 881 default: 882 llvm_unreachable("unreachable!"); 883 } 884 885 CompUnitSP comp_unit; 886 std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr); 887 // Some globals has modi points to the linker module, ignore them. 888 if (!modi || modi >= GetNumCompileUnits()) 889 return nullptr; 890 891 CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); 892 comp_unit = GetOrCreateCompileUnit(cci); 893 894 Declaration decl; 895 PdbTypeSymId tid(ti, false); 896 SymbolFileTypeSP type_sp = 897 std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid)); 898 Variable::RangeList ranges; 899 auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage()); 900 if (auto err = ts_or_err.takeError()) 901 return nullptr; 902 auto ts = *ts_or_err; 903 if (!ts) 904 return nullptr; 905 906 ts->GetNativePDBParser()->GetOrCreateVariableDecl(var_id); 907 908 ModuleSP module_sp = GetObjectFile()->GetModule(); 909 DWARFExpressionList location( 910 module_sp, MakeGlobalLocationExpression(section, offset, module_sp), 911 nullptr); 912 913 std::string global_name("::"); 914 global_name += name; 915 bool artificial = false; 916 bool location_is_constant_data = false; 917 bool static_member = false; 918 VariableSP var_sp = std::make_shared<Variable>( 919 toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp, 920 scope, comp_unit.get(), ranges, &decl, location, is_external, artificial, 921 location_is_constant_data, static_member); 922 923 return var_sp; 924 } 925 926 lldb::VariableSP 927 SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, 928 const CVSymbol &cvs) { 929 TpiStream &tpi = m_index->tpi(); 930 ConstantSym constant(cvs.kind()); 931 932 llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(cvs, constant)); 933 std::string global_name("::"); 934 global_name += constant.Name; 935 PdbTypeSymId tid(constant.Type, false); 936 SymbolFileTypeSP type_sp = 937 std::make_shared<SymbolFileType>(*this, toOpaqueUid(tid)); 938 939 Declaration decl; 940 Variable::RangeList ranges; 941 ModuleSP module = GetObjectFile()->GetModule(); 942 DWARFExpressionList location(module, 943 MakeConstantLocationExpression( 944 constant.Type, tpi, constant.Value, module), 945 nullptr); 946 947 bool external = false; 948 bool artificial = false; 949 bool location_is_constant_data = true; 950 bool static_member = false; 951 VariableSP var_sp = std::make_shared<Variable>( 952 toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), 953 type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location, 954 external, artificial, location_is_constant_data, static_member); 955 return var_sp; 956 } 957 958 VariableSP 959 SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) { 960 auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr); 961 if (emplace_result.second) { 962 if (VariableSP var_sp = CreateGlobalVariable(var_id)) 963 emplace_result.first->second = var_sp; 964 else 965 return nullptr; 966 } 967 968 return emplace_result.first->second; 969 } 970 971 lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) { 972 return GetOrCreateType(PdbTypeSymId(ti, false)); 973 } 974 975 FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id, 976 CompileUnit &comp_unit) { 977 auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr); 978 if (emplace_result.second) 979 emplace_result.first->second = CreateFunction(func_id, comp_unit); 980 981 return emplace_result.first->second; 982 } 983 984 CompUnitSP 985 SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) { 986 987 auto emplace_result = 988 m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr); 989 if (emplace_result.second) 990 emplace_result.first->second = CreateCompileUnit(cci); 991 992 lldbassert(emplace_result.first->second); 993 return emplace_result.first->second; 994 } 995 996 Block *SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) { 997 auto iter = m_blocks.find(toOpaqueUid(block_id)); 998 if (iter != m_blocks.end()) 999 return iter->second.get(); 1000 1001 return CreateBlock(block_id); 1002 } 1003 1004 void SymbolFileNativePDB::ParseDeclsForContext( 1005 lldb_private::CompilerDeclContext decl_ctx) { 1006 TypeSystem* ts_or_err = decl_ctx.GetTypeSystem(); 1007 if (!ts_or_err) 1008 return; 1009 PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser(); 1010 clang::DeclContext *context = ast_builder->FromCompilerDeclContext(decl_ctx); 1011 if (!context) 1012 return; 1013 ast_builder->ParseDeclsForContext(*context); 1014 } 1015 1016 lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) { 1017 if (index >= GetNumCompileUnits()) 1018 return CompUnitSP(); 1019 lldbassert(index < UINT16_MAX); 1020 if (index >= UINT16_MAX) 1021 return nullptr; 1022 1023 CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index); 1024 1025 return GetOrCreateCompileUnit(item); 1026 } 1027 1028 lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) { 1029 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1030 PdbSymUid uid(comp_unit.GetID()); 1031 lldbassert(uid.kind() == PdbSymUidKind::Compiland); 1032 1033 CompilandIndexItem *item = 1034 m_index->compilands().GetCompiland(uid.asCompiland().modi); 1035 lldbassert(item); 1036 if (!item->m_compile_opts) 1037 return lldb::eLanguageTypeUnknown; 1038 1039 return TranslateLanguage(item->m_compile_opts->getLanguage()); 1040 } 1041 1042 void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {} 1043 1044 size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) { 1045 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1046 PdbSymUid uid{comp_unit.GetID()}; 1047 lldbassert(uid.kind() == PdbSymUidKind::Compiland); 1048 uint16_t modi = uid.asCompiland().modi; 1049 CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi); 1050 1051 size_t count = comp_unit.GetNumFunctions(); 1052 const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray(); 1053 for (auto iter = syms.begin(); iter != syms.end(); ++iter) { 1054 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) 1055 continue; 1056 1057 PdbCompilandSymId sym_id{modi, iter.offset()}; 1058 1059 FunctionSP func = GetOrCreateFunction(sym_id, comp_unit); 1060 } 1061 1062 size_t new_count = comp_unit.GetNumFunctions(); 1063 lldbassert(new_count >= count); 1064 return new_count - count; 1065 } 1066 1067 static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) { 1068 // If any of these flags are set, we need to resolve the compile unit. 1069 uint32_t flags = eSymbolContextCompUnit; 1070 flags |= eSymbolContextVariable; 1071 flags |= eSymbolContextFunction; 1072 flags |= eSymbolContextBlock; 1073 flags |= eSymbolContextLineEntry; 1074 return (resolve_scope & flags) != 0; 1075 } 1076 1077 uint32_t SymbolFileNativePDB::ResolveSymbolContext( 1078 const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) { 1079 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1080 uint32_t resolved_flags = 0; 1081 lldb::addr_t file_addr = addr.GetFileAddress(); 1082 1083 if (NeedsResolvedCompileUnit(resolve_scope)) { 1084 std::optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr); 1085 if (!modi) 1086 return 0; 1087 CompUnitSP cu_sp = GetCompileUnitAtIndex(*modi); 1088 if (!cu_sp) 1089 return 0; 1090 1091 sc.comp_unit = cu_sp.get(); 1092 resolved_flags |= eSymbolContextCompUnit; 1093 } 1094 1095 if (resolve_scope & eSymbolContextFunction || 1096 resolve_scope & eSymbolContextBlock) { 1097 lldbassert(sc.comp_unit); 1098 std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr); 1099 // Search the matches in reverse. This way if there are multiple matches 1100 // (for example we are 3 levels deep in a nested scope) it will find the 1101 // innermost one first. 1102 for (const auto &match : llvm::reverse(matches)) { 1103 if (match.uid.kind() != PdbSymUidKind::CompilandSym) 1104 continue; 1105 1106 PdbCompilandSymId csid = match.uid.asCompilandSym(); 1107 CVSymbol cvs = m_index->ReadSymbolRecord(csid); 1108 PDB_SymType type = CVSymToPDBSym(cvs.kind()); 1109 if (type != PDB_SymType::Function && type != PDB_SymType::Block) 1110 continue; 1111 if (type == PDB_SymType::Function) { 1112 sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get(); 1113 if (sc.function) { 1114 Block &block = sc.function->GetBlock(true); 1115 addr_t func_base = sc.function->GetAddress().GetFileAddress(); 1116 addr_t offset = file_addr - func_base; 1117 sc.block = block.FindInnermostBlockByOffset(offset); 1118 } 1119 } 1120 1121 if (type == PDB_SymType::Block) { 1122 Block *block = GetOrCreateBlock(csid); 1123 if (!block) 1124 continue; 1125 sc.function = block->CalculateSymbolContextFunction(); 1126 if (sc.function) { 1127 sc.function->GetBlock(true); 1128 addr_t func_base = sc.function->GetAddress().GetFileAddress(); 1129 addr_t offset = file_addr - func_base; 1130 sc.block = block->FindInnermostBlockByOffset(offset); 1131 } 1132 } 1133 if (sc.function) 1134 resolved_flags |= eSymbolContextFunction; 1135 if (sc.block) 1136 resolved_flags |= eSymbolContextBlock; 1137 break; 1138 } 1139 } 1140 1141 if (resolve_scope & eSymbolContextLineEntry) { 1142 lldbassert(sc.comp_unit); 1143 if (auto *line_table = sc.comp_unit->GetLineTable()) { 1144 if (line_table->FindLineEntryByAddress(addr, sc.line_entry)) 1145 resolved_flags |= eSymbolContextLineEntry; 1146 } 1147 } 1148 1149 return resolved_flags; 1150 } 1151 1152 uint32_t SymbolFileNativePDB::ResolveSymbolContext( 1153 const SourceLocationSpec &src_location_spec, 1154 lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { 1155 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1156 const uint32_t prev_size = sc_list.GetSize(); 1157 if (resolve_scope & eSymbolContextCompUnit) { 1158 for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus; 1159 ++cu_idx) { 1160 CompileUnit *cu = ParseCompileUnitAtIndex(cu_idx).get(); 1161 if (!cu) 1162 continue; 1163 1164 bool file_spec_matches_cu_file_spec = FileSpec::Match( 1165 src_location_spec.GetFileSpec(), cu->GetPrimaryFile()); 1166 if (file_spec_matches_cu_file_spec) { 1167 cu->ResolveSymbolContext(src_location_spec, resolve_scope, sc_list); 1168 break; 1169 } 1170 } 1171 } 1172 return sc_list.GetSize() - prev_size; 1173 } 1174 1175 bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { 1176 // Unfortunately LLDB is set up to parse the entire compile unit line table 1177 // all at once, even if all it really needs is line info for a specific 1178 // function. In the future it would be nice if it could set the sc.m_function 1179 // member, and we could only get the line info for the function in question. 1180 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1181 PdbSymUid cu_id(comp_unit.GetID()); 1182 lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); 1183 uint16_t modi = cu_id.asCompiland().modi; 1184 CompilandIndexItem *cii = m_index->compilands().GetCompiland(modi); 1185 lldbassert(cii); 1186 1187 // Parse DEBUG_S_LINES subsections first, then parse all S_INLINESITE records 1188 // in this CU. Add line entries into the set first so that if there are line 1189 // entries with same addres, the later is always more accurate than the 1190 // former. 1191 std::set<LineTable::Entry, LineTableEntryComparator> line_set; 1192 1193 // This is basically a copy of the .debug$S subsections from all original COFF 1194 // object files merged together with address relocations applied. We are 1195 // looking for all DEBUG_S_LINES subsections. 1196 for (const DebugSubsectionRecord &dssr : 1197 cii->m_debug_stream.getSubsectionsArray()) { 1198 if (dssr.kind() != DebugSubsectionKind::Lines) 1199 continue; 1200 1201 DebugLinesSubsectionRef lines; 1202 llvm::BinaryStreamReader reader(dssr.getRecordData()); 1203 if (auto EC = lines.initialize(reader)) { 1204 llvm::consumeError(std::move(EC)); 1205 return false; 1206 } 1207 1208 const LineFragmentHeader *lfh = lines.header(); 1209 uint64_t virtual_addr = 1210 m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); 1211 if (virtual_addr == LLDB_INVALID_ADDRESS) 1212 continue; 1213 1214 for (const LineColumnEntry &group : lines) { 1215 llvm::Expected<uint32_t> file_index_or_err = 1216 GetFileIndex(*cii, group.NameIndex); 1217 if (!file_index_or_err) 1218 continue; 1219 uint32_t file_index = file_index_or_err.get(); 1220 lldbassert(!group.LineNumbers.empty()); 1221 CompilandIndexItem::GlobalLineTable::Entry line_entry( 1222 LLDB_INVALID_ADDRESS, 0); 1223 for (const LineNumberEntry &entry : group.LineNumbers) { 1224 LineInfo cur_info(entry.Flags); 1225 1226 if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto()) 1227 continue; 1228 1229 uint64_t addr = virtual_addr + entry.Offset; 1230 1231 bool is_statement = cur_info.isStatement(); 1232 bool is_prologue = IsFunctionPrologue(*cii, addr); 1233 bool is_epilogue = IsFunctionEpilogue(*cii, addr); 1234 1235 uint32_t lno = cur_info.getStartLine(); 1236 1237 LineTable::Entry new_entry(addr, lno, 0, file_index, is_statement, false, 1238 is_prologue, is_epilogue, false); 1239 // Terminal entry has lower precedence than new entry. 1240 auto iter = line_set.find(new_entry); 1241 if (iter != line_set.end() && iter->is_terminal_entry) 1242 line_set.erase(iter); 1243 line_set.insert(new_entry); 1244 1245 if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) { 1246 line_entry.SetRangeEnd(addr); 1247 cii->m_global_line_table.Append(line_entry); 1248 } 1249 line_entry.SetRangeBase(addr); 1250 line_entry.data = {file_index, lno}; 1251 } 1252 LineInfo last_line(group.LineNumbers.back().Flags); 1253 line_set.emplace(virtual_addr + lfh->CodeSize, last_line.getEndLine(), 0, 1254 file_index, false, false, false, false, true); 1255 1256 if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) { 1257 line_entry.SetRangeEnd(virtual_addr + lfh->CodeSize); 1258 cii->m_global_line_table.Append(line_entry); 1259 } 1260 } 1261 } 1262 1263 cii->m_global_line_table.Sort(); 1264 1265 // Parse all S_INLINESITE in this CU. 1266 const CVSymbolArray &syms = cii->m_debug_stream.getSymbolArray(); 1267 for (auto iter = syms.begin(); iter != syms.end();) { 1268 if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) { 1269 ++iter; 1270 continue; 1271 } 1272 1273 uint32_t record_offset = iter.offset(); 1274 CVSymbol func_record = 1275 cii->m_debug_stream.readSymbolAtOffset(record_offset); 1276 SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record); 1277 addr_t file_vm_addr = 1278 m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset); 1279 if (file_vm_addr == LLDB_INVALID_ADDRESS) 1280 continue; 1281 1282 Address func_base(file_vm_addr, comp_unit.GetModule()->GetSectionList()); 1283 PdbCompilandSymId func_id{modi, record_offset}; 1284 1285 // Iterate all S_INLINESITEs in the function. 1286 auto parse_inline_sites = [&](SymbolKind kind, PdbCompilandSymId id) { 1287 if (kind != S_INLINESITE) 1288 return false; 1289 1290 ParseInlineSite(id, func_base); 1291 1292 for (const auto &line_entry : 1293 m_inline_sites[toOpaqueUid(id)]->line_entries) { 1294 // If line_entry is not terminal entry, remove previous line entry at 1295 // the same address and insert new one. Terminal entry inside an inline 1296 // site might not be terminal entry for its parent. 1297 if (!line_entry.is_terminal_entry) 1298 line_set.erase(line_entry); 1299 line_set.insert(line_entry); 1300 } 1301 // No longer useful after adding to line_set. 1302 m_inline_sites[toOpaqueUid(id)]->line_entries.clear(); 1303 return true; 1304 }; 1305 ParseSymbolArrayInScope(func_id, parse_inline_sites); 1306 // Jump to the end of the function record. 1307 iter = syms.at(getScopeEndOffset(func_record)); 1308 } 1309 1310 cii->m_global_line_table.Clear(); 1311 1312 // Add line entries in line_set to line_table. 1313 auto line_table = std::make_unique<LineTable>(&comp_unit); 1314 std::unique_ptr<LineSequence> sequence( 1315 line_table->CreateLineSequenceContainer()); 1316 for (const auto &line_entry : line_set) { 1317 line_table->AppendLineEntryToSequence( 1318 sequence.get(), line_entry.file_addr, line_entry.line, 1319 line_entry.column, line_entry.file_idx, 1320 line_entry.is_start_of_statement, line_entry.is_start_of_basic_block, 1321 line_entry.is_prologue_end, line_entry.is_epilogue_begin, 1322 line_entry.is_terminal_entry); 1323 } 1324 line_table->InsertSequence(sequence.get()); 1325 1326 if (line_table->GetSize() == 0) 1327 return false; 1328 1329 comp_unit.SetLineTable(line_table.release()); 1330 return true; 1331 } 1332 1333 bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) { 1334 // PDB doesn't contain information about macros 1335 return false; 1336 } 1337 1338 llvm::Expected<uint32_t> 1339 SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, 1340 uint32_t file_id) { 1341 if (!cii.m_strings.hasChecksums() || !cii.m_strings.hasStrings()) 1342 return llvm::make_error<RawError>(raw_error_code::no_entry); 1343 1344 const auto &checksums = cii.m_strings.checksums().getArray(); 1345 const auto &strings = cii.m_strings.strings(); 1346 // Indices in this structure are actually offsets of records in the 1347 // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index 1348 // into the global PDB string table. 1349 auto iter = checksums.at(file_id); 1350 if (iter == checksums.end()) 1351 return llvm::make_error<RawError>(raw_error_code::no_entry); 1352 1353 llvm::Expected<llvm::StringRef> efn = strings.getString(iter->FileNameOffset); 1354 if (!efn) { 1355 return efn.takeError(); 1356 } 1357 1358 // LLDB wants the index of the file in the list of support files. 1359 auto fn_iter = llvm::find(cii.m_file_list, *efn); 1360 if (fn_iter != cii.m_file_list.end()) 1361 return std::distance(cii.m_file_list.begin(), fn_iter); 1362 return llvm::make_error<RawError>(raw_error_code::no_entry); 1363 } 1364 1365 bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit, 1366 SupportFileList &support_files) { 1367 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1368 PdbSymUid cu_id(comp_unit.GetID()); 1369 lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); 1370 CompilandIndexItem *cci = 1371 m_index->compilands().GetCompiland(cu_id.asCompiland().modi); 1372 lldbassert(cci); 1373 1374 for (llvm::StringRef f : cci->m_file_list) { 1375 FileSpec::Style style = 1376 f.starts_with("/") ? FileSpec::Style::posix : FileSpec::Style::windows; 1377 FileSpec spec(f, style); 1378 support_files.Append(spec); 1379 } 1380 return true; 1381 } 1382 1383 bool SymbolFileNativePDB::ParseImportedModules( 1384 const SymbolContext &sc, std::vector<SourceModule> &imported_modules) { 1385 // PDB does not yet support module debug info 1386 return false; 1387 } 1388 1389 void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, 1390 Address func_addr) { 1391 lldb::user_id_t opaque_uid = toOpaqueUid(id); 1392 if (m_inline_sites.contains(opaque_uid)) 1393 return; 1394 1395 addr_t func_base = func_addr.GetFileAddress(); 1396 CompilandIndexItem *cii = m_index->compilands().GetCompiland(id.modi); 1397 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(id.offset); 1398 CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); 1399 1400 InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind())); 1401 cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site)); 1402 PdbCompilandSymId parent_id(id.modi, inline_site.Parent); 1403 1404 std::shared_ptr<InlineSite> inline_site_sp = 1405 std::make_shared<InlineSite>(parent_id); 1406 1407 // Get the inlined function declaration info. 1408 auto iter = cii->m_inline_map.find(inline_site.Inlinee); 1409 if (iter == cii->m_inline_map.end()) 1410 return; 1411 InlineeSourceLine inlinee_line = iter->second; 1412 1413 const SupportFileList &files = comp_unit->GetSupportFiles(); 1414 FileSpec decl_file; 1415 llvm::Expected<uint32_t> file_index_or_err = 1416 GetFileIndex(*cii, inlinee_line.Header->FileID); 1417 if (!file_index_or_err) 1418 return; 1419 uint32_t file_offset = file_index_or_err.get(); 1420 decl_file = files.GetFileSpecAtIndex(file_offset); 1421 uint32_t decl_line = inlinee_line.Header->SourceLineNum; 1422 std::unique_ptr<Declaration> decl_up = 1423 std::make_unique<Declaration>(decl_file, decl_line); 1424 1425 // Parse range and line info. 1426 uint32_t code_offset = 0; 1427 int32_t line_offset = 0; 1428 std::optional<uint32_t> code_offset_base; 1429 std::optional<uint32_t> code_offset_end; 1430 std::optional<int32_t> cur_line_offset; 1431 std::optional<int32_t> next_line_offset; 1432 std::optional<uint32_t> next_file_offset; 1433 1434 bool is_terminal_entry = false; 1435 bool is_start_of_statement = true; 1436 // The first instruction is the prologue end. 1437 bool is_prologue_end = true; 1438 1439 auto update_code_offset = [&](uint32_t code_delta) { 1440 if (!code_offset_base) 1441 code_offset_base = code_offset; 1442 else if (!code_offset_end) 1443 code_offset_end = *code_offset_base + code_delta; 1444 }; 1445 auto update_line_offset = [&](int32_t line_delta) { 1446 line_offset += line_delta; 1447 if (!code_offset_base || !cur_line_offset) 1448 cur_line_offset = line_offset; 1449 else 1450 next_line_offset = line_offset; 1451 ; 1452 }; 1453 auto update_file_offset = [&](uint32_t offset) { 1454 if (!code_offset_base) 1455 file_offset = offset; 1456 else 1457 next_file_offset = offset; 1458 }; 1459 1460 for (auto &annot : inline_site.annotations()) { 1461 switch (annot.OpCode) { 1462 case BinaryAnnotationsOpCode::CodeOffset: 1463 case BinaryAnnotationsOpCode::ChangeCodeOffset: 1464 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: 1465 code_offset += annot.U1; 1466 update_code_offset(annot.U1); 1467 break; 1468 case BinaryAnnotationsOpCode::ChangeLineOffset: 1469 update_line_offset(annot.S1); 1470 break; 1471 case BinaryAnnotationsOpCode::ChangeCodeLength: 1472 update_code_offset(annot.U1); 1473 code_offset += annot.U1; 1474 is_terminal_entry = true; 1475 break; 1476 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: 1477 code_offset += annot.U1; 1478 update_code_offset(annot.U1); 1479 update_line_offset(annot.S1); 1480 break; 1481 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: 1482 code_offset += annot.U2; 1483 update_code_offset(annot.U2); 1484 update_code_offset(annot.U1); 1485 code_offset += annot.U1; 1486 is_terminal_entry = true; 1487 break; 1488 case BinaryAnnotationsOpCode::ChangeFile: 1489 update_file_offset(annot.U1); 1490 break; 1491 default: 1492 break; 1493 } 1494 1495 // Add range if current range is finished. 1496 if (code_offset_base && code_offset_end && cur_line_offset) { 1497 inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( 1498 *code_offset_base, *code_offset_end - *code_offset_base, 1499 decl_line + *cur_line_offset)); 1500 // Set base, end, file offset and line offset for next range. 1501 if (next_file_offset) 1502 file_offset = *next_file_offset; 1503 if (next_line_offset) { 1504 cur_line_offset = next_line_offset; 1505 next_line_offset = std::nullopt; 1506 } 1507 code_offset_base = is_terminal_entry ? std::nullopt : code_offset_end; 1508 code_offset_end = next_file_offset = std::nullopt; 1509 } 1510 if (code_offset_base && cur_line_offset) { 1511 if (is_terminal_entry) { 1512 LineTable::Entry line_entry( 1513 func_base + *code_offset_base, decl_line + *cur_line_offset, 0, 1514 file_offset, false, false, false, false, true); 1515 inline_site_sp->line_entries.push_back(line_entry); 1516 } else { 1517 LineTable::Entry line_entry(func_base + *code_offset_base, 1518 decl_line + *cur_line_offset, 0, 1519 file_offset, is_start_of_statement, false, 1520 is_prologue_end, false, false); 1521 inline_site_sp->line_entries.push_back(line_entry); 1522 is_prologue_end = false; 1523 is_start_of_statement = false; 1524 } 1525 } 1526 if (is_terminal_entry) 1527 is_start_of_statement = true; 1528 is_terminal_entry = false; 1529 } 1530 1531 inline_site_sp->ranges.Sort(); 1532 1533 // Get the inlined function callsite info. 1534 std::unique_ptr<Declaration> callsite_up; 1535 if (!inline_site_sp->ranges.IsEmpty()) { 1536 auto *entry = inline_site_sp->ranges.GetEntryAtIndex(0); 1537 addr_t base_offset = entry->GetRangeBase(); 1538 if (cii->m_debug_stream.readSymbolAtOffset(parent_id.offset).kind() == 1539 S_INLINESITE) { 1540 // Its parent is another inline site, lookup parent site's range vector 1541 // for callsite line. 1542 ParseInlineSite(parent_id, func_base); 1543 std::shared_ptr<InlineSite> parent_site = 1544 m_inline_sites[toOpaqueUid(parent_id)]; 1545 FileSpec &parent_decl_file = 1546 parent_site->inline_function_info->GetDeclaration().GetFile(); 1547 if (auto *parent_entry = 1548 parent_site->ranges.FindEntryThatContains(base_offset)) { 1549 callsite_up = 1550 std::make_unique<Declaration>(parent_decl_file, parent_entry->data); 1551 } 1552 } else { 1553 // Its parent is a function, lookup global line table for callsite. 1554 if (auto *entry = cii->m_global_line_table.FindEntryThatContains( 1555 func_base + base_offset)) { 1556 const FileSpec &callsite_file = 1557 files.GetFileSpecAtIndex(entry->data.first); 1558 callsite_up = 1559 std::make_unique<Declaration>(callsite_file, entry->data.second); 1560 } 1561 } 1562 } 1563 1564 // Get the inlined function name. 1565 CVType inlinee_cvt = m_index->ipi().getType(inline_site.Inlinee); 1566 std::string inlinee_name; 1567 if (inlinee_cvt.kind() == LF_MFUNC_ID) { 1568 MemberFuncIdRecord mfr; 1569 cantFail( 1570 TypeDeserializer::deserializeAs<MemberFuncIdRecord>(inlinee_cvt, mfr)); 1571 LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); 1572 inlinee_name.append(std::string(types.getTypeName(mfr.ClassType))); 1573 inlinee_name.append("::"); 1574 inlinee_name.append(mfr.getName().str()); 1575 } else if (inlinee_cvt.kind() == LF_FUNC_ID) { 1576 FuncIdRecord fir; 1577 cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(inlinee_cvt, fir)); 1578 TypeIndex parent_idx = fir.getParentScope(); 1579 if (!parent_idx.isNoneType()) { 1580 LazyRandomTypeCollection &ids = m_index->ipi().typeCollection(); 1581 inlinee_name.append(std::string(ids.getTypeName(parent_idx))); 1582 inlinee_name.append("::"); 1583 } 1584 inlinee_name.append(fir.getName().str()); 1585 } 1586 inline_site_sp->inline_function_info = std::make_shared<InlineFunctionInfo>( 1587 inlinee_name.c_str(), llvm::StringRef(), decl_up.get(), 1588 callsite_up.get()); 1589 1590 m_inline_sites[opaque_uid] = inline_site_sp; 1591 } 1592 1593 size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { 1594 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1595 PdbCompilandSymId func_id = PdbSymUid(func.GetID()).asCompilandSym(); 1596 // After we iterate through inline sites inside the function, we already get 1597 // all the info needed, removing from the map to save memory. 1598 std::set<uint64_t> remove_uids; 1599 auto parse_blocks = [&](SymbolKind kind, PdbCompilandSymId id) { 1600 if (kind == S_GPROC32 || kind == S_LPROC32 || kind == S_BLOCK32 || 1601 kind == S_INLINESITE) { 1602 GetOrCreateBlock(id); 1603 if (kind == S_INLINESITE) 1604 remove_uids.insert(toOpaqueUid(id)); 1605 return true; 1606 } 1607 return false; 1608 }; 1609 size_t count = ParseSymbolArrayInScope(func_id, parse_blocks); 1610 for (uint64_t uid : remove_uids) { 1611 m_inline_sites.erase(uid); 1612 } 1613 return count; 1614 } 1615 1616 size_t SymbolFileNativePDB::ParseSymbolArrayInScope( 1617 PdbCompilandSymId parent_id, 1618 llvm::function_ref<bool(SymbolKind, PdbCompilandSymId)> fn) { 1619 CompilandIndexItem *cii = m_index->compilands().GetCompiland(parent_id.modi); 1620 CVSymbolArray syms = 1621 cii->m_debug_stream.getSymbolArrayForScope(parent_id.offset); 1622 1623 size_t count = 1; 1624 for (auto iter = syms.begin(); iter != syms.end(); ++iter) { 1625 PdbCompilandSymId child_id(parent_id.modi, iter.offset()); 1626 if (fn(iter->kind(), child_id)) 1627 ++count; 1628 } 1629 1630 return count; 1631 } 1632 1633 void SymbolFileNativePDB::DumpClangAST(Stream &s) { 1634 auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); 1635 if (!ts_or_err) 1636 return; 1637 auto ts = *ts_or_err; 1638 TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get()); 1639 if (!clang) 1640 return; 1641 clang->GetNativePDBParser()->Dump(s); 1642 } 1643 1644 void SymbolFileNativePDB::FindGlobalVariables( 1645 ConstString name, const CompilerDeclContext &parent_decl_ctx, 1646 uint32_t max_matches, VariableList &variables) { 1647 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1648 using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; 1649 1650 std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName( 1651 name.GetStringRef(), m_index->symrecords()); 1652 for (const SymbolAndOffset &result : results) { 1653 switch (result.second.kind()) { 1654 case SymbolKind::S_GDATA32: 1655 case SymbolKind::S_LDATA32: 1656 case SymbolKind::S_GTHREAD32: 1657 case SymbolKind::S_LTHREAD32: 1658 case SymbolKind::S_CONSTANT: { 1659 PdbGlobalSymId global(result.first, false); 1660 if (VariableSP var = GetOrCreateGlobalVariable(global)) 1661 variables.AddVariable(var); 1662 break; 1663 } 1664 default: 1665 continue; 1666 } 1667 } 1668 } 1669 1670 void SymbolFileNativePDB::FindFunctions( 1671 const Module::LookupInfo &lookup_info, 1672 const CompilerDeclContext &parent_decl_ctx, bool include_inlines, 1673 SymbolContextList &sc_list) { 1674 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1675 ConstString name = lookup_info.GetLookupName(); 1676 FunctionNameType name_type_mask = lookup_info.GetNameTypeMask(); 1677 if (name_type_mask & eFunctionNameTypeFull) 1678 name = lookup_info.GetName(); 1679 1680 // For now we only support lookup by method name or full name. 1681 if (!(name_type_mask & eFunctionNameTypeFull || 1682 name_type_mask & eFunctionNameTypeMethod)) 1683 return; 1684 1685 using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; 1686 1687 std::vector<SymbolAndOffset> matches = m_index->globals().findRecordsByName( 1688 name.GetStringRef(), m_index->symrecords()); 1689 for (const SymbolAndOffset &match : matches) { 1690 if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF) 1691 continue; 1692 ProcRefSym proc(match.second.kind()); 1693 cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(match.second, proc)); 1694 1695 if (!IsValidRecord(proc)) 1696 continue; 1697 1698 CompilandIndexItem &cci = 1699 m_index->compilands().GetOrCreateCompiland(proc.modi()); 1700 SymbolContext sc; 1701 1702 sc.comp_unit = GetOrCreateCompileUnit(cci).get(); 1703 PdbCompilandSymId func_id(proc.modi(), proc.SymOffset); 1704 sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get(); 1705 1706 sc_list.Append(sc); 1707 } 1708 } 1709 1710 void SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex, 1711 bool include_inlines, 1712 SymbolContextList &sc_list) {} 1713 1714 void SymbolFileNativePDB::FindTypes(const lldb_private::TypeQuery &query, 1715 lldb_private::TypeResults &results) { 1716 1717 // Make sure we haven't already searched this SymbolFile before. 1718 if (results.AlreadySearched(this)) 1719 return; 1720 1721 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1722 1723 std::vector<TypeIndex> matches = 1724 m_index->tpi().findRecordsByName(query.GetTypeBasename().GetStringRef()); 1725 1726 for (TypeIndex type_idx : matches) { 1727 TypeSP type_sp = GetOrCreateType(type_idx); 1728 if (!type_sp) 1729 continue; 1730 1731 // We resolved a type. Get the fully qualified name to ensure it matches. 1732 ConstString name = type_sp->GetQualifiedName(); 1733 TypeQuery type_match(name.GetStringRef(), TypeQueryOptions::e_exact_match); 1734 if (query.ContextMatches(type_match.GetContextRef())) { 1735 results.InsertUnique(type_sp); 1736 if (results.Done(query)) 1737 return; 1738 } 1739 } 1740 } 1741 1742 void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name, 1743 uint32_t max_matches, 1744 TypeMap &types) { 1745 1746 std::vector<TypeIndex> matches = m_index->tpi().findRecordsByName(name); 1747 if (max_matches > 0 && max_matches < matches.size()) 1748 matches.resize(max_matches); 1749 1750 for (TypeIndex ti : matches) { 1751 TypeSP type = GetOrCreateType(ti); 1752 if (!type) 1753 continue; 1754 1755 types.Insert(type); 1756 } 1757 } 1758 1759 size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) { 1760 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 1761 // Only do the full type scan the first time. 1762 if (m_done_full_type_scan) 1763 return 0; 1764 1765 const size_t old_count = GetTypeList().GetSize(); 1766 LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); 1767 1768 // First process the entire TPI stream. 1769 for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { 1770 TypeSP type = GetOrCreateType(*ti); 1771 if (type) 1772 (void)type->GetFullCompilerType(); 1773 } 1774 1775 // Next look for S_UDT records in the globals stream. 1776 for (const uint32_t gid : m_index->globals().getGlobalsTable()) { 1777 PdbGlobalSymId global{gid, false}; 1778 CVSymbol sym = m_index->ReadSymbolRecord(global); 1779 if (sym.kind() != S_UDT) 1780 continue; 1781 1782 UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); 1783 bool is_typedef = true; 1784 if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) { 1785 CVType cvt = m_index->tpi().getType(udt.Type); 1786 llvm::StringRef name = CVTagRecord::create(cvt).name(); 1787 if (name == udt.Name) 1788 is_typedef = false; 1789 } 1790 1791 if (is_typedef) 1792 GetOrCreateTypedef(global); 1793 } 1794 1795 const size_t new_count = GetTypeList().GetSize(); 1796 1797 m_done_full_type_scan = true; 1798 1799 return new_count - old_count; 1800 } 1801 1802 size_t 1803 SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit, 1804 VariableList &variables) { 1805 PdbSymUid sym_uid(comp_unit.GetID()); 1806 lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland); 1807 for (const uint32_t gid : m_index->globals().getGlobalsTable()) { 1808 PdbGlobalSymId global{gid, false}; 1809 CVSymbol sym = m_index->ReadSymbolRecord(global); 1810 // TODO: S_CONSTANT is not handled here to prevent a possible crash in 1811 // lldb_private::npdb::MakeConstantLocationExpression when it's a record 1812 // type (e.g. std::strong_ordering::equal). That function needs to be 1813 // updated to handle this case when we add S_CONSTANT case here. 1814 switch (sym.kind()) { 1815 case SymbolKind::S_GDATA32: 1816 case SymbolKind::S_LDATA32: 1817 case SymbolKind::S_GTHREAD32: 1818 case SymbolKind::S_LTHREAD32: { 1819 if (VariableSP var = GetOrCreateGlobalVariable(global)) 1820 variables.AddVariable(var); 1821 break; 1822 } 1823 default: 1824 break; 1825 } 1826 } 1827 return variables.GetSize(); 1828 } 1829 1830 VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, 1831 PdbCompilandSymId var_id, 1832 bool is_param) { 1833 ModuleSP module = GetObjectFile()->GetModule(); 1834 Block *block = GetOrCreateBlock(scope_id); 1835 if (!block) 1836 return nullptr; 1837 1838 // Get function block. 1839 Block *func_block = block; 1840 while (func_block->GetParent()) { 1841 func_block = func_block->GetParent(); 1842 } 1843 1844 Address addr; 1845 func_block->GetStartAddress(addr); 1846 VariableInfo var_info = 1847 GetVariableLocationInfo(*m_index, var_id, *func_block, module); 1848 Function *func = func_block->CalculateSymbolContextFunction(); 1849 if (!func) 1850 return nullptr; 1851 // Use empty dwarf expr if optimized away so that it won't be filtered out 1852 // when lookuping local variables in this scope. 1853 if (!var_info.location.IsValid()) 1854 var_info.location = DWARFExpressionList(module, DWARFExpression(), nullptr); 1855 var_info.location.SetFuncFileAddress(func->GetAddress().GetFileAddress()); 1856 CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi); 1857 CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii); 1858 TypeSP type_sp = GetOrCreateType(var_info.type); 1859 if (!type_sp) 1860 return nullptr; 1861 std::string name = var_info.name.str(); 1862 Declaration decl; 1863 SymbolFileTypeSP sftype = 1864 std::make_shared<SymbolFileType>(*this, type_sp->GetID()); 1865 1866 is_param |= var_info.is_param; 1867 ValueType var_scope = 1868 is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal; 1869 bool external = false; 1870 bool artificial = false; 1871 bool location_is_constant_data = false; 1872 bool static_member = false; 1873 Variable::RangeList scope_ranges; 1874 VariableSP var_sp = std::make_shared<Variable>( 1875 toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, block, 1876 scope_ranges, &decl, var_info.location, external, artificial, 1877 location_is_constant_data, static_member); 1878 if (!is_param) { 1879 auto ts_or_err = GetTypeSystemForLanguage(comp_unit_sp->GetLanguage()); 1880 if (auto err = ts_or_err.takeError()) 1881 return nullptr; 1882 auto ts = *ts_or_err; 1883 if (!ts) 1884 return nullptr; 1885 1886 ts->GetNativePDBParser()->GetOrCreateVariableDecl(scope_id, var_id); 1887 } 1888 m_local_variables[toOpaqueUid(var_id)] = var_sp; 1889 return var_sp; 1890 } 1891 1892 VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable( 1893 PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) { 1894 auto iter = m_local_variables.find(toOpaqueUid(var_id)); 1895 if (iter != m_local_variables.end()) 1896 return iter->second; 1897 1898 return CreateLocalVariable(scope_id, var_id, is_param); 1899 } 1900 1901 TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) { 1902 CVSymbol sym = m_index->ReadSymbolRecord(id); 1903 lldbassert(sym.kind() == SymbolKind::S_UDT); 1904 1905 UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); 1906 1907 TypeSP target_type = GetOrCreateType(udt.Type); 1908 1909 auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 1910 if (auto err = ts_or_err.takeError()) 1911 return nullptr; 1912 auto ts = *ts_or_err; 1913 if (!ts) 1914 return nullptr; 1915 1916 ts->GetNativePDBParser()->GetOrCreateTypedefDecl(id); 1917 1918 Declaration decl; 1919 return MakeType( 1920 toOpaqueUid(id), ConstString(udt.Name), target_type->GetByteSize(nullptr), 1921 nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, 1922 decl, target_type->GetForwardCompilerType(), 1923 lldb_private::Type::ResolveState::Forward); 1924 } 1925 1926 TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) { 1927 auto iter = m_types.find(toOpaqueUid(id)); 1928 if (iter != m_types.end()) 1929 return iter->second; 1930 1931 return CreateTypedef(id); 1932 } 1933 1934 size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { 1935 Block *block = GetOrCreateBlock(block_id); 1936 if (!block) 1937 return 0; 1938 1939 size_t count = 0; 1940 1941 CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); 1942 CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); 1943 uint32_t params_remaining = 0; 1944 switch (sym.kind()) { 1945 case S_GPROC32: 1946 case S_LPROC32: { 1947 ProcSym proc(static_cast<SymbolRecordKind>(sym.kind())); 1948 cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc)); 1949 CVType signature = m_index->tpi().getType(proc.FunctionType); 1950 if (signature.kind() == LF_PROCEDURE) { 1951 ProcedureRecord sig; 1952 if (llvm::Error e = TypeDeserializer::deserializeAs<ProcedureRecord>( 1953 signature, sig)) { 1954 llvm::consumeError(std::move(e)); 1955 return 0; 1956 } 1957 params_remaining = sig.getParameterCount(); 1958 } else if (signature.kind() == LF_MFUNCTION) { 1959 MemberFunctionRecord sig; 1960 if (llvm::Error e = TypeDeserializer::deserializeAs<MemberFunctionRecord>( 1961 signature, sig)) { 1962 llvm::consumeError(std::move(e)); 1963 return 0; 1964 } 1965 params_remaining = sig.getParameterCount(); 1966 } else 1967 return 0; 1968 break; 1969 } 1970 case S_BLOCK32: 1971 break; 1972 case S_INLINESITE: 1973 break; 1974 default: 1975 lldbassert(false && "Symbol is not a block!"); 1976 return 0; 1977 } 1978 1979 VariableListSP variables = block->GetBlockVariableList(false); 1980 if (!variables) { 1981 variables = std::make_shared<VariableList>(); 1982 block->SetVariableList(variables); 1983 } 1984 1985 CVSymbolArray syms = limitSymbolArrayToScope( 1986 cii->m_debug_stream.getSymbolArray(), block_id.offset); 1987 1988 // Skip the first record since it's a PROC32 or BLOCK32, and there's 1989 // no point examining it since we know it's not a local variable. 1990 syms.drop_front(); 1991 auto iter = syms.begin(); 1992 auto end = syms.end(); 1993 1994 while (iter != end) { 1995 uint32_t record_offset = iter.offset(); 1996 CVSymbol variable_cvs = *iter; 1997 PdbCompilandSymId child_sym_id(block_id.modi, record_offset); 1998 ++iter; 1999 2000 // If this is a block or inline site, recurse into its children and then 2001 // skip it. 2002 if (variable_cvs.kind() == S_BLOCK32 || 2003 variable_cvs.kind() == S_INLINESITE) { 2004 uint32_t block_end = getScopeEndOffset(variable_cvs); 2005 count += ParseVariablesForBlock(child_sym_id); 2006 iter = syms.at(block_end); 2007 continue; 2008 } 2009 2010 bool is_param = params_remaining > 0; 2011 VariableSP variable; 2012 switch (variable_cvs.kind()) { 2013 case S_REGREL32: 2014 case S_REGISTER: 2015 case S_LOCAL: 2016 variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param); 2017 if (is_param) 2018 --params_remaining; 2019 if (variable) 2020 variables->AddVariableIfUnique(variable); 2021 break; 2022 default: 2023 break; 2024 } 2025 } 2026 2027 // Pass false for set_children, since we call this recursively so that the 2028 // children will call this for themselves. 2029 block->SetDidParseVariables(true, false); 2030 2031 return count; 2032 } 2033 2034 size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) { 2035 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 2036 lldbassert(sc.function || sc.comp_unit); 2037 2038 VariableListSP variables; 2039 if (sc.block) { 2040 PdbSymUid block_id(sc.block->GetID()); 2041 2042 size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); 2043 return count; 2044 } 2045 2046 if (sc.function) { 2047 PdbSymUid block_id(sc.function->GetID()); 2048 2049 size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); 2050 return count; 2051 } 2052 2053 if (sc.comp_unit) { 2054 variables = sc.comp_unit->GetVariableList(false); 2055 if (!variables) { 2056 variables = std::make_shared<VariableList>(); 2057 sc.comp_unit->SetVariableList(variables); 2058 } 2059 return ParseVariablesForCompileUnit(*sc.comp_unit, *variables); 2060 } 2061 2062 llvm_unreachable("Unreachable!"); 2063 } 2064 2065 CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) { 2066 auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 2067 if (auto err = ts_or_err.takeError()) 2068 return CompilerDecl(); 2069 auto ts = *ts_or_err; 2070 if (!ts) 2071 return {}; 2072 2073 if (auto decl = ts->GetNativePDBParser()->GetOrCreateDeclForUid(uid)) 2074 return *decl; 2075 return CompilerDecl(); 2076 } 2077 2078 CompilerDeclContext 2079 SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) { 2080 auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 2081 if (auto err = ts_or_err.takeError()) 2082 return {}; 2083 auto ts = *ts_or_err; 2084 if (!ts) 2085 return {}; 2086 2087 PdbAstBuilder *ast_builder = ts->GetNativePDBParser(); 2088 clang::DeclContext *context = 2089 ast_builder->GetOrCreateDeclContextForUid(PdbSymUid(uid)); 2090 if (!context) 2091 return {}; 2092 2093 return ast_builder->ToCompilerDeclContext(*context); 2094 } 2095 2096 CompilerDeclContext 2097 SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { 2098 auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); 2099 if (auto err = ts_or_err.takeError()) 2100 return CompilerDeclContext(); 2101 auto ts = *ts_or_err; 2102 if (!ts) 2103 return {}; 2104 2105 PdbAstBuilder *ast_builder = ts->GetNativePDBParser(); 2106 clang::DeclContext *context = ast_builder->GetParentDeclContext(PdbSymUid(uid)); 2107 if (!context) 2108 return CompilerDeclContext(); 2109 return ast_builder->ToCompilerDeclContext(*context); 2110 } 2111 2112 Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) { 2113 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 2114 auto iter = m_types.find(type_uid); 2115 // lldb should not be passing us non-sensical type uids. the only way it 2116 // could have a type uid in the first place is if we handed it out, in which 2117 // case we should know about the type. However, that doesn't mean we've 2118 // instantiated it yet. We can vend out a UID for a future type. So if the 2119 // type doesn't exist, let's instantiate it now. 2120 if (iter != m_types.end()) 2121 return &*iter->second; 2122 2123 PdbSymUid uid(type_uid); 2124 lldbassert(uid.kind() == PdbSymUidKind::Type); 2125 PdbTypeSymId type_id = uid.asTypeSym(); 2126 if (type_id.index.isNoneType()) 2127 return nullptr; 2128 2129 TypeSP type_sp = CreateAndCacheType(type_id); 2130 if (!type_sp) 2131 return nullptr; 2132 return &*type_sp; 2133 } 2134 2135 std::optional<SymbolFile::ArrayInfo> 2136 SymbolFileNativePDB::GetDynamicArrayInfoForUID( 2137 lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { 2138 return std::nullopt; 2139 } 2140 2141 bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { 2142 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); 2143 auto ts = compiler_type.GetTypeSystem(); 2144 auto clang_type_system = ts.dyn_cast_or_null<TypeSystemClang>(); 2145 if (!clang_type_system) 2146 return false; 2147 2148 PdbAstBuilder *ast_builder = 2149 static_cast<PdbAstBuilder *>(clang_type_system->GetNativePDBParser()); 2150 if (ast_builder && 2151 ast_builder->GetClangASTImporter().CanImport(compiler_type)) 2152 return ast_builder->GetClangASTImporter().CompleteType(compiler_type); 2153 clang::QualType qt = 2154 clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType()); 2155 2156 return ast_builder->CompleteType(qt); 2157 } 2158 2159 void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, 2160 TypeClass type_mask, 2161 lldb_private::TypeList &type_list) {} 2162 2163 CompilerDeclContext SymbolFileNativePDB::FindNamespace( 2164 ConstString name, const CompilerDeclContext &parent_decl_ctx, bool) { 2165 return {}; 2166 } 2167 2168 llvm::Expected<lldb::TypeSystemSP> 2169 SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { 2170 auto type_system_or_err = 2171 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language); 2172 if (type_system_or_err) 2173 if (auto ts = *type_system_or_err) 2174 ts->SetSymbolFile(this); 2175 return type_system_or_err; 2176 } 2177 2178 uint64_t SymbolFileNativePDB::GetDebugInfoSize(bool load_all_debug_info) { 2179 // PDB files are a separate file that contains all debug info. 2180 return m_index->pdb().getFileSize(); 2181 } 2182 2183 void SymbolFileNativePDB::BuildParentMap() { 2184 LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); 2185 2186 llvm::DenseMap<TypeIndex, TypeIndex> forward_to_full; 2187 llvm::DenseMap<TypeIndex, TypeIndex> full_to_forward; 2188 2189 struct RecordIndices { 2190 TypeIndex forward; 2191 TypeIndex full; 2192 }; 2193 2194 llvm::StringMap<RecordIndices> record_indices; 2195 2196 for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { 2197 CVType type = types.getType(*ti); 2198 if (!IsTagRecord(type)) 2199 continue; 2200 2201 CVTagRecord tag = CVTagRecord::create(type); 2202 2203 RecordIndices &indices = record_indices[tag.asTag().getUniqueName()]; 2204 if (tag.asTag().isForwardRef()) 2205 indices.forward = *ti; 2206 else 2207 indices.full = *ti; 2208 2209 if (indices.full != TypeIndex::None() && 2210 indices.forward != TypeIndex::None()) { 2211 forward_to_full[indices.forward] = indices.full; 2212 full_to_forward[indices.full] = indices.forward; 2213 } 2214 2215 // We're looking for LF_NESTTYPE records in the field list, so ignore 2216 // forward references (no field list), and anything without a nested class 2217 // (since there won't be any LF_NESTTYPE records). 2218 if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass()) 2219 continue; 2220 2221 struct ProcessTpiStream : public TypeVisitorCallbacks { 2222 ProcessTpiStream(PdbIndex &index, TypeIndex parent, 2223 const CVTagRecord &parent_cvt, 2224 llvm::DenseMap<TypeIndex, TypeIndex> &parents) 2225 : index(index), parents(parents), parent(parent), 2226 parent_cvt(parent_cvt) {} 2227 2228 PdbIndex &index; 2229 llvm::DenseMap<TypeIndex, TypeIndex> &parents; 2230 2231 unsigned unnamed_type_index = 1; 2232 TypeIndex parent; 2233 const CVTagRecord &parent_cvt; 2234 2235 llvm::Error visitKnownMember(CVMemberRecord &CVR, 2236 NestedTypeRecord &Record) override { 2237 std::string unnamed_type_name; 2238 if (Record.Name.empty()) { 2239 unnamed_type_name = 2240 llvm::formatv("<unnamed-type-$S{0}>", unnamed_type_index).str(); 2241 Record.Name = unnamed_type_name; 2242 ++unnamed_type_index; 2243 } 2244 std::optional<CVTagRecord> tag = 2245 GetNestedTagDefinition(Record, parent_cvt, index.tpi()); 2246 if (!tag) 2247 return llvm::ErrorSuccess(); 2248 2249 parents[Record.Type] = parent; 2250 return llvm::ErrorSuccess(); 2251 } 2252 }; 2253 2254 CVType field_list_cvt = m_index->tpi().getType(tag.asTag().FieldList); 2255 ProcessTpiStream process(*m_index, *ti, tag, m_parent_types); 2256 FieldListRecord field_list; 2257 if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( 2258 field_list_cvt, field_list)) 2259 llvm::consumeError(std::move(error)); 2260 if (llvm::Error error = visitMemberRecordStream(field_list.Data, process)) 2261 llvm::consumeError(std::move(error)); 2262 } 2263 2264 // Now that we know the forward -> full mapping of all type indices, we can 2265 // re-write all the indices. At the end of this process, we want a mapping 2266 // consisting of fwd -> full and full -> full for all child -> parent indices. 2267 // We can re-write the values in place, but for the keys, we must save them 2268 // off so that we don't modify the map in place while also iterating it. 2269 std::vector<TypeIndex> full_keys; 2270 std::vector<TypeIndex> fwd_keys; 2271 for (auto &entry : m_parent_types) { 2272 TypeIndex key = entry.first; 2273 TypeIndex value = entry.second; 2274 2275 auto iter = forward_to_full.find(value); 2276 if (iter != forward_to_full.end()) 2277 entry.second = iter->second; 2278 2279 iter = forward_to_full.find(key); 2280 if (iter != forward_to_full.end()) 2281 fwd_keys.push_back(key); 2282 else 2283 full_keys.push_back(key); 2284 } 2285 for (TypeIndex fwd : fwd_keys) { 2286 TypeIndex full = forward_to_full[fwd]; 2287 TypeIndex parent_idx = m_parent_types[fwd]; 2288 m_parent_types[full] = parent_idx; 2289 } 2290 for (TypeIndex full : full_keys) { 2291 TypeIndex fwd = full_to_forward[full]; 2292 m_parent_types[fwd] = m_parent_types[full]; 2293 } 2294 } 2295 2296 std::optional<PdbCompilandSymId> 2297 SymbolFileNativePDB::FindSymbolScope(PdbCompilandSymId id) { 2298 CVSymbol sym = m_index->ReadSymbolRecord(id); 2299 if (symbolOpensScope(sym.kind())) { 2300 // If this exact symbol opens a scope, we can just directly access its 2301 // parent. 2302 id.offset = getScopeParentOffset(sym); 2303 // Global symbols have parent offset of 0. Return std::nullopt to indicate 2304 // this. 2305 if (id.offset == 0) 2306 return std::nullopt; 2307 return id; 2308 } 2309 2310 // Otherwise we need to start at the beginning and iterate forward until we 2311 // reach (or pass) this particular symbol 2312 CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(id.modi); 2313 const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray(); 2314 2315 auto begin = syms.begin(); 2316 auto end = syms.at(id.offset); 2317 std::vector<PdbCompilandSymId> scope_stack; 2318 2319 while (begin != end) { 2320 if (begin.offset() > id.offset) { 2321 // We passed it. We couldn't even find this symbol record. 2322 lldbassert(false && "Invalid compiland symbol id!"); 2323 return std::nullopt; 2324 } 2325 2326 // We haven't found the symbol yet. Check if we need to open or close the 2327 // scope stack. 2328 if (symbolOpensScope(begin->kind())) { 2329 // We can use the end offset of the scope to determine whether or not 2330 // we can just outright skip this entire scope. 2331 uint32_t scope_end = getScopeEndOffset(*begin); 2332 if (scope_end < id.offset) { 2333 begin = syms.at(scope_end); 2334 } else { 2335 // The symbol we're looking for is somewhere in this scope. 2336 scope_stack.emplace_back(id.modi, begin.offset()); 2337 } 2338 } else if (symbolEndsScope(begin->kind())) { 2339 scope_stack.pop_back(); 2340 } 2341 ++begin; 2342 } 2343 if (scope_stack.empty()) 2344 return std::nullopt; 2345 // We have a match! Return the top of the stack 2346 return scope_stack.back(); 2347 } 2348 2349 std::optional<llvm::codeview::TypeIndex> 2350 SymbolFileNativePDB::GetParentType(llvm::codeview::TypeIndex ti) { 2351 auto parent_iter = m_parent_types.find(ti); 2352 if (parent_iter == m_parent_types.end()) 2353 return std::nullopt; 2354 return parent_iter->second; 2355 } 2356