Alexandre Julliard : ntdll: Add support for FPU registers in signal context on ARM.
Module: wine Branch: master Commit: f30ba2cf256054c4aa6b75ff2f282dfe8e2c219a URL: https://source.winehq.org/git/wine.git/?a=commit;h=f30ba2cf256054c4aa6b75ff2... Author: Alexandre Julliard <julliard(a)winehq.org> Date: Wed Jul 15 10:23:34 2020 +0200 ntdll: Add support for FPU registers in signal context on ARM. Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntdll/unix/signal_arm.c | 73 +++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index abe47da929..1fadb0aa07 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -104,6 +104,48 @@ typedef struct ucontext # define ERROR_sig(context) REG_sig(error_code, context) # define TRAP_sig(context) REG_sig(trap_no, context) +struct extended_ctx +{ + unsigned long magic; + unsigned long size; +}; + +struct vfp_sigframe +{ + struct extended_ctx ctx; + unsigned long long fpregs[32]; + unsigned long fpscr; +}; + +static void *get_extended_sigcontext( const ucontext_t *sigcontext, unsigned int magic ) +{ + struct extended_ctx *ctx = (struct extended_ctx *)sigcontext->uc_regspace; + while ((char *)ctx < (char *)(sigcontext + 1) && ctx->magic && ctx->size) + { + if (ctx->magic == magic) return ctx; + ctx = (struct extended_ctx *)((char *)ctx + ctx->size); + } + return NULL; +} + +static void save_fpu( CONTEXT *context, const ucontext_t *sigcontext ) +{ + struct vfp_sigframe *frame = get_extended_sigcontext( sigcontext, 0x56465001 ); + + if (!frame) return; + memcpy( context->u.D, frame->fpregs, sizeof(context->u.D) ); + context->Fpscr = frame->fpscr; +} + +static void restore_fpu( const CONTEXT *context, ucontext_t *sigcontext ) +{ + struct vfp_sigframe *frame = get_extended_sigcontext( sigcontext, 0x56465001 ); + + if (!frame) return; + memcpy( frame->fpregs, context->u.D, sizeof(context->u.D) ); + frame->fpscr = context->Fpscr; +} + #elif defined(__FreeBSD__) /* All Registers access - only for local access */ @@ -117,6 +159,9 @@ typedef struct ucontext # define IP_sig(context) REGn_sig(_REG_R12, context) /* Intra-Procedure-call scratch register */ # define FP_sig(context) REGn_sig(_REG_FP, context) /* Frame pointer */ +static void save_fpu( CONTEXT *context, const ucontext_t *sigcontext ) { } +static void restore_fpu( const CONTEXT *context, ucontext_t *sigcontext ) { } + #endif /* linux */ enum arm_trap_code @@ -200,6 +245,7 @@ static void save_context( CONTEXT *context, const ucontext_t *sigcontext ) context->Cpsr = CPSR_sig(sigcontext); /* Current State Register */ context->R11 = FP_sig(sigcontext); /* Frame pointer */ context->R12 = IP_sig(sigcontext); /* Intra-Procedure-call scratch register */ + save_fpu( context, sigcontext ); } @@ -216,33 +262,12 @@ static void restore_context( const CONTEXT *context, ucontext_t *sigcontext ) #undef C SP_sig(sigcontext) = context->Sp; /* Stack pointer */ - LR_sig(sigcontext) = context->Lr ; /* Link register */ + LR_sig(sigcontext) = context->Lr; /* Link register */ PC_sig(sigcontext) = context->Pc; /* Program Counter */ CPSR_sig(sigcontext) = context->Cpsr; /* Current State Register */ FP_sig(sigcontext) = context->R11; /* Frame pointer */ IP_sig(sigcontext) = context->R12; /* Intra-Procedure-call scratch register */ -} - - -/*********************************************************************** - * save_fpu - * - * Set the FPU context from a sigcontext. - */ -static inline void save_fpu( CONTEXT *context, const ucontext_t *sigcontext ) -{ - FIXME("not implemented\n"); -} - - -/*********************************************************************** - * restore_fpu - * - * Restore the FPU context to a sigcontext. - */ -static inline void restore_fpu( CONTEXT *context, const ucontext_t *sigcontext ) -{ - FIXME("not implemented\n"); + restore_fpu( context, sigcontext ); } @@ -661,7 +686,6 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) CONTEXT context; NTSTATUS status; - save_fpu( &context, sigcontext ); save_context( &context, sigcontext ); switch (siginfo->si_code & 0xffff ) @@ -716,7 +740,6 @@ static void fpe_handler( int signal, siginfo_t *siginfo, void *sigcontext ) if (status) RtlRaiseStatus( status ); restore_context( &context, sigcontext ); - restore_fpu( &context, sigcontext ); }
participants (1)
-
Alexandre Julliard