[Lldb-commits] [lldb] [lldb] fix step in AArch64 trampoline (PR #90783)
Vincent Belliard via lldb-commits
lldb-commits at lists.llvm.org
Wed May 1 14:33:57 PDT 2024
https://github.com/v-bulle created https://github.com/llvm/llvm-project/pull/90783
Detects AArch64 trampolines in order to be able to step in a function through a trampoline on AArch64.
>From 12464941c1b11ffad0ff2566642df3d30976a3f9 Mon Sep 17 00:00:00 2001
From: Vincent Belliard <v-bulle at github.com>
Date: Thu, 18 Apr 2024 10:39:59 -0700
Subject: [PATCH] [lldb] fix step in AArch64 trampoline
---
.../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 26 ++++++++++++++++---
.../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 19 +++++++++++++-
.../StepIn/Inputs/aarch64_thunk.cc | 15 +++++++++++
.../StepIn/step_through-aarch64-thunk.test | 17 ++++++++++++
4 files changed, 73 insertions(+), 4 deletions(-)
create mode 100644 lldb/test/Shell/ExecControl/StepIn/Inputs/aarch64_thunk.cc
create mode 100644 lldb/test/Shell/ExecControl/StepIn/step_through-aarch64-thunk.test
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 9fa245fc41d40c..232030268e42c8 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -506,9 +506,29 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread,
Target &target = thread.GetProcess()->GetTarget();
const ModuleList &images = target.GetImages();
- images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
- if (!target_symbols.GetSize())
- return thread_plan_sp;
+ 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_")) {
+ // An empty target name can happen when for trampolines generated for
+ // section-referencing relocations.
+ if (!target_name.empty()) {
+ images.FindSymbolsWithNameAndType(ConstString(target_name),
+ eSymbolTypeCode, target_symbols);
+ }
+ } else if (target_name.consume_front("__AArch64AbsLongThunk_")) {
+ // An empty target name can happen when for trampolines generated for
+ // section-referencing relocations.
+ if (!target_name.empty()) {
+ images.FindSymbolsWithNameAndType(ConstString(target_name),
+ eSymbolTypeCode, target_symbols);
+ }
+ } else {
+ images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode,
+ target_symbols);
+ }
typedef std::vector<lldb::addr_t> AddressVector;
AddressVector addrs;
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 16f6d2e884b577..1646ee9aa34a61 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -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.
diff --git a/lldb/test/Shell/ExecControl/StepIn/Inputs/aarch64_thunk.cc b/lldb/test/Shell/ExecControl/StepIn/Inputs/aarch64_thunk.cc
new file mode 100644
index 00000000000000..02f3bef32a59a3
--- /dev/null
+++ b/lldb/test/Shell/ExecControl/StepIn/Inputs/aarch64_thunk.cc
@@ -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();
+}
diff --git a/lldb/test/Shell/ExecControl/StepIn/step_through-aarch64-thunk.test b/lldb/test/Shell/ExecControl/StepIn/step_through-aarch64-thunk.test
new file mode 100644
index 00000000000000..336a746fa3a418
--- /dev/null
+++ b/lldb/test/Shell/ExecControl/StepIn/step_through-aarch64-thunk.test
@@ -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()
More information about the lldb-commits
mailing list