diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 9fa245fc41d40..51e4b3e6728f2 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -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; diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 16f6d2e884b57..1646ee9aa34a6 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 0000000000000..02f3bef32a59a --- /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 0000000000000..336a746fa3a41 --- /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()