From 0b862a795a3500b07aa757ce7b457c9bf198e2b1 Mon Sep 17 00:00:00 2001 From: Alex Arslan Date: Fri, 27 Feb 2026 13:51:28 -0800 Subject: [PATCH] arm64: Expose ESR in mcontext At present, the exception syndrome register (ESR) is not accessible via the user context on FreeBSD AArch64, which makes it difficult to determine the cause of an exception. For example, a signal handler might get a `SIGSEGV` with `SEGV_ACCERR`, but it can't know whether that occurred due to a bad read or write. The change implemented here includes ESR in `struct __mcontext`, thereby allowing access via `ucontext_t` for use by signal handlers, sanitizers, debuggers, etc. Note that this addition consumes one of the seven spare 64-bit slots in `struct __mcontext`. Signed-off-by: Alex Arslan Reviewed by: andrew Pull Request: https://github.com/freebsd/freebsd-src/pull/2053 --- sys/arm64/arm64/exec_machdep.c | 5 +++++ sys/arm64/include/ucontext.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/arm64/arm64/exec_machdep.c b/sys/arm64/arm64/exec_machdep.c index d0a7302e2f7..dd433907de1 100644 --- a/sys/arm64/arm64/exec_machdep.c +++ b/sys/arm64/arm64/exec_machdep.c @@ -484,6 +484,7 @@ int get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { struct trapframe *tf = td->td_frame; + ksiginfo_t *ksi = td->td_proc->p_ksi; if (clear_ret & GET_MC_CLEAR_RET) { mcp->mc_gpregs.gp_x[0] = 0; @@ -499,6 +500,10 @@ get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) mcp->mc_gpregs.gp_sp = tf->tf_sp; mcp->mc_gpregs.gp_lr = tf->tf_lr; mcp->mc_gpregs.gp_elr = tf->tf_elr; + if (ksi != NULL && (ksi->ksi_flags & KSI_EXCEPT) != 0) { + mcp->mc_esr = tf->tf_esr; + mcp->mc_flags |= _MC_ESR_VALID; + } get_fpcontext(td, mcp); return (0); diff --git a/sys/arm64/include/ucontext.h b/sys/arm64/include/ucontext.h index a4f0ee243b3..11befe4e302 100644 --- a/sys/arm64/include/ucontext.h +++ b/sys/arm64/include/ucontext.h @@ -76,9 +76,11 @@ struct __mcontext { struct fpregs mc_fpregs; int mc_flags; #define _MC_FP_VALID 0x1 /* Set when mc_fpregs has valid data */ +#define _MC_ESR_VALID 0x2 /* Set when mc_esr has valid data */ int mc_pad; /* Padding */ __uint64_t mc_ptr; /* Address of extra_regs struct */ - __uint64_t mc_spare[7]; /* Space for expansion, set to zero */ + __register_t mc_esr; /* Exception syndrome register */ + __uint64_t mc_spare[6]; /* Space for expansion, set to zero */ };