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, ®s ) == -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, ®s ) == -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, ®s ) == -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) ®s ) == -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 );
}