lldb::SymbolType symbol_type,
SymbolContextList &sc_list);
- void FindSymbolsMatchingRegExAndType(const RegularExpression ®ex,
- lldb::SymbolType symbol_type,
- SymbolContextList &sc_list);
+ void FindSymbolsMatchingRegExAndType(
+ const RegularExpression ®ex, lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list,
+ Mangled::NamePreference mangling_preference = Mangled::ePreferDemangled);
/// Find a function symbols in the object file's symbol table.
///
Debug symbol_debug_type,
Visibility symbol_visibility,
std::vector<uint32_t> &matches);
- uint32_t
- AppendSymbolIndexesMatchingRegExAndType(const RegularExpression ®ex,
- lldb::SymbolType symbol_type,
- std::vector<uint32_t> &indexes);
+ uint32_t AppendSymbolIndexesMatchingRegExAndType(
+ const RegularExpression ®ex, lldb::SymbolType symbol_type,
+ std::vector<uint32_t> &indexes,
+ Mangled::NamePreference name_preference = Mangled::ePreferDemangled);
uint32_t AppendSymbolIndexesMatchingRegExAndType(
const RegularExpression ®ex, 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);
void FindAllSymbolsMatchingRexExAndType(
const RegularExpression ®ex, 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,
}
}
-void Module::FindSymbolsMatchingRegExAndType(const RegularExpression ®ex,
- SymbolType symbol_type,
- SymbolContextList &sc_list) {
+void Module::FindSymbolsMatchingRegExAndType(
+ const RegularExpression ®ex, 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(
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);
}
}
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
const RegularExpression ®exp, 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();
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);
uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType(
const RegularExpression ®exp, 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();
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);
void Symtab::FindAllSymbolsMatchingRexExAndType(
const RegularExpression ®ex, 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,
--- /dev/null
+--- !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
+...
--- /dev/null
+# 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()
--- /dev/null
+# 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
#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"
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::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.
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));
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) {
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)