Skip to content

Commit 3aef968

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
1 parent f23076f commit 3aef968

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
@@ -261,9 +261,10 @@ class Module : public std::enable_shared_from_this<Module>,
261261
lldb::SymbolType symbol_type,
262262
SymbolContextList &sc_list);
263263

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

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

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
@@ -1367,9 +1367,9 @@ void Module::FindSymbolsWithNameAndType(ConstString name,
13671367
}
13681368
}
13691369

1370-
void Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
1371-
SymbolType symbol_type,
1372-
SymbolContextList &sc_list) {
1370+
void Module::FindSymbolsMatchingRegExAndType(
1371+
const RegularExpression &regex, SymbolType symbol_type,
1372+
SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {
13731373
// No need to protect this call using m_mutex all other method calls are
13741374
// already thread safe.
13751375
LLDB_SCOPED_TIMERF(
@@ -1379,7 +1379,7 @@ void Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
13791379
std::vector<uint32_t> symbol_indexes;
13801380
symtab->FindAllSymbolsMatchingRexExAndType(
13811381
regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
1382-
symbol_indexes);
1382+
symbol_indexes, mangling_preference);
13831383
SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
13841384
}
13851385
}

lldb/source/Symbol/Symtab.cpp

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

745745
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
746746
const RegularExpression &regexp, SymbolType symbol_type,
747-
std::vector<uint32_t> &indexes) {
747+
std::vector<uint32_t> &indexes, Mangled::NamePreference name_preference) {
748748
std::lock_guard<std::recursive_mutex> guard(m_mutex);
749749

750750
uint32_t prev_size = indexes.size();
@@ -753,7 +753,8 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
753753
for (uint32_t i = 0; i < sym_end; i++) {
754754
if (symbol_type == eSymbolTypeAny ||
755755
m_symbols[i].GetType() == symbol_type) {
756-
const char *name = m_symbols[i].GetName().AsCString();
756+
const char *name =
757+
m_symbols[i].GetMangled().GetName(name_preference).AsCString();
757758
if (name) {
758759
if (regexp.Execute(name))
759760
indexes.push_back(i);
@@ -766,7 +767,7 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
766767
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
767768
const RegularExpression &regexp, SymbolType symbol_type,
768769
Debug symbol_debug_type, Visibility symbol_visibility,
769-
std::vector<uint32_t> &indexes) {
770+
std::vector<uint32_t> &indexes, Mangled::NamePreference name_preference) {
770771
std::lock_guard<std::recursive_mutex> guard(m_mutex);
771772

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

781-
const char *name = m_symbols[i].GetName().AsCString();
782+
const char *name =
783+
m_symbols[i].GetMangled().GetName(name_preference).AsCString();
782784
if (name) {
783785
if (regexp.Execute(name))
784786
indexes.push_back(i);
@@ -847,11 +849,13 @@ void Symtab::FindAllSymbolsWithNameAndType(
847849
void Symtab::FindAllSymbolsMatchingRexExAndType(
848850
const RegularExpression &regex, SymbolType symbol_type,
849851
Debug symbol_debug_type, Visibility symbol_visibility,
850-
std::vector<uint32_t> &symbol_indexes) {
852+
std::vector<uint32_t> &symbol_indexes,
853+
Mangled::NamePreference name_preference) {
851854
std::lock_guard<std::recursive_mutex> guard(m_mutex);
852855

853856
AppendSymbolIndexesMatchingRegExAndType(regex, symbol_type, symbol_debug_type,
854-
symbol_visibility, symbol_indexes);
857+
symbol_visibility, symbol_indexes,
858+
name_preference);
855859
}
856860

857861
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)