Skip to content

Commit

Permalink
[lldb] Allow SymbolTable regex search functions to match mangled name
Browse files Browse the repository at this point in the history
It may be useful to search symbol table entries by mangled instead
of demangled names. Add this optional functionality in the SymbolTable
functions.

Differential Revision: https://reviews.llvm.org/D130803
  • Loading branch information
augusto2112 committed Aug 3, 2022
1 parent f23076f commit 3aef968
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 19 deletions.
7 changes: 4 additions & 3 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,10 @@ class Module : public std::enable_shared_from_this<Module>,
lldb::SymbolType symbol_type,
SymbolContextList &sc_list);

void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
lldb::SymbolType symbol_type,
SymbolContextList &sc_list);
void FindSymbolsMatchingRegExAndType(
const RegularExpression &regex, lldb::SymbolType symbol_type,
SymbolContextList &sc_list,
Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled);

/// Find a function symbols in the object file's symbol table.
///
Expand Down
15 changes: 9 additions & 6 deletions lldb/include/lldb/Symbol/Symtab.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,16 @@ class Symtab {
Debug symbol_debug_type,
Visibility symbol_visibility,
std::vector<uint32_t> &matches);
uint32_t
AppendSymbolIndexesMatchingRegExAndType(const RegularExpression &regex,
lldb::SymbolType symbol_type,
std::vector<uint32_t> &indexes);
uint32_t AppendSymbolIndexesMatchingRegExAndType(
const RegularExpression &regex, lldb::SymbolType symbol_type,
std::vector<uint32_t> &indexes,
Mangled::NamePreference name_preference = Mangled::ePreferDemangled);
uint32_t AppendSymbolIndexesMatchingRegExAndType(
const RegularExpression &regex, lldb::SymbolType symbol_type,
Debug symbol_debug_type, Visibility symbol_visibility,
std::vector<uint32_t> &indexes);
std::vector<uint32_t> &indexes,
Mangled::NamePreference name_preference =
Mangled::NamePreference::ePreferDemangled);
void FindAllSymbolsWithNameAndType(ConstString name,
lldb::SymbolType symbol_type,
std::vector<uint32_t> &symbol_indexes);
Expand All @@ -108,7 +110,8 @@ class Symtab {
void FindAllSymbolsMatchingRexExAndType(
const RegularExpression &regex, lldb::SymbolType symbol_type,
Debug symbol_debug_type, Visibility symbol_visibility,
std::vector<uint32_t> &symbol_indexes);
std::vector<uint32_t> &symbol_indexes,
Mangled::NamePreference name_preference = Mangled::ePreferDemangled);
Symbol *FindFirstSymbolWithNameAndType(ConstString name,
lldb::SymbolType symbol_type,
Debug symbol_debug_type,
Expand Down
8 changes: 4 additions & 4 deletions lldb/source/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1367,9 +1367,9 @@ void Module::FindSymbolsWithNameAndType(ConstString name,
}
}

void Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
SymbolType symbol_type,
SymbolContextList &sc_list) {
void Module::FindSymbolsMatchingRegExAndType(
const RegularExpression &regex, SymbolType symbol_type,
SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {
// No need to protect this call using m_mutex all other method calls are
// already thread safe.
LLDB_SCOPED_TIMERF(
Expand All @@ -1379,7 +1379,7 @@ void Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
std::vector<uint32_t> symbol_indexes;
symtab->FindAllSymbolsMatchingRexExAndType(
regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
symbol_indexes);
symbol_indexes, mangling_preference);
SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
}
}
Expand Down
16 changes: 10 additions & 6 deletions lldb/source/Symbol/Symtab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ uint32_t Symtab::AppendSymbolIndexesWithNameAndType(

uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
const RegularExpression &regexp, SymbolType symbol_type,
std::vector<uint32_t> &indexes) {
std::vector<uint32_t> &indexes, Mangled::NamePreference name_preference) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);

uint32_t prev_size = indexes.size();
Expand All @@ -753,7 +753,8 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
for (uint32_t i = 0; i < sym_end; i++) {
if (symbol_type == eSymbolTypeAny ||
m_symbols[i].GetType() == symbol_type) {
const char *name = m_symbols[i].GetName().AsCString();
const char *name =
m_symbols[i].GetMangled().GetName(name_preference).AsCString();
if (name) {
if (regexp.Execute(name))
indexes.push_back(i);
Expand All @@ -766,7 +767,7 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
const RegularExpression &regexp, SymbolType symbol_type,
Debug symbol_debug_type, Visibility symbol_visibility,
std::vector<uint32_t> &indexes) {
std::vector<uint32_t> &indexes, Mangled::NamePreference name_preference) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);

uint32_t prev_size = indexes.size();
Expand All @@ -778,7 +779,8 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
if (!CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
continue;

const char *name = m_symbols[i].GetName().AsCString();
const char *name =
m_symbols[i].GetMangled().GetName(name_preference).AsCString();
if (name) {
if (regexp.Execute(name))
indexes.push_back(i);
Expand Down Expand Up @@ -847,11 +849,13 @@ void Symtab::FindAllSymbolsWithNameAndType(
void Symtab::FindAllSymbolsMatchingRexExAndType(
const RegularExpression &regex, SymbolType symbol_type,
Debug symbol_debug_type, Visibility symbol_visibility,
std::vector<uint32_t> &symbol_indexes) {
std::vector<uint32_t> &symbol_indexes,
Mangled::NamePreference name_preference) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);

AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type,
symbol_visibility, symbol_indexes);
symbol_visibility, symbol_indexes,
name_preference);
}

Symbol *Symtab::FindFirstSymbolWithNameAndType(ConstString name,
Expand Down
48 changes: 48 additions & 0 deletions lldb/test/Shell/Symtab/Inputs/symbols.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_AARCH64
SectionHeaderStringTable: .strtab
Sections:
- Name: .text
Type: SHT_PROGBITS
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
AddressAlign: 0x4
- Type: SectionHeaderTable
Sections:
- Name: .text
- Name: .strtab
- Name: .symtab
Symbols:
- Name: _Z8someFunciii
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
Size: 0x1C
- Name: _Z8someFuncci
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
Value: 0x1C
Size: 0x18
- Name: _Z13someOtherFuncv
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
Value: 0x34
Size: 0x4
- Name: _Z13someOtherFuncd
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
Value: 0x38
Size: 0x10
- Name: _Z18ignoreThisFunctionv
Type: STT_FUNC
Section: .text
Binding: STB_GLOBAL
Value: 0x48
Size: 0x8
...
9 changes: 9 additions & 0 deletions lldb/test/Shell/Symtab/symtab-regex-demangled.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# RUN: yaml2obj %S/Inputs/symbols.yaml -o %t
#

# RUN: lldb-test symtab --find-symbols-by-regex='.*some.*' --mangling-preference=demangled %t | Filecheck %s
# CHECK: someFunc(int, int, int)
# CHECK: someFunc(char, int)
# CHECK: someOtherFunc()
# CHECK: someOtherFunc(double)
# CHECK-NOT: ignoreThisFunction()
9 changes: 9 additions & 0 deletions lldb/test/Shell/Symtab/symtab-regex-mangled.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# RUN: yaml2obj %S/Inputs/symbols.yaml -o %t
#

# RUN: lldb-test symtab --find-symbols-by-regex='.*some.*' --mangling-preference=mangled %t | Filecheck %s
# CHECK: _Z8someFunciii
# CHECK: _Z8someFuncci
# CHECK: _Z13someOtherFuncv
# CHECK: _Z13someOtherFuncd
# CHECK-NOT: _Z18ignoreThisFunctionv
98 changes: 98 additions & 0 deletions lldb/tools/lldb-test/lldb-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Symbol/VariableList.h"
Expand Down Expand Up @@ -57,13 +58,16 @@ static cl::SubCommand BreakpointSubcommand("breakpoints",
cl::SubCommand ObjectFileSubcommand("object-file",
"Display LLDB object file information");
cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
cl::SubCommand SymTabSubcommand("symtab",
"Test symbol table functionality");
cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
cl::SubCommand AssertSubcommand("assert", "Test assert handling");

cl::opt<std::string> Log("log", cl::desc("Path to a log file"), cl::init(""),
cl::sub(BreakpointSubcommand),
cl::sub(ObjectFileSubcommand),
cl::sub(SymbolsSubcommand),
cl::sub(SymTabSubcommand),
cl::sub(IRMemoryMapSubcommand));

/// Create a target using the file pointed to by \p Filename, or abort.
Expand Down Expand Up @@ -102,6 +106,48 @@ cl::list<std::string> InputFilenames(cl::Positional, cl::desc("<input files>"),
cl::sub(ObjectFileSubcommand));
} // namespace object

namespace symtab {

/// The same enum as Mangled::NamePreference but with a default
/// 'None' case. This is needed to disambiguate wheter "ManglingPreference" was
/// explicitly set or not.
enum class ManglingPreference {
None,
Mangled,
Demangled,
MangledWithoutArguments,
};

static cl::opt<std::string> FindSymbolsByRegex(
"find-symbols-by-regex",
cl::desc(
"Dump symbols found in the symbol table matching the specified regex."),
cl::sub(SymTabSubcommand));

static cl::opt<ManglingPreference> ManglingPreference(
"mangling-preference",
cl::desc("Preference on mangling scheme the regex should match against and "
"dumped."),
cl::values(
clEnumValN(ManglingPreference::Mangled, "mangled", "Prefer mangled"),
clEnumValN(ManglingPreference::Demangled, "demangled",
"Prefer demangled"),
clEnumValN(ManglingPreference::MangledWithoutArguments,
"demangled-without-args", "Prefer mangled without args")),
cl::sub(SymTabSubcommand));

static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
cl::Required, cl::sub(SymTabSubcommand));

/// Validate that the options passed make sense.
static llvm::Optional<llvm::Error> validate();

/// Transforms the selected mangling preference into a Mangled::NamePreference
static Mangled::NamePreference getNamePreference();

static int handleSymtabCommand(Debugger &Dbg);
} // namespace symtab

namespace symbols {
static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
cl::Required, cl::sub(SymbolsSubcommand));
Expand Down Expand Up @@ -814,6 +860,56 @@ Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
llvm_unreachable("Unsupported symbol action.");
}

llvm::Optional<llvm::Error> opts::symtab::validate() {
if (ManglingPreference != ManglingPreference::None &&
FindSymbolsByRegex.empty())
return make_string_error("Mangling preference set but no regex specified.");

return {};
}

static Mangled::NamePreference opts::symtab::getNamePreference() {
switch (ManglingPreference) {
case ManglingPreference::None:
case ManglingPreference::Mangled:
return Mangled::ePreferMangled;
case ManglingPreference::Demangled:
return Mangled::ePreferDemangled;
case ManglingPreference::MangledWithoutArguments:
return Mangled::ePreferDemangledWithoutArguments;
}
}

int opts::symtab::handleSymtabCommand(Debugger &Dbg) {
if (auto error = validate()) {
logAllUnhandledErrors(std::move(error.getValue()), WithColor::error(), "");
return 1;
}

if (!FindSymbolsByRegex.empty()) {
ModuleSpec Spec{FileSpec(InputFile)};

auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
auto *Symtab = ModulePtr->GetSymtab();
auto NamePreference = getNamePreference();
std::vector<uint32_t> Indexes;

Symtab->FindAllSymbolsMatchingRexExAndType(
RegularExpression(FindSymbolsByRegex), lldb::eSymbolTypeAny,
Symtab::eDebugAny, Symtab::eVisibilityAny, Indexes, NamePreference);
for (auto i : Indexes) {
auto *symbol = Symtab->SymbolAtIndex(i);
if (symbol) {
StreamString stream;
symbol->Dump(&stream, nullptr, i, NamePreference);
outs() << stream.GetString();
}
}
}

return 0;
}

int opts::symbols::dumpSymbols(Debugger &Dbg) {
auto ActionOr = getAction();
if (!ActionOr) {
Expand Down Expand Up @@ -1128,6 +1224,8 @@ int main(int argc, const char *argv[]) {
return dumpObjectFiles(*Dbg);
if (opts::SymbolsSubcommand)
return opts::symbols::dumpSymbols(*Dbg);
if (opts::SymTabSubcommand)
return opts::symtab::handleSymtabCommand(*Dbg);
if (opts::IRMemoryMapSubcommand)
return opts::irmemorymap::evaluateMemoryMapCommands(*Dbg);
if (opts::AssertSubcommand)
Expand Down

0 comments on commit 3aef968

Please sign in to comment.