On Tuesday, May 6, 2003, at 12:42 AM, Alexandre Julliard wrote:
"Pierre d'Herbemont" <stegefin@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.
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