Skip to content

[lldb] fix step in AArch64 trampoline #90783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,19 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
Target &target = thread.GetProcess()->GetTarget();
const ModuleList &images = target.GetImages();

llvm::StringRef target_name = sym_name.GetStringRef();
// On AArch64, the trampoline name has a prefix (__AArch64ADRPThunk_ or
// __AArch64AbsLongThunk_) added to the function name. If we detect a
// trampoline with the prefix, we need to remove the prefix to find the
// function symbol.
if (target_name.consume_front("__AArch64ADRPThunk_") ||
target_name.consume_front("__AArch64AbsLongThunk_")) {
// An empty target name can happen for trampolines generated for
// section-referencing relocations.
if (!target_name.empty()) {
sym_name = ConstString(target_name);
}
}
images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
if (!target_symbols.GetSize())
return thread_plan_sp;
Expand Down
19 changes: 18 additions & 1 deletion lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2356,13 +2356,30 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
bool symbol_size_valid =
symbol.st_size != 0 || symbol.getType() != STT_FUNC;

bool is_trampoline = false;
if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64)) {
// On AArch64, trampolines are registered as code.
// If we detect a trampoline (which starts with __AArch64ADRPThunk_ or
// __AArch64AbsLongThunk_) we register the symbol as a trampoline. This
// way we will be able to detect the trampoline when we step in a function
// and step through the trampoline.
if (symbol_type == eSymbolTypeCode) {
llvm::StringRef trampoline_name = mangled.GetName().GetStringRef();
if (trampoline_name.starts_with("__AArch64ADRPThunk_") ||
trampoline_name.starts_with("__AArch64AbsLongThunk_")) {
symbol_type = eSymbolTypeTrampoline;
is_trampoline = true;
}
}
}

Symbol dc_symbol(
i + start_id, // ID is the original symbol table index.
mangled,
symbol_type, // Type of this symbol
is_global, // Is this globally visible?
false, // Is this symbol debug info?
false, // Is this symbol a trampoline?
is_trampoline, // Is this symbol a trampoline?
false, // Is this symbol artificial?
AddressRange(symbol_section_sp, // Section in which this symbol is
// defined or null.
Expand Down
15 changes: 15 additions & 0 deletions lldb/test/Shell/ExecControl/StepIn/Inputs/aarch64_thunk.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
extern "C" int __attribute__((naked)) __AArch64ADRPThunk_step_here() {
asm (
"adrp x16, step_here\n"
"add x16, x16, :lo12:step_here\n"
"br x16"
);
}

extern "C" __attribute__((used)) int step_here() {
return 47;
}

int main() {
return __AArch64ADRPThunk_step_here();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# REQUIRES: native && target-aarch64

# This test is specific to elf platforms.
# UNSUPPORTED: system-windows, system-darwin

# RUN: %clangxx_host %p/Inputs/aarch64_thunk.cc -g -o %t.out
# RUN: %lldb %t.out -s %s | FileCheck %s

b main
# CHECK: Breakpoint 1: where = step_through-aarch64-thunk.test.tmp.out`main

r
# CHECK: stop reason = breakpoint 1.1

s
# CHECK: stop reason = step in
# CHECK: frame #0: {{.*}} step_through-aarch64-thunk.test.tmp.out`::step_here()