server: Define a generic context structure instead of using the platform-specific version.
diff --git a/server/Makefile.in b/server/Makefile.in
index 044c0c1..828d7b0 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -14,11 +14,6 @@
 	clipboard.c \
 	completion.c \
 	console.c \
-	context_alpha.c \
-	context_i386.c \
-	context_powerpc.c \
-	context_sparc.c \
-	context_x86_64.c \
 	debugger.c \
 	device.c \
 	directory.c \
diff --git a/server/context_alpha.c b/server/context_alpha.c
deleted file mode 100644
index 3aed4f8..0000000
--- a/server/context_alpha.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Alpha register context support
- *
- * Copyright (C) 2004 Vincent BĂ©ron
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#ifdef __ALPHA__
-
-#include <assert.h>
-#include <errno.h>
-#ifdef HAVE_SYS_REG_H
-# include <sys/reg.h>
-#endif
-#include <stdarg.h>
-#include <unistd.h>
-#ifdef HAVE_SYS_PTRACE_H
-# include <sys/ptrace.h>
-#endif
-
-#include "file.h"
-#include "thread.h"
-#include "request.h"
-
-#if 0  /* no longer used */
-
-#ifdef HAVE_SYS_USER_H
-# include <sys/user.h>
-#endif
-
-/* user definitions from asm/user.h */
-struct kernel_user_struct
-{
-    unsigned long regs[EF_SIZE/8+32];
-    size_t u_tsize;
-    size_t u_dsize;
-    size_t u_ssize;
-    unsigned long start_code;
-    unsigned long start_data;
-    unsigned long start_stack;
-    long int signal;
-    struct regs * u_ar0;
-    unsigned long magic;
-    char u_comm[32];
-};
-
-/* get thread context */
-static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
-{
-    int pid = get_ptrace_pid(thread);
-    if (flags & CONTEXT_FULL)
-    {
-        struct kernel_user_struct regs;
-        if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1) goto error;
-        if (flags & CONTEXT_INTEGER)
-        {
-            context->IntV0 = regs.regs[EF_V0];
-            context->IntT0 = regs.regs[EF_T0];
-            context->IntT1 = regs.regs[EF_T1];
-            context->IntT2 = regs.regs[EF_T2];
-            context->IntT3 = regs.regs[EF_T3];
-            context->IntT4 = regs.regs[EF_T4];
-            context->IntT5 = regs.regs[EF_T5];
-            context->IntT6 = regs.regs[EF_T6];
-            context->IntT7 = regs.regs[EF_T7];
-            context->IntS0 = regs.regs[EF_S0];
-            context->IntS1 = regs.regs[EF_S1];
-            context->IntS2 = regs.regs[EF_S2];
-            context->IntS3 = regs.regs[EF_S3];
-            context->IntS4 = regs.regs[EF_S4];
-            context->IntS5 = regs.regs[EF_S5];
-            context->IntFp = regs.regs[EF_S6];
-            context->IntA0 = regs.regs[EF_A0];
-            context->IntA1 = regs.regs[EF_A1];
-            context->IntA2 = regs.regs[EF_A2];
-            context->IntA3 = regs.regs[EF_A3];
-            context->IntA4 = regs.regs[EF_A4];
-            context->IntA5 = regs.regs[EF_A5];
-            context->IntT8 = regs.regs[EF_T8];
-            context->IntT9 = regs.regs[EF_T9];
-            context->IntT10 = regs.regs[EF_T10];
-            context->IntT11 = regs.regs[EF_T11];
-            context->IntT12 = regs.regs[EF_T12];
-            context->IntAt = regs.regs[EF_AT];
-            context->IntZero = 0;
-        }
-        if (flags & CONTEXT_CONTROL)
-        {
-            context->IntRa = regs.regs[EF_RA];
-            context->IntGp = regs.regs[EF_GP];
-            context->IntSp = regs.regs[EF_SP];
-            context->Fir = regs.regs[EF_PC];
-            context->Psr = regs.regs[EF_PS];
-        }
-        if (flags & CONTEXT_FLOATING_POINT)
-        {
-            context->FltF0 = regs.regs[EF_SIZE/8+0];
-            context->FltF1 = regs.regs[EF_SIZE/8+1];
-            context->FltF2 = regs.regs[EF_SIZE/8+2];
-            context->FltF3 = regs.regs[EF_SIZE/8+3];
-            context->FltF4 = regs.regs[EF_SIZE/8+4];
-            context->FltF5 = regs.regs[EF_SIZE/8+5];
-            context->FltF6 = regs.regs[EF_SIZE/8+6];
-            context->FltF7 = regs.regs[EF_SIZE/8+7];
-            context->FltF8 = regs.regs[EF_SIZE/8+8];
-            context->FltF9 = regs.regs[EF_SIZE/8+9];
-            context->FltF10 = regs.regs[EF_SIZE/8+10];
-            context->FltF11 = regs.regs[EF_SIZE/8+11];
-            context->FltF12 = regs.regs[EF_SIZE/8+12];
-            context->FltF13 = regs.regs[EF_SIZE/8+13];
-            context->FltF14 = regs.regs[EF_SIZE/8+14];
-            context->FltF15 = regs.regs[EF_SIZE/8+15];
-            context->FltF16 = regs.regs[EF_SIZE/8+16];
-            context->FltF17 = regs.regs[EF_SIZE/8+17];
-            context->FltF18 = regs.regs[EF_SIZE/8+18];
-            context->FltF19 = regs.regs[EF_SIZE/8+19];
-            context->FltF20 = regs.regs[EF_SIZE/8+20];
-            context->FltF21 = regs.regs[EF_SIZE/8+21];
-            context->FltF22 = regs.regs[EF_SIZE/8+22];
-            context->FltF23 = regs.regs[EF_SIZE/8+23];
-            context->FltF24 = regs.regs[EF_SIZE/8+24];
-            context->FltF25 = regs.regs[EF_SIZE/8+25];
-            context->FltF26 = regs.regs[EF_SIZE/8+26];
-            context->FltF27 = regs.regs[EF_SIZE/8+27];
-            context->FltF28 = regs.regs[EF_SIZE/8+28];
-            context->FltF29 = regs.regs[EF_SIZE/8+29];
-            context->FltF30 = regs.regs[EF_SIZE/8+30];
-            context->FltF31 = 0;
-            context->Fpcr = regs.regs[EF_SIZE/8+31];
-            context->SoftFpcr = 0; /* FIXME */
-        }
-        context->ContextFlags |= flags & CONTEXT_FULL;
-    }
-    return;
- error:
-    file_set_error();
-}
-
-/* set a thread context */
-static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context )
-{
-    int pid = get_ptrace_pid(thread);
-    if (flags & CONTEXT_FULL)
-    {
-        struct kernel_user_struct regs;
-        if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1) goto error;
-        if (flags & CONTEXT_INTEGER)
-        {
-            regs.regs[EF_V0] = context->IntV0;
-            regs.regs[EF_T0] = context->IntT0;
-            regs.regs[EF_T1] = context->IntT1;
-            regs.regs[EF_T2] = context->IntT2;
-            regs.regs[EF_T3] = context->IntT3;
-            regs.regs[EF_T4] = context->IntT4;
-            regs.regs[EF_T5] = context->IntT5;
-            regs.regs[EF_T6] = context->IntT6;
-            regs.regs[EF_T7] = context->IntT7;
-            regs.regs[EF_S0] = context->IntS0;
-            regs.regs[EF_S1] = context->IntS1;
-            regs.regs[EF_S2] = context->IntS2;
-            regs.regs[EF_S3] = context->IntS3;
-            regs.regs[EF_S4] = context->IntS4;
-            regs.regs[EF_S5] = context->IntS5;
-            regs.regs[EF_S6] = context->IntFp;
-            regs.regs[EF_A0] = context->IntA0;
-            regs.regs[EF_A1] = context->IntA1;
-            regs.regs[EF_A2] = context->IntA2;
-            regs.regs[EF_A3] = context->IntA3;
-            regs.regs[EF_A4] = context->IntA4;
-            regs.regs[EF_A5] = context->IntA5;
-            regs.regs[EF_T8] = context->IntT8;
-            regs.regs[EF_T9] = context->IntT9;
-            regs.regs[EF_T10] = context->IntT10;
-            regs.regs[EF_T11] = context->IntT11;
-            regs.regs[EF_T12] = context->IntT12;
-            regs.regs[EF_AT] = context->IntAt;
-        }
-        if (flags & CONTEXT_CONTROL)
-        {
-            regs.regs[EF_RA] = context->IntRa;
-            regs.regs[EF_GP] = context->IntGp;
-            regs.regs[EF_SP] = context->IntSp;
-            regs.regs[EF_PC] = context->Fir;
-            regs.regs[EF_PS] = context->Psr;
-        }
-        if (flags & CONTEXT_FLOATING_POINT)
-        {
-            regs.regs[EF_SIZE/8+0] = context->FltF0;
-            regs.regs[EF_SIZE/8+1] = context->FltF1;
-            regs.regs[EF_SIZE/8+2] = context->FltF2;
-            regs.regs[EF_SIZE/8+3] = context->FltF3;
-            regs.regs[EF_SIZE/8+4] = context->FltF4;
-            regs.regs[EF_SIZE/8+5] = context->FltF5;
-            regs.regs[EF_SIZE/8+6] = context->FltF6;
-            regs.regs[EF_SIZE/8+7] = context->FltF7;
-            regs.regs[EF_SIZE/8+8] = context->FltF8;
-            regs.regs[EF_SIZE/8+9] = context->FltF9;
-            regs.regs[EF_SIZE/8+10] = context->FltF10;
-            regs.regs[EF_SIZE/8+11] = context->FltF11;
-            regs.regs[EF_SIZE/8+12] = context->FltF12;
-            regs.regs[EF_SIZE/8+13] = context->FltF13;
-            regs.regs[EF_SIZE/8+14] = context->FltF14;
-            regs.regs[EF_SIZE/8+15] = context->FltF15;
-            regs.regs[EF_SIZE/8+16] = context->FltF16;
-            regs.regs[EF_SIZE/8+17] = context->FltF17;
-            regs.regs[EF_SIZE/8+18] = context->FltF18;
-            regs.regs[EF_SIZE/8+19] = context->FltF19;
-            regs.regs[EF_SIZE/8+20] = context->FltF20;
-            regs.regs[EF_SIZE/8+21] = context->FltF21;
-            regs.regs[EF_SIZE/8+22] = context->FltF22;
-            regs.regs[EF_SIZE/8+23] = context->FltF23;
-            regs.regs[EF_SIZE/8+24] = context->FltF24;
-            regs.regs[EF_SIZE/8+25] = context->FltF25;
-            regs.regs[EF_SIZE/8+26] = context->FltF26;
-            regs.regs[EF_SIZE/8+27] = context->FltF27;
-            regs.regs[EF_SIZE/8+28] = context->FltF28;
-            regs.regs[EF_SIZE/8+29] = context->FltF29;
-            regs.regs[EF_SIZE/8+30] = context->FltF30;
-            regs.regs[EF_SIZE/8+31] = context->Fpcr;
-        }
-        if (ptrace( PTRACE_SETREGS, pid, 0, &regs ) == -1) goto error;
-    }
-    return;
- error:
-    file_set_error();
-}
-
-#endif /* 0 */
-
-/* copy a context structure according to the flags */
-void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
-{
-    flags &= ~CONTEXT_ALPHA;  /* get rid of CPU id */
-    if (flags & CONTEXT_CONTROL)
-    {
-        to->IntRa = from->IntRa;
-        to->IntGp = from->IntGp;
-        to->IntSp = from->IntSp;
-        to->Fir = from->Fir;
-        to->Psr = from->Psr;
-    }
-    if (flags & CONTEXT_INTEGER)
-    {
-        to->IntV0 = from->IntV0;
-        to->IntT0 = from->IntT0;
-        to->IntT1 = from->IntT1;
-        to->IntT2 = from->IntT2;
-        to->IntT3 = from->IntT3;
-        to->IntT4 = from->IntT4;
-        to->IntT5 = from->IntT5;
-        to->IntT6 = from->IntT6;
-        to->IntT7 = from->IntT7;
-        to->IntS0 = from->IntS0;
-        to->IntS1 = from->IntS1;
-        to->IntS2 = from->IntS2;
-        to->IntS3 = from->IntS3;
-        to->IntS4 = from->IntS4;
-        to->IntS5 = from->IntS5;
-        to->IntFp = from->IntFp;
-        to->IntA0 = from->IntA0;
-        to->IntA1 = from->IntA1;
-        to->IntA2 = from->IntA2;
-        to->IntA3 = from->IntA3;
-        to->IntA4 = from->IntA4;
-        to->IntA5 = from->IntA5;
-        to->IntT8 = from->IntT8;
-        to->IntT9 = from->IntT9;
-        to->IntT10 = from->IntT10;
-        to->IntT11 = from->IntT11;
-        to->IntT12 = from->IntT12;
-        to->IntAt = from->IntAt;
-        to->IntZero = from->IntZero;
-    }
-    if (flags & CONTEXT_FLOATING_POINT)
-    {
-        to->FltF0 = from->FltF0;
-        to->FltF1 = from->FltF1;
-        to->FltF2 = from->FltF2;
-        to->FltF3 = from->FltF3;
-        to->FltF4 = from->FltF4;
-        to->FltF5 = from->FltF5;
-        to->FltF6 = from->FltF6;
-        to->FltF7 = from->FltF7;
-        to->FltF8 = from->FltF8;
-        to->FltF9 = from->FltF9;
-        to->FltF10 = from->FltF10;
-        to->FltF11 = from->FltF11;
-        to->FltF12 = from->FltF12;
-        to->FltF13 = from->FltF13;
-        to->FltF14 = from->FltF14;
-        to->FltF15 = from->FltF15;
-        to->FltF16 = from->FltF16;
-        to->FltF17 = from->FltF17;
-        to->FltF18 = from->FltF18;
-        to->FltF19 = from->FltF19;
-        to->FltF20 = from->FltF20;
-        to->FltF21 = from->FltF21;
-        to->FltF22 = from->FltF22;
-        to->FltF23 = from->FltF23;
-        to->FltF24 = from->FltF24;
-        to->FltF25 = from->FltF25;
-        to->FltF26 = from->FltF26;
-        to->FltF27 = from->FltF27;
-        to->FltF28 = from->FltF28;
-        to->FltF29 = from->FltF29;
-        to->FltF30 = from->FltF30;
-        to->FltF31 = from->FltF31;
-        to->Fpcr = from->Fpcr;
-        to->SoftFpcr = from->SoftFpcr;
-    }
-    to->ContextFlags |= flags;
-}
-
-/* retrieve the current instruction pointer of a context */
-client_ptr_t get_context_ip( const CONTEXT *context )
-{
-    return context->Fir;
-}
-
-/* return the context flag that contains the CPU id */
-unsigned int get_context_cpu_flag(void)
-{
-    return CONTEXT_ALPHA;
-}
-
-/* return only the context flags that correspond to system regs */
-/* (system regs are the ones we can't access on the client side) */
-unsigned int get_context_system_regs( unsigned int flags )
-{
-    return 0;  /* FIXME: implement client-side handling */
-}
-
-#endif  /* __ALPHA__ */
diff --git a/server/context_i386.c b/server/context_i386.c
deleted file mode 100644
index 458b04f..0000000
--- a/server/context_i386.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * i386 register context support
- *
- * Copyright (C) 1999 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#ifdef __i386__
-
-#include <assert.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <unistd.h>
-
-#include "windef.h"
-
-#include "file.h"
-#include "thread.h"
-#include "request.h"
-
-/* copy a context structure according to the flags */
-void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
-{
-    flags &= ~CONTEXT_i386;  /* get rid of CPU id */
-    if (flags & CONTEXT_CONTROL)
-    {
-        to->Ebp    = from->Ebp;
-        to->Eip    = from->Eip;
-        to->Esp    = from->Esp;
-        to->SegCs  = from->SegCs;
-        to->SegSs  = from->SegSs;
-        to->EFlags = from->EFlags;
-    }
-    if (flags & CONTEXT_INTEGER)
-    {
-        to->Eax = from->Eax;
-        to->Ebx = from->Ebx;
-        to->Ecx = from->Ecx;
-        to->Edx = from->Edx;
-        to->Esi = from->Esi;
-        to->Edi = from->Edi;
-    }
-    if (flags & CONTEXT_SEGMENTS)
-    {
-        to->SegDs = from->SegDs;
-        to->SegEs = from->SegEs;
-        to->SegFs = from->SegFs;
-        to->SegGs = from->SegGs;
-    }
-    if (flags & CONTEXT_FLOATING_POINT)
-    {
-        to->FloatSave = from->FloatSave;
-    }
-    if (flags & CONTEXT_EXTENDED_REGISTERS)
-    {
-        memcpy( to->ExtendedRegisters, from->ExtendedRegisters, sizeof(to->ExtendedRegisters) );
-    }
-    if (flags & CONTEXT_DEBUG_REGISTERS)
-    {
-        to->Dr0 = from->Dr0;
-        to->Dr1 = from->Dr1;
-        to->Dr2 = from->Dr2;
-        to->Dr3 = from->Dr3;
-        to->Dr6 = from->Dr6;
-        to->Dr7 = from->Dr7;
-    }
-    to->ContextFlags |= flags;
-}
-
-/* retrieve the current instruction pointer of a context */
-client_ptr_t get_context_ip( const CONTEXT *context )
-{
-    return context->Eip;
-}
-
-/* return the context flag that contains the CPU id */
-unsigned int get_context_cpu_flag(void)
-{
-    return CONTEXT_i386;
-}
-
-/* return only the context flags that correspond to system regs */
-/* (system regs are the ones we can't access on the client side) */
-unsigned int get_context_system_regs( unsigned int flags )
-{
-    return flags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386);
-}
-
-#endif  /* __i386__ */
diff --git a/server/context_powerpc.c b/server/context_powerpc.c
deleted file mode 100644
index 9825a4a..0000000
--- a/server/context_powerpc.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * PowerPC register context support
- *
- * Copyright (C) 2002 Marcus Meissner, SuSE Linux AG.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#ifdef __powerpc__
-
-#include <assert.h>
-#include <errno.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_REG_H
-# include <sys/reg.h>
-#endif
-#include <stdarg.h>
-#include <unistd.h>
-#ifdef HAVE_SYS_PTRACE_H
-# include <sys/ptrace.h>
-#endif
-
-#include "windef.h"
-
-#if 0  /* no longer used */
-
-#ifndef PTRACE_PEEKUSER
-# ifdef PT_READ_D
-#  define PTRACE_PEEKUSER PT_READ_D
-# endif
-#endif /* PTRACE_PEEKUSER */
-
-#ifndef PTRACE_POKEUSER
-# ifdef PT_WRITE_D
-#  define PTRACE_POKEUSER PT_WRITE_D
-# endif
-#endif /* PTRACE_POKEUSER */
-
-#include "file.h"
-#include "thread.h"
-#include "request.h"
-
-/* retrieve a thread context */
-static void get_thread_context_ptrace( struct thread *thread, unsigned int flags, CONTEXT *context )
-{
-    int pid = get_ptrace_pid(thread);
-    if (flags & CONTEXT_INTEGER)
-    {
-#define XREG(x,y) if (ptrace( PTRACE_PEEKUSER, pid, (void*)(x<<2), &context->y) == -1) goto error;
-#define IREG(x) if (ptrace( PTRACE_PEEKUSER, pid, (void*)(x<<2), &context->Gpr##x) == -1) goto error;
-        IREG(0); IREG(1); IREG(2); IREG(3); IREG(4); IREG(5); IREG(6);
-        IREG(7); IREG(8); IREG(9); IREG(10); IREG(11); IREG(12); IREG(13);
-        IREG(14); IREG(15); IREG(16); IREG(17); IREG(18); IREG(19);
-        IREG(20); IREG(21); IREG(22); IREG(23); IREG(24); IREG(25);
-        IREG(26); IREG(27); IREG(28); IREG(29); IREG(30); IREG(31);
-#undef IREG
-        XREG(37,Xer);
-        XREG(38,Cr);
-        context->ContextFlags |= CONTEXT_INTEGER;
-    }
-    if (flags & CONTEXT_CONTROL)
-    {
-        XREG(32,Iar);
-        XREG(33,Msr);
-        XREG(35,Ctr);
-        XREG(36,Lr); /* 36 is LNK ... probably Lr ? */
-        context->ContextFlags |= CONTEXT_CONTROL;
-    }
-    if (flags & CONTEXT_FLOATING_POINT)
-    {
-#define FREG(x) if (ptrace( PTRACE_PEEKUSER, pid, (void*)((48+x*2)<<2), &context->Fpr##x) == -1) goto error;
-	FREG(0);
-	FREG(1);
-	FREG(2);
-	FREG(3);
-	FREG(4);
-	FREG(5);
-	FREG(6);
-	FREG(7);
-	FREG(8);
-	FREG(9);
-	FREG(10);
-	FREG(11);
-	FREG(12);
-	FREG(13);
-	FREG(14);
-	FREG(15);
-	FREG(16);
-	FREG(17);
-	FREG(18);
-	FREG(19);
-	FREG(20);
-	FREG(21);
-	FREG(22);
-	FREG(23);
-	FREG(24);
-	FREG(25);
-	FREG(26);
-	FREG(27);
-	FREG(28);
-	FREG(29);
-	FREG(30);
-	FREG(31);
-	XREG((48+32*2),Fpscr);
-        context->ContextFlags |= CONTEXT_FLOATING_POINT;
-    }
-    return;
- error:
-    file_set_error();
-}
-#undef XREG
-#undef IREG
-#undef FREG
-
-#define XREG(x,y) if (ptrace( PTRACE_POKEUSER, pid, (void*)(x<<2), &context->y) == -1) goto error;
-#define IREG(x) if (ptrace( PTRACE_POKEUSER, pid, (void*)(x<<2), &context->Gpr##x) == -1) goto error;
-#define FREG(x) if (ptrace( PTRACE_POKEUSER, pid, (void*)((48+x*2)<<2), &context->Fpr##x) == -1) goto error;
-/* set a thread context */
-static void set_thread_context_ptrace( struct thread *thread, unsigned int flags, const CONTEXT *context )
-{
-    int pid = get_ptrace_pid(thread);
-    if (flags & CONTEXT_FULL)
-    {
-        if (flags & CONTEXT_INTEGER)
-        {
-	    IREG(0); IREG(1); IREG(2); IREG(3); IREG(4); IREG(5); IREG(6);
-	    IREG(7); IREG(8); IREG(9); IREG(10); IREG(11); IREG(12); IREG(13);
-	    IREG(14); IREG(15); IREG(16); IREG(17); IREG(18); IREG(19);
-	    IREG(20); IREG(21); IREG(22); IREG(23); IREG(24); IREG(25);
-	    IREG(26); IREG(27); IREG(28); IREG(29); IREG(30); IREG(31);
-	    XREG(37,Xer);
-	    XREG(38,Cr);
-
-        }
-        if (flags & CONTEXT_CONTROL)
-        {
-	    XREG(32,Iar);
-	    XREG(33,Msr);
-	    XREG(35,Ctr);
-	    XREG(36,Lr);
-        }
-    }
-    if (flags & CONTEXT_FLOATING_POINT)
-    {
-	FREG(0);
-	FREG(1);
-	FREG(2);
-	FREG(3);
-	FREG(4);
-	FREG(5);
-	FREG(6);
-	FREG(7);
-	FREG(8);
-	FREG(9);
-	FREG(10);
-	FREG(11);
-	FREG(12);
-	FREG(13);
-	FREG(14);
-	FREG(15);
-	FREG(16);
-	FREG(17);
-	FREG(18);
-	FREG(19);
-	FREG(20);
-	FREG(21);
-	FREG(22);
-	FREG(23);
-	FREG(24);
-	FREG(25);
-	FREG(26);
-	FREG(27);
-	FREG(28);
-	FREG(29);
-	FREG(30);
-	FREG(31);
-#undef FREG
-	XREG((48+32*2),Fpscr);
-    }
-    return;
- error:
-    file_set_error();
-}
-#undef XREG
-#undef IREG
-#undef FREG
-
-#endif /* 0 */
-
-#define IREG(x) to->Gpr##x = from->Gpr##x;
-#define FREG(x) to->Fpr##x = from->Fpr##x;
-#define CREG(x) to->x = from->x;
-/* copy a context structure according to the flags */
-void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
-{
-    if (flags & CONTEXT_CONTROL)
-    {
-    	CREG(Msr);
-    	CREG(Ctr);
-    	CREG(Iar);
-        to->ContextFlags |= CONTEXT_CONTROL;
-    }
-    if (flags & CONTEXT_INTEGER)
-    {
-	IREG(0); IREG(1); IREG(2); IREG(3); IREG(4); IREG(5); IREG(6);
-	IREG(7); IREG(8); IREG(9); IREG(10); IREG(11); IREG(12); IREG(13);
-	IREG(14); IREG(15); IREG(16); IREG(17); IREG(18); IREG(19);
-	IREG(20); IREG(21); IREG(22); IREG(23); IREG(24); IREG(25);
-	IREG(26); IREG(27); IREG(28); IREG(29); IREG(30); IREG(31);
-	CREG(Xer);
-	CREG(Cr);
-        to->ContextFlags |= CONTEXT_INTEGER;
-    }
-    if (flags & CONTEXT_FLOATING_POINT)
-    {
-	FREG(0);
-	FREG(1);
-	FREG(2);
-	FREG(3);
-	FREG(4);
-	FREG(5);
-	FREG(6);
-	FREG(7);
-	FREG(8);
-	FREG(9);
-	FREG(10);
-	FREG(11);
-	FREG(12);
-	FREG(13);
-	FREG(14);
-	FREG(15);
-	FREG(16);
-	FREG(17);
-	FREG(18);
-	FREG(19);
-	FREG(20);
-	FREG(21);
-	FREG(22);
-	FREG(23);
-	FREG(24);
-	FREG(25);
-	FREG(26);
-	FREG(27);
-	FREG(28);
-	FREG(29);
-	FREG(30);
-	FREG(31);
-	CREG(Fpscr);
-        to->ContextFlags |= CONTEXT_FLOATING_POINT;
-    }
-}
-
-/* retrieve the current instruction pointer of a context */
-client_ptr_t get_context_ip( const CONTEXT *context )
-{
-    return context->Iar;
-}
-
-/* return the context flag that contains the CPU id */
-unsigned int get_context_cpu_flag(void)
-{
-    return 0;
-}
-
-/* return only the context flags that correspond to system regs */
-/* (system regs are the ones we can't access on the client side) */
-unsigned int get_context_system_regs( unsigned int flags )
-{
-    return 0;  /* FIXME: implement client-side handling */
-}
-
-#endif  /* __powerpc__ */
diff --git a/server/context_sparc.c b/server/context_sparc.c
deleted file mode 100644
index b94d917..0000000
--- a/server/context_sparc.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Sparc register context support
- *
- * Copyright (C) 2000 Ulrich Weigand
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#ifdef __sparc__
-
-#include <assert.h>
-#include <errno.h>
-#include <sys/types.h>
-#ifdef HAVE_SYS_REG_H
-# include <sys/reg.h>
-#endif
-#include <stdarg.h>
-#include <unistd.h>
-#ifdef HAVE_SYS_PTRACE_H
-# include <sys/ptrace.h>
-#endif
-
-#include "windef.h"
-
-#include "file.h"
-#include "thread.h"
-#include "request.h"
-
-#if 0  /* no longer used */
-
-#if defined(__sun) || defined(__sun__)
-
-/* retrieve a thread context */
-static void get_thread_context_ptrace( struct thread *thread, unsigned int flags, CONTEXT *context )
-{
-    int pid = get_ptrace_pid(thread);
-    if (flags & CONTEXT_FULL)
-    {
-        struct regs regs;
-        if (ptrace( PTRACE_GETREGS, pid, 0, (int) &regs ) == -1) goto error;
-        if (flags & CONTEXT_INTEGER)
-        {
-            context->g0 = 0;
-            context->g1 = regs.r_g1;
-            context->g2 = regs.r_g2;
-            context->g3 = regs.r_g3;
-            context->g4 = regs.r_g4;
-            context->g5 = regs.r_g5;
-            context->g6 = regs.r_g6;
-            context->g7 = regs.r_g7;
-
-            context->o0 = regs.r_o0;
-            context->o1 = regs.r_o1;
-            context->o2 = regs.r_o2;
-            context->o3 = regs.r_o3;
-            context->o4 = regs.r_o4;
-            context->o5 = regs.r_o5;
-            context->o6 = regs.r_o6;
-            context->o7 = regs.r_o7;
-
-            /* FIXME: local and in registers */
-        }
-        if (flags & CONTEXT_CONTROL)
-        {
-            context->psr = regs.r_psr;
-            context->pc  = regs.r_pc;
-            context->npc = regs.r_npc;
-            context->y   = regs.r_y;
-            context->wim = 0;  /* FIXME */
-            context->tbr = 0;  /* FIXME */
-        }
-        context |= flags & (CONTEXT_CONTROL|CONTEXT_INTEGER);
-    }
-    if (flags & CONTEXT_FLOATING_POINT)
-    {
-        /* FIXME */
-    }
-    return;
- error:
-    file_set_error();
-}
-
-
-/* set a thread context */
-static void set_thread_context_ptrace( struct thread *thread, unsigned int flags, const CONTEXT *context )
-{
-    /* FIXME */
-}
-
-#else  /* __sun__ */
-#error You must implement get/set_thread_context_ptrace for your platform
-#endif  /* __sun__ */
-
-#endif /* 0 */
-
-/* copy a context structure according to the flags */
-void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
-{
-    flags &= ~CONTEXT_SPARC;  /* get rid of CPU id */
-    if (flags & CONTEXT_CONTROL)
-    {
-        to->psr    = from->psr;
-        to->pc     = from->pc;
-        to->npc    = from->npc;
-        to->y      = from->y;
-        to->wim    = from->wim;
-        to->tbr    = from->tbr;
-    }
-    if (flags & CONTEXT_INTEGER)
-    {
-        to->g0 = from->g0;
-        to->g1 = from->g1;
-        to->g2 = from->g2;
-        to->g3 = from->g3;
-        to->g4 = from->g4;
-        to->g5 = from->g5;
-        to->g6 = from->g6;
-        to->g7 = from->g7;
-        to->o0 = from->o0;
-        to->o1 = from->o1;
-        to->o2 = from->o2;
-        to->o3 = from->o3;
-        to->o4 = from->o4;
-        to->o5 = from->o5;
-        to->o6 = from->o6;
-        to->o7 = from->o7;
-        to->l0 = from->l0;
-        to->l1 = from->l1;
-        to->l2 = from->l2;
-        to->l3 = from->l3;
-        to->l4 = from->l4;
-        to->l5 = from->l5;
-        to->l6 = from->l6;
-        to->l7 = from->l7;
-        to->i0 = from->i0;
-        to->i1 = from->i1;
-        to->i2 = from->i2;
-        to->i3 = from->i3;
-        to->i4 = from->i4;
-        to->i5 = from->i5;
-        to->i6 = from->i6;
-        to->i7 = from->i7;
-    }
-    if (flags & CONTEXT_FLOATING_POINT)
-    {
-        /* FIXME */
-    }
-    context |= flags & (CONTEXT_CONTROL|CONTEXT_INTEGER);
-}
-
-/* retrieve the current instruction pointer of a context */
-client_ptr_t get_context_ip( const CONTEXT *context )
-{
-    return context->pc;
-}
-
-/* return the context flag that contains the CPU id */
-unsigned int get_context_cpu_flag(void)
-{
-    return CONTEXT_SPARC;
-}
-
-/* return only the context flags that correspond to system regs */
-/* (system regs are the ones we can't access on the client side) */
-unsigned int get_context_system_regs( unsigned int flags )
-{
-    return 0;  /* FIXME: implement client-side handling */
-}
-
-#endif  /* __sparc__ */
diff --git a/server/context_x86_64.c b/server/context_x86_64.c
deleted file mode 100644
index 264c549..0000000
--- a/server/context_x86_64.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * x86-64 register context support
- *
- * Copyright (C) 1999, 2005 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "config.h"
-
-#ifdef __x86_64__
-
-#include <assert.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <unistd.h>
-
-#define NONAMELESSUNION
-#include "windef.h"
-#include "winbase.h"
-
-#include "file.h"
-#include "thread.h"
-#include "request.h"
-
-/* copy a context structure according to the flags */
-void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags )
-{
-    flags &= ~CONTEXT_AMD64;  /* get rid of CPU id */
-    if (flags & CONTEXT_CONTROL)
-    {
-        to->Rbp    = from->Rbp;
-        to->Rip    = from->Rip;
-        to->Rsp    = from->Rsp;
-        to->SegCs  = from->SegCs;
-        to->SegSs  = from->SegSs;
-        to->EFlags = from->EFlags;
-        to->MxCsr  = from->MxCsr;
-    }
-    if (flags & CONTEXT_INTEGER)
-    {
-        to->Rax = from->Rax;
-        to->Rcx = from->Rcx;
-        to->Rdx = from->Rdx;
-        to->Rbx = from->Rbx;
-        to->Rsi = from->Rsi;
-        to->Rdi = from->Rdi;
-        to->R8  = from->R8;
-        to->R9  = from->R9;
-        to->R10 = from->R10;
-        to->R11 = from->R11;
-        to->R12 = from->R12;
-        to->R13 = from->R13;
-        to->R14 = from->R14;
-        to->R15 = from->R15;
-    }
-    if (flags & CONTEXT_SEGMENTS)
-    {
-        to->SegDs = from->SegDs;
-        to->SegEs = from->SegEs;
-        to->SegFs = from->SegFs;
-        to->SegGs = from->SegGs;
-    }
-    if (flags & CONTEXT_FLOATING_POINT)
-    {
-        to->u.FltSave = from->u.FltSave;
-    }
-    /* we don't bother copying the debug registers, since they */
-    /* always need to be accessed by ptrace anyway */
-    to->ContextFlags |= flags & ~CONTEXT_DEBUG_REGISTERS;
-}
-
-/* retrieve the current instruction pointer of a context */
-client_ptr_t get_context_ip( const CONTEXT *context )
-{
-    return context->Rip;
-}
-
-/* return the context flag that contains the CPU id */
-unsigned int get_context_cpu_flag(void)
-{
-    return CONTEXT_AMD64;
-}
-
-/* return only the context flags that correspond to system regs */
-/* (system regs are the ones we can't access on the client side) */
-unsigned int get_context_system_regs( unsigned int flags )
-{
-    return flags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64);
-}
-
-#endif  /* __x86_64__ */
diff --git a/server/debugger.c b/server/debugger.c
index 9399cb3..c01ab45 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -49,7 +49,7 @@
     enum debug_event_state state;     /* event state */
     int                    status;    /* continuation status */
     debug_event_t          data;      /* event data */
-    CONTEXT                context;   /* register context */
+    context_t              context;   /* register context */
 };
 
 /* debug context */
@@ -652,11 +652,11 @@
 
         if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data )))
         {
-            const CONTEXT *context = (const CONTEXT *)((char *)get_req_data() + req->len);
+            const context_t *context = (const context_t *)((char *)get_req_data() + req->len);
             data_size_t size = get_req_data_size() - req->len;
 
             memset( &event->context, 0, sizeof(event->context) );
-            memcpy( &event->context, context, size );
+            memcpy( &event->context, context, min( sizeof(event->context), size ) );
             current->context = &event->context;
 
             if ((reply->handle = alloc_handle( current->process, event, SYNCHRONIZE, 0 )))
@@ -682,7 +682,7 @@
         {
             if (current->context == &event->context)
             {
-                data_size_t size = min( sizeof(CONTEXT), get_reply_max_size() );
+                data_size_t size = min( sizeof(context_t), get_reply_max_size() );
                 set_reply_data( &event->context, size );
                 current->context = NULL;
             }
diff --git a/server/mach.c b/server/mach.c
index fcc87a3..f9490f3 100644
--- a/server/mach.c
+++ b/server/mach.c
@@ -160,7 +160,7 @@
 }
 
 /* retrieve the thread x86 registers */
-void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
+void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
 {
 #ifdef __i386__
     x86_debug_state32_t state;
@@ -169,7 +169,7 @@
     mach_port_t port, process_port = get_process_port( thread->process );
 
     /* all other regs are handled on the client side */
-    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
+    assert( flags == SERVER_CTX_DEBUG_REGISTERS );
 
     if (thread->unix_pid == -1 || !process_port ||
         mach_port_extract_right( process_port, thread->unix_tid,
@@ -183,28 +183,28 @@
     {
 /* work around silly renaming of struct members in OS X 10.5 */
 #if __DARWIN_UNIX03 && defined(_STRUCT_X86_DEBUG_STATE32)
-        context->Dr0 = state.__dr0;
-        context->Dr1 = state.__dr1;
-        context->Dr2 = state.__dr2;
-        context->Dr3 = state.__dr3;
-        context->Dr6 = state.__dr6;
-        context->Dr7 = state.__dr7;
+        context->debug.i386_regs.dr0 = state.__dr0;
+        context->debug.i386_regs.dr1 = state.__dr1;
+        context->debug.i386_regs.dr2 = state.__dr2;
+        context->debug.i386_regs.dr3 = state.__dr3;
+        context->debug.i386_regs.dr6 = state.__dr6;
+        context->debug.i386_regs.dr7 = state.__dr7;
 #else
-        context->Dr0 = state.dr0;
-        context->Dr1 = state.dr1;
-        context->Dr2 = state.dr2;
-        context->Dr3 = state.dr3;
-        context->Dr6 = state.dr6;
-        context->Dr7 = state.dr7;
+        context->debug.i386_regs.dr0 = state.dr0;
+        context->debug.i386_regs.dr1 = state.dr1;
+        context->debug.i386_regs.dr2 = state.dr2;
+        context->debug.i386_regs.dr3 = state.dr3;
+        context->debug.i386_regs.dr6 = state.dr6;
+        context->debug.i386_regs.dr7 = state.dr7;
 #endif
-        context->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
+        context->flags |= SERVER_CTX_DEBUG_REGISTERS;
     }
     mach_port_deallocate( mach_task_self(), port );
 #endif
 }
 
 /* set the thread x86 registers */
-void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
+void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
 {
 #ifdef __i386__
     x86_debug_state32_t state;
@@ -213,7 +213,7 @@
     mach_port_t port, process_port = get_process_port( thread->process );
 
     /* all other regs are handled on the client side */
-    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
+    assert( flags == SERVER_CTX_DEBUG_REGISTERS );
 
     if (thread->unix_pid == -1 || !process_port ||
         mach_port_extract_right( process_port, thread->unix_tid,
@@ -224,35 +224,28 @@
     }
 
 #if __DARWIN_UNIX03 && defined(_STRUCT_X86_DEBUG_STATE32)
-    state.__dr0 = context->Dr0;
-    state.__dr1 = context->Dr1;
-    state.__dr2 = context->Dr2;
-    state.__dr3 = context->Dr3;
+    state.__dr0 = context->debug.i386_regs.dr0;
+    state.__dr1 = context->debug.i386_regs.dr1;
+    state.__dr2 = context->debug.i386_regs.dr2;
+    state.__dr3 = context->debug.i386_regs.dr3;
     state.__dr4 = 0;
     state.__dr5 = 0;
-    state.__dr6 = context->Dr6;
-    state.__dr7 = context->Dr7;
+    state.__dr6 = context->debug.i386_regs.dr6;
+    state.__dr7 = context->debug.i386_regs.dr7;
 #else
-    state.dr0 = context->Dr0;
-    state.dr1 = context->Dr1;
-    state.dr2 = context->Dr2;
-    state.dr3 = context->Dr3;
+    state.dr0 = context->debug.i386_regs.dr0;
+    state.dr1 = context->debug.i386_regs.dr1;
+    state.dr2 = context->debug.i386_regs.dr2;
+    state.dr3 = context->debug.i386_regs.dr3;
     state.dr4 = 0;
     state.dr5 = 0;
-    state.dr6 = context->Dr6;
-    state.dr7 = context->Dr7;
+    state.dr6 = context->debug.i386_regs.dr6;
+    state.dr7 = context->debug.i386_regs.dr7;
 #endif
     if (!thread_set_state( port, x86_DEBUG_STATE32, (thread_state_t)&state, count ))
     {
         if (thread->context)  /* update the cached values */
-        {
-            thread->context->Dr0 = context->Dr0;
-            thread->context->Dr1 = context->Dr1;
-            thread->context->Dr2 = context->Dr2;
-            thread->context->Dr3 = context->Dr3;
-            thread->context->Dr6 = context->Dr6;
-            thread->context->Dr7 = context->Dr7;
-        }
+            thread->context->debug.i386_regs = context->debug.i386_regs;
     }
     mach_port_deallocate( mach_task_self(), port );
 #endif
diff --git a/server/procfs.c b/server/procfs.c
index 5978bbc..3b74e14 100644
--- a/server/procfs.c
+++ b/server/procfs.c
@@ -200,20 +200,14 @@
 }
 
 /* retrieve the thread registers */
-void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
+void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
 {
-    /* all other regs are handled on the client side */
-    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
-
     /* FIXME: get debug registers */
 }
 
 /* set the thread registers */
-void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
+void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
 {
-    /* all other regs are handled on the client side */
-    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
-
     /* FIXME: set debug registers */
 }
 
diff --git a/server/protocol.def b/server/protocol.def
index 0f7e7de..004f4c9 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -150,6 +150,63 @@
 };
 typedef int cpu_type_t;
 
+/* context data */
+typedef struct
+{
+    cpu_type_t       cpu;        /* cpu type */
+    unsigned int     flags;      /* SERVER_CTX_* flags */
+    union
+    {
+        struct { unsigned int eip, ebp, esp, eflags, cs, ss; } i386_regs;
+        struct { unsigned __int64 rip, rbp, rsp;
+                 unsigned int cs, ss, flags, mxcsr; } x86_64_regs;
+        struct { unsigned __int64 fir;
+                 unsigned int psr; } alpha_regs;
+        struct { unsigned int iar, msr, ctr, lr, dar, dsisr, trap; } powerpc_regs;
+        struct { unsigned int psr, pc, npc, y, wim, tbr; } sparc_regs;
+    } ctl;  /* selected by SERVER_CTX_CONTROL */
+    union
+    {
+        struct { unsigned int eax, ebx, ecx, edx, esi, edi; } i386_regs;
+        struct { unsigned __int64 rax,rbx, rcx, rdx, rsi, rdi,
+                                  r8, r9, r10, r11, r12, r13, r14, r15; } x86_64_regs;
+        struct { unsigned __int64 v0, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12,
+                                  s0, s1, s2, s3, s4, s5, s6, a0, a1, a2, a3, a4, a5, at; } alpha_regs;
+        struct { unsigned int gpr[32], cr, xer; } powerpc_regs;
+        struct { unsigned int g[8], o[8], l[8], i[8]; } sparc_regs;
+    } integer;  /* selected by SERVER_CTX_INTEGER */
+    union
+    {
+        struct { unsigned int ds, es, fs, gs; } i386_regs;
+        struct { unsigned int ds, es, fs, gs; } x86_64_regs;
+    } seg;  /* selected by SERVER_CTX_SEGMENTS */
+    union
+    {
+        struct { unsigned int ctrl, status, tag, err_off, err_sel, data_off, data_sel, cr0npx;
+                 unsigned char regs[80]; } i386_regs;
+        struct { struct { unsigned __int64 low, high; } fpregs[32]; } x86_64_regs;
+        struct { unsigned __int64 f[32], fpcr, softfpcr; } alpha_regs;
+        struct { double fpr[32], fpscr; } powerpc_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;
+    } debug;  /* selected by SERVER_CTX_DEBUG_REGISTERS */
+    union
+    {
+        unsigned char i386_regs[512];
+    } ext;                       /* selected by SERVER_CTX_EXTENDED_REGISTERS */
+} context_t;
+
+#define SERVER_CTX_CONTROL            0x01
+#define SERVER_CTX_INTEGER            0x02
+#define SERVER_CTX_SEGMENTS           0x04
+#define SERVER_CTX_FLOATING_POINT     0x08
+#define SERVER_CTX_DEBUG_REGISTERS    0x10
+#define SERVER_CTX_EXTENDED_REGISTERS 0x20
+
 /* structure used in sending an fd from client to server */
 struct send_fd
 {
@@ -1732,7 +1789,6 @@
 /* Set the current context of a thread */
 @REQ(set_thread_context)
     obj_handle_t handle;       /* thread handle */
-    unsigned int flags;        /* context flags */
     int          suspend;      /* if setting context during suspend */
     VARARG(context,context);   /* thread context */
 @REPLY
diff --git a/server/ptrace.c b/server/ptrace.c
index b446de9..72e2b44 100644
--- a/server/ptrace.c
+++ b/server/ptrace.c
@@ -527,13 +527,13 @@
 #define DR_OFFSET(dr) ((((struct user *)0)->u_debugreg) + (dr))
 
 /* retrieve the thread x86 registers */
-void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
+void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
 {
     int i, pid = get_ptrace_tid(thread);
     long data[8];
 
     /* all other regs are handled on the client side */
-    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
+    assert( flags == SERVER_CTX_DEBUG_REGISTERS );
 
     if (!suspend_for_ptrace( thread )) return;
 
@@ -548,39 +548,39 @@
             goto done;
         }
     }
-    context->Dr0 = data[0];
-    context->Dr1 = data[1];
-    context->Dr2 = data[2];
-    context->Dr3 = data[3];
-    context->Dr6 = data[6];
-    context->Dr7 = data[7];
-    context->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
+    context->debug.i386_regs.dr0 = data[0];
+    context->debug.i386_regs.dr1 = data[1];
+    context->debug.i386_regs.dr2 = data[2];
+    context->debug.i386_regs.dr3 = data[3];
+    context->debug.i386_regs.dr6 = data[6];
+    context->debug.i386_regs.dr7 = data[7];
+    context->flags |= SERVER_CTX_DEBUG_REGISTERS;
 done:
     resume_after_ptrace( thread );
 }
 
 /* set the thread x86 registers */
-void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
+void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
 {
     int pid = get_ptrace_tid( thread );
 
     /* all other regs are handled on the client side */
-    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
+    assert( flags == SERVER_CTX_DEBUG_REGISTERS );
 
     if (!suspend_for_ptrace( thread )) return;
 
-    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(0), context->Dr0 ) == -1) goto error;
-    if (thread->context) thread->context->Dr0 = context->Dr0;
-    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(1), context->Dr1 ) == -1) goto error;
-    if (thread->context) thread->context->Dr1 = context->Dr1;
-    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(2), context->Dr2 ) == -1) goto error;
-    if (thread->context) thread->context->Dr2 = context->Dr2;
-    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(3), context->Dr3 ) == -1) goto error;
-    if (thread->context) thread->context->Dr3 = context->Dr3;
-    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(6), context->Dr6 ) == -1) goto error;
-    if (thread->context) thread->context->Dr6 = context->Dr6;
-    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(7), context->Dr7 ) == -1) goto error;
-    if (thread->context) thread->context->Dr7 = context->Dr7;
+    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(0), context->debug.i386_regs.dr0 ) == -1) goto error;
+    if (thread->context) thread->context->debug.i386_regs.dr0 = context->debug.i386_regs.dr0;
+    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(1), context->debug.i386_regs.dr1 ) == -1) goto error;
+    if (thread->context) thread->context->debug.i386_regs.dr1 = context->debug.i386_regs.dr1;
+    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(2), context->debug.i386_regs.dr2 ) == -1) goto error;
+    if (thread->context) thread->context->debug.i386_regs.dr2 = context->debug.i386_regs.dr2;
+    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(3), context->debug.i386_regs.dr3 ) == -1) goto error;
+    if (thread->context) thread->context->debug.i386_regs.dr3 = context->debug.i386_regs.dr3;
+    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(6), context->debug.i386_regs.dr6 ) == -1) goto error;
+    if (thread->context) thread->context->debug.i386_regs.dr6 = context->debug.i386_regs.dr6;
+    if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(7), context->debug.i386_regs.dr7 ) == -1) goto error;
+    if (thread->context) thread->context->debug.i386_regs.dr7 = context->debug.i386_regs.dr7;
     resume_after_ptrace( thread );
     return;
  error:
@@ -594,13 +594,13 @@
 #include <machine/reg.h>
 
 /* retrieve the thread x86 registers */
-void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
+void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
 {
     int pid = get_ptrace_tid(thread);
     struct dbreg dbregs;
 
     /* all other regs are handled on the client side */
-    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
+    assert( flags == SERVER_CTX_DEBUG_REGISTERS );
 
     if (!suspend_for_ptrace( thread )) return;
 
@@ -609,78 +609,71 @@
     {
 #ifdef DBREG_DRX
         /* needed for FreeBSD, the structure fields have changed under 5.x */
-        context->Dr0 = DBREG_DRX((&dbregs), 0);
-        context->Dr1 = DBREG_DRX((&dbregs), 1);
-        context->Dr2 = DBREG_DRX((&dbregs), 2);
-        context->Dr3 = DBREG_DRX((&dbregs), 3);
-        context->Dr6 = DBREG_DRX((&dbregs), 6);
-        context->Dr7 = DBREG_DRX((&dbregs), 7);
+        context->debug.i386_regs.dr0 = DBREG_DRX((&dbregs), 0);
+        context->debug.i386_regs.dr1 = DBREG_DRX((&dbregs), 1);
+        context->debug.i386_regs.dr2 = DBREG_DRX((&dbregs), 2);
+        context->debug.i386_regs.dr3 = DBREG_DRX((&dbregs), 3);
+        context->debug.i386_regs.dr6 = DBREG_DRX((&dbregs), 6);
+        context->debug.i386_regs.dr7 = DBREG_DRX((&dbregs), 7);
 #else
-        context->Dr0 = dbregs.dr0;
-        context->Dr1 = dbregs.dr1;
-        context->Dr2 = dbregs.dr2;
-        context->Dr3 = dbregs.dr3;
-        context->Dr6 = dbregs.dr6;
-        context->Dr7 = dbregs.dr7;
+        context->debug.i386_regs.dr0 = dbregs.dr0;
+        context->debug.i386_regs.dr1 = dbregs.dr1;
+        context->debug.i386_regs.dr2 = dbregs.dr2;
+        context->debug.i386_regs.dr3 = dbregs.dr3;
+        context->debug.i386_regs.dr6 = dbregs.dr6;
+        context->debug.i386_regs.dr7 = dbregs.dr7;
 #endif
-        context->ContextFlags |= CONTEXT_DEBUG_REGISTERS;
+        context->flags |= SERVER_CTX_DEBUG_REGISTERS;
     }
     resume_after_ptrace( thread );
 }
 
 /* set the thread x86 registers */
-void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
+void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
 {
     int pid = get_ptrace_tid(thread);
     struct dbreg dbregs;
 
     /* all other regs are handled on the client side */
-    assert( (flags | CONTEXT_i386) == CONTEXT_DEBUG_REGISTERS );
+    assert( flags == SERVER_CTX_DEBUG_REGISTERS );
 
     if (!suspend_for_ptrace( thread )) return;
 
 #ifdef DBREG_DRX
     /* needed for FreeBSD, the structure fields have changed under 5.x */
-    DBREG_DRX((&dbregs), 0) = context->Dr0;
-    DBREG_DRX((&dbregs), 1) = context->Dr1;
-    DBREG_DRX((&dbregs), 2) = context->Dr2;
-    DBREG_DRX((&dbregs), 3) = context->Dr3;
+    DBREG_DRX((&dbregs), 0) = context->debug.i386_regs.dr0;
+    DBREG_DRX((&dbregs), 1) = context->debug.i386_regs.dr1;
+    DBREG_DRX((&dbregs), 2) = context->debug.i386_regs.dr2;
+    DBREG_DRX((&dbregs), 3) = context->debug.i386_regs.dr3;
     DBREG_DRX((&dbregs), 4) = 0;
     DBREG_DRX((&dbregs), 5) = 0;
-    DBREG_DRX((&dbregs), 6) = context->Dr6;
-    DBREG_DRX((&dbregs), 7) = context->Dr7;
+    DBREG_DRX((&dbregs), 6) = context->debug.i386_regs.dr6;
+    DBREG_DRX((&dbregs), 7) = context->debug.i386_regs.dr7;
 #else
-    dbregs.dr0 = context->Dr0;
-    dbregs.dr1 = context->Dr1;
-    dbregs.dr2 = context->Dr2;
-    dbregs.dr3 = context->Dr3;
+    dbregs.dr0 = context->debug.i386_regs.dr0;
+    dbregs.dr1 = context->debug.i386_regs.dr1;
+    dbregs.dr2 = context->debug.i386_regs.dr2;
+    dbregs.dr3 = context->debug.i386_regs.dr3;
     dbregs.dr4 = 0;
     dbregs.dr5 = 0;
-    dbregs.dr6 = context->Dr6;
-    dbregs.dr7 = context->Dr7;
+    dbregs.dr6 = context->debug.i386_regs.dr6;
+    dbregs.dr7 = context->debug.i386_regs.dr7;
 #endif
     if (ptrace( PTRACE_SETDBREGS, pid, (caddr_t) &dbregs, 0 ) == -1) file_set_error();
-    else if (thread->context)  /* update the cached values */
-    {
-        thread->context->Dr0 = context->Dr0;
-        thread->context->Dr1 = context->Dr1;
-        thread->context->Dr2 = context->Dr2;
-        thread->context->Dr3 = context->Dr3;
-        thread->context->Dr6 = context->Dr6;
-        thread->context->Dr7 = context->Dr7;
-    }
+    else if (thread->context)
+        thread->context->debug.i386_regs = context->debug.i386_regs;  /* update the cached values */
     resume_after_ptrace( thread );
 }
 
 #else  /* linux || __FreeBSD__ */
 
 /* retrieve the thread x86 registers */
-void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags )
+void get_thread_context( struct thread *thread, context_t *context, unsigned int flags )
 {
 }
 
 /* set the thread x86 debug registers */
-void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags )
+void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags )
 {
 }
 
diff --git a/server/request.h b/server/request.h
index 3984ab1..f0ebcba 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1212,8 +1212,7 @@
 C_ASSERT( FIELD_OFFSET(struct get_thread_context_reply, self) == 8 );
 C_ASSERT( sizeof(struct get_thread_context_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, handle) == 12 );
-C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, flags) == 16 );
-C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, suspend) == 20 );
+C_ASSERT( FIELD_OFFSET(struct set_thread_context_request, suspend) == 16 );
 C_ASSERT( FIELD_OFFSET(struct set_thread_context_reply, self) == 8 );
 C_ASSERT( sizeof(struct set_thread_context_reply) == 16 );
 C_ASSERT( FIELD_OFFSET(struct get_selector_entry_request, handle) == 12 );
diff --git a/server/thread.c b/server/thread.c
index 5520d68..6ce59c8 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -944,6 +944,34 @@
     release_object( thread );
 }
 
+/* copy parts of a context structure */
+static void copy_context( context_t *to, const context_t *from, unsigned int flags )
+{
+    assert( to->cpu == from->cpu );
+    to->flags |= flags;
+    if (flags & SERVER_CTX_CONTROL) to->ctl = from->ctl;
+    if (flags & SERVER_CTX_INTEGER) to->integer = from->integer;
+    if (flags & SERVER_CTX_SEGMENTS) to->seg = from->seg;
+    if (flags & SERVER_CTX_FLOATING_POINT) to->fp = from->fp;
+    if (flags & SERVER_CTX_DEBUG_REGISTERS) to->debug = from->debug;
+    if (flags & SERVER_CTX_EXTENDED_REGISTERS) to->ext = from->ext;
+}
+
+/* return the context flags that correspond to system regs */
+/* (system regs are the ones we can't access on the client side) */
+static unsigned int get_context_system_regs( enum cpu_type cpu )
+{
+    switch (cpu)
+    {
+    case CPU_x86:     return SERVER_CTX_DEBUG_REGISTERS;
+    case CPU_x86_64:  return SERVER_CTX_DEBUG_REGISTERS;
+    case CPU_ALPHA:   return 0;
+    case CPU_POWERPC: return 0;
+    case CPU_SPARC:   return 0;
+    }
+    return 0;
+}
+
 /* trigger a breakpoint event in a given thread */
 void break_thread( struct thread *thread )
 {
@@ -955,7 +983,24 @@
     data.exception.first     = 1;
     data.exception.exc_code  = STATUS_BREAKPOINT;
     data.exception.flags     = EXCEPTION_CONTINUABLE;
-    data.exception.address   = get_context_ip( thread->context );
+    switch (thread->context->cpu)
+    {
+    case CPU_x86:
+        data.exception.address = thread->context->ctl.i386_regs.eip;
+        break;
+    case CPU_x86_64:
+        data.exception.address = thread->context->ctl.x86_64_regs.rip;
+        break;
+    case CPU_ALPHA:
+        data.exception.address = thread->context->ctl.alpha_regs.fir;
+        break;
+    case CPU_POWERPC:
+        data.exception.address = thread->context->ctl.powerpc_regs.iar;
+        break;
+    case CPU_SPARC:
+        data.exception.address = thread->context->ctl.sparc_regs.pc;
+        break;
+    }
     generate_debug_event( thread, EXCEPTION_DEBUG_EVENT, &data );
     thread->debug_break = 0;
 }
@@ -1357,9 +1402,9 @@
 DECL_HANDLER(get_thread_context)
 {
     struct thread *thread;
-    CONTEXT *context;
+    context_t *context;
 
-    if (get_reply_max_size() < sizeof(CONTEXT))
+    if (get_reply_max_size() < sizeof(context_t))
     {
         set_error( STATUS_INVALID_PARAMETER );
         return;
@@ -1376,7 +1421,7 @@
         else
         {
             if (thread->context == thread->suspend_context) thread->context = NULL;
-            set_reply_data_ptr( thread->suspend_context, sizeof(CONTEXT) );
+            set_reply_data_ptr( thread->suspend_context, sizeof(context_t) );
             thread->suspend_context = NULL;
         }
     }
@@ -1386,12 +1431,12 @@
         if (thread->state != RUNNING) set_error( STATUS_ACCESS_DENIED );
         else set_error( STATUS_PENDING );
     }
-    else if ((context = set_reply_data_size( sizeof(CONTEXT) )))
+    else if ((context = set_reply_data_size( sizeof(context_t) )))
     {
-        unsigned int flags = get_context_system_regs( req->flags );
+        unsigned int flags = get_context_system_regs( thread->process->cpu );
 
-        memset( context, 0, sizeof(CONTEXT) );
-        context->ContextFlags = get_context_cpu_flag();
+        memset( context, 0, sizeof(context_t) );
+        context->cpu = thread->process->cpu;
         if (thread->context) copy_context( context, thread->context, req->flags & ~flags );
         if (flags) get_thread_context( thread, context, flags );
     }
@@ -1403,8 +1448,9 @@
 DECL_HANDLER(set_thread_context)
 {
     struct thread *thread;
+    const context_t *context = get_req_data();
 
-    if (get_req_data_size() < sizeof(CONTEXT))
+    if (get_req_data_size() < sizeof(context_t))
     {
         set_error( STATUS_INVALID_PARAMETER );
         return;
@@ -1413,14 +1459,14 @@
 
     if (req->suspend)
     {
-        if (thread != current || thread->context)
+        if (thread != current || thread->context || context->cpu != thread->process->cpu)
         {
             /* nested suspend or exception, shouldn't happen */
             set_error( STATUS_INVALID_PARAMETER );
         }
-        else if ((thread->suspend_context = mem_alloc( sizeof(CONTEXT) )))
+        else if ((thread->suspend_context = mem_alloc( sizeof(context_t) )))
         {
-            memcpy( thread->suspend_context, get_req_data(), sizeof(CONTEXT) );
+            memcpy( thread->suspend_context, get_req_data(), sizeof(context_t) );
             thread->context = thread->suspend_context;
             if (thread->debug_break) break_thread( thread );
         }
@@ -1431,15 +1477,16 @@
         if (thread->state != RUNNING) set_error( STATUS_ACCESS_DENIED );
         else set_error( STATUS_PENDING );
     }
-    else
+    else if (context->cpu == thread->process->cpu)
     {
-        const CONTEXT *context = get_req_data();
-        unsigned int flags = get_context_system_regs( req->flags );
+        unsigned int system_flags = get_context_system_regs(context->cpu) & context->flags;
+        unsigned int client_flags = context->flags & ~system_flags;
 
-        if (flags) set_thread_context( thread, context, flags );
-        if (thread->context && !get_error())
-            copy_context( thread->context, context, req->flags & ~flags );
+        if (system_flags) set_thread_context( thread, context, system_flags );
+        if (thread->context && !get_error()) copy_context( thread->context, context, client_flags );
     }
+    else set_error( STATUS_INVALID_PARAMETER );
+
     reply->self = (thread == current);
     release_object( thread );
 }
diff --git a/server/thread.h b/server/thread.h
index 2e33470..b6c1cf5 100644
--- a/server/thread.h
+++ b/server/thread.h
@@ -76,8 +76,8 @@
     int                    exit_code;     /* thread exit code */
     int                    unix_pid;      /* Unix pid of client */
     int                    unix_tid;      /* Unix tid of client */
-    CONTEXT               *context;       /* current context if in an exception handler */
-    CONTEXT               *suspend_context; /* current context if suspended */
+    context_t             *context;       /* current context if in an exception handler */
+    context_t             *suspend_context; /* current context if suspended */
     client_ptr_t           teb;           /* TEB address (in client address space) */
     affinity_t             affinity;      /* affinity mask */
     int                    priority;      /* priority level */
@@ -119,17 +119,11 @@
 extern struct thread_snapshot *thread_snap( int *count );
 extern struct token *thread_get_impersonation_token( struct thread *thread );
 
-/* CPU context functions */
-extern void copy_context( CONTEXT *to, const CONTEXT *from, unsigned int flags );
-extern client_ptr_t get_context_ip( const CONTEXT *context );
-extern unsigned int get_context_cpu_flag(void);
-extern unsigned int get_context_system_regs( unsigned int flags );
-
 /* ptrace functions */
 
 extern void sigchld_callback(void);
-extern void get_thread_context( struct thread *thread, CONTEXT *context, unsigned int flags );
-extern void set_thread_context( struct thread *thread, const CONTEXT *context, unsigned int flags );
+extern void get_thread_context( struct thread *thread, context_t *context, unsigned int flags );
+extern void set_thread_context( struct thread *thread, const context_t *context, unsigned int flags );
 extern int send_thread_signal( struct thread *thread, int sig );
 extern void get_selector_entry( struct thread *thread, int entry, unsigned int *base,
                                 unsigned int *limit, unsigned char *flags );
diff --git a/server/trace.c b/server/trace.c
index 88ea5e5..4a7bfa5 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -298,33 +298,6 @@
     fprintf( stderr, "%s%d.%u", prefix, luid->high_part, luid->low_part );
 }
 
-static void dump_context( const CONTEXT *context, data_size_t size )
-{
-    CONTEXT ctx;
-
-    memset( &ctx, 0, sizeof(ctx) );
-    memcpy( &ctx, context, min( size, sizeof(CONTEXT) ));
-#ifdef __i386__
-    fprintf( stderr, "{flags=%08x,eax=%08x,ebx=%08x,ecx=%08x,edx=%08x,esi=%08x,edi=%08x,"
-             "ebp=%08x,eip=%08x,esp=%08x,eflags=%08x,cs=%04x,ds=%04x,es=%04x,"
-             "fs=%04x,gs=%04x,dr0=%08x,dr1=%08x,dr2=%08x,dr3=%08x,dr6=%08x,dr7=%08x,",
-             ctx.ContextFlags, ctx.Eax, ctx.Ebx, ctx.Ecx, ctx.Edx,
-             ctx.Esi, ctx.Edi, ctx.Ebp, ctx.Eip, ctx.Esp, ctx.EFlags,
-             ctx.SegCs, ctx.SegDs, ctx.SegEs, ctx.SegFs, ctx.SegGs,
-             ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr6, ctx.Dr7 );
-    fprintf( stderr, "float=" );
-    dump_uints( (const int *)&ctx.FloatSave, sizeof(ctx.FloatSave) / sizeof(int) );
-    if (size > FIELD_OFFSET( CONTEXT, ExtendedRegisters ))
-    {
-        fprintf( stderr, ",extended=" );
-        dump_uints( (const int *)&ctx.ExtendedRegisters, sizeof(ctx.ExtendedRegisters) / sizeof(int) );
-    }
-    fprintf( stderr, "}" );
-#else
-    dump_uints( (const int *)&ctx, sizeof(ctx) / sizeof(int) );
-#endif
-}
-
 static void dump_varargs_ints( const char *prefix, data_size_t size )
 {
     const int *data = cur_data;
@@ -428,14 +401,190 @@
 
 static void dump_varargs_context( const char *prefix, data_size_t size )
 {
+    const context_t *context = cur_data;
+    context_t ctx;
+    unsigned int i;
+
     if (!size)
     {
         fprintf( stderr, "%s{}", prefix );
         return;
     }
-    fprintf( stderr, "%s", prefix );
-    dump_context( cur_data, size );
-    remove_data( min( size, sizeof(CONTEXT) ));
+    size = min( size, sizeof(ctx) );
+    memset( &ctx, 0, sizeof(ctx) );
+    memcpy( &ctx, context, size );
+
+    fprintf( stderr,"%s{", prefix );
+    dump_cpu_type( "cpu=", &ctx.cpu );
+    switch (ctx.cpu)
+    {
+    case CPU_x86:
+        if (ctx.flags & SERVER_CTX_CONTROL)
+            fprintf( stderr, ",eip=%08x,esp=%08x,ebp=%08x,eflags=%08x,cs=%04x,ss=%04x",
+                     ctx.ctl.i386_regs.eip, ctx.ctl.i386_regs.esp, ctx.ctl.i386_regs.ebp,
+                     ctx.ctl.i386_regs.eflags, ctx.ctl.i386_regs.cs, ctx.ctl.i386_regs.ss );
+        if (ctx.flags & SERVER_CTX_SEGMENTS)
+            fprintf( stderr, ",ds=%04x,es=%04x,fs=%04x,gs=%04x",
+                     ctx.seg.i386_regs.ds, ctx.seg.i386_regs.es,
+                     ctx.seg.i386_regs.fs, ctx.seg.i386_regs.gs );
+        if (ctx.flags & SERVER_CTX_INTEGER)
+            fprintf( stderr, ",eax=%08x,ebx=%08x,ecx=%08x,edx=%08x,esi=%08x,edi=%08x",
+                     ctx.integer.i386_regs.eax, ctx.integer.i386_regs.ebx, ctx.integer.i386_regs.ecx,
+                     ctx.integer.i386_regs.edx, ctx.integer.i386_regs.esi, ctx.integer.i386_regs.edi );
+        if (ctx.flags & SERVER_CTX_DEBUG_REGISTERS)
+            fprintf( stderr, ",dr0=%08x,dr1=%08x,dr2=%08x,dr3=%08x,dr6=%08x,dr7=%08x",
+                     ctx.debug.i386_regs.dr0, ctx.debug.i386_regs.dr1, ctx.debug.i386_regs.dr2,
+                     ctx.debug.i386_regs.dr3, ctx.debug.i386_regs.dr6, ctx.debug.i386_regs.dr7 );
+        if (ctx.flags & SERVER_CTX_FLOATING_POINT)
+        {
+            fprintf( stderr, "fp.ctrl=%08x,fp.status=%08x,fp.tag=%08x,fp.err_off=%08x,fp.err_sel=%08x",
+                     ctx.fp.i386_regs.ctrl, ctx.fp.i386_regs.status, ctx.fp.i386_regs.tag,
+                     ctx.fp.i386_regs.err_off, ctx.fp.i386_regs.err_sel );
+            fprintf( stderr, ",fp.data_off=%08x,fp.data_sel=%08x,fp.cr0npx=%08x",
+                     ctx.fp.i386_regs.data_off, ctx.fp.i386_regs.data_sel, ctx.fp.i386_regs.cr0npx );
+            for (i = 0; i < 8; i++)
+                fprintf( stderr, ",fp.reg%u=%Lg", i, *(long double *)&ctx.fp.i386_regs.regs[10*i] );
+        }
+        if (ctx.flags & SERVER_CTX_EXTENDED_REGISTERS)
+        {
+            fprintf( stderr, ",extended=" );
+            dump_uints( (const int *)ctx.ext.i386_regs, sizeof(ctx.ext.i386_regs) / sizeof(int) );
+        }
+        break;
+    case CPU_x86_64:
+        if (ctx.flags & SERVER_CTX_CONTROL)
+        {
+            dump_uint64( ",rip=", &ctx.ctl.x86_64_regs.rip );
+            dump_uint64( ",rbp=", &ctx.ctl.x86_64_regs.rbp );
+            dump_uint64( ",rsp=", &ctx.ctl.x86_64_regs.rsp );
+            fprintf( stderr, ",cs=%04x,ss=%04x,flags=%08x,mxcsr=%08x",
+                     ctx.ctl.x86_64_regs.cs, ctx.ctl.x86_64_regs.ss,
+                     ctx.ctl.x86_64_regs.flags, ctx.ctl.x86_64_regs.mxcsr );
+        }
+        if (ctx.flags & SERVER_CTX_INTEGER)
+        {
+            dump_uint64( ",rax=", &ctx.integer.x86_64_regs.rax );
+            dump_uint64( ",rbx=", &ctx.integer.x86_64_regs.rbx );
+            dump_uint64( ",rcx=", &ctx.integer.x86_64_regs.rcx );
+            dump_uint64( ",rdx=", &ctx.integer.x86_64_regs.rdx );
+            dump_uint64( ",rsi=", &ctx.integer.x86_64_regs.rsi );
+            dump_uint64( ",rdi=", &ctx.integer.x86_64_regs.rdi );
+            dump_uint64( ",r8=",  &ctx.integer.x86_64_regs.r8 );
+            dump_uint64( ",r9=",  &ctx.integer.x86_64_regs.r9 );
+            dump_uint64( ",r10=", &ctx.integer.x86_64_regs.r10 );
+            dump_uint64( ",r11=", &ctx.integer.x86_64_regs.r11 );
+            dump_uint64( ",r12=", &ctx.integer.x86_64_regs.r12 );
+            dump_uint64( ",r13=", &ctx.integer.x86_64_regs.r13 );
+            dump_uint64( ",r14=", &ctx.integer.x86_64_regs.r14 );
+            dump_uint64( ",r15=", &ctx.integer.x86_64_regs.r15 );
+        }
+        if (ctx.flags & SERVER_CTX_SEGMENTS)
+            fprintf( stderr, ",ds=%04x,es=%04x,fs=%04x,gs=%04x",
+                     ctx.seg.x86_64_regs.ds, ctx.seg.x86_64_regs.es,
+                     ctx.seg.x86_64_regs.fs, ctx.seg.x86_64_regs.gs );
+        if (ctx.flags & SERVER_CTX_DEBUG_REGISTERS)
+        {
+            dump_uint64( ",dr0=", &ctx.debug.x86_64_regs.dr0 );
+            dump_uint64( ",dr1=", &ctx.debug.x86_64_regs.dr1 );
+            dump_uint64( ",dr2=", &ctx.debug.x86_64_regs.dr2 );
+            dump_uint64( ",dr3=", &ctx.debug.x86_64_regs.dr3 );
+            dump_uint64( ",dr6=", &ctx.debug.x86_64_regs.dr6 );
+            dump_uint64( ",dr7=", &ctx.debug.x86_64_regs.dr7 );
+        }
+        if (ctx.flags & SERVER_CTX_FLOATING_POINT)
+        {
+            for (i = 0; i < 32; i++)
+                fprintf( stderr, ",fp%u=%08x%08x%08x%08x", i,
+                         (unsigned int)(ctx.fp.x86_64_regs.fpregs[i].high >> 32),
+                         (unsigned int)ctx.fp.x86_64_regs.fpregs[i].high,
+                         (unsigned int)(ctx.fp.x86_64_regs.fpregs[i].low >> 32),
+                         (unsigned int)ctx.fp.x86_64_regs.fpregs[i].low );
+        }
+        break;
+    case CPU_ALPHA:
+        if (ctx.flags & SERVER_CTX_CONTROL)
+        {
+            dump_uint64( ",fir=", &ctx.ctl.alpha_regs.fir );
+            fprintf( stderr, ",psr=%08x", ctx.ctl.alpha_regs.psr );
+        }
+        if (ctx.flags & SERVER_CTX_INTEGER)
+        {
+            dump_uint64( ",v0=",  &ctx.integer.alpha_regs.v0 );
+            dump_uint64( ",t0=",  &ctx.integer.alpha_regs.t0 );
+            dump_uint64( ",t1=",  &ctx.integer.alpha_regs.t1 );
+            dump_uint64( ",t2=",  &ctx.integer.alpha_regs.t2 );
+            dump_uint64( ",t3=",  &ctx.integer.alpha_regs.t3 );
+            dump_uint64( ",t4=",  &ctx.integer.alpha_regs.t4 );
+            dump_uint64( ",t5=",  &ctx.integer.alpha_regs.t5 );
+            dump_uint64( ",t6=",  &ctx.integer.alpha_regs.t6 );
+            dump_uint64( ",t7=",  &ctx.integer.alpha_regs.t7 );
+            dump_uint64( ",t8=",  &ctx.integer.alpha_regs.t8 );
+            dump_uint64( ",t9=",  &ctx.integer.alpha_regs.t9 );
+            dump_uint64( ",t10=", &ctx.integer.alpha_regs.t10 );
+            dump_uint64( ",t11=", &ctx.integer.alpha_regs.t11 );
+            dump_uint64( ",t12=", &ctx.integer.alpha_regs.t12 );
+            dump_uint64( ",s0=",  &ctx.integer.alpha_regs.s0 );
+            dump_uint64( ",s1=",  &ctx.integer.alpha_regs.s1 );
+            dump_uint64( ",s2=",  &ctx.integer.alpha_regs.s2 );
+            dump_uint64( ",s3=",  &ctx.integer.alpha_regs.s3 );
+            dump_uint64( ",s4=",  &ctx.integer.alpha_regs.s4 );
+            dump_uint64( ",s5=",  &ctx.integer.alpha_regs.s5 );
+            dump_uint64( ",s6=",  &ctx.integer.alpha_regs.s6 );
+            dump_uint64( ",a0=",  &ctx.integer.alpha_regs.a0 );
+            dump_uint64( ",a1=",  &ctx.integer.alpha_regs.a1 );
+            dump_uint64( ",a2=",  &ctx.integer.alpha_regs.a2 );
+            dump_uint64( ",a3=",  &ctx.integer.alpha_regs.a3 );
+            dump_uint64( ",a4=",  &ctx.integer.alpha_regs.a4 );
+            dump_uint64( ",a5=",  &ctx.integer.alpha_regs.a5 );
+            dump_uint64( ",at=",  &ctx.integer.alpha_regs.at );
+        }
+        if (ctx.flags & SERVER_CTX_FLOATING_POINT)
+        {
+            for (i = 0; i < 32; i++)
+            {
+                fprintf( stderr, ",f%u", i );
+                dump_uint64( "=", &ctx.fp.alpha_regs.f[i] );
+            }
+            dump_uint64( ",fpcr=", &ctx.fp.alpha_regs.fpcr );
+            dump_uint64( ",softfpcr=", &ctx.fp.alpha_regs.softfpcr );
+        }
+        break;
+    case CPU_POWERPC:
+        if (ctx.flags & SERVER_CTX_CONTROL)
+            fprintf( stderr, ",iar=%08x,msr=%08x,ctr=%08x,lr=%08x,dar=%08x,dsisr=%08x,trap=%08x",
+                     ctx.ctl.powerpc_regs.iar, ctx.ctl.powerpc_regs.msr, ctx.ctl.powerpc_regs.ctr,
+                     ctx.ctl.powerpc_regs.lr, ctx.ctl.powerpc_regs.dar, ctx.ctl.powerpc_regs.dsisr,
+                     ctx.ctl.powerpc_regs.trap );
+        if (ctx.flags & SERVER_CTX_INTEGER)
+        {
+            for (i = 0; i < 32; i++) fprintf( stderr, ",gpr%u=%08x", i, ctx.integer.powerpc_regs.gpr[i] );
+            fprintf( stderr, ",cr=%08x,xer=%08x",
+                     ctx.integer.powerpc_regs.cr, ctx.integer.powerpc_regs.xer );
+        }
+        if (ctx.flags & SERVER_CTX_DEBUG_REGISTERS)
+            for (i = 0; i < 8; i++) fprintf( stderr, ",dr%u=%08x", i, ctx.debug.powerpc_regs.dr[i] );
+        if (ctx.flags & SERVER_CTX_FLOATING_POINT)
+        {
+            for (i = 0; i < 32; i++) fprintf( stderr, ",fpr%u=%g", i, ctx.fp.powerpc_regs.fpr[i] );
+            fprintf( stderr, ",fpscr=%g", ctx.fp.powerpc_regs.fpscr );
+        }
+        break;
+    case CPU_SPARC:
+        if (ctx.flags & SERVER_CTX_CONTROL)
+            fprintf( stderr, ",psr=%08x,pc=%08x,npc=%08x,y=%08x,wim=%08x,tbr=%08x",
+                     ctx.ctl.sparc_regs.psr, ctx.ctl.sparc_regs.pc, ctx.ctl.sparc_regs.npc,
+                     ctx.ctl.sparc_regs.y, ctx.ctl.sparc_regs.wim, ctx.ctl.sparc_regs.tbr );
+        if (ctx.flags & SERVER_CTX_INTEGER)
+        {
+            for (i = 0; i < 8; i++) fprintf( stderr, ",g%u=%08x", i, ctx.integer.sparc_regs.g[i] );
+            for (i = 0; i < 8; i++) fprintf( stderr, ",o%u=%08x", i, ctx.integer.sparc_regs.o[i] );
+            for (i = 0; i < 8; i++) fprintf( stderr, ",l%u=%08x", i, ctx.integer.sparc_regs.l[i] );
+            for (i = 0; i < 8; i++) fprintf( stderr, ",i%u=%08x", i, ctx.integer.sparc_regs.i[i] );
+        }
+        break;
+    }
+    fputc( '}', stderr );
+    remove_data( size );
 }
 
 static void dump_varargs_debug_event( const char *prefix, data_size_t size )
@@ -2128,7 +2277,6 @@
 static void dump_set_thread_context_request( const struct set_thread_context_request *req )
 {
     fprintf( stderr, " handle=%04x", req->handle );
-    fprintf( stderr, ", flags=%08x", req->flags );
     fprintf( stderr, ", suspend=%d", req->suspend );
     dump_varargs_context( ", context=", cur_size );
 }