[Lldb-commits] [lldb] [lldb] Improve trampoline function detection (PR #178695)
Ebuka Ezike via lldb-commits
lldb-commits at lists.llvm.org
Thu Jan 29 08:32:49 PST 2026
https://github.com/da-viper created https://github.com/llvm/llvm-project/pull/178695
The mold linker adds a function symbol to the symbol table (.symtab) for every shared library exported function.
So if we try to step into a library, lldb will fail because the symbol at the address is not a trampline function.
Example:
```cpp
lib.c
int lib_add(int a, int b);
```
when we link the library to an executable, mold will create the normal trampoline functions in the .plt section but add an extra symbol in symbol table `lib_add$plt`.
I cannot think of a way to add another symbol in the trampoline's file address without linking with mold.
Is there a way to write a test for this ?
>From 8ef6eac983b5f31ddb75825180e1bd056f1a19d9 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at gmail.com>
Date: Thu, 29 Jan 2026 16:17:05 +0000
Subject: [PATCH] [lldb] Improve trampoline function detection
The mold linker adds a function symbol to the symbol table (.symtab) for
every shared library exported function.
So if we try to step into a library, lldb will fail because the symbol
at the address is not a trampline function.
Example:
```cpp
lib.c
int lib_add(int a, int b);
```
when we link the library to an executable, mold will create the normal
trampoline functions in the .plt section but add an extra symbol in
symbol table `lib_add$plt`.
This patch adds a new method Module::FindSymbolsContainingFileAddress()
to find symbols of a specific type that contain a given file address.
---
lldb/include/lldb/Core/Module.h | 4 +++
lldb/source/Core/Module.cpp | 17 ++++++++++++
.../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 27 +++++++++++++++++--
3 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 643b9a5c3bf54..87d828fb41eed 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -265,6 +265,10 @@ class Module : public std::enable_shared_from_this<Module>,
lldb::SymbolType symbol_type,
SymbolContextList &sc_list);
+ void FindSymbolsContainingFileAddress(const Address &addr,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list);
+
void FindSymbolsMatchingRegExAndType(
const RegularExpression ®ex, lldb::SymbolType symbol_type,
SymbolContextList &sc_list,
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 486af1a053344..436c4ce027d84 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1316,6 +1316,23 @@ void Module::FindSymbolsWithNameAndType(ConstString name,
}
}
+void Module::FindSymbolsContainingFileAddress(const Address &addr,
+ lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list) {
+ if (Symtab *symtab = GetSymtab()) {
+ std::vector<uint32_t> symbol_indexes;
+ symtab->ForEachSymbolContainingFileAddress(
+ addr.GetFileAddress(), [&, symbol_type](Symbol *match_sym) {
+ if (const lldb::SymbolType curr_type = match_sym->GetType();
+ curr_type == lldb::eSymbolTypeAny || curr_type == symbol_type) {
+ symbol_indexes.push_back(symtab->GetIndexForSymbol(match_sym));
+ }
+ return true;
+ });
+ SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
+ }
+}
+
void Module::FindSymbolsMatchingRegExAndType(
const RegularExpression ®ex, SymbolType symbol_type,
SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 6705ac139f0fb..8802b4b7cd27b 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -540,11 +540,34 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
- const Symbol *sym = context.symbol;
- if (sym == nullptr || !sym->IsTrampoline())
+ Symbol *sym = context.symbol;
+ if (sym == nullptr)
return thread_plan_sp;
+ if (!sym->IsTrampoline()) {
+ if (sym->GetType() != lldb::eSymbolTypeCode)
+ return thread_plan_sp;
+
+ SymbolContextList addr_ctx_list;
+ context.module_sp->FindSymbolsContainingFileAddress(
+ context.GetFunctionOrSymbolAddress(), eSymbolTypeTrampoline,
+ addr_ctx_list);
+ if (addr_ctx_list.IsEmpty())
+ return thread_plan_sp;
+
+ for (const auto &sym_ctx : addr_ctx_list.SymbolContexts()) {
+ if (sym_ctx.symbol != nullptr) {
+ sym = sym_ctx.symbol;
+ break;
+ }
+ }
+
+ // may not find a match
+ if (sym == nullptr)
+ return thread_plan_sp;
+ }
+
ConstString sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled);
if (!sym_name)
return thread_plan_sp;
More information about the lldb-commits
mailing list