Skip to content

Commit e4cb49f

Browse files
committed
[lldb] Allow SymbolTable regex search functions to match mangled name
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 (cherry picked from commit 3aef968)
1 parent 07d1485 commit e4cb49f

File tree

8 files changed

+191
-19
lines changed

8 files changed

+191
-19
lines changed

lldb/include/lldb/Core/Module.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,10 @@ class Module : public std::enable_shared_from_this<Module>,
262262
lldb::SymbolType symbol_type,
263263
SymbolContextList &sc_list);
264264

265-
void FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
266-
lldb::SymbolType symbol_type,
267-
SymbolContextList &sc_list);
265+
void FindSymbolsMatchingRegExAndType(
266+
const RegularExpression &regex, lldb::SymbolType symbol_type,
267+
SymbolContextList &sc_list,
268+
Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled);
268269

269270
/// Find a function symbols in the object file's symbol table.
270271
///

lldb/include/lldb/Symbol/Symtab.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,16 @@ class Symtab {
8989
Debug symbol_debug_type,
9090
Visibility symbol_visibility,
9191
std::vector<uint32_t> &matches);
92-
uint32_t
93-
AppendSymbolIndexesMatchingRegExAndType(const RegularExpression &regex,
94-
lldb::SymbolType symbol_type,
95-
std::vector<uint32_t> &indexes);
92+
uint32_t AppendSymbolIndexesMatchingRegExAndType(
93+
const RegularExpression &regex, lldb::SymbolType symbol_type,
94+
std::vector<uint32_t> &indexes,
95+
Mangled::NamePreference name_preference = Mangled::ePreferDemangled);
9696
uint32_t AppendSymbolIndexesMatchingRegExAndType(
9797
const RegularExpression &regex, lldb::SymbolType symbol_type,
9898
Debug symbol_debug_type, Visibility symbol_visibility,
99-
std::vector<uint32_t> &indexes);
99+
std::vector<uint32_t> &indexes,
100+
Mangled::NamePreference name_preference =
101+
Mangled::NamePreference::ePreferDemangled);
100102
void FindAllSymbolsWithNameAndType(ConstString name,
101103
lldb::SymbolType symbol_type,
102104
std::vector<uint32_t> &symbol_indexes);
@@ -108,7 +110,8 @@ class Symtab {
108110
void FindAllSymbolsMatchingRexExAndType(
109111
const RegularExpression &regex, lldb::SymbolType symbol_type,
110112
Debug symbol_debug_type, Visibility symbol_visibility,
111-
std::vector<uint32_t> &symbol_indexes);
113+
std::vector<uint32_t> &symbol_indexes,
114+
Mangled::NamePreference name_preference = Mangled::ePreferDemangled);
112115
Symbol *FindFirstSymbolWithNameAndType(ConstString name,
113116
lldb::SymbolType symbol_type,
114117
Debug symbol_debug_type,

lldb/source/Core/Module.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,9 +1436,9 @@ void Module::FindSymbolsWithNameAndType(ConstString name,
14361436
}
14371437
}
14381438

1439-
void Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
1440-
SymbolType symbol_type,
1441-
SymbolContextList &sc_list) {
1439+
void Module::FindSymbolsMatchingRegExAndType(
1440+
const RegularExpression &regex, SymbolType symbol_type,
1441+
SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {
14421442
// No need to protect this call using m_mutex all other method calls are
14431443
// already thread safe.
14441444
LLDB_SCOPED_TIMERF(
@@ -1448,7 +1448,7 @@ void Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
14481448
std::vector<uint32_t> symbol_indexes;
14491449
symtab->FindAllSymbolsMatchingRexExAndType(
14501450
regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
1451-
symbol_indexes);
1451+
symbol_indexes, mangling_preference);
14521452
SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
14531453
}
14541454
}

lldb/source/Symbol/Symtab.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ uint32_t Symtab::AppendSymbolIndexesWithNameAndType(
768768

769769
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
770770
const RegularExpression &regexp, SymbolType symbol_type,
771-
std::vector<uint32_t> &indexes) {
771+
std::vector<uint32_t> &indexes, Mangled::NamePreference name_preference) {
772772
std::lock_guard<std::recursive_mutex> guard(m_mutex);
773773

774774
uint32_t prev_size = indexes.size();
@@ -777,7 +777,8 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
777777
for (uint32_t i = 0; i < sym_end; i++) {
778778
if (symbol_type == eSymbolTypeAny ||
779779
m_symbols[i].GetType() == symbol_type) {
780-
const char *name = m_symbols[i].GetName().AsCString();
780+
const char *name =
781+
m_symbols[i].GetMangled().GetName(name_preference).AsCString();
781782
if (name) {
782783
if (regexp.Execute(name))
783784
indexes.push_back(i);
@@ -790,7 +791,7 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
790791
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
791792
const RegularExpression &regexp, SymbolType symbol_type,
792793
Debug symbol_debug_type, Visibility symbol_visibility,
793-
std::vector<uint32_t> &indexes) {
794+
std::vector<uint32_t> &indexes, Mangled::NamePreference name_preference) {
794795
std::lock_guard<std::recursive_mutex> guard(m_mutex);
795796

796797
uint32_t prev_size = indexes.size();
@@ -802,7 +803,8 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
802803
if (!CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility))
803804
continue;
804805

805-
const char *name = m_symbols[i].GetName().AsCString();
806+
const char *name =
807+
m_symbols[i].GetMangled().GetName(name_preference).AsCString();
806808
if (name) {
807809
if (regexp.Execute(name))
808810
indexes.push_back(i);
@@ -871,11 +873,13 @@ void Symtab::FindAllSymbolsWithNameAndType(
871873
void Symtab::FindAllSymbolsMatchingRexExAndType(
872874
const RegularExpression &regex, SymbolType symbol_type,
873875
Debug symbol_debug_type, Visibility symbol_visibility,
874-
std::vector<uint32_t> &symbol_indexes) {
876+
std::vector<uint32_t> &symbol_indexes,
877+
Mangled::NamePreference name_preference) {
875878
std::lock_guard<std::recursive_mutex> guard(m_mutex);
876879

877880
AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type,
878-
symbol_visibility, symbol_indexes);
881+
symbol_visibility, symbol_indexes,
882+
name_preference);
879883
}
880884

881885
Symbol *Symtab::FindFirstSymbolWithNameAndType(ConstString name,
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--- !ELF
2+
FileHeader:
3+
Class: ELFCLASS64
4+
Data: ELFDATA2LSB
5+
Type: ET_REL
6+
Machine: EM_AARCH64
7+
SectionHeaderStringTable: .strtab
8+
Sections:
9+
- Name: .text
10+
Type: SHT_PROGBITS
11+
Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
12+
AddressAlign: 0x4
13+
- Type: SectionHeaderTable
14+
Sections:
15+
- Name: .text
16+
- Name: .strtab
17+
- Name: .symtab
18+
Symbols:
19+
- Name: _Z8someFunciii
20+
Type: STT_FUNC
21+
Section: .text
22+
Binding: STB_GLOBAL
23+
Size: 0x1C
24+
- Name: _Z8someFuncci
25+
Type: STT_FUNC
26+
Section: .text
27+
Binding: STB_GLOBAL
28+
Value: 0x1C
29+
Size: 0x18
30+
- Name: _Z13someOtherFuncv
31+
Type: STT_FUNC
32+
Section: .text
33+
Binding: STB_GLOBAL
34+
Value: 0x34
35+
Size: 0x4
36+
- Name: _Z13someOtherFuncd
37+
Type: STT_FUNC
38+
Section: .text
39+
Binding: STB_GLOBAL
40+
Value: 0x38
41+
Size: 0x10
42+
- Name: _Z18ignoreThisFunctionv
43+
Type: STT_FUNC
44+
Section: .text
45+
Binding: STB_GLOBAL
46+
Value: 0x48
47+
Size: 0x8
48+
...
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# RUN: yaml2obj %S/Inputs/symbols.yaml -o %t
2+
#
3+
4+
# RUN: lldb-test symtab --find-symbols-by-regex='.*some.*' --mangling-preference=demangled %t | FileCheck %s
5+
# CHECK: someFunc(int, int, int)
6+
# CHECK: someFunc(char, int)
7+
# CHECK: someOtherFunc()
8+
# CHECK: someOtherFunc(double)
9+
# CHECK-NOT: ignoreThisFunction()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# RUN: yaml2obj %S/Inputs/symbols.yaml -o %t
2+
#
3+
4+
# RUN: lldb-test symtab --find-symbols-by-regex='.*some.*' --mangling-preference=mangled %t | FileCheck %s
5+
# CHECK: _Z8someFunciii
6+
# CHECK: _Z8someFuncci
7+
# CHECK: _Z13someOtherFuncv
8+
# CHECK: _Z13someOtherFuncd
9+
# CHECK-NOT: _Z18ignoreThisFunctionv

lldb/tools/lldb-test/lldb-test.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "lldb/Symbol/CompileUnit.h"
2323
#include "lldb/Symbol/LineTable.h"
2424
#include "lldb/Symbol/SymbolFile.h"
25+
#include "lldb/Symbol/Symtab.h"
2526
#include "lldb/Symbol/TypeList.h"
2627
#include "lldb/Symbol/TypeMap.h"
2728
#include "lldb/Symbol/VariableList.h"
@@ -57,13 +58,16 @@ static cl::SubCommand BreakpointSubcommand("breakpoints",
5758
cl::SubCommand ObjectFileSubcommand("object-file",
5859
"Display LLDB object file information");
5960
cl::SubCommand SymbolsSubcommand("symbols", "Dump symbols for an object file");
61+
cl::SubCommand SymTabSubcommand("symtab",
62+
"Test symbol table functionality");
6063
cl::SubCommand IRMemoryMapSubcommand("ir-memory-map", "Test IRMemoryMap");
6164
cl::SubCommand AssertSubcommand("assert", "Test assert handling");
6265

6366
cl::opt<std::string> Log("log", cl::desc("Path to a log file"), cl::init(""),
6467
cl::sub(BreakpointSubcommand),
6568
cl::sub(ObjectFileSubcommand),
6669
cl::sub(SymbolsSubcommand),
70+
cl::sub(SymTabSubcommand),
6771
cl::sub(IRMemoryMapSubcommand));
6872

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

109+
namespace symtab {
110+
111+
/// The same enum as Mangled::NamePreference but with a default
112+
/// 'None' case. This is needed to disambiguate wheter "ManglingPreference" was
113+
/// explicitly set or not.
114+
enum class ManglingPreference {
115+
None,
116+
Mangled,
117+
Demangled,
118+
MangledWithoutArguments,
119+
};
120+
121+
static cl::opt<std::string> FindSymbolsByRegex(
122+
"find-symbols-by-regex",
123+
cl::desc(
124+
"Dump symbols found in the symbol table matching the specified regex."),
125+
cl::sub(SymTabSubcommand));
126+
127+
static cl::opt<ManglingPreference> ManglingPreference(
128+
"mangling-preference",
129+
cl::desc("Preference on mangling scheme the regex should match against and "
130+
"dumped."),
131+
cl::values(
132+
clEnumValN(ManglingPreference::Mangled, "mangled", "Prefer mangled"),
133+
clEnumValN(ManglingPreference::Demangled, "demangled",
134+
"Prefer demangled"),
135+
clEnumValN(ManglingPreference::MangledWithoutArguments,
136+
"demangled-without-args", "Prefer mangled without args")),
137+
cl::sub(SymTabSubcommand));
138+
139+
static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
140+
cl::Required, cl::sub(SymTabSubcommand));
141+
142+
/// Validate that the options passed make sense.
143+
static llvm::Optional<llvm::Error> validate();
144+
145+
/// Transforms the selected mangling preference into a Mangled::NamePreference
146+
static Mangled::NamePreference getNamePreference();
147+
148+
static int handleSymtabCommand(Debugger &Dbg);
149+
} // namespace symtab
150+
105151
namespace symbols {
106152
static cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input file>"),
107153
cl::Required, cl::sub(SymbolsSubcommand));
@@ -814,6 +860,56 @@ Expected<Error (*)(lldb_private::Module &)> opts::symbols::getAction() {
814860
llvm_unreachable("Unsupported symbol action.");
815861
}
816862

863+
llvm::Optional<llvm::Error> opts::symtab::validate() {
864+
if (ManglingPreference != ManglingPreference::None &&
865+
FindSymbolsByRegex.empty())
866+
return make_string_error("Mangling preference set but no regex specified.");
867+
868+
return {};
869+
}
870+
871+
static Mangled::NamePreference opts::symtab::getNamePreference() {
872+
switch (ManglingPreference) {
873+
case ManglingPreference::None:
874+
case ManglingPreference::Mangled:
875+
return Mangled::ePreferMangled;
876+
case ManglingPreference::Demangled:
877+
return Mangled::ePreferDemangled;
878+
case ManglingPreference::MangledWithoutArguments:
879+
return Mangled::ePreferDemangledWithoutArguments;
880+
}
881+
}
882+
883+
int opts::symtab::handleSymtabCommand(Debugger &Dbg) {
884+
if (auto error = validate()) {
885+
logAllUnhandledErrors(std::move(error.getValue()), WithColor::error(), "");
886+
return 1;
887+
}
888+
889+
if (!FindSymbolsByRegex.empty()) {
890+
ModuleSpec Spec{FileSpec(InputFile)};
891+
892+
auto ModulePtr = std::make_shared<lldb_private::Module>(Spec);
893+
auto *Symtab = ModulePtr->GetSymtab();
894+
auto NamePreference = getNamePreference();
895+
std::vector<uint32_t> Indexes;
896+
897+
Symtab->FindAllSymbolsMatchingRexExAndType(
898+
RegularExpression(FindSymbolsByRegex), lldb::eSymbolTypeAny,
899+
Symtab::eDebugAny, Symtab::eVisibilityAny, Indexes, NamePreference);
900+
for (auto i : Indexes) {
901+
auto *symbol = Symtab->SymbolAtIndex(i);
902+
if (symbol) {
903+
StreamString stream;
904+
symbol->Dump(&stream, nullptr, i, NamePreference);
905+
outs() << stream.GetString();
906+
}
907+
}
908+
}
909+
910+
return 0;
911+
}
912+
817913
int opts::symbols::dumpSymbols(Debugger &Dbg) {
818914
auto ActionOr = getAction();
819915
if (!ActionOr) {
@@ -1128,6 +1224,8 @@ int main(int argc, const char *argv[]) {
11281224
return dumpObjectFiles(*Dbg);
11291225
if (opts::SymbolsSubcommand)
11301226
return opts::symbols::dumpSymbols(*Dbg);
1227+
if (opts::SymTabSubcommand)
1228+
return opts::symtab::handleSymtabCommand(*Dbg);
11311229
if (opts::IRMemoryMapSubcommand)
11321230
return opts::irmemorymap::evaluateMemoryMapCommands(*Dbg);
11331231
if (opts::AssertSubcommand)

0 commit comments

Comments
 (0)