summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksandr Urakov <aleksandr.urakov@jetbrains.com>2018-11-30 06:56:37 +0000
committerAleksandr Urakov <aleksandr.urakov@jetbrains.com>2018-11-30 06:56:37 +0000
commite72cb7d00294605d25256abdfa47308888f14946 (patch)
tree99ff6598ef6306e8d8b65f83e5953ed49e3b6a59
parentbeb9d995b35026cc23ed3d1ec6928858090e97ed (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.h2
-rw-r--r--lldb/include/lldb/Symbol/SymbolVendor.h2
-rw-r--r--lldb/source/Core/Address.cpp6
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp52
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h2
-rw-r--r--lldb/source/Symbol/SymbolVendor.cpp27
-rw-r--r--lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp17
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());
+}