From 4ba0f628f9d2c03e419304fc8acbc316afbb91b3 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 5 Dec 2017 10:30:28 +0100 Subject: [PATCH] server: Add floating point and debug registers to the ARM context. Signed-off-by: Alexandre Julliard --- dlls/ntdll/signal_arm.c | 39 ++++++++++++++++++++++++++++++++-- include/wine/server_protocol.h | 4 +++- server/protocol.def | 2 ++ server/thread.c | 2 +- server/trace.c | 17 +++++++++++++++ 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index a0b7bb8ed40..64ff1e010e4 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -347,6 +347,11 @@ static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags ) to->R11 = from->R11; to->R12 = from->R12; } + if (flags & CONTEXT_FLOATING_POINT) + { + to->Fpscr = from->Fpscr; + memcpy( to->u.D, from->u.D, sizeof(to->u.D) ); + } } @@ -357,7 +362,7 @@ static void copy_context( CONTEXT *to, const CONTEXT *from, DWORD flags ) */ NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) { - DWORD flags = from->ContextFlags & ~CONTEXT_ARM; /* get rid of CPU id */ + DWORD i, flags = from->ContextFlags & ~CONTEXT_ARM; /* get rid of CPU id */ memset( to, 0, sizeof(*to) ); to->cpu = CPU_ARM; @@ -387,6 +392,20 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) to->integer.arm_regs.r[11] = from->R11; to->integer.arm_regs.r[12] = from->R12; } + if (flags & CONTEXT_FLOATING_POINT) + { + to->flags |= SERVER_CTX_FLOATING_POINT; + for (i = 0; i < 32; i++) to->fp.arm_regs.d[i] = from->u.D[i]; + to->fp.arm_regs.fpscr = from->Fpscr; + } + if (flags & CONTEXT_DEBUG_REGISTERS) + { + to->flags |= SERVER_CTX_DEBUG_REGISTERS; + for (i = 0; i < ARM_MAX_BREAKPOINTS; i++) to->debug.arm_regs.bvr[i] = from->Bvr[i]; + for (i = 0; i < ARM_MAX_BREAKPOINTS; i++) to->debug.arm_regs.bcr[i] = from->Bcr[i]; + for (i = 0; i < ARM_MAX_WATCHPOINTS; i++) to->debug.arm_regs.wvr[i] = from->Wvr[i]; + for (i = 0; i < ARM_MAX_WATCHPOINTS; i++) to->debug.arm_regs.wcr[i] = from->Wcr[i]; + } return STATUS_SUCCESS; } @@ -398,6 +417,8 @@ NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) */ NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) { + DWORD i; + if (from->cpu != CPU_ARM) return STATUS_INVALID_PARAMETER; to->ContextFlags = CONTEXT_ARM; @@ -425,7 +446,21 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) to->R10 = from->integer.arm_regs.r[10]; to->R11 = from->integer.arm_regs.r[11]; to->R12 = from->integer.arm_regs.r[12]; - } + } + if (from->flags & SERVER_CTX_FLOATING_POINT) + { + to->ContextFlags |= CONTEXT_FLOATING_POINT; + for (i = 0; i < 32; i++) to->u.D[i] = from->fp.arm_regs.d[i]; + to->Fpscr = from->fp.arm_regs.fpscr; + } + if (from->flags & SERVER_CTX_DEBUG_REGISTERS) + { + to->ContextFlags |= CONTEXT_DEBUG_REGISTERS; + for (i = 0; i < ARM_MAX_BREAKPOINTS; i++) to->Bvr[i] = from->debug.arm_regs.bvr[i]; + for (i = 0; i < ARM_MAX_BREAKPOINTS; i++) to->Bcr[i] = from->debug.arm_regs.bcr[i]; + for (i = 0; i < ARM_MAX_WATCHPOINTS; i++) to->Wvr[i] = from->debug.arm_regs.wvr[i]; + for (i = 0; i < ARM_MAX_WATCHPOINTS; i++) to->Wcr[i] = from->debug.arm_regs.wcr[i]; + } return STATUS_SUCCESS; } diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index d8a93b68805..569a23fb51c 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -155,12 +155,14 @@ typedef struct unsigned char regs[80]; } i386_regs; struct { struct { unsigned __int64 low, high; } fpregs[32]; } x86_64_regs; struct { double fpr[32], fpscr; } powerpc_regs; + struct { unsigned __int64 d[32]; unsigned int fpscr; } arm_regs; } fp; union { struct { unsigned int dr0, dr1, dr2, dr3, dr6, dr7; } i386_regs; struct { unsigned __int64 dr0, dr1, dr2, dr3, dr6, dr7; } x86_64_regs; struct { unsigned int dr[8]; } powerpc_regs; + struct { unsigned int bvr[8], bcr[8], wvr[1], wcr[1]; } arm_regs; } debug; union { @@ -6475,6 +6477,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 544 +#define SERVER_PROTOCOL_VERSION 545 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index a3f46409f81..9f11e67c0f1 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -171,12 +171,14 @@ typedef struct unsigned char regs[80]; } i386_regs; struct { struct { unsigned __int64 low, high; } fpregs[32]; } x86_64_regs; struct { double fpr[32], fpscr; } powerpc_regs; + struct { unsigned __int64 d[32]; unsigned int fpscr; } arm_regs; } fp; /* selected by SERVER_CTX_FLOATING_POINT */ union { struct { unsigned int dr0, dr1, dr2, dr3, dr6, dr7; } i386_regs; struct { unsigned __int64 dr0, dr1, dr2, dr3, dr6, dr7; } x86_64_regs; struct { unsigned int dr[8]; } powerpc_regs; + struct { unsigned int bvr[8], bcr[8], wvr[1], wcr[1]; } arm_regs; } debug; /* selected by SERVER_CTX_DEBUG_REGISTERS */ union { diff --git a/server/thread.c b/server/thread.c index 2a57bc9e409..0d647c7a5ba 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1147,7 +1147,7 @@ static unsigned int get_context_system_regs( enum cpu_type cpu ) case CPU_x86: return SERVER_CTX_DEBUG_REGISTERS; case CPU_x86_64: return SERVER_CTX_DEBUG_REGISTERS; case CPU_POWERPC: return 0; - case CPU_ARM: return 0; + case CPU_ARM: return SERVER_CTX_DEBUG_REGISTERS; case CPU_ARM64: return 0; } return 0; diff --git a/server/trace.c b/server/trace.c index 7f84e2a02f1..89506e0fa08 100644 --- a/server/trace.c +++ b/server/trace.c @@ -664,6 +664,23 @@ static void dump_varargs_context( const char *prefix, data_size_t size ) ctx.ctl.arm_regs.pc, ctx.ctl.arm_regs.cpsr ); if (ctx.flags & SERVER_CTX_INTEGER) for (i = 0; i < 13; i++) fprintf( stderr, ",r%u=%08x", i, ctx.integer.arm_regs.r[i] ); + if (ctx.flags & SERVER_CTX_DEBUG_REGISTERS) + { + for (i = 0; i < 8; i++) + fprintf( stderr, ",bcr%u=%08x,bvr%u=%08x", + i, ctx.debug.arm_regs.bcr[i], i, ctx.debug.arm_regs.bvr[i] ); + fprintf( stderr, ",wcr0=%08x,wvr0=%08x", + ctx.debug.arm_regs.wcr[0], ctx.debug.arm_regs.wvr[0] ); + } + if (ctx.flags & SERVER_CTX_FLOATING_POINT) + { + for (i = 0; i < 32; i++) + { + fprintf( stderr, ",d%u=", i ); + dump_uint64( "", &ctx.fp.arm_regs.d[i] ); + } + fprintf( stderr, ",fpscr=%08x", ctx.fp.arm_regs.fpscr ); + } break; case CPU_ARM64: if (ctx.flags & SERVER_CTX_CONTROL)