diff options
author | Aleksandr Urakov <aleksandr.urakov@jetbrains.com> | 2018-11-30 06:56:37 +0000 |
---|---|---|
committer | Aleksandr Urakov <aleksandr.urakov@jetbrains.com> | 2018-11-30 06:56:37 +0000 |
commit | e72cb7d00294605d25256abdfa47308888f14946 (patch) | |
tree | 99ff6598ef6306e8d8b65f83e5953ed49e3b6a59 | |
parent | beb9d995b35026cc23ed3d1ec6928858090e97ed (diff) |
[Symbol] Search symbols with name and type in a symbol file
Summary:
This patch adds possibility of searching a public symbol with name and type in
a symbol file, not only in a symtab. It is helpful when working with PE, because
PE's symtabs contain only imported / exported symbols only. Such a search is
required for e.g. evaluation of an expression that calls some function of
the debuggee.
Reviewers: zturner, asmith, labath, clayborg, espindola
Reviewed By: clayborg
Subscribers: davide, emaste, arichardson, aleksandr.urakov, jingham,
lldb-commits, stella.stamenova
Tags: #lldb
Differential Revision: https://reviews.llvm.org/D53368
-rw-r--r-- | lldb/include/lldb/Symbol/SymbolFile.h | 2 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/SymbolVendor.h | 2 | ||||
-rw-r--r-- | lldb/source/Core/Address.cpp | 6 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 52 | ||||
-rw-r--r-- | lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h | 2 | ||||
-rw-r--r-- | lldb/source/Symbol/SymbolVendor.cpp | 27 | ||||
-rw-r--r-- | lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp | 17 |
7 files changed, 97 insertions, 11 deletions
diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h index 01bbc388703..30a2e7c4dd6 100644 --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -233,6 +233,8 @@ public: return {}; } + virtual void AddSymbols(Symtab &symtab) {} + //------------------------------------------------------------------ /// Notify the SymbolFile that the file addresses in the Sections /// for this module have been changed. diff --git a/lldb/include/lldb/Symbol/SymbolVendor.h b/lldb/include/lldb/Symbol/SymbolVendor.h index a6e4df58f3f..77733de0823 100644 --- a/lldb/include/lldb/Symbol/SymbolVendor.h +++ b/lldb/include/lldb/Symbol/SymbolVendor.h @@ -165,6 +165,8 @@ protected: // file) std::unique_ptr<SymbolFile> 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: //------------------------------------------------------------------ diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index 0705ac7e177..a4dc364b701 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -988,8 +988,10 @@ AddressClass Address::GetAddressClass() const { if (module_sp) { ObjectFile *obj_file = module_sp->GetObjectFile(); if (obj_file) { - // Give the symbol vendor a chance to add to the unified section list. - module_sp->GetSymbolVendor(); + // Give the symbol vendor a chance to add to the unified section list + // and to symtab from symbol file + if (SymbolVendor *vendor = module_sp->GetSymbolVendor()) + vendor->GetSymtab(); return obj_file->GetAddressClass(GetFileAddress()); } } diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 93ff6e205f2..da878a9c0d1 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1328,6 +1328,58 @@ void SymbolFilePDB::GetMangledNamesForFunction( const std::string &scope_qualified_name, std::vector<lldb_private::ConstString> &mangled_names) {} +void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { + std::set<lldb::addr_t> 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<PDBSymbolPublicSymbol>(); + if (!results) + return; + + auto section_list = m_obj_file->GetSectionList(); + if (!section_list) + return; + + while (auto pub_symbol = results->getNext()) { + auto section_idx = pub_symbol->getAddressSection() - 1; + if (section_idx >= section_list->GetSize()) + continue; + + auto section = section_list->GetSectionAtIndex(section_idx); + if (!section) + continue; + + auto offset = pub_symbol->getAddressOffset(); + + auto file_addr = section->GetFileAddress() + offset; + if (sym_addresses.find(file_addr) != sym_addresses.end()) + continue; + sym_addresses.insert(file_addr); + + auto size = pub_symbol->getLength(); + symtab.AddSymbol( + Symbol(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 + offset, // value + size, // size + size != 0, // size_is_valid + false, // contains_linker_annotations + 0 // flags + )); + } + + symtab.CalculateSymbolSizes(); + symtab.Finalize(); +} + uint32_t SymbolFilePDB::FindTypes( const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 12491e30bf2..e4ca3b6fd24 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -136,6 +136,8 @@ public: const std::string &scope_qualified_name, std::vector<lldb_private::ConstString> &mangled_names) override; + void AddSymbols(lldb_private::Symtab &symtab) override; + uint32_t FindTypes(const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, diff --git a/lldb/source/Symbol/SymbolVendor.cpp b/lldb/source/Symbol/SymbolVendor.cpp index e201b413169..c0d1763d32d 100644 --- a/lldb/source/Symbol/SymbolVendor.cpp +++ b/lldb/source/Symbol/SymbolVendor.cpp @@ -57,7 +57,7 @@ SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp, //---------------------------------------------------------------------- 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 @@ -434,14 +434,23 @@ FileSpec SymbolVendor::GetMainFileSpec() const { 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<std::recursive_mutex> 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() { diff --git a/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp b/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp index 5ad4cff5b2e..32c7002a15c 100644 --- a/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp +++ b/lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp @@ -620,3 +620,20 @@ TEST_F(SymbolFilePDBTests, TestNullName) { EXPECT_EQ(0u, num_results); EXPECT_EQ(0u, results.GetSize()); } + +TEST_F(SymbolFilePDBTests, TestFindSymbolsWithNameAndType) { + FileSpec fspec(m_pdb_test_exe.c_str()); + ArchSpec aspec("i686-pc-windows"); + lldb::ModuleSP module = std::make_shared<Module>(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()); +} |