Skip to content

Commit

Permalink
[Symbol] Search symbols with name and type in a symbol file
Browse files Browse the repository at this point in the history
Summary:
This patch adds possibility of searching a public symbol with name and type in a
symbol file. 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: emaste, arichardson, aleksandr.urakov, jingham, lldb-commits, stella.stamenova

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D53368

llvm-svn: 345957
  • Loading branch information
Aleksandr Urakov committed Nov 2, 2018
1 parent 54bb316 commit 15da768
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 24 deletions.
2 changes: 2 additions & 0 deletions lldb/include/lldb/Symbol/SymbolFile.h
Expand Up @@ -214,6 +214,8 @@ class SymbolFile : public PluginInterface {
return {};
}

virtual void AddSymbols(Symtab &symtab) {}

//------------------------------------------------------------------
/// Notify the SymbolFile that the file addresses in the Sections
/// for this module have been changed.
Expand Down
2 changes: 2 additions & 0 deletions lldb/include/lldb/Symbol/SymbolVendor.h
Expand Up @@ -165,6 +165,8 @@ class SymbolVendor : public ModuleChild, public PluginInterface {
// 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:
//------------------------------------------------------------------
Expand Down
2 changes: 0 additions & 2 deletions lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Expand Up @@ -2876,8 +2876,6 @@ Symtab *ObjectFileELF::GetSymtab() {
// do the section lookup next time.
if (m_symtab_ap == nullptr)
m_symtab_ap.reset(new Symtab(this));

m_symtab_ap->CalculateSymbolSizes();
}

return m_symtab_ap.get();
Expand Down
1 change: 0 additions & 1 deletion lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp
Expand Up @@ -124,7 +124,6 @@ Symtab *ObjectFileJIT::GetSymtab() {
if (delegate_sp)
delegate_sp->PopulateSymtab(this, *m_symtab_ap);
// TODO: get symbols from delegate
m_symtab_ap->Finalize();
}
}
return m_symtab_ap.get();
Expand Down
11 changes: 0 additions & 11 deletions lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Expand Up @@ -1315,7 +1315,6 @@ Symtab *ObjectFileMachO::GetSymtab() {
std::lock_guard<std::recursive_mutex> symtab_guard(
m_symtab_ap->GetMutex());
ParseSymtab();
m_symtab_ap->Finalize();
}
}
return m_symtab_ap.get();
Expand Down Expand Up @@ -4807,16 +4806,6 @@ size_t ObjectFileMachO::ParseSymtab() {
}
}

// StreamFile s(stdout, false);
// s.Printf ("Symbol table before CalculateSymbolSizes():\n");
// symtab->Dump(&s, NULL, eSortOrderNone);
// Set symbol byte sizes correctly since mach-o nlist entries don't have
// sizes
symtab->CalculateSymbolSizes();

// s.Printf ("Symbol table after CalculateSymbolSizes():\n");
// symtab->Dump(&s, NULL, eSortOrderNone);

return symtab->GetNumSymbols();
}
return 0;
Expand Down
1 change: 0 additions & 1 deletion lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
Expand Up @@ -651,7 +651,6 @@ Symtab *ObjectFilePECOFF::GetSymtab() {
symbols[i].SetDebug(true);
}
}
m_symtab_ap->CalculateSymbolSizes();
}
}
return m_symtab_ap.get();
Expand Down
49 changes: 49 additions & 0 deletions lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
Expand Up @@ -1331,6 +1331,55 @@ 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
));
}
}

uint32_t SymbolFilePDB::FindTypes(
const lldb_private::SymbolContext &sc,
const lldb_private::ConstString &name,
Expand Down
2 changes: 2 additions & 0 deletions lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
Expand Up @@ -133,6 +133,8 @@ class SymbolFilePDB : public lldb_private::SymbolFile {
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,
Expand Down
30 changes: 21 additions & 9 deletions lldb/source/Symbol/SymbolVendor.cpp
Expand Up @@ -61,7 +61,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
Expand Down Expand Up @@ -438,14 +438,26 @@ 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);

m_symtab->CalculateSymbolSizes();
m_symtab->Finalize();

return m_symtab;
}

void SymbolVendor::ClearSymtab() {
Expand Down
17 changes: 17 additions & 0 deletions lldb/unittests/SymbolFile/PDB/SymbolFilePDBTests.cpp
Expand Up @@ -621,3 +621,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(), false);
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());
}

0 comments on commit 15da768

Please sign in to comment.