2128 lines · cpp
1//===-- SymbolFilePDB.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-exception6//7//===----------------------------------------------------------------------===//8 9#include "SymbolFilePDB.h"10 11#include "PDBASTParser.h"12#include "PDBLocationToDWARFExpression.h"13 14#include "clang/Lex/Lexer.h"15 16#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"17#include "lldb/Core/Debugger.h"18#include "lldb/Core/Mangled.h"19#include "lldb/Core/Module.h"20#include "lldb/Core/PluginManager.h"21#include "lldb/Symbol/CompileUnit.h"22#include "lldb/Symbol/LineTable.h"23#include "lldb/Symbol/ObjectFile.h"24#include "lldb/Symbol/SymbolContext.h"25#include "lldb/Symbol/SymbolVendor.h"26#include "lldb/Symbol/TypeList.h"27#include "lldb/Symbol/TypeMap.h"28#include "lldb/Symbol/Variable.h"29#include "lldb/Utility/LLDBLog.h"30#include "lldb/Utility/Log.h"31#include "lldb/Utility/RegularExpression.h"32 33#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_DIA_SDK34#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"35#include "llvm/DebugInfo/PDB/GenericError.h"36#include "llvm/DebugInfo/PDB/IPDBDataStream.h"37#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"38#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"39#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"40#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"41#include "llvm/DebugInfo/PDB/IPDBTable.h"42#include "llvm/DebugInfo/PDB/PDBSymbol.h"43#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"44#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"45#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"46#include "llvm/DebugInfo/PDB/PDBSymbolData.h"47#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"48#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"49#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"50#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"51#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"52#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"53#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"54#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"55#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"56#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"57 58#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h"59#include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h"60 61#if defined(_WIN32)62#include "llvm/Config/llvm-config.h"63#include <optional>64#endif65 66using namespace lldb;67using namespace lldb_private;68using namespace llvm::pdb;69 70LLDB_PLUGIN_DEFINE(SymbolFilePDB)71 72char SymbolFilePDB::ID;73 74namespace {75 76enum PDBReader {77 ePDBReaderDefault,78 ePDBReaderDIA,79 ePDBReaderNative,80};81 82constexpr OptionEnumValueElement g_pdb_reader_enums[] = {83 {84 ePDBReaderDefault,85 "default",86 "Use native PDB reader unless LLDB_USE_NATIVE_PDB_READER environment "87 "is set to 0",88 },89 {90 ePDBReaderDIA,91 "dia",92 "Use DIA PDB reader",93 },94 {95 ePDBReaderNative,96 "native",97 "Use native PDB reader",98 },99};100 101#define LLDB_PROPERTIES_symbolfilepdb102#include "SymbolFilePDBProperties.inc"103 104enum {105#define LLDB_PROPERTIES_symbolfilepdb106#include "SymbolFilePDBPropertiesEnum.inc"107};108 109static const bool g_should_use_native_reader_by_default = [] {110 llvm::StringRef env_value = ::getenv("LLDB_USE_NATIVE_PDB_READER");111 112 return !env_value.equals_insensitive("off") &&113 !env_value.equals_insensitive("no") &&114 !env_value.equals_insensitive("0") &&115 !env_value.equals_insensitive("false");116}();117 118class PluginProperties : public Properties {119public:120 static llvm::StringRef GetSettingName() {121 return SymbolFilePDB::GetPluginNameStatic();122 }123 124 PluginProperties() {125 m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());126 m_collection_sp->Initialize(g_symbolfilepdb_properties);127 }128 129 bool UseNativeReader() const {130#if LLVM_ENABLE_DIA_SDK && defined(_WIN32)131 return IsNativeReaderRequested();132#else133 if (!IsNativeReaderRequested()) {134 static std::once_flag g_warning_shown;135 Debugger::ReportWarning(136 "the DIA PDB reader was explicitly requested, but LLDB was built "137 "without the DIA SDK. The native reader will be used instead",138 {}, &g_warning_shown);139 }140 return true;141#endif142 }143 144private:145 bool IsNativeReaderRequested() const {146 auto value =147 GetPropertyAtIndexAs<PDBReader>(ePropertyReader, ePDBReaderDefault);148 switch (value) {149 case ePDBReaderNative:150 return true;151 case ePDBReaderDIA:152 return false;153 default:154 return g_should_use_native_reader_by_default;155 }156 }157};158 159PluginProperties &GetGlobalPluginProperties() {160 static PluginProperties g_settings;161 return g_settings;162}163 164lldb::LanguageType TranslateLanguage(PDB_Lang lang) {165 switch (lang) {166 case PDB_Lang::Cpp:167 return lldb::LanguageType::eLanguageTypeC_plus_plus;168 case PDB_Lang::C:169 return lldb::LanguageType::eLanguageTypeC;170 case PDB_Lang::Swift:171 return lldb::LanguageType::eLanguageTypeSwift;172 case PDB_Lang::Rust:173 return lldb::LanguageType::eLanguageTypeRust;174 case PDB_Lang::ObjC:175 return lldb::LanguageType::eLanguageTypeObjC;176 case PDB_Lang::ObjCpp:177 return lldb::LanguageType::eLanguageTypeObjC_plus_plus;178 default:179 return lldb::LanguageType::eLanguageTypeUnknown;180 }181}182 183bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line,184 uint32_t addr_length) {185 return ((requested_line == 0 || actual_line == requested_line) &&186 addr_length > 0);187}188} // namespace189 190void SymbolFilePDB::Initialize() {191 // Initialize both but check in CreateInstance for the desired plugin192 npdb::SymbolFileNativePDB::Initialize();193 194 PluginManager::RegisterPlugin(GetPluginNameStatic(),195 GetPluginDescriptionStatic(), CreateInstance,196 DebuggerInitialize);197}198 199void SymbolFilePDB::Terminate() {200 npdb::SymbolFileNativePDB::Terminate();201 202 PluginManager::UnregisterPlugin(CreateInstance);203}204 205bool SymbolFilePDB::UseNativePDB() {206 return GetGlobalPluginProperties().UseNativeReader();207}208 209void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {210 if (!PluginManager::GetSettingForSymbolFilePlugin(211 debugger, PluginProperties::GetSettingName())) {212 PluginManager::CreateSettingForSymbolFilePlugin(213 debugger, GetGlobalPluginProperties().GetValueProperties(),214 "Properties for the PDB symbol-file plug-in.", true);215 }216}217 218llvm::StringRef SymbolFilePDB::GetPluginDescriptionStatic() {219 return "Microsoft PDB debug symbol file reader.";220}221 222lldb_private::SymbolFile *223SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) {224 if (UseNativePDB())225 return nullptr;226 227 return new SymbolFilePDB(std::move(objfile_sp));228}229 230SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp)231 : SymbolFileCommon(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {}232 233SymbolFilePDB::~SymbolFilePDB() = default;234 235uint32_t SymbolFilePDB::CalculateAbilities() {236 uint32_t abilities = 0;237 if (!m_objfile_sp)238 return 0;239 240 if (!m_session_up) {241 // Lazily load and match the PDB file, but only do this once.242 std::string exePath = m_objfile_sp->GetFileSpec().GetPath();243 auto error = loadDataForEXE(PDB_ReaderType::DIA, llvm::StringRef(exePath),244 m_session_up);245 if (error) {246 llvm::consumeError(std::move(error));247 auto module_sp = m_objfile_sp->GetModule();248 if (!module_sp)249 return 0;250 // See if any symbol file is specified through `--symfile` option.251 FileSpec symfile = module_sp->GetSymbolFileFileSpec();252 if (!symfile)253 return 0;254 error = loadDataForPDB(PDB_ReaderType::DIA,255 llvm::StringRef(symfile.GetPath()), m_session_up);256 if (error) {257 llvm::consumeError(std::move(error));258 return 0;259 }260 }261 }262 if (!m_session_up)263 return 0;264 265 auto enum_tables_up = m_session_up->getEnumTables();266 if (!enum_tables_up)267 return 0;268 while (auto table_up = enum_tables_up->getNext()) {269 if (table_up->getItemCount() == 0)270 continue;271 auto type = table_up->getTableType();272 switch (type) {273 case PDB_TableType::Symbols:274 // This table represents a store of symbols with types listed in275 // PDBSym_Type276 abilities |= (CompileUnits | Functions | Blocks | GlobalVariables |277 LocalVariables | VariableTypes);278 break;279 case PDB_TableType::LineNumbers:280 abilities |= LineTables;281 break;282 default:283 break;284 }285 }286 return abilities;287}288 289void SymbolFilePDB::InitializeObject() {290 lldb::addr_t obj_load_address = m_objfile_sp->GetModule()291 ->GetObjectFile()292 ->GetBaseAddress()293 .GetFileAddress();294 lldbassert(obj_load_address && obj_load_address != LLDB_INVALID_ADDRESS);295 m_session_up->setLoadAddress(obj_load_address);296 if (!m_global_scope_up)297 m_global_scope_up = m_session_up->getGlobalScope();298 lldbassert(m_global_scope_up.get());299}300 301uint32_t SymbolFilePDB::CalculateNumCompileUnits() {302 auto compilands = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();303 if (!compilands)304 return 0;305 306 // The linker could link *.dll (compiland language = LINK), or import307 // *.dll. For example, a compiland with name `Import:KERNEL32.dll` could be308 // found as a child of the global scope (PDB executable). Usually, such309 // compilands contain `thunk` symbols in which we are not interested for310 // now. However we still count them in the compiland list. If we perform311 // any compiland related activity, like finding symbols through312 // llvm::pdb::IPDBSession methods, such compilands will all be searched313 // automatically no matter whether we include them or not.314 uint32_t compile_unit_count = compilands->getChildCount();315 316 // The linker can inject an additional "dummy" compilation unit into the317 // PDB. Ignore this special compile unit for our purposes, if it is there.318 // It is always the last one.319 auto last_compiland_up = compilands->getChildAtIndex(compile_unit_count - 1);320 lldbassert(last_compiland_up.get());321 std::string name = last_compiland_up->getName();322 if (name == "* Linker *")323 --compile_unit_count;324 return compile_unit_count;325}326 327void SymbolFilePDB::GetCompileUnitIndex(328 const llvm::pdb::PDBSymbolCompiland &pdb_compiland, uint32_t &index) {329 auto results_up = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();330 if (!results_up)331 return;332 auto uid = pdb_compiland.getSymIndexId();333 for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {334 auto compiland_up = results_up->getChildAtIndex(cu_idx);335 if (!compiland_up)336 continue;337 if (compiland_up->getSymIndexId() == uid) {338 index = cu_idx;339 return;340 }341 }342 index = UINT32_MAX;343}344 345std::unique_ptr<llvm::pdb::PDBSymbolCompiland>346SymbolFilePDB::GetPDBCompilandByUID(uint32_t uid) {347 return m_session_up->getConcreteSymbolById<PDBSymbolCompiland>(uid);348}349 350lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) {351 if (index >= GetNumCompileUnits())352 return CompUnitSP();353 354 // Assuming we always retrieve same compilands listed in same order through355 // `PDBSymbolExe::findAllChildren` method, otherwise using `index` to get a356 // compile unit makes no sense.357 auto results = m_global_scope_up->findAllChildren<PDBSymbolCompiland>();358 if (!results)359 return CompUnitSP();360 auto compiland_up = results->getChildAtIndex(index);361 if (!compiland_up)362 return CompUnitSP();363 return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index);364}365 366lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) {367 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());368 auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());369 if (!compiland_up)370 return lldb::eLanguageTypeUnknown;371 auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();372 if (!details)373 return lldb::eLanguageTypeUnknown;374 return TranslateLanguage(details->getLanguage());375}376 377lldb_private::Function *378SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,379 CompileUnit &comp_unit) {380 if (FunctionSP result = comp_unit.FindFunctionByUID(pdb_func.getSymIndexId()))381 return result.get();382 383 auto file_vm_addr = pdb_func.getVirtualAddress();384 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)385 return nullptr;386 387 auto func_length = pdb_func.getLength();388 Address func_addr(file_vm_addr,389 GetObjectFile()->GetModule()->GetSectionList());390 if (!func_addr.IsValid())391 return nullptr;392 393 lldb_private::Type *func_type = ResolveTypeUID(pdb_func.getSymIndexId());394 if (!func_type)395 return nullptr;396 397 user_id_t func_type_uid = pdb_func.getSignatureId();398 399 Mangled mangled = GetMangledForPDBFunc(pdb_func);400 401 FunctionSP func_sp = std::make_shared<Function>(402 &comp_unit, pdb_func.getSymIndexId(), func_type_uid, mangled, func_type,403 func_addr, AddressRanges{AddressRange(func_addr, func_length)});404 405 comp_unit.AddFunction(func_sp);406 407 LanguageType lang = ParseLanguage(comp_unit);408 auto type_system_or_err = GetTypeSystemForLanguage(lang);409 if (auto err = type_system_or_err.takeError()) {410 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),411 "Unable to parse PDBFunc: {0}");412 return nullptr;413 }414 415 auto ts = *type_system_or_err;416 TypeSystemClang *clang_type_system =417 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());418 if (!clang_type_system)419 return nullptr;420 clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);421 422 return func_sp.get();423}424 425size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) {426 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());427 size_t func_added = 0;428 auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());429 if (!compiland_up)430 return 0;431 auto results_up = compiland_up->findAllChildren<PDBSymbolFunc>();432 if (!results_up)433 return 0;434 while (auto pdb_func_up = results_up->getNext()) {435 auto func_sp = comp_unit.FindFunctionByUID(pdb_func_up->getSymIndexId());436 if (!func_sp) {437 if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, comp_unit))438 ++func_added;439 }440 }441 return func_added;442}443 444bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) {445 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());446 if (comp_unit.GetLineTable())447 return true;448 return ParseCompileUnitLineTable(comp_unit, 0);449}450 451bool SymbolFilePDB::ParseDebugMacros(CompileUnit &comp_unit) {452 // PDB doesn't contain information about macros453 return false;454}455 456bool SymbolFilePDB::ParseSupportFiles(457 CompileUnit &comp_unit, lldb_private::SupportFileList &support_files) {458 459 // In theory this is unnecessary work for us, because all of this information460 // is easily (and quickly) accessible from DebugInfoPDB, so caching it a461 // second time seems like a waste. Unfortunately, there's no good way around462 // this short of a moderate refactor since SymbolVendor depends on being able463 // to cache this list.464 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());465 auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());466 if (!compiland_up)467 return false;468 auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);469 if (!files || files->getChildCount() == 0)470 return false;471 472 while (auto file = files->getNext()) {473 FileSpec spec(file->getFileName(), FileSpec::Style::windows);474 support_files.AppendIfUnique(spec);475 }476 477 return true;478}479 480bool SymbolFilePDB::ParseImportedModules(481 const lldb_private::SymbolContext &sc,482 std::vector<SourceModule> &imported_modules) {483 // PDB does not yet support module debug info484 return false;485}486 487static size_t ParseFunctionBlocksForPDBSymbol(488 uint64_t func_file_vm_addr, const llvm::pdb::PDBSymbol *pdb_symbol,489 lldb_private::Block *parent_block, bool is_top_parent) {490 assert(pdb_symbol && parent_block);491 492 size_t num_added = 0;493 494 if (!is_top_parent) {495 // Ranges for the top block were parsed together with the function.496 if (pdb_symbol->getSymTag() != PDB_SymType::Block)497 return num_added;498 499 auto &raw_sym = pdb_symbol->getRawSymbol();500 assert(llvm::isa<PDBSymbolBlock>(pdb_symbol));501 auto uid = pdb_symbol->getSymIndexId();502 if (parent_block->FindBlockByID(uid))503 return num_added;504 if (raw_sym.getVirtualAddress() < func_file_vm_addr)505 return num_added;506 507 Block *block = parent_block->CreateChild(pdb_symbol->getSymIndexId()).get();508 block->AddRange(Block::Range(509 raw_sym.getVirtualAddress() - func_file_vm_addr, raw_sym.getLength()));510 block->FinalizeRanges();511 }512 auto results_up = pdb_symbol->findAllChildren();513 if (!results_up)514 return num_added;515 516 while (auto symbol_up = results_up->getNext()) {517 num_added += ParseFunctionBlocksForPDBSymbol(518 func_file_vm_addr, symbol_up.get(), parent_block, false);519 }520 return num_added;521}522 523size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) {524 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());525 size_t num_added = 0;526 auto uid = func.GetID();527 auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);528 if (!pdb_func_up)529 return 0;530 Block &parent_block = func.GetBlock(false);531 num_added = ParseFunctionBlocksForPDBSymbol(532 pdb_func_up->getVirtualAddress(), pdb_func_up.get(), &parent_block, true);533 return num_added;534}535 536size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) {537 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());538 539 size_t num_added = 0;540 auto compiland = GetPDBCompilandByUID(comp_unit.GetID());541 if (!compiland)542 return 0;543 544 auto ParseTypesByTagFn = [&num_added, this](const PDBSymbol &raw_sym) {545 std::unique_ptr<IPDBEnumSymbols> results;546 PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,547 PDB_SymType::UDT};548 for (auto tag : tags_to_search) {549 results = raw_sym.findAllChildren(tag);550 if (!results || results->getChildCount() == 0)551 continue;552 while (auto symbol = results->getNext()) {553 switch (symbol->getSymTag()) {554 case PDB_SymType::Enum:555 case PDB_SymType::UDT:556 case PDB_SymType::Typedef:557 break;558 default:559 continue;560 }561 562 // This should cause the type to get cached and stored in the `m_types`563 // lookup.564 if (auto type = ResolveTypeUID(symbol->getSymIndexId())) {565 // Resolve the type completely to avoid a completion566 // (and so a list change, which causes an iterators invalidation)567 // during a TypeList dumping568 type->GetFullCompilerType();569 ++num_added;570 }571 }572 }573 };574 575 ParseTypesByTagFn(*compiland);576 577 // Also parse global types particularly coming from this compiland.578 // Unfortunately, PDB has no compiland information for each global type. We579 // have to parse them all. But ensure we only do this once.580 static bool parse_all_global_types = false;581 if (!parse_all_global_types) {582 ParseTypesByTagFn(*m_global_scope_up);583 parse_all_global_types = true;584 }585 return num_added;586}587 588size_t589SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {590 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());591 if (!sc.comp_unit)592 return 0;593 594 size_t num_added = 0;595 if (sc.function) {596 auto pdb_func = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(597 sc.function->GetID());598 if (!pdb_func)599 return 0;600 601 num_added += ParseVariables(sc, *pdb_func);602 sc.function->GetBlock(false).SetDidParseVariables(true, true);603 } else if (sc.comp_unit) {604 auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID());605 if (!compiland)606 return 0;607 608 if (sc.comp_unit->GetVariableList(false))609 return 0;610 611 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();612 if (results && results->getChildCount()) {613 while (auto result = results->getNext()) {614 auto cu_id = GetCompilandId(*result);615 // FIXME: We are not able to determine variable's compile unit.616 if (cu_id == 0)617 continue;618 619 if (cu_id == sc.comp_unit->GetID())620 num_added += ParseVariables(sc, *result);621 }622 }623 624 // FIXME: A `file static` or `global constant` variable appears both in625 // compiland's children and global scope's children with unexpectedly626 // different symbol's Id making it ambiguous.627 628 // FIXME: 'local constant', for example, const char var[] = "abc", declared629 // in a function scope, can't be found in PDB.630 631 // Parse variables in this compiland.632 num_added += ParseVariables(sc, *compiland);633 }634 635 return num_added;636}637 638lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {639 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());640 auto find_result = m_types.find(type_uid);641 if (find_result != m_types.end())642 return find_result->second.get();643 644 auto type_system_or_err =645 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);646 if (auto err = type_system_or_err.takeError()) {647 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),648 "Unable to ResolveTypeUID: {0}");649 return nullptr;650 }651 652 auto ts = *type_system_or_err;653 TypeSystemClang *clang_type_system =654 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());655 if (!clang_type_system)656 return nullptr;657 PDBASTParser *pdb = clang_type_system->GetPDBParser();658 if (!pdb)659 return nullptr;660 661 auto pdb_type = m_session_up->getSymbolById(type_uid);662 if (pdb_type == nullptr)663 return nullptr;664 665 lldb::TypeSP result = pdb->CreateLLDBTypeFromPDBType(*pdb_type);666 if (result) {667 m_types.insert(std::make_pair(type_uid, result));668 }669 return result.get();670}671 672std::optional<SymbolFile::ArrayInfo> SymbolFilePDB::GetDynamicArrayInfoForUID(673 lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) {674 return std::nullopt;675}676 677bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {678 std::lock_guard<std::recursive_mutex> guard(679 GetObjectFile()->GetModule()->GetMutex());680 681 auto type_system_or_err =682 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);683 if (auto err = type_system_or_err.takeError()) {684 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),685 "Unable to get dynamic array info for UID: {0}");686 return false;687 }688 auto ts = *type_system_or_err;689 TypeSystemClang *clang_ast_ctx =690 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());691 692 if (!clang_ast_ctx)693 return false;694 695 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();696 if (!pdb)697 return false;698 699 return pdb->CompleteTypeFromPDB(compiler_type);700}701 702lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {703 auto type_system_or_err =704 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);705 if (auto err = type_system_or_err.takeError()) {706 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),707 "Unable to get decl for UID: {0}");708 return CompilerDecl();709 }710 auto ts = *type_system_or_err;711 TypeSystemClang *clang_ast_ctx =712 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());713 if (!clang_ast_ctx)714 return CompilerDecl();715 716 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();717 if (!pdb)718 return CompilerDecl();719 720 auto symbol = m_session_up->getSymbolById(uid);721 if (!symbol)722 return CompilerDecl();723 724 auto decl = pdb->GetDeclForSymbol(*symbol);725 if (!decl)726 return CompilerDecl();727 728 return clang_ast_ctx->GetCompilerDecl(decl);729}730 731lldb_private::CompilerDeclContext732SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {733 auto type_system_or_err =734 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);735 if (auto err = type_system_or_err.takeError()) {736 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),737 "Unable to get DeclContext for UID: {0}");738 return CompilerDeclContext();739 }740 741 auto ts = *type_system_or_err;742 TypeSystemClang *clang_ast_ctx =743 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());744 if (!clang_ast_ctx)745 return CompilerDeclContext();746 747 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();748 if (!pdb)749 return CompilerDeclContext();750 751 auto symbol = m_session_up->getSymbolById(uid);752 if (!symbol)753 return CompilerDeclContext();754 755 auto decl_context = pdb->GetDeclContextForSymbol(*symbol);756 if (!decl_context)757 return GetDeclContextContainingUID(uid);758 759 return clang_ast_ctx->CreateDeclContext(decl_context);760}761 762lldb_private::CompilerDeclContext763SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {764 auto type_system_or_err =765 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);766 if (auto err = type_system_or_err.takeError()) {767 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),768 "Unable to get DeclContext containing UID: {0}");769 return CompilerDeclContext();770 }771 772 auto ts = *type_system_or_err;773 TypeSystemClang *clang_ast_ctx =774 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());775 if (!clang_ast_ctx)776 return CompilerDeclContext();777 778 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();779 if (!pdb)780 return CompilerDeclContext();781 782 auto symbol = m_session_up->getSymbolById(uid);783 if (!symbol)784 return CompilerDeclContext();785 786 auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol);787 assert(decl_context);788 789 return clang_ast_ctx->CreateDeclContext(decl_context);790}791 792void SymbolFilePDB::ParseDeclsForContext(793 lldb_private::CompilerDeclContext decl_ctx) {794 auto type_system_or_err =795 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);796 if (auto err = type_system_or_err.takeError()) {797 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),798 "Unable to parse decls for context: {0}");799 return;800 }801 802 auto ts = *type_system_or_err;803 TypeSystemClang *clang_ast_ctx =804 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());805 if (!clang_ast_ctx)806 return;807 808 PDBASTParser *pdb = clang_ast_ctx->GetPDBParser();809 if (!pdb)810 return;811 812 pdb->ParseDeclsForDeclContext(813 static_cast<clang::DeclContext *>(decl_ctx.GetOpaqueDeclContext()));814}815 816uint32_t817SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr,818 SymbolContextItem resolve_scope,819 lldb_private::SymbolContext &sc) {820 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());821 uint32_t resolved_flags = 0;822 if (resolve_scope & eSymbolContextCompUnit ||823 resolve_scope & eSymbolContextVariable ||824 resolve_scope & eSymbolContextFunction ||825 resolve_scope & eSymbolContextBlock ||826 resolve_scope & eSymbolContextLineEntry) {827 auto cu_sp = GetCompileUnitContainsAddress(so_addr);828 if (!cu_sp) {829 if (resolved_flags & eSymbolContextVariable) {830 // TODO: Resolve variables831 }832 return 0;833 }834 sc.comp_unit = cu_sp.get();835 resolved_flags |= eSymbolContextCompUnit;836 lldbassert(sc.module_sp == cu_sp->GetModule());837 }838 839 if (resolve_scope & eSymbolContextFunction ||840 resolve_scope & eSymbolContextBlock) {841 addr_t file_vm_addr = so_addr.GetFileAddress();842 auto symbol_up =843 m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function);844 if (symbol_up) {845 auto *pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());846 assert(pdb_func);847 auto func_uid = pdb_func->getSymIndexId();848 sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();849 if (sc.function == nullptr)850 sc.function =851 ParseCompileUnitFunctionForPDBFunc(*pdb_func, *sc.comp_unit);852 if (sc.function) {853 resolved_flags |= eSymbolContextFunction;854 if (resolve_scope & eSymbolContextBlock) {855 auto block_symbol = m_session_up->findSymbolByAddress(856 file_vm_addr, PDB_SymType::Block);857 auto block_id = block_symbol ? block_symbol->getSymIndexId()858 : sc.function->GetID();859 sc.block = sc.function->GetBlock(true).FindBlockByID(block_id);860 if (sc.block)861 resolved_flags |= eSymbolContextBlock;862 }863 }864 }865 }866 867 if (resolve_scope & eSymbolContextLineEntry) {868 if (auto *line_table = sc.comp_unit->GetLineTable()) {869 Address addr(so_addr);870 if (line_table->FindLineEntryByAddress(addr, sc.line_entry))871 resolved_flags |= eSymbolContextLineEntry;872 }873 }874 875 return resolved_flags;876}877 878uint32_t SymbolFilePDB::ResolveSymbolContext(879 const lldb_private::SourceLocationSpec &src_location_spec,880 SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) {881 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());882 const size_t old_size = sc_list.GetSize();883 const FileSpec &file_spec = src_location_spec.GetFileSpec();884 const uint32_t line = src_location_spec.GetLine().value_or(0);885 if (resolve_scope & lldb::eSymbolContextCompUnit) {886 // Locate all compilation units with line numbers referencing the specified887 // file. For example, if `file_spec` is <vector>, then this should return888 // all source files and header files that reference <vector>, either889 // directly or indirectly.890 auto compilands = m_session_up->findCompilandsForSourceFile(891 file_spec.GetPath(), PDB_NameSearchFlags::NS_CaseInsensitive);892 893 if (!compilands)894 return 0;895 896 // For each one, either find its previously parsed data or parse it afresh897 // and add it to the symbol context list.898 while (auto compiland = compilands->getNext()) {899 // If we're not checking inlines, then don't add line information for900 // this file unless the FileSpec matches. For inline functions, we don't901 // have to match the FileSpec since they could be defined in headers902 // other than file specified in FileSpec.903 if (!src_location_spec.GetCheckInlines()) {904 std::string source_file = compiland->getSourceFileFullPath();905 if (source_file.empty())906 continue;907 FileSpec this_spec(source_file, FileSpec::Style::windows);908 bool need_full_match = !file_spec.GetDirectory().IsEmpty();909 if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0)910 continue;911 }912 913 SymbolContext sc;914 auto cu = ParseCompileUnitForUID(compiland->getSymIndexId());915 if (!cu)916 continue;917 sc.comp_unit = cu.get();918 sc.module_sp = cu->GetModule();919 920 // If we were asked to resolve line entries, add all entries to the line921 // table that match the requested line (or all lines if `line` == 0).922 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock |923 eSymbolContextLineEntry)) {924 bool has_line_table = ParseCompileUnitLineTable(*sc.comp_unit, line);925 926 if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) {927 // The query asks for line entries, but we can't get them for the928 // compile unit. This is not normal for `line` = 0. So just assert929 // it.930 assert(line && "Couldn't get all line entries!\n");931 932 // Current compiland does not have the requested line. Search next.933 continue;934 }935 936 if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock)) {937 if (!has_line_table)938 continue;939 940 auto *line_table = sc.comp_unit->GetLineTable();941 lldbassert(line_table);942 943 uint32_t num_line_entries = line_table->GetSize();944 // Skip the terminal line entry.945 --num_line_entries;946 947 // If `line `!= 0, see if we can resolve function for each line entry948 // in the line table.949 for (uint32_t line_idx = 0; line && line_idx < num_line_entries;950 ++line_idx) {951 if (!line_table->GetLineEntryAtIndex(line_idx, sc.line_entry))952 continue;953 954 auto file_vm_addr =955 sc.line_entry.range.GetBaseAddress().GetFileAddress();956 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)957 continue;958 959 auto symbol_up = m_session_up->findSymbolByAddress(960 file_vm_addr, PDB_SymType::Function);961 if (symbol_up) {962 auto func_uid = symbol_up->getSymIndexId();963 sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get();964 if (sc.function == nullptr) {965 auto pdb_func = llvm::dyn_cast<PDBSymbolFunc>(symbol_up.get());966 assert(pdb_func);967 sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func,968 *sc.comp_unit);969 }970 if (sc.function && (resolve_scope & eSymbolContextBlock)) {971 Block &block = sc.function->GetBlock(true);972 sc.block = block.FindBlockByID(sc.function->GetID());973 }974 }975 sc_list.Append(sc);976 }977 } else if (has_line_table) {978 // We can parse line table for the compile unit. But no query to979 // resolve function or block. We append `sc` to the list anyway.980 sc_list.Append(sc);981 }982 } else {983 // No query for line entry, function or block. But we have a valid984 // compile unit, append `sc` to the list.985 sc_list.Append(sc);986 }987 }988 }989 return sc_list.GetSize() - old_size;990}991 992std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) {993 // Cache public names at first994 if (m_public_names.empty())995 if (auto result_up =996 m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol))997 while (auto symbol_up = result_up->getNext())998 if (auto addr = symbol_up->getRawSymbol().getVirtualAddress())999 m_public_names[addr] = symbol_up->getRawSymbol().getName();1000 1001 // Look up the name in the cache1002 return m_public_names.lookup(pdb_data.getVirtualAddress());1003}1004 1005VariableSP SymbolFilePDB::ParseVariableForPDBData(1006 const lldb_private::SymbolContext &sc,1007 const llvm::pdb::PDBSymbolData &pdb_data) {1008 VariableSP var_sp;1009 uint32_t var_uid = pdb_data.getSymIndexId();1010 auto result = m_variables.find(var_uid);1011 if (result != m_variables.end())1012 return result->second;1013 1014 ValueType scope = eValueTypeInvalid;1015 bool is_static_member = false;1016 bool is_external = false;1017 bool is_artificial = false;1018 1019 switch (pdb_data.getDataKind()) {1020 case PDB_DataKind::Global:1021 scope = eValueTypeVariableGlobal;1022 is_external = true;1023 break;1024 case PDB_DataKind::Local:1025 scope = eValueTypeVariableLocal;1026 break;1027 case PDB_DataKind::FileStatic:1028 scope = eValueTypeVariableStatic;1029 break;1030 case PDB_DataKind::StaticMember:1031 is_static_member = true;1032 scope = eValueTypeVariableStatic;1033 break;1034 case PDB_DataKind::Member:1035 scope = eValueTypeVariableStatic;1036 break;1037 case PDB_DataKind::Param:1038 scope = eValueTypeVariableArgument;1039 break;1040 case PDB_DataKind::Constant:1041 scope = eValueTypeConstResult;1042 break;1043 default:1044 break;1045 }1046 1047 switch (pdb_data.getLocationType()) {1048 case PDB_LocType::TLS:1049 scope = eValueTypeVariableThreadLocal;1050 break;1051 case PDB_LocType::RegRel: {1052 // It is a `this` pointer.1053 if (pdb_data.getDataKind() == PDB_DataKind::ObjectPtr) {1054 scope = eValueTypeVariableArgument;1055 is_artificial = true;1056 }1057 } break;1058 default:1059 break;1060 }1061 1062 Declaration decl;1063 if (!is_artificial && !pdb_data.isCompilerGenerated()) {1064 if (auto lines = pdb_data.getLineNumbers()) {1065 if (auto first_line = lines->getNext()) {1066 uint32_t src_file_id = first_line->getSourceFileId();1067 auto src_file = m_session_up->getSourceFileById(src_file_id);1068 if (src_file) {1069 FileSpec spec(src_file->getFileName());1070 decl.SetFile(spec);1071 decl.SetColumn(first_line->getColumnNumber());1072 decl.SetLine(first_line->getLineNumber());1073 }1074 }1075 }1076 }1077 1078 Variable::RangeList ranges;1079 SymbolContextScope *context_scope = sc.comp_unit;1080 if (scope == eValueTypeVariableLocal || scope == eValueTypeVariableArgument) {1081 if (sc.function) {1082 Block &function_block = sc.function->GetBlock(true);1083 Block *block =1084 function_block.FindBlockByID(pdb_data.getLexicalParentId());1085 if (!block)1086 block = &function_block;1087 1088 context_scope = block;1089 1090 for (size_t i = 0, num_ranges = block->GetNumRanges(); i < num_ranges;1091 ++i) {1092 AddressRange range;1093 if (!block->GetRangeAtIndex(i, range))1094 continue;1095 1096 ranges.Append(range.GetBaseAddress().GetFileAddress(),1097 range.GetByteSize());1098 }1099 }1100 }1101 1102 SymbolFileTypeSP type_sp =1103 std::make_shared<SymbolFileType>(*this, pdb_data.getTypeId());1104 1105 auto var_name = pdb_data.getName();1106 auto mangled = GetMangledForPDBData(pdb_data);1107 auto mangled_cstr = mangled.empty() ? nullptr : mangled.c_str();1108 1109 bool is_constant;1110 ModuleSP module_sp = GetObjectFile()->GetModule();1111 DWARFExpressionList location(module_sp,1112 ConvertPDBLocationToDWARFExpression(1113 module_sp, pdb_data, ranges, is_constant),1114 nullptr);1115 1116 var_sp = std::make_shared<Variable>(1117 var_uid, var_name.c_str(), mangled_cstr, type_sp, scope, context_scope,1118 ranges, &decl, location, is_external, is_artificial, is_constant,1119 is_static_member);1120 1121 m_variables.insert(std::make_pair(var_uid, var_sp));1122 return var_sp;1123}1124 1125size_t1126SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc,1127 const llvm::pdb::PDBSymbol &pdb_symbol,1128 lldb_private::VariableList *variable_list) {1129 size_t num_added = 0;1130 1131 if (auto pdb_data = llvm::dyn_cast<PDBSymbolData>(&pdb_symbol)) {1132 VariableListSP local_variable_list_sp;1133 1134 auto result = m_variables.find(pdb_data->getSymIndexId());1135 if (result != m_variables.end()) {1136 if (variable_list)1137 variable_list->AddVariableIfUnique(result->second);1138 } else {1139 // Prepare right VariableList for this variable.1140 if (auto lexical_parent = pdb_data->getLexicalParent()) {1141 switch (lexical_parent->getSymTag()) {1142 case PDB_SymType::Exe:1143 assert(sc.comp_unit);1144 [[fallthrough]];1145 case PDB_SymType::Compiland: {1146 if (sc.comp_unit) {1147 local_variable_list_sp = sc.comp_unit->GetVariableList(false);1148 if (!local_variable_list_sp) {1149 local_variable_list_sp = std::make_shared<VariableList>();1150 sc.comp_unit->SetVariableList(local_variable_list_sp);1151 }1152 }1153 } break;1154 case PDB_SymType::Block:1155 case PDB_SymType::Function: {1156 if (sc.function) {1157 Block *block = sc.function->GetBlock(true).FindBlockByID(1158 lexical_parent->getSymIndexId());1159 if (block) {1160 local_variable_list_sp = block->GetBlockVariableList(false);1161 if (!local_variable_list_sp) {1162 local_variable_list_sp = std::make_shared<VariableList>();1163 block->SetVariableList(local_variable_list_sp);1164 }1165 }1166 }1167 } break;1168 default:1169 break;1170 }1171 }1172 1173 if (local_variable_list_sp) {1174 if (auto var_sp = ParseVariableForPDBData(sc, *pdb_data)) {1175 local_variable_list_sp->AddVariableIfUnique(var_sp);1176 if (variable_list)1177 variable_list->AddVariableIfUnique(var_sp);1178 ++num_added;1179 PDBASTParser *ast = GetPDBAstParser();1180 if (ast)1181 ast->GetDeclForSymbol(*pdb_data);1182 }1183 }1184 }1185 }1186 1187 if (auto results = pdb_symbol.findAllChildren()) {1188 while (auto result = results->getNext())1189 num_added += ParseVariables(sc, *result, variable_list);1190 }1191 1192 return num_added;1193}1194 1195void SymbolFilePDB::FindGlobalVariables(1196 lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx,1197 uint32_t max_matches, lldb_private::VariableList &variables) {1198 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1199 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))1200 return;1201 if (name.IsEmpty())1202 return;1203 1204 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();1205 if (!results)1206 return;1207 1208 uint32_t matches = 0;1209 size_t old_size = variables.GetSize();1210 while (auto result = results->getNext()) {1211 auto pdb_data = llvm::dyn_cast<PDBSymbolData>(result.get());1212 if (max_matches > 0 && matches >= max_matches)1213 break;1214 1215 SymbolContext sc;1216 sc.module_sp = m_objfile_sp->GetModule();1217 lldbassert(sc.module_sp.get());1218 1219 if (name.GetStringRef() !=1220 MSVCUndecoratedNameParser::DropScope(pdb_data->getName()))1221 continue;1222 1223 sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();1224 // FIXME: We are not able to determine the compile unit.1225 if (sc.comp_unit == nullptr)1226 continue;1227 1228 if (parent_decl_ctx.IsValid() &&1229 GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx)1230 continue;1231 1232 ParseVariables(sc, *pdb_data, &variables);1233 matches = variables.GetSize() - old_size;1234 }1235}1236 1237void SymbolFilePDB::FindGlobalVariables(1238 const lldb_private::RegularExpression ®ex, uint32_t max_matches,1239 lldb_private::VariableList &variables) {1240 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1241 if (!regex.IsValid())1242 return;1243 auto results = m_global_scope_up->findAllChildren<PDBSymbolData>();1244 if (!results)1245 return;1246 1247 uint32_t matches = 0;1248 size_t old_size = variables.GetSize();1249 while (auto pdb_data = results->getNext()) {1250 if (max_matches > 0 && matches >= max_matches)1251 break;1252 1253 auto var_name = pdb_data->getName();1254 if (var_name.empty())1255 continue;1256 if (!regex.Execute(var_name))1257 continue;1258 SymbolContext sc;1259 sc.module_sp = m_objfile_sp->GetModule();1260 lldbassert(sc.module_sp.get());1261 1262 sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get();1263 // FIXME: We are not able to determine the compile unit.1264 if (sc.comp_unit == nullptr)1265 continue;1266 1267 ParseVariables(sc, *pdb_data, &variables);1268 matches = variables.GetSize() - old_size;1269 }1270}1271 1272bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func,1273 bool include_inlines,1274 lldb_private::SymbolContextList &sc_list) {1275 lldb_private::SymbolContext sc;1276 sc.comp_unit = ParseCompileUnitForUID(pdb_func.getCompilandId()).get();1277 if (!sc.comp_unit)1278 return false;1279 sc.module_sp = sc.comp_unit->GetModule();1280 sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, *sc.comp_unit);1281 if (!sc.function)1282 return false;1283 1284 sc_list.Append(sc);1285 return true;1286}1287 1288bool SymbolFilePDB::ResolveFunction(uint32_t uid, bool include_inlines,1289 lldb_private::SymbolContextList &sc_list) {1290 auto pdb_func_up = m_session_up->getConcreteSymbolById<PDBSymbolFunc>(uid);1291 if (!pdb_func_up && !(include_inlines && pdb_func_up->hasInlineAttribute()))1292 return false;1293 return ResolveFunction(*pdb_func_up, include_inlines, sc_list);1294}1295 1296void SymbolFilePDB::CacheFunctionNames() {1297 if (!m_func_full_names.IsEmpty())1298 return;1299 1300 std::map<uint64_t, uint32_t> addr_ids;1301 1302 if (auto results_up = m_global_scope_up->findAllChildren<PDBSymbolFunc>()) {1303 while (auto pdb_func_up = results_up->getNext()) {1304 if (pdb_func_up->isCompilerGenerated())1305 continue;1306 1307 auto name = pdb_func_up->getName();1308 auto demangled_name = pdb_func_up->getUndecoratedName();1309 if (name.empty() && demangled_name.empty())1310 continue;1311 1312 auto uid = pdb_func_up->getSymIndexId();1313 if (!demangled_name.empty() && pdb_func_up->getVirtualAddress())1314 addr_ids.insert(std::make_pair(pdb_func_up->getVirtualAddress(), uid));1315 1316 if (auto parent = pdb_func_up->getClassParent()) {1317 1318 // PDB have symbols for class/struct methods or static methods in Enum1319 // Class. We won't bother to check if the parent is UDT or Enum here.1320 m_func_method_names.Append(ConstString(name), uid);1321 1322 // To search a method name, like NS::Class:MemberFunc, LLDB searches1323 // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does1324 // not have information of this, we extract base names and cache them1325 // by our own effort.1326 llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);1327 if (!basename.empty())1328 m_func_base_names.Append(ConstString(basename), uid);1329 else {1330 m_func_base_names.Append(ConstString(name), uid);1331 }1332 1333 if (!demangled_name.empty())1334 m_func_full_names.Append(ConstString(demangled_name), uid);1335 1336 } else {1337 // Handle not-method symbols.1338 1339 // The function name might contain namespace, or its lexical scope.1340 llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name);1341 if (!basename.empty())1342 m_func_base_names.Append(ConstString(basename), uid);1343 else1344 m_func_base_names.Append(ConstString(name), uid);1345 1346 if (name == "main") {1347 m_func_full_names.Append(ConstString(name), uid);1348 1349 if (!demangled_name.empty() && name != demangled_name) {1350 m_func_full_names.Append(ConstString(demangled_name), uid);1351 m_func_base_names.Append(ConstString(demangled_name), uid);1352 }1353 } else if (!demangled_name.empty()) {1354 m_func_full_names.Append(ConstString(demangled_name), uid);1355 } else {1356 m_func_full_names.Append(ConstString(name), uid);1357 }1358 }1359 }1360 }1361 1362 if (auto results_up =1363 m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>()) {1364 while (auto pub_sym_up = results_up->getNext()) {1365 if (!pub_sym_up->isFunction())1366 continue;1367 auto name = pub_sym_up->getName();1368 if (name.empty())1369 continue;1370 1371 if (Mangled::IsMangledName(name.c_str())) {1372 // PDB public symbol has mangled name for its associated function.1373 if (auto vm_addr = pub_sym_up->getVirtualAddress()) {1374 if (auto it = addr_ids.find(vm_addr); it != addr_ids.end())1375 // Cache mangled name.1376 m_func_full_names.Append(ConstString(name), it->second);1377 }1378 }1379 }1380 }1381 // Sort them before value searching is working properly1382 m_func_full_names.Sort();1383 m_func_full_names.SizeToFit();1384 m_func_method_names.Sort();1385 m_func_method_names.SizeToFit();1386 m_func_base_names.Sort();1387 m_func_base_names.SizeToFit();1388}1389 1390void SymbolFilePDB::FindFunctions(1391 const lldb_private::Module::LookupInfo &lookup_info,1392 const lldb_private::CompilerDeclContext &parent_decl_ctx,1393 bool include_inlines,1394 lldb_private::SymbolContextList &sc_list) {1395 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1396 ConstString name = lookup_info.GetLookupName();1397 FunctionNameType name_type_mask = lookup_info.GetNameTypeMask();1398 lldbassert((name_type_mask & eFunctionNameTypeAuto) == 0);1399 1400 if (name_type_mask & eFunctionNameTypeFull)1401 name = lookup_info.GetName();1402 1403 if (name_type_mask == eFunctionNameTypeNone)1404 return;1405 if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))1406 return;1407 if (name.IsEmpty())1408 return;1409 1410 if (name_type_mask & eFunctionNameTypeFull ||1411 name_type_mask & eFunctionNameTypeBase ||1412 name_type_mask & eFunctionNameTypeMethod) {1413 CacheFunctionNames();1414 1415 std::set<uint32_t> resolved_ids;1416 auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list,1417 &resolved_ids](UniqueCStringMap<uint32_t> &Names) {1418 std::vector<uint32_t> ids;1419 if (!Names.GetValues(name, ids))1420 return;1421 1422 for (uint32_t id : ids) {1423 if (resolved_ids.find(id) != resolved_ids.end())1424 continue;1425 1426 if (parent_decl_ctx.IsValid() &&1427 GetDeclContextContainingUID(id) != parent_decl_ctx)1428 continue;1429 1430 if (ResolveFunction(id, include_inlines, sc_list))1431 resolved_ids.insert(id);1432 }1433 };1434 if (name_type_mask & eFunctionNameTypeFull) {1435 ResolveFn(m_func_full_names);1436 ResolveFn(m_func_base_names);1437 ResolveFn(m_func_method_names);1438 }1439 if (name_type_mask & eFunctionNameTypeBase)1440 ResolveFn(m_func_base_names);1441 if (name_type_mask & eFunctionNameTypeMethod)1442 ResolveFn(m_func_method_names);1443 }1444}1445 1446void SymbolFilePDB::FindFunctions(const lldb_private::RegularExpression ®ex,1447 bool include_inlines,1448 lldb_private::SymbolContextList &sc_list) {1449 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1450 if (!regex.IsValid())1451 return;1452 1453 CacheFunctionNames();1454 1455 std::set<uint32_t> resolved_ids;1456 auto ResolveFn = [®ex, include_inlines, &sc_list, &resolved_ids,1457 this](UniqueCStringMap<uint32_t> &Names) {1458 std::vector<uint32_t> ids;1459 if (Names.GetValues(regex, ids)) {1460 for (auto id : ids) {1461 if (resolved_ids.find(id) == resolved_ids.end())1462 if (ResolveFunction(id, include_inlines, sc_list))1463 resolved_ids.insert(id);1464 }1465 }1466 };1467 ResolveFn(m_func_full_names);1468 ResolveFn(m_func_base_names);1469}1470 1471void SymbolFilePDB::GetMangledNamesForFunction(1472 const std::string &scope_qualified_name,1473 std::vector<lldb_private::ConstString> &mangled_names) {}1474 1475void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {1476 std::set<lldb::addr_t> sym_addresses;1477 for (size_t i = 0; i < symtab.GetNumSymbols(); i++)1478 sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress());1479 1480 auto results = m_global_scope_up->findAllChildren<PDBSymbolPublicSymbol>();1481 if (!results)1482 return;1483 1484 auto section_list =1485 m_objfile_sp->GetModule()->GetObjectFile()->GetSectionList();1486 if (!section_list)1487 return;1488 1489 while (auto pub_symbol = results->getNext()) {1490 auto section_id = pub_symbol->getAddressSection();1491 1492 auto section = section_list->FindSectionByID(section_id);1493 if (!section)1494 continue;1495 1496 auto offset = pub_symbol->getAddressOffset();1497 1498 auto file_addr = section->GetFileAddress() + offset;1499 if (sym_addresses.find(file_addr) != sym_addresses.end())1500 continue;1501 sym_addresses.insert(file_addr);1502 1503 auto size = pub_symbol->getLength();1504 symtab.AddSymbol(1505 Symbol(pub_symbol->getSymIndexId(), // symID1506 pub_symbol->getName().c_str(), // name1507 pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type1508 true, // external1509 false, // is_debug1510 false, // is_trampoline1511 false, // is_artificial1512 section, // section_sp1513 offset, // value1514 size, // size1515 size != 0, // size_is_valid1516 false, // contains_linker_annotations1517 0 // flags1518 ));1519 }1520 1521 symtab.Finalize();1522}1523 1524void SymbolFilePDB::DumpClangAST(Stream &s, llvm::StringRef filter,1525 bool show_color) {1526 auto type_system_or_err =1527 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);1528 if (auto err = type_system_or_err.takeError()) {1529 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),1530 "Unable to dump ClangAST: {0}");1531 return;1532 }1533 1534 auto ts = *type_system_or_err;1535 TypeSystemClang *clang_type_system =1536 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());1537 if (!clang_type_system)1538 return;1539 clang_type_system->Dump(s.AsRawOstream(), filter, show_color);1540}1541 1542void SymbolFilePDB::FindTypesByRegex(1543 const lldb_private::RegularExpression ®ex, uint32_t max_matches,1544 lldb_private::TypeMap &types) {1545 // When searching by regex, we need to go out of our way to limit the search1546 // space as much as possible since this searches EVERYTHING in the PDB,1547 // manually doing regex comparisons. PDB library isn't optimized for regex1548 // searches or searches across multiple symbol types at the same time, so the1549 // best we can do is to search enums, then typedefs, then classes one by one,1550 // and do a regex comparison against each of them.1551 PDB_SymType tags_to_search[] = {PDB_SymType::Enum, PDB_SymType::Typedef,1552 PDB_SymType::UDT};1553 std::unique_ptr<IPDBEnumSymbols> results;1554 1555 uint32_t matches = 0;1556 1557 for (auto tag : tags_to_search) {1558 results = m_global_scope_up->findAllChildren(tag);1559 if (!results)1560 continue;1561 1562 while (auto result = results->getNext()) {1563 if (max_matches > 0 && matches >= max_matches)1564 break;1565 1566 std::string type_name;1567 if (auto enum_type = llvm::dyn_cast<PDBSymbolTypeEnum>(result.get()))1568 type_name = enum_type->getName();1569 else if (auto typedef_type =1570 llvm::dyn_cast<PDBSymbolTypeTypedef>(result.get()))1571 type_name = typedef_type->getName();1572 else if (auto class_type = llvm::dyn_cast<PDBSymbolTypeUDT>(result.get()))1573 type_name = class_type->getName();1574 else {1575 // We're looking only for types that have names. Skip symbols, as well1576 // as unnamed types such as arrays, pointers, etc.1577 continue;1578 }1579 1580 if (!regex.Execute(type_name))1581 continue;1582 1583 // This should cause the type to get cached and stored in the `m_types`1584 // lookup.1585 if (!ResolveTypeUID(result->getSymIndexId()))1586 continue;1587 1588 auto iter = m_types.find(result->getSymIndexId());1589 if (iter == m_types.end())1590 continue;1591 types.Insert(iter->second);1592 ++matches;1593 }1594 }1595}1596 1597void SymbolFilePDB::FindTypes(const lldb_private::TypeQuery &query,1598 lldb_private::TypeResults &type_results) {1599 1600 // Make sure we haven't already searched this SymbolFile before.1601 if (type_results.AlreadySearched(this))1602 return;1603 1604 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1605 1606 std::unique_ptr<IPDBEnumSymbols> results;1607 llvm::StringRef basename = query.GetTypeBasename().GetStringRef();1608 if (basename.empty())1609 return;1610 results = m_global_scope_up->findAllChildren(PDB_SymType::None);1611 if (!results)1612 return;1613 1614 while (auto result = results->getNext()) {1615 1616 switch (result->getSymTag()) {1617 case PDB_SymType::Enum:1618 case PDB_SymType::UDT:1619 case PDB_SymType::Typedef:1620 break;1621 default:1622 // We're looking only for types that have names. Skip symbols, as well1623 // as unnamed types such as arrays, pointers, etc.1624 continue;1625 }1626 1627 if (MSVCUndecoratedNameParser::DropScope(1628 result->getRawSymbol().getName()) != basename)1629 continue;1630 1631 // This should cause the type to get cached and stored in the `m_types`1632 // lookup.1633 if (!ResolveTypeUID(result->getSymIndexId()))1634 continue;1635 1636 auto iter = m_types.find(result->getSymIndexId());1637 if (iter == m_types.end())1638 continue;1639 // We resolved a type. Get the fully qualified name to ensure it matches.1640 ConstString name = iter->second->GetQualifiedName();1641 TypeQuery type_match(name.GetStringRef(), TypeQueryOptions::e_exact_match);1642 if (query.ContextMatches(type_match.GetContextRef())) {1643 type_results.InsertUnique(iter->second);1644 if (type_results.Done(query))1645 return;1646 }1647 }1648}1649 1650void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,1651 uint32_t type_mask,1652 TypeCollection &type_collection) {1653 bool can_parse = false;1654 switch (pdb_symbol.getSymTag()) {1655 case PDB_SymType::ArrayType:1656 can_parse = ((type_mask & eTypeClassArray) != 0);1657 break;1658 case PDB_SymType::BuiltinType:1659 can_parse = ((type_mask & eTypeClassBuiltin) != 0);1660 break;1661 case PDB_SymType::Enum:1662 can_parse = ((type_mask & eTypeClassEnumeration) != 0);1663 break;1664 case PDB_SymType::Function:1665 case PDB_SymType::FunctionSig:1666 can_parse = ((type_mask & eTypeClassFunction) != 0);1667 break;1668 case PDB_SymType::PointerType:1669 can_parse = ((type_mask & (eTypeClassPointer | eTypeClassBlockPointer |1670 eTypeClassMemberPointer)) != 0);1671 break;1672 case PDB_SymType::Typedef:1673 can_parse = ((type_mask & eTypeClassTypedef) != 0);1674 break;1675 case PDB_SymType::UDT: {1676 auto *udt = llvm::dyn_cast<PDBSymbolTypeUDT>(&pdb_symbol);1677 assert(udt);1678 can_parse = (udt->getUdtKind() != PDB_UdtType::Interface &&1679 ((type_mask & (eTypeClassClass | eTypeClassStruct |1680 eTypeClassUnion)) != 0));1681 } break;1682 default:1683 break;1684 }1685 1686 if (can_parse) {1687 if (auto *type = ResolveTypeUID(pdb_symbol.getSymIndexId())) {1688 if (!llvm::is_contained(type_collection, type))1689 type_collection.push_back(type);1690 }1691 }1692 1693 auto results_up = pdb_symbol.findAllChildren();1694 while (auto symbol_up = results_up->getNext())1695 GetTypesForPDBSymbol(*symbol_up, type_mask, type_collection);1696}1697 1698void SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,1699 TypeClass type_mask,1700 lldb_private::TypeList &type_list) {1701 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1702 TypeCollection type_collection;1703 CompileUnit *cu =1704 sc_scope ? sc_scope->CalculateSymbolContextCompileUnit() : nullptr;1705 if (cu) {1706 auto compiland_up = GetPDBCompilandByUID(cu->GetID());1707 if (!compiland_up)1708 return;1709 GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);1710 } else {1711 for (uint32_t cu_idx = 0; cu_idx < GetNumCompileUnits(); ++cu_idx) {1712 auto cu_sp = ParseCompileUnitAtIndex(cu_idx);1713 if (cu_sp) {1714 if (auto compiland_up = GetPDBCompilandByUID(cu_sp->GetID()))1715 GetTypesForPDBSymbol(*compiland_up, type_mask, type_collection);1716 }1717 }1718 }1719 1720 for (auto type : type_collection) {1721 type->GetForwardCompilerType();1722 type_list.Insert(type->shared_from_this());1723 }1724}1725 1726llvm::Expected<lldb::TypeSystemSP>1727SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {1728 auto type_system_or_err =1729 m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);1730 if (type_system_or_err) {1731 if (auto ts = *type_system_or_err)1732 ts->SetSymbolFile(this);1733 }1734 return type_system_or_err;1735}1736 1737PDBASTParser *SymbolFilePDB::GetPDBAstParser() {1738 auto type_system_or_err =1739 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);1740 if (auto err = type_system_or_err.takeError()) {1741 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),1742 "Unable to get PDB AST parser: {0}");1743 return nullptr;1744 }1745 1746 auto ts = *type_system_or_err;1747 auto *clang_type_system =1748 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());1749 if (!clang_type_system)1750 return nullptr;1751 1752 return clang_type_system->GetPDBParser();1753}1754 1755lldb_private::CompilerDeclContext1756SymbolFilePDB::FindNamespace(lldb_private::ConstString name,1757 const CompilerDeclContext &parent_decl_ctx, bool) {1758 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());1759 auto type_system_or_err =1760 GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);1761 if (auto err = type_system_or_err.takeError()) {1762 LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),1763 "Unable to find namespace {1}: {0}", name.AsCString());1764 return CompilerDeclContext();1765 }1766 auto ts = *type_system_or_err;1767 auto *clang_type_system =1768 llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());1769 if (!clang_type_system)1770 return CompilerDeclContext();1771 1772 PDBASTParser *pdb = clang_type_system->GetPDBParser();1773 if (!pdb)1774 return CompilerDeclContext();1775 1776 clang::DeclContext *decl_context = nullptr;1777 if (parent_decl_ctx)1778 decl_context = static_cast<clang::DeclContext *>(1779 parent_decl_ctx.GetOpaqueDeclContext());1780 1781 auto namespace_decl =1782 pdb->FindNamespaceDecl(decl_context, name.GetStringRef());1783 if (!namespace_decl)1784 return CompilerDeclContext();1785 1786 return clang_type_system->CreateDeclContext(namespace_decl);1787}1788 1789IPDBSession &SymbolFilePDB::GetPDBSession() { return *m_session_up; }1790 1791const IPDBSession &SymbolFilePDB::GetPDBSession() const {1792 return *m_session_up;1793}1794 1795lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id,1796 uint32_t index) {1797 auto found_cu = m_comp_units.find(id);1798 if (found_cu != m_comp_units.end())1799 return found_cu->second;1800 1801 auto compiland_up = GetPDBCompilandByUID(id);1802 if (!compiland_up)1803 return CompUnitSP();1804 1805 lldb::LanguageType lang;1806 auto details = compiland_up->findOneChild<PDBSymbolCompilandDetails>();1807 if (!details)1808 lang = lldb::eLanguageTypeC_plus_plus;1809 else1810 lang = TranslateLanguage(details->getLanguage());1811 1812 if (lang == lldb::LanguageType::eLanguageTypeUnknown)1813 return CompUnitSP();1814 1815 std::string path = compiland_up->getSourceFileFullPath();1816 if (path.empty())1817 return CompUnitSP();1818 1819 // Don't support optimized code for now, DebugInfoPDB does not return this1820 // information.1821 LazyBool optimized = eLazyBoolNo;1822 auto cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr,1823 path.c_str(), id, lang, optimized);1824 1825 if (!cu_sp)1826 return CompUnitSP();1827 1828 m_comp_units.insert(std::make_pair(id, cu_sp));1829 if (index == UINT32_MAX)1830 GetCompileUnitIndex(*compiland_up, index);1831 lldbassert(index != UINT32_MAX);1832 SetCompileUnitAtIndex(index, cu_sp);1833 return cu_sp;1834}1835 1836bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit,1837 uint32_t match_line) {1838 auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID());1839 if (!compiland_up)1840 return false;1841 1842 // LineEntry needs the *index* of the file into the list of support files1843 // returned by ParseCompileUnitSupportFiles. But the underlying SDK gives us1844 // a globally unique idenfitifier in the namespace of the PDB. So, we have1845 // to do a mapping so that we can hand out indices.1846 llvm::DenseMap<uint32_t, uint32_t> index_map;1847 BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map);1848 auto line_table = std::make_unique<LineTable>(&comp_unit);1849 1850 // Find contributions to `compiland` from all source and header files.1851 auto files = m_session_up->getSourceFilesForCompiland(*compiland_up);1852 if (!files)1853 return false;1854 1855 // For each source and header file, create a LineTable::Sequence for1856 // contributions to the compiland from that file, and add the sequence.1857 while (auto file = files->getNext()) {1858 LineTable::Sequence sequence;1859 auto lines = m_session_up->findLineNumbers(*compiland_up, *file);1860 if (!lines)1861 continue;1862 int entry_count = lines->getChildCount();1863 1864 uint64_t prev_addr;1865 uint32_t prev_length;1866 uint32_t prev_line;1867 uint32_t prev_source_idx;1868 1869 for (int i = 0; i < entry_count; ++i) {1870 auto line = lines->getChildAtIndex(i);1871 1872 uint64_t lno = line->getLineNumber();1873 uint64_t addr = line->getVirtualAddress();1874 uint32_t length = line->getLength();1875 uint32_t source_id = line->getSourceFileId();1876 uint32_t col = line->getColumnNumber();1877 uint32_t source_idx = index_map[source_id];1878 1879 // There was a gap between the current entry and the previous entry if1880 // the addresses don't perfectly line up.1881 bool is_gap = (i > 0) && (prev_addr + prev_length < addr);1882 1883 // Before inserting the current entry, insert a terminal entry at the end1884 // of the previous entry's address range if the current entry resulted in1885 // a gap from the previous entry.1886 if (is_gap && ShouldAddLine(match_line, prev_line, prev_length)) {1887 line_table->AppendLineEntryToSequence(sequence, prev_addr + prev_length,1888 prev_line, 0, prev_source_idx,1889 false, false, false, false, true);1890 1891 line_table->InsertSequence(std::move(sequence));1892 }1893 1894 if (ShouldAddLine(match_line, lno, length)) {1895 bool is_statement = line->isStatement();1896 bool is_prologue = false;1897 bool is_epilogue = false;1898 auto func =1899 m_session_up->findSymbolByAddress(addr, PDB_SymType::Function);1900 if (func) {1901 auto prologue = func->findOneChild<PDBSymbolFuncDebugStart>();1902 if (prologue)1903 is_prologue = (addr == prologue->getVirtualAddress());1904 1905 auto epilogue = func->findOneChild<PDBSymbolFuncDebugEnd>();1906 if (epilogue)1907 is_epilogue = (addr == epilogue->getVirtualAddress());1908 }1909 1910 line_table->AppendLineEntryToSequence(sequence, addr, lno, col,1911 source_idx, is_statement, false,1912 is_prologue, is_epilogue, false);1913 }1914 1915 prev_addr = addr;1916 prev_length = length;1917 prev_line = lno;1918 prev_source_idx = source_idx;1919 }1920 1921 if (entry_count > 0 && ShouldAddLine(match_line, prev_line, prev_length)) {1922 // The end is always a terminal entry, so insert it regardless.1923 line_table->AppendLineEntryToSequence(sequence, prev_addr + prev_length,1924 prev_line, 0, prev_source_idx,1925 false, false, false, false, true);1926 }1927 1928 line_table->InsertSequence(std::move(sequence));1929 }1930 1931 if (line_table->GetSize()) {1932 comp_unit.SetLineTable(line_table.release());1933 return true;1934 }1935 return false;1936}1937 1938void SymbolFilePDB::BuildSupportFileIdToSupportFileIndexMap(1939 const PDBSymbolCompiland &compiland,1940 llvm::DenseMap<uint32_t, uint32_t> &index_map) const {1941 // This is a hack, but we need to convert the source id into an index into1942 // the support files array. We don't want to do path comparisons to avoid1943 // basename / full path issues that may or may not even be a problem, so we1944 // use the globally unique source file identifiers. Ideally we could use the1945 // global identifiers everywhere, but LineEntry currently assumes indices.1946 auto source_files = m_session_up->getSourceFilesForCompiland(compiland);1947 if (!source_files)1948 return;1949 1950 int index = 0;1951 while (auto file = source_files->getNext()) {1952 uint32_t source_id = file->getUniqueId();1953 index_map[source_id] = index++;1954 }1955}1956 1957lldb::CompUnitSP SymbolFilePDB::GetCompileUnitContainsAddress(1958 const lldb_private::Address &so_addr) {1959 lldb::addr_t file_vm_addr = so_addr.GetFileAddress();1960 if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0)1961 return nullptr;1962 1963 // If it is a PDB function's vm addr, this is the first sure bet.1964 if (auto lines =1965 m_session_up->findLineNumbersByAddress(file_vm_addr, /*Length=*/1)) {1966 if (auto first_line = lines->getNext())1967 return ParseCompileUnitForUID(first_line->getCompilandId());1968 }1969 1970 // Otherwise we resort to section contributions.1971 if (auto sec_contribs = m_session_up->getSectionContribs()) {1972 while (auto section = sec_contribs->getNext()) {1973 auto va = section->getVirtualAddress();1974 if (file_vm_addr >= va && file_vm_addr < va + section->getLength())1975 return ParseCompileUnitForUID(section->getCompilandId());1976 }1977 }1978 return nullptr;1979}1980 1981Mangled1982SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) {1983 Mangled mangled;1984 auto func_name = pdb_func.getName();1985 auto func_undecorated_name = pdb_func.getUndecoratedName();1986 std::string func_decorated_name;1987 1988 // Seek from public symbols for non-static function's decorated name if any.1989 // For static functions, they don't have undecorated names and aren't exposed1990 // in Public Symbols either.1991 if (!func_undecorated_name.empty()) {1992 auto result_up = m_global_scope_up->findChildren(1993 PDB_SymType::PublicSymbol, func_undecorated_name,1994 PDB_NameSearchFlags::NS_UndecoratedName);1995 if (result_up) {1996 while (auto symbol_up = result_up->getNext()) {1997 // For a public symbol, it is unique.1998 lldbassert(result_up->getChildCount() == 1);1999 if (auto *pdb_public_sym =2000 llvm::dyn_cast_or_null<PDBSymbolPublicSymbol>(2001 symbol_up.get())) {2002 if (pdb_public_sym->isFunction()) {2003 func_decorated_name = pdb_public_sym->getName();2004 break;2005 }2006 }2007 }2008 }2009 }2010 if (!func_decorated_name.empty()) {2011 mangled.SetMangledName(ConstString(func_decorated_name));2012 2013 // For MSVC, format of C function's decorated name depends on calling2014 // convention. Unfortunately none of the format is recognized by current2015 // LLDB. For example, `_purecall` is a __cdecl C function. From PDB,2016 // `__purecall` is retrieved as both its decorated and undecorated name2017 // (using PDBSymbolFunc::getUndecoratedName method). However `__purecall`2018 // string is not treated as mangled in LLDB (neither `?` nor `_Z` prefix).2019 // Mangled::GetDemangledName method will fail internally and caches an2020 // empty string as its undecorated name. So we will face a contradiction2021 // here for the same symbol:2022 // non-empty undecorated name from PDB2023 // empty undecorated name from LLDB2024 if (!func_undecorated_name.empty() && mangled.GetDemangledName().IsEmpty())2025 mangled.SetDemangledName(ConstString(func_undecorated_name));2026 2027 // LLDB uses several flags to control how a C++ decorated name is2028 // undecorated for MSVC. See `safeUndecorateName` in Class Mangled. So the2029 // yielded name could be different from what we retrieve from2030 // PDB source unless we also apply same flags in getting undecorated2031 // name through PDBSymbolFunc::getUndecoratedNameEx method.2032 if (!func_undecorated_name.empty() &&2033 mangled.GetDemangledName() != ConstString(func_undecorated_name))2034 mangled.SetDemangledName(ConstString(func_undecorated_name));2035 } else if (!func_undecorated_name.empty()) {2036 mangled.SetDemangledName(ConstString(func_undecorated_name));2037 } else if (!func_name.empty())2038 mangled.SetValue(ConstString(func_name));2039 2040 return mangled;2041}2042 2043bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(2044 const lldb_private::CompilerDeclContext &decl_ctx) {2045 if (!decl_ctx.IsValid())2046 return true;2047 2048 TypeSystem *decl_ctx_type_system = decl_ctx.GetTypeSystem();2049 if (!decl_ctx_type_system)2050 return false;2051 auto type_system_or_err = GetTypeSystemForLanguage(2052 decl_ctx_type_system->GetMinimumLanguage(nullptr));2053 if (auto err = type_system_or_err.takeError()) {2054 LLDB_LOG_ERROR(2055 GetLog(LLDBLog::Symbols), std::move(err),2056 "Unable to determine if DeclContext matches this symbol file: {0}");2057 return false;2058 }2059 2060 if (decl_ctx_type_system == type_system_or_err->get())2061 return true; // The type systems match, return true2062 2063 return false;2064}2065 2066uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) {2067 static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) {2068 return lhs < rhs.Offset;2069 };2070 2071 // Cache section contributions2072 if (m_sec_contribs.empty()) {2073 if (auto SecContribs = m_session_up->getSectionContribs()) {2074 while (auto SectionContrib = SecContribs->getNext()) {2075 auto comp_id = SectionContrib->getCompilandId();2076 if (!comp_id)2077 continue;2078 2079 auto sec = SectionContrib->getAddressSection();2080 auto &sec_cs = m_sec_contribs[sec];2081 2082 auto offset = SectionContrib->getAddressOffset();2083 auto it = llvm::upper_bound(sec_cs, offset, pred_upper);2084 2085 auto size = SectionContrib->getLength();2086 sec_cs.insert(it, {offset, size, comp_id});2087 }2088 }2089 }2090 2091 // Check by line number2092 if (auto Lines = data.getLineNumbers()) {2093 if (auto FirstLine = Lines->getNext())2094 return FirstLine->getCompilandId();2095 }2096 2097 // Retrieve section + offset2098 uint32_t DataSection = data.getAddressSection();2099 uint32_t DataOffset = data.getAddressOffset();2100 if (DataSection == 0) {2101 if (auto RVA = data.getRelativeVirtualAddress())2102 m_session_up->addressForRVA(RVA, DataSection, DataOffset);2103 }2104 2105 if (DataSection) {2106 // Search by section contributions2107 auto &sec_cs = m_sec_contribs[DataSection];2108 auto it = llvm::upper_bound(sec_cs, DataOffset, pred_upper);2109 if (it != sec_cs.begin()) {2110 --it;2111 if (DataOffset < it->Offset + it->Size)2112 return it->CompilandId;2113 }2114 } else {2115 // Search in lexical tree2116 auto LexParentId = data.getLexicalParentId();2117 while (auto LexParent = m_session_up->getSymbolById(LexParentId)) {2118 if (LexParent->getSymTag() == PDB_SymType::Exe)2119 break;2120 if (LexParent->getSymTag() == PDB_SymType::Compiland)2121 return LexParentId;2122 LexParentId = LexParent->getRawSymbol().getLexicalParentId();2123 }2124 }2125 2126 return 0;2127}2128