From: cocolato <haiizhu@outlook.com>
To: gdb-patches@sourceware.org
Subject: [PATCH] gdb/aarch64: Step through GNU ld's erratum 843419 veneers
Date: Wed, 30 Sep 2026 13:49:30 +0800 [thread overview]
Message-ID: <SY7P300MB0131D94B934409547A608942B28B2@SY7P300MB0131.AUSP300.PROD.OUTLOOK.COM> (raw)
GNU ld's Cortex-A53 erratum 843419 workaround can move an instruction
into an e843419@ veneer. A plain branch replaces the original
instruction; the veneer executes it and branches back to the next
instruction in the same function. Neither branch updates the link
register.
When next or finish from an inline frame enters the veneer, GDB can
mistake it for a function call. With no veneer unwind information, GDB
can use an earlier call's return address from the link register for a
step-resume breakpoint, running the inferior to completion instead of
stopping after the inline function.
Recognize GNU ld's named e843419@ veneers through the existing
in_indirect_branch_thunk hook, before subroutine-entry handling.
Recognize both veneer instructions; minimal-symbol lookup already
checks the bounds of GNU ld's sized symbols. Stripped veneer symbols
remain unsupported.
skip_trampoline_code is too late on the forward STEP_OVER_ALL path:
GDB has already set the caller-return breakpoint and returned. The
existing hook needs no generic stepping changes or instruction decoding.
The assembly and DWARF regression test exercises next and inline finish
using explicitly defined veneer instructions and symbols. It reproduces the
GDB stepping bug without a Cortex-A53 CPU or the hardware erratum,
independent of compiler optimization and linker sequence detection.
A call to helper leaves a stale link register before entering the
veneer, which has no debug or unwind information. The assertions check
the initial inline backtrace, returned source line, and exact stop
address.
To reproduce on a native AArch64 ELF target:
1. Build GDB at the base commit below and retain its executable and
data-directory. Apply this patch and build the patched GDB.
2. From the patched build's gdb/testsuite directory, run the same test
with each GDB. Use absolute executable and data-directory paths:
make check \
RUNTESTFLAGS="GDB=/path/to/gdb \
GDBFLAGS=--data-directory=/path/to/data-directory \
gdb.arch/aarch64-erratum-843419-veneer.exp"
Save gdb.sum and gdb.log after each run; the next run overwrites them.
Recorded next sessions (patched source path shortened):
Before:
(gdb) next
[Inferior 1 (process 46367) exited normally]
(gdb) p $pc == (void *) &inline_high
No registers.
After:
(gdb) next
outer () at .../aarch64-erratum-843419-veneer.S:58
58 /* Outer after inline. */
(gdb) p $pc == (void *) &inline_high
$1 = 1
finish likewise changes from normal inferior exit to stopping at
inline_high in outer. The new test changes from 4 PASS and 4 FAIL to
8 PASS and no FAIL.
Tested on native aarch64-unknown-linux-gnu in an Ubuntu 26.04 container,
with GCC 15.2.0, GNU ld 2.46, and GDB 19.0.50.20260929-git.
Base commit: 4ba6bd8393418b63dc3efa0ec6f934903a10f140.
These eight existing test files stayed at 241 PASS and no FAIL in both
runs:
gdb.arch/aarch64-prologue.exp
gdb.arch/aarch64-unwind-pc.exp
gdb.opt/inline-cmds.exp
gdb.opt/inline-bt.exp
gdb.dwarf2/dw2-inline-stepping.exp
gdb.base/finish.exp
gdb.base/step-over-no-symbols.exp
gdb.base/step-line.exp
A rerun after comment-only cleanup also gave 8 PASS and no FAIL.
The full GDB testsuite and other targets were not tested.
CPython issue #157965 reports layout-sensitive failures in
test_bt_unwinds_from_inside_jit_executor on AArch64 release builds.
Later main builds did not consistently reproduce them, so the standalone
fixture is the regression test.
A separate check used a preserved CPython binary with a GNU ld-generated
e843419@ veneer and PYTHON_JIT=0. Before the fix, finish ran the inferior
to exit and bt reported "No stack." With the fix, it stopped in
mro_invoke with a valid backtrace. This used an existing binary; current
CPython main was not rebuilt and the issue's JIT test was not rerun.
Related report: https://github.com/python/cpython/issues/157965
---
This is my first contribution to GDB. I have not completed an FSF
copyright assignment. Could you please point me to the appropriate form?
gdb/aarch64-tdep.c | 16 +++
.../gdb.arch/aarch64-erratum-843419-veneer.S | 84 +++++++++++++
.../aarch64-erratum-843419-veneer.exp | 111 ++++++++++++++++++
3 files changed, 211 insertions(+)
create mode 100644 gdb/testsuite/gdb.arch/aarch64-erratum-843419-veneer.S
create mode 100644 gdb/testsuite/gdb.arch/aarch64-erratum-843419-veneer.exp
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index 950ad4f6..9e1b5612 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -34,6 +34,7 @@
#include "frame-base.h"
#include "trad-frame.h"
#include "objfiles.h"
+#include "symtab.h"
#include "dwarf2.h"
#include "dwarf2/frame.h"
#include "gdbtypes.h"
@@ -4158,6 +4159,19 @@ aarch64_cannot_store_register (struct gdbarch *gdbarch, int regnum)
&& regnum < tdep->pauth_reg_base + tdep->pauth_reg_count);
}
+/* Implement the in_indirect_branch_thunk gdbarch method. GNU ld's
+ Cortex-A53 erratum 843419 veneers branch back into the same function,
+ so step through them rather than treating them as function calls. */
+
+static bool
+aarch64_in_indirect_branch_thunk (gdbarch *, CORE_ADDR pc)
+{
+ bound_minimal_symbol minsym = lookup_minimal_symbol_by_pc (pc);
+
+ return (minsym.minsym != nullptr
+ && startswith (minsym.minsym->linkage_name (), "e843419@"));
+}
+
/* Implement the stack_frame_destroyed_p gdbarch method. */
static bool
@@ -4788,6 +4802,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
aarch64_breakpoint::bp_from_kind);
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, true);
set_gdbarch_get_next_pcs (gdbarch, aarch64_software_single_step);
+ set_gdbarch_in_indirect_branch_thunk (gdbarch,
+ aarch64_in_indirect_branch_thunk);
/* Information about registers, etc. */
set_gdbarch_sp_regnum (gdbarch, AARCH64_SP_REGNUM);
diff --git a/gdb/testsuite/gdb.arch/aarch64-erratum-843419-veneer.S b/gdb/testsuite/gdb.arch/aarch64-erratum-843419-veneer.S
new file mode 100644
index 00000000..e14a0d14
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/aarch64-erratum-843419-veneer.S
@@ -0,0 +1,84 @@
+/* Copyright 2026 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* Calling helper leaves a stale link register. The veneer has no debug
+ or unwind information. */
+ .text
+ .global main
+ .type main, %function
+main:
+ .cfi_startproc
+ stp x29, x30, [sp, -16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset x29, -16
+ .cfi_offset x30, -8
+ mov x29, sp
+ bl outer
+ mov w0, 0
+ ldp x29, x30, [sp], 16
+ .cfi_def_cfa_offset 0
+ .cfi_restore x29
+ .cfi_restore x30
+ ret
+ .cfi_endproc
+ .size main, .-main
+
+ .global outer
+ .type outer, %function
+outer:
+ .cfi_startproc
+ stp x29, x30, [sp, -16]!
+ .cfi_def_cfa_offset 16
+ .cfi_offset x29, -16
+ .cfi_offset x30, -8
+ mov x29, sp
+ mov x0, sp
+
+ /* Outer call line. */
+ /* Inline body line. */
+ .global inline_low
+inline_low:
+ bl helper
+ b .Lveneer
+
+ /* Outer after inline. */
+ .global inline_high
+inline_high:
+ ldp x29, x30, [sp], 16
+ .cfi_def_cfa_offset 0
+ .cfi_restore x29
+ .cfi_restore x30
+ ret
+ .cfi_endproc
+ .global outer_end
+outer_end:
+ .size outer, .-outer
+
+helper:
+ ret
+
+ .type "e843419@0000_00000000_0000", %function
+"e843419@0000_00000000_0000":
+.Lveneer:
+ ldr x2, [x0]
+ b inline_high
+ .size "e843419@0000_00000000_0000", .-.Lveneer
+
+ .global program_end
+program_end:
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/gdb/testsuite/gdb.arch/aarch64-erratum-843419-veneer.exp b/gdb/testsuite/gdb.arch/aarch64-erratum-843419-veneer.exp
new file mode 100644
index 00000000..67a76052
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/aarch64-erratum-843419-veneer.exp
@@ -0,0 +1,111 @@
+# Copyright 2026 Free Software Foundation, Inc.
+
+# This file is part of GDB.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test stepping over a Cortex-A53 erratum 843419 veneer in an inline function.
+# Fixed instructions and debug information avoid dependence on compiler
+# optimizations or linker layout.
+
+load_lib dwarf.exp
+
+require is_aarch64_target
+require is_elf_target
+require dwarf2_support
+
+standard_testfile .S -dw.S
+
+set outer_call_line [gdb_get_line_number "Outer call line"]
+set inline_line [gdb_get_line_number "Inline body line"]
+set outer_after_line [gdb_get_line_number "Outer after inline"]
+
+set dwarf_asm [standard_output_file $srcfile2]
+Dwarf::assemble $dwarf_asm {
+ global srcdir subdir srcfile
+ global outer_call_line inline_line outer_after_line
+
+ declare_labels lines_label inline_subprogram
+
+ cu {} {
+ compile_unit {
+ DW_AT_language @DW_LANG_C
+ DW_AT_name $srcfile
+ DW_AT_stmt_list $lines_label DW_FORM_sec_offset
+ DW_AT_low_pc main addr
+ DW_AT_high_pc program_end addr
+ } {
+ inline_subprogram: subprogram {
+ DW_AT_name inline_func
+ DW_AT_inline 3 data1
+ }
+ subprogram {
+ DW_AT_name outer
+ DW_AT_low_pc outer addr
+ DW_AT_high_pc outer_end addr
+ } {
+ inlined_subroutine {
+ DW_AT_abstract_origin %$inline_subprogram
+ DW_AT_low_pc inline_low addr
+ DW_AT_high_pc inline_high addr
+ DW_AT_call_file 1 data1
+ DW_AT_call_line $outer_call_line data1
+ }
+ }
+ }
+ }
+
+ lines {version 2} lines_label {
+ include_dir "$srcdir/$subdir"
+ file_name "$srcfile" 1
+
+ program {
+ DW_LNE_set_address outer
+ line $outer_call_line
+ DW_LNS_copy
+ # Describe the inline call site before the inline function's body.
+ DW_LNE_set_address inline_low
+ line $outer_call_line
+ DW_LNS_copy
+ DW_LNE_set_address inline_low
+ line $inline_line
+ DW_LNS_copy
+ DW_LNE_set_address inline_high
+ line $outer_after_line
+ DW_LNS_copy
+ DW_LNE_set_address outer_end
+ DW_LNE_end_sequence
+ }
+ }
+}
+
+if { [prepare_for_testing "failed to prepare" $testfile \
+ [list $srcfile $dwarf_asm] {nodebug nopie}] } {
+ return
+}
+
+foreach_with_prefix command {next finish} {
+ if { ![runto_main] } {
+ return
+ }
+
+ gdb_breakpoint "*inline_low"
+ gdb_continue_to_breakpoint "inline function"
+
+ gdb_test "bt" "#0 inline_func.*#1 outer.*#2 .*main.*" \
+ "backtrace in inline function"
+ gdb_test $command "Outer after inline.*" "step through erratum veneer"
+ gdb_test {p $pc == (void *) &inline_high} " = 1" \
+ "stopped after inline function"
+}
base-commit: 4ba6bd8393418b63dc3efa0ec6f934903a10f140
--
2.54.0 (Apple Git-157)
next reply other threads:[~2026-09-30 5:50 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-30 5:49 cocolato [this message]
2026-10-03 10:17 ` Luis
2026-10-03 12:44 ` 朱 海
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=SY7P300MB0131D94B934409547A608942B28B2@SY7P300MB0131.AUSP300.PROD.OUTLOOK.COM \
--to=haiizhu@outlook.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox