Index: include/lldb/Symbol/SymbolFile.h =================================================================== --- include/lldb/Symbol/SymbolFile.h +++ include/lldb/Symbol/SymbolFile.h @@ -213,6 +213,8 @@ return {}; } + virtual void AddSymbols(Symtab &symtab) {} + //------------------------------------------------------------------ /// Notify the SymbolFile that the file addresses in the Sections /// for this module have been changed. Index: include/lldb/Symbol/SymbolVendor.h =================================================================== --- include/lldb/Symbol/SymbolVendor.h +++ include/lldb/Symbol/SymbolVendor.h @@ -164,6 +164,8 @@ // file) std::unique_ptr m_sym_file_ap; // A single symbol file. Subclasses // can add more of these if needed. + Symtab *m_symtab; // Save a symtab once to not pass it through `AddSymbols` of + // the symbol file each time when it is needed private: //------------------------------------------------------------------ Index: include/lldb/lldb-forward.h =================================================================== --- include/lldb/lldb-forward.h +++ include/lldb/lldb-forward.h @@ -441,6 +441,7 @@ StructuredDataPluginSP; typedef std::weak_ptr StructuredDataPluginWP; +typedef std::shared_ptr SymbolSP; typedef std::shared_ptr SymbolFileSP; typedef std::shared_ptr SymbolFileTypeSP; typedef std::weak_ptr SymbolFileTypeWP; Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -132,6 +132,8 @@ const std::string &scope_qualified_name, std::vector &mangled_names) override; + void AddSymbols(lldb_private::Symtab &symtab) override; + uint32_t FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, @@ -236,9 +238,13 @@ uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data); + lldb_private::Symbol * + GetPublicSymbol(const llvm::pdb::PDBSymbolPublicSymbol &pub_symbol); + llvm::DenseMap m_comp_units; llvm::DenseMap m_types; llvm::DenseMap m_variables; + llvm::DenseMap m_public_symbols; llvm::DenseMap m_public_names; SecContribsMap m_sec_contribs; Index: source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1331,6 +1331,31 @@ const std::string &scope_qualified_name, std::vector &mangled_names) {} +void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { + std::set sym_addresses; + for (size_t i = 0; i < symtab.GetNumSymbols(); i++) + sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress()); + + auto results = m_global_scope_up->findAllChildren(); + if (!results) + return; + + while (auto pub_symbol = results->getNext()) { + auto symbol_ptr = GetPublicSymbol(*pub_symbol); + if (!symbol_ptr) + continue; + + auto file_addr = symbol_ptr->GetFileAddress(); + if (sym_addresses.find(file_addr) != sym_addresses.end()) + continue; + sym_addresses.insert(file_addr); + + symtab.AddSymbol(*symbol_ptr); + } + + symtab.CalculateSymbolSizes(); +} + uint32_t SymbolFilePDB::FindTypes( const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, @@ -1939,3 +1964,45 @@ return 0; } + +lldb_private::Symbol *SymbolFilePDB::GetPublicSymbol( + const llvm::pdb::PDBSymbolPublicSymbol &pub_symbol) { + auto it = m_public_symbols.find(pub_symbol.getSymIndexId()); + if (it != m_public_symbols.end()) + return it->second.get(); + + auto section_list = m_obj_file->GetSectionList(); + if (!section_list) + return nullptr; + + auto section_idx = pub_symbol.getAddressSection() - 1; + if (section_idx >= section_list->GetSize()) + return nullptr; + + auto section = section_list->GetSectionAtIndex(section_idx); + if (!section) + return nullptr; + + auto size = pub_symbol.getLength(); + + auto symbol_sp = std::make_shared( + pub_symbol.getSymIndexId(), // symID + pub_symbol.getName().c_str(), // name + true, // name_is_mangled + pub_symbol.isCode() ? eSymbolTypeCode : eSymbolTypeData, // type + true, // external + false, // is_debug + false, // is_trampoline + false, // is_artificial + section, // section_sp + pub_symbol.getAddressOffset(), // value + size, // size + size != 0, // size_is_valid + false, // contains_linker_annotations + 0 // flags + ); + + m_public_symbols[pub_symbol.getSymIndexId()] = symbol_sp; + + return symbol_sp.get(); +} Index: source/Symbol/SymbolVendor.cpp =================================================================== --- source/Symbol/SymbolVendor.cpp +++ source/Symbol/SymbolVendor.cpp @@ -61,7 +61,7 @@ //---------------------------------------------------------------------- SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) : ModuleChild(module_sp), m_type_list(), m_compile_units(), - m_sym_file_ap() {} + m_sym_file_ap(), m_symtab() {} //---------------------------------------------------------------------- // Destructor @@ -438,14 +438,23 @@ Symtab *SymbolVendor::GetSymtab() { ModuleSP module_sp(GetModule()); - if (module_sp) { - ObjectFile *objfile = module_sp->GetObjectFile(); - if (objfile) { - // Get symbol table from unified section list. - return objfile->GetSymtab(); - } - } - return nullptr; + if (!module_sp) + return nullptr; + + std::lock_guard guard(module_sp->GetMutex()); + + if (m_symtab) + return m_symtab; + + ObjectFile *objfile = module_sp->GetObjectFile(); + if (!objfile) + return nullptr; + + m_symtab = objfile->GetSymtab(); + if (m_symtab && m_sym_file_ap) + m_sym_file_ap->AddSymbols(*m_symtab); + + return m_symtab; } void SymbolVendor::ClearSymtab() { Index: unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp =================================================================== --- unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -616,3 +616,20 @@ EXPECT_EQ(0u, num_results); EXPECT_EQ(0u, results.GetSize()); } + +TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) { + FileSpec fspec(m_pdb_test_exe.c_str(), false); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared(fspec, aspec); + + SymbolContextList sc_list; + EXPECT_EQ(1u, + module->FindSymbolsWithNameAndType(ConstString("?foo@@YAHH@Z"), + lldb::eSymbolTypeAny, sc_list)); + EXPECT_EQ(1u, sc_list.GetSize()); + + SymbolContext sc; + EXPECT_TRUE(sc_list.GetContextAtIndex(0, sc)); + EXPECT_STREQ("int foo(int)", + sc.GetFunctionName(Mangled::ePreferDemangled).AsCString()); +}