Skip to content

Commit b22a6f1

Browse files
v-bulleVincent Belliard
andauthored
[lldb] fix step in AArch64 trampoline (llvm#90783)
Detects AArch64 trampolines in order to be able to step in a function through a trampoline on AArch64. --------- Co-authored-by: Vincent Belliard <[email protected]>
1 parent 6f2997c commit b22a6f1

File tree

4 files changed

+63
-1
lines changed

4 files changed

+63
-1
lines changed

lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,19 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
506506
Target &target = thread.GetProcess()->GetTarget();
507507
const ModuleList &images = target.GetImages();
508508

509+
llvm::StringRef target_name = sym_name.GetStringRef();
510+
// On AArch64, the trampoline name has a prefix (__AArch64ADRPThunk_ or
511+
// __AArch64AbsLongThunk_) added to the function name. If we detect a
512+
// trampoline with the prefix, we need to remove the prefix to find the
513+
// function symbol.
514+
if (target_name.consume_front("__AArch64ADRPThunk_") ||
515+
target_name.consume_front("__AArch64AbsLongThunk_")) {
516+
// An empty target name can happen for trampolines generated for
517+
// section-referencing relocations.
518+
if (!target_name.empty()) {
519+
sym_name = ConstString(target_name);
520+
}
521+
}
509522
images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
510523
if (!target_symbols.GetSize())
511524
return thread_plan_sp;

lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2356,13 +2356,30 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
23562356
bool symbol_size_valid =
23572357
symbol.st_size != 0 || symbol.getType() != STT_FUNC;
23582358

2359+
bool is_trampoline = false;
2360+
if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64)) {
2361+
// On AArch64, trampolines are registered as code.
2362+
// If we detect a trampoline (which starts with __AArch64ADRPThunk_ or
2363+
// __AArch64AbsLongThunk_) we register the symbol as a trampoline. This
2364+
// way we will be able to detect the trampoline when we step in a function
2365+
// and step through the trampoline.
2366+
if (symbol_type == eSymbolTypeCode) {
2367+
llvm::StringRef trampoline_name = mangled.GetName().GetStringRef();
2368+
if (trampoline_name.starts_with("__AArch64ADRPThunk_") ||
2369+
trampoline_name.starts_with("__AArch64AbsLongThunk_")) {
2370+
symbol_type = eSymbolTypeTrampoline;
2371+
is_trampoline = true;
2372+
}
2373+
}
2374+
}
2375+
23592376
Symbol dc_symbol(
23602377
i + start_id, // ID is the original symbol table index.
23612378
mangled,
23622379
symbol_type, // Type of this symbol
23632380
is_global, // Is this globally visible?
23642381
false, // Is this symbol debug info?
2365-
false, // Is this symbol a trampoline?
2382+
is_trampoline, // Is this symbol a trampoline?
23662383
false, // Is this symbol artificial?
23672384
AddressRange(symbol_section_sp, // Section in which this symbol is
23682385
// defined or null.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
extern "C" int __attribute__((naked)) __AArch64ADRPThunk_step_here() {
2+
asm (
3+
"adrp x16, step_here\n"
4+
"add x16, x16, :lo12:step_here\n"
5+
"br x16"
6+
);
7+
}
8+
9+
extern "C" __attribute__((used)) int step_here() {
10+
return 47;
11+
}
12+
13+
int main() {
14+
return __AArch64ADRPThunk_step_here();
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# REQUIRES: native && target-aarch64
2+
3+
# This test is specific to elf platforms.
4+
# UNSUPPORTED: system-windows, system-darwin
5+
6+
# RUN: %clangxx_host %p/Inputs/aarch64_thunk.cc -g -o %t.out
7+
# RUN: %lldb %t.out -s %s | FileCheck %s
8+
9+
b main
10+
# CHECK: Breakpoint 1: where = step_through-aarch64-thunk.test.tmp.out`main
11+
12+
r
13+
# CHECK: stop reason = breakpoint 1.1
14+
15+
s
16+
# CHECK: stop reason = step in
17+
# CHECK: frame #0: {{.*}} step_through-aarch64-thunk.test.tmp.out`::step_here()

0 commit comments

Comments
 (0)