Mac OS X Support : Signals support
Pierre d'Herbemont
stegefin at free.fr
Wed May 7 13:36:11 CDT 2003
On Tuesday, May 6, 2003, at 12:42 AM, Alexandre Julliard wrote:
> "Pierre d'Herbemont" <stegefin at free.fr> writes:
>
>> Hi,
>> This patch add in signal_powerpc.c of ntdll support for darwin signal.
>
> You should define a set of macros or inline functions to access the
> sigcontext structure fields, instead of duplicating the whole handler
> functions. For an example, check how the i386 code is doing it.
>
Ok, thanks :)
Here is the correction, Hope it will be ok...
ChangeLog:
Add Signal support for Darwin and PowerPC.
-------------- next part --------------
Index: dlls/ntdll/signal_powerpc.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/signal_powerpc.c,v
retrieving revision 1.13
diff -u -r1.13 signal_powerpc.c
--- dlls/ntdll/signal_powerpc.c 4 May 2003 02:25:07 -0000 1.13
+++ dlls/ntdll/signal_powerpc.c 7 May 2003 18:26:09 -0000
@@ -65,11 +65,102 @@
/***********************************************************************
* signal context platform-specific definitions
*/
+#ifdef linux
+# warning Please define registers for your platform linux ppc some are missing
typedef struct ucontext SIGCONTEXT;
-#define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
-#define HANDLER_CONTEXT (__context)
+# define HANDLER_DEF(name) void name( int __signal, struct siginfo *__siginfo, SIGCONTEXT *__context )
+# define HANDLER_CONTEXT (__context)
+
+/* All Registers access - only for local access */
+# define REG_sig(reg_name, context) (context)->uc_mcontext.regs->reg_name
+
+
+/* Gpr Registers access */
+# define GPR_sig(reg_num, context) REG_sig(r##reg_num, context)
+
+# define IAR_sig(context) REG_sig(nip, context) /* Programm counter */
+# define MSR_sig(context) REG_sig(msr, context) /* Machine State Register (Supervisor) */
+# define CTR_sig(context) REG_sig(ctr, context) /* Count register */
+
+# define XER_sig(context) #error XER_sig not defined on your platform /* Link register */
+# define LR_sig(context) #error LR_sig not defined on your platform /* User's integer exception register */
+# define CR_sig(context) #error CR_sig not defined on your platform /* Condition register */
+
+/* Float Registers access */
+# define FLOAT_sig(reg_num, context) #error FLOAT_sig not defined on your platform /* Float registers */
+
+# define FPSCR_sig(reg_num, context) #error FPSCR_sig not defined on your platform /* Float registers */
+
+/* Exception Registers access */
+# define DAR_sig(context) #error DAR_sig not defined on your platform
+# define DSISR_sig(context) #error DSISR_sig not defined on your platform
+# define TRAP_sig(context) #error TRAP_sig not defined on your platform
+
+#endif /* linux */
+
+#ifdef __darwin__
+
+# include <sys/ucontext.h>
+
+# include <sys/types.h>
+# include <signal.h>
+typedef siginfo_t siginfo;
+
+typedef struct ucontext SIGCONTEXT;
+
+
+# define HANDLER_DEF(name) void name( int __signal, siginfo *__siginfo, SIGCONTEXT *__context )
+# define HANDLER_CONTEXT (__context)
+
+/* All Registers access - only for local access */
+# define REG_sig(reg_name, context) (context)->uc_mcontext->ss.reg_name
+# define FLOATREG_sig(reg_name, context) (context)->uc_mcontext->fs.reg_name
+# define EXCEPREG_sig(reg_name, context) (context)->uc_mcontext->es.reg_name
+# define VECREG_sig(reg_name, context) (context)->uc_mcontext->vs.reg_name
+
+/* Gpr Registers access */
+# define GPR_sig(reg_num, context) REG_sig(r##reg_num, context)
+
+# define IAR_sig(context) REG_sig(srr0, context) /* Programm counter */
+# define MSR_sig(context) REG_sig(srr1, context) /* Machine State Register (Supervisor) */
+# define CTR_sig(context) REG_sig(ctr, context)
+
+# define XER_sig(context) REG_sig(xer, context) /* Link register */
+# define LR_sig(context) REG_sig(lr, context) /* User's integer exception register */
+# define CR_sig(context) REG_sig(cr, context) /* Condition register */
+
+/* Float Registers access */
+# define FLOAT_sig(reg_num, context) FLOATREG_sig(fpregs[reg_num], context)
+
+# define FPSCR_sig(context) (double)( FLOATREG_sig(fpscr, context) )
+
+/* Exception Registers access */
+# define DAR_sig(context) EXCEPREG_sig(dar, context) /* Fault registers for coredump */
+# define DSISR_sig(context) EXCEPREG_sig(dsisr, context)
+# define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
+
+/* Signal defs : Those are undefined on darwin
+SIGBUS
+#undef BUS_ADRERR
+#undef BUS_OBJERR
+SIGILL
+#undef ILL_ILLOPN
+#undef ILL_ILLTRP
+#undef ILL_ILLADR
+#undef ILL_COPROC
+#undef ILL_PRVREG
+#undef ILL_BADSTK
+SIGTRAP
+#undef TRAP_BRKPT
+#undef TRAP_TRACE
+SIGFPE
+*/
+
+#endif /* __darwin__ */
+
+
typedef int (*wine_signal_handler)(unsigned int sig);
@@ -93,30 +184,27 @@
*/
static void save_context( CONTEXT *context, const SIGCONTEXT *sigcontext )
{
-#define CX(x,y) context->x = sigcontext->uc_mcontext.regs->y
-#define C(x) CX(Gpr##x,gpr[x])
+
+#define C(x) context->Gpr##x = GPR_sig(x,sigcontext)
+ /* Save Gpr registers */
C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
C(31);
+#undef C
- CX(Iar,nip);
- CX(Msr,msr);
- CX(Ctr,ctr);
-#undef CX
- /* FIXME: fp regs? */
-
- /* FIXME: missing pt_regs ...
- unsigned long link;
- unsigned long xer;
- unsigned long ccr;
- unsigned long mq;
-
- unsigned long trap;
- unsigned long dar;
- unsigned long dsisr;
-
- */
+ context->Iar = IAR_sig(sigcontext); /* Program Counter */
+ context->Msr = MSR_sig(sigcontext); /* Machine State Register (Supervisor) */
+ context->Ctr = CTR_sig(sigcontext);
+
+ context->Xer = XER_sig(sigcontext);
+ context->Lr = LR_sig(sigcontext);
+ context->Cr = CR_sig(sigcontext);
+
+ /* Saving Exception regs */
+ context->Dar = DAR_sig(sigcontext);
+ context->Dsisr = DSISR_sig(sigcontext);
+ context->Trap = TRAP_sig(sigcontext);
}
@@ -127,16 +215,26 @@
*/
static void restore_context( const CONTEXT *context, SIGCONTEXT *sigcontext )
{
-#define CX(x,y) sigcontext->uc_mcontext.regs->y = context->x
+
+#define C(x) GPR_sig(x,sigcontext) = context->Gpr##x
C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
C(31);
+#undef C
- CX(Iar,nip);
- CX(Msr,msr);
- CX(Ctr,ctr);
-#undef CX
+ IAR_sig(sigcontext) = context->Iar; /* Program Counter */
+ MSR_sig(sigcontext) = context->Msr; /* Machine State Register (Supervisor) */
+ CTR_sig(sigcontext) = context->Ctr;
+
+ XER_sig(sigcontext) = context->Xer;
+ LR_sig(sigcontext) = context->Lr;
+ CR_sig(sigcontext) = context->Cr;
+
+ /* Setting Exception regs */
+ DAR_sig(sigcontext) = context->Dar;
+ DSISR_sig(sigcontext) = context->Dsisr;
+ TRAP_sig(sigcontext) = context->Trap;
}
@@ -147,7 +245,13 @@
*/
inline static void save_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
{
- /* FIXME? */
+#define C(x) context->Fpr##x = FLOAT_sig(x,sigcontext)
+ C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
+ C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
+ C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
+ C(31);
+#undef C
+ context->Fpscr = FPSCR_sig(sigcontext);
}
@@ -158,7 +262,13 @@
*/
inline static void restore_fpu( CONTEXT *context, const SIGCONTEXT *sigcontext )
{
- /* FIXME? */
+#define C(x) FLOAT_sig(x,sigcontext) = context->Fpr##x
+ C(0); C(1); C(2); C(3); C(4); C(5); C(6); C(7); C(8); C(9); C(10);
+ C(11); C(12); C(13); C(14); C(15); C(16); C(17); C(18); C(19); C(20);
+ C(21); C(22); C(23); C(24); C(25); C(26); C(27); C(28); C(29); C(30);
+ C(31);
+#undef C
+ FPSCR_sig(sigcontext) = context->Fpscr;
}
@@ -169,7 +279,7 @@
*/
static inline DWORD get_fpu_code( const CONTEXT *context )
{
- DWORD status = 0 /* FIXME */;
+ DWORD status = context->Fpscr;
if (status & 0x01) /* IE */
{
@@ -186,164 +296,227 @@
return EXCEPTION_FLT_INVALID_OPERATION; /* generic error */
}
-
/**********************************************************************
- * segv_handler
+ * do_segv
*
- * Handler for SIGSEGV and related errors.
+ * Implementation of SIGSEGV handler.
*/
-static HANDLER_DEF(segv_handler)
+static void do_segv( CONTEXT *context, int trap, int err, int code, void * addr )
{
- CONTEXT context;
EXCEPTION_RECORD rec;
DWORD page_fault_code = EXCEPTION_ACCESS_VIOLATION;
- save_context( &context, HANDLER_CONTEXT );
-
rec.ExceptionRecord = NULL;
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
- rec.ExceptionAddress = (LPVOID)HANDLER_CONTEXT->uc_mcontext.regs->nip;
+ rec.ExceptionAddress = addr;
rec.NumberParameters = 0;
- switch (__siginfo->si_signo) {
+
+ switch (trap) {
case SIGSEGV:
- switch ( __siginfo->si_code & 0xffff ) {
+ switch ( code & 0xffff ) {
case SEGV_MAPERR:
case SEGV_ACCERR:
rec.NumberParameters = 2;
rec.ExceptionInformation[0] = 0; /* FIXME ? */
- rec.ExceptionInformation[1] = (DWORD)__siginfo->si_addr;
- if (!(page_fault_code=VIRTUAL_HandleFault(__siginfo->si_addr)))
+ rec.ExceptionInformation[1] = (DWORD)addr;
+ if (!(page_fault_code=VIRTUAL_HandleFault(addr)))
return;
rec.ExceptionCode = page_fault_code;
break;
- default:FIXME("Unhandled SIGSEGV/%x\n",__siginfo->si_code);
+ default:FIXME("Unhandled SIGSEGV/%x\n",code);
break;
}
break;
case SIGBUS:
- switch ( __siginfo->si_code & 0xffff ) {
+ switch ( code & 0xffff ) {
case BUS_ADRALN:
rec.ExceptionCode = EXCEPTION_DATATYPE_MISALIGNMENT;
break;
+#ifdef BUS_ADRERR
case BUS_ADRERR:
+#endif
+#ifdef BUS_OBJERR
case BUS_OBJERR:
/* FIXME: correct for all cases ? */
rec.NumberParameters = 2;
rec.ExceptionInformation[0] = 0; /* FIXME ? */
- rec.ExceptionInformation[1] = (DWORD)__siginfo->si_addr;
- if (!(page_fault_code=VIRTUAL_HandleFault(__siginfo->si_addr)))
+ rec.ExceptionInformation[1] = (DWORD)addr;
+ if (!(page_fault_code=VIRTUAL_HandleFault(addr)))
return;
rec.ExceptionCode = page_fault_code;
break;
- default:FIXME("Unhandled SIGBUS/%x\n",__siginfo->si_code);
+#endif
+ default:FIXME("Unhandled SIGBUS/%x\n",code);
break;
}
break;
case SIGILL:
- switch ( __siginfo->si_code & 0xffff ) {
+ switch ( code & 0xffff ) {
case ILL_ILLOPC: /* illegal opcode */
+#ifdef ILL_ILLOPN
case ILL_ILLOPN: /* illegal operand */
+#endif
+#ifdef ILL_ILLADR
case ILL_ILLADR: /* illegal addressing mode */
+#endif
+#ifdef ILL_ILLTRP
case ILL_ILLTRP: /* illegal trap */
+#endif
+#ifdef ILL_COPROC
case ILL_COPROC: /* coprocessor error */
+#endif
rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break;
case ILL_PRVOPC: /* privileged opcode */
+#ifdef ILL_PRVREG
case ILL_PRVREG: /* privileged register */
+#endif
rec.ExceptionCode = EXCEPTION_PRIV_INSTRUCTION;
break;
+#ifdef ILL_BADSTK
case ILL_BADSTK: /* internal stack error */
rec.ExceptionCode = EXCEPTION_STACK_OVERFLOW;
break;
- default:FIXME("Unhandled SIGILL/%x\n",__siginfo->si_code);
+#endif
+ default:FIXME("Unhandled SIGILL/%x\n", code);
break;
}
break;
}
- EXC_RtlRaiseException( &rec, &context );
- restore_context( &context, HANDLER_CONTEXT );
+ EXC_RtlRaiseException( &rec, context );
}
/**********************************************************************
- * trap_handler
+ * do_trap
*
- * Handler for SIGTRAP.
+ * Implementation of SIGTRAP handler.
*/
-static HANDLER_DEF(trap_handler)
+static void do_trap( CONTEXT *context, int code, void * addr )
{
- CONTEXT context;
EXCEPTION_RECORD rec;
- save_context( &context, HANDLER_CONTEXT );
-
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL;
- rec.ExceptionAddress = (LPVOID)__context->uc_mcontext.regs->nip;
+ rec.ExceptionAddress = addr;
rec.NumberParameters = 0;
/* FIXME: check if we might need to modify PC */
- switch (__siginfo->si_code & 0xffff) {
+ switch (code & 0xffff) {
+#ifdef TRAP_BRKPT
case TRAP_BRKPT:
rec.ExceptionCode = EXCEPTION_BREAKPOINT;
break;
+#endif
+#ifdef TRAP_TRACE
case TRAP_TRACE:
rec.ExceptionCode = EXCEPTION_SINGLE_STEP;
break;
+#endif
+ default:FIXME("Unhandled SIGTRAP/%x\n", code);
+ break;
}
- EXC_RtlRaiseException( &rec, &context );
- restore_context( &context, HANDLER_CONTEXT );
+ EXC_RtlRaiseException( &rec, context );
}
-
/**********************************************************************
- * fpe_handler
+ * do_trap
*
- * Handler for SIGFPE.
+ * Implementation of SIGFPE handler.
*/
-static HANDLER_DEF(fpe_handler)
+static void do_fpe( CONTEXT *context, int code, void * addr )
{
- CONTEXT context;
EXCEPTION_RECORD rec;
- /*save_fpu( &context, HANDLER_CONTEXT );*/
- save_context( &context, HANDLER_CONTEXT );
-
- switch ( __siginfo->si_code & 0xffff ) {
+ switch ( code & 0xffff ) {
+#ifdef FPE_FLTSUB
case FPE_FLTSUB:
rec.ExceptionCode = EXCEPTION_ARRAY_BOUNDS_EXCEEDED;
break;
+#endif
+#ifdef FPE_INTDIV
case FPE_INTDIV:
rec.ExceptionCode = EXCEPTION_INT_DIVIDE_BY_ZERO;
break;
+#endif
+#ifdef FPE_INTOVF
case FPE_INTOVF:
rec.ExceptionCode = EXCEPTION_INT_OVERFLOW;
break;
+#endif
+#ifdef FPE_FLTDIV
case FPE_FLTDIV:
rec.ExceptionCode = EXCEPTION_FLT_DIVIDE_BY_ZERO;
break;
+#endif
+#ifdef FPE_FLTOVF
case FPE_FLTOVF:
rec.ExceptionCode = EXCEPTION_FLT_OVERFLOW;
break;
+#endif
+#ifdef FPE_FLTUND
case FPE_FLTUND:
rec.ExceptionCode = EXCEPTION_FLT_UNDERFLOW;
break;
+#endif
+#ifdef FPE_FLTRES
case FPE_FLTRES:
rec.ExceptionCode = EXCEPTION_FLT_INEXACT_RESULT;
break;
+#endif
+#ifdef FPE_FLTINV
case FPE_FLTINV:
+#endif
default:
rec.ExceptionCode = EXCEPTION_FLT_INVALID_OPERATION;
break;
}
rec.ExceptionFlags = EXCEPTION_CONTINUABLE;
rec.ExceptionRecord = NULL;
- rec.ExceptionAddress = (LPVOID)__context->uc_mcontext.regs->nip;
+ rec.ExceptionAddress = addr;
rec.NumberParameters = 0;
- EXC_RtlRaiseException( &rec, &context );
+ EXC_RtlRaiseException( &rec, context );
+}
+
+/**********************************************************************
+ * segv_handler
+ *
+ * Handler for SIGSEGV and related errors.
+ */
+static HANDLER_DEF(segv_handler)
+{
+ CONTEXT context;
+ save_context( &context, HANDLER_CONTEXT );
+ do_segv( &context, __siginfo->si_signo, __siginfo->si_errno, __siginfo->si_code, __siginfo->si_addr );
restore_context( &context, HANDLER_CONTEXT );
- /*restore_fpu( &context, HANDLER_CONTEXT );*/
}
+/**********************************************************************
+ * trap_handler
+ *
+ * Handler for SIGTRAP.
+ */
+static HANDLER_DEF(trap_handler)
+{
+ CONTEXT context;
+ save_context( &context, HANDLER_CONTEXT );
+ do_trap( &context, __siginfo->si_code, __siginfo->si_addr );
+ restore_context( &context, HANDLER_CONTEXT );
+}
+
+/**********************************************************************
+ * fpe_handler
+ *
+ * Handler for SIGFPE.
+ */
+static HANDLER_DEF(fpe_handler)
+{
+ CONTEXT context;
+ save_fpu( &context, HANDLER_CONTEXT );
+ save_context( &context, HANDLER_CONTEXT );
+ do_fpe( &context, __siginfo->si_code, __siginfo->si_addr );
+ restore_context( &context, HANDLER_CONTEXT );
+ restore_fpu( &context, HANDLER_CONTEXT );
+}
/**********************************************************************
* int_handler
-------------- next part --------------
More information about the wine-patches
mailing list