The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0b862a795a3500b07aa757ce7b457c9bf198e2b1

commit 0b862a795a3500b07aa757ce7b457c9bf198e2b1
Author:     Alex Arslan <[email protected]>
AuthorDate: 2026-02-27 21:51:28 +0000
Commit:     Andrew Turner <[email protected]>
CommitDate: 2026-06-05 16:15:36 +0000

    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 <[email protected]>
    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 d0a7302e2f7d..dd433907de12 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 a4f0ee243b3a..11befe4e3023 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 */
 };
 
 

Reply via email to