+ uctx.uc_onstack = oonstack;
+ uctx.uc_sigmask = mask;
+ uctx.uc_stack.ss_sp = (char *)sp;
+ uctx.uc_stack.ss_size = stack_size;
+ if (oonstack)
+ uctx.uc_stack.ss_flags |= SS_ONSTACK;
+
+ uctx.uc_link = 0;
+ if (ctx32 == 0)
+ uctx.uc_mcsize = (size_t)((PPC_EXCEPTION_STATE64_COUNT + PPC_THREAD_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int));
+ else
+ uctx.uc_mcsize = (size_t)((PPC_EXCEPTION_STATE_COUNT + PPC_THREAD_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int));
+
+ if (vec_used)
+ uctx.uc_mcsize += (size_t)(PPC_VECTOR_STATE_COUNT * sizeof(int));
+
+ if (ctx32 == 0)
+ uctx.uc_mcontext = (void *)p_mctx64;
+ else
+ uctx.uc_mcontext = (void *)p_mctx;
+
+ /* setup siginfo */
+ bzero((caddr_t)&sinfo, sizeof(siginfo_t));
+ sinfo.si_signo = sig;
+ sinfo.si_addr = (void *)mctx.ss.srr0;
+ sinfo.pad[0] = (unsigned int)mctx.ss.r1;
+
+ switch (sig) {
+ case SIGCHLD:
+ sinfo.si_pid = p->si_pid;
+ p->si_pid =0;
+ sinfo.si_status = p->si_status;
+ p->si_status = 0;
+ sinfo.si_uid = p->si_uid;
+ p->si_uid =0;
+ sinfo.si_code = p->si_code;
+ p->si_code = 0;
+ if (sinfo.si_code == CLD_EXITED) {
+ if (WIFEXITED(sinfo.si_status))
+ sinfo.si_code = CLD_EXITED;
+ else if (WIFSIGNALED(sinfo.si_status)) {
+ if (WCOREDUMP(sinfo.si_status))
+ sinfo.si_code = CLD_DUMPED;
+ else
+ sinfo.si_code = CLD_KILLED;
+ }
+ }
+ break;
+ case SIGILL:
+ sinfo.si_addr = (void *)mctx.ss.srr0;
+ if (mctx.ss.srr1 & (1 << (31 - SRR1_PRG_ILL_INS_BIT)))
+ sinfo.si_code = ILL_ILLOPC;
+ else if (mctx.ss.srr1 & (1 << (31 - SRR1_PRG_PRV_INS_BIT)))
+ sinfo.si_code = ILL_PRVOPC;
+ else if (mctx.ss.srr1 & (1 << (31 - SRR1_PRG_TRAP_BIT)))
+ sinfo.si_code = ILL_ILLTRP;
+ else
+ sinfo.si_code = ILL_NOOP;
+ break;
+ case SIGFPE:
+#define FPSCR_VX 2
+#define FPSCR_OX 3
+#define FPSCR_UX 4
+#define FPSCR_ZX 5
+#define FPSCR_XX 6
+ sinfo.si_addr = (void *)mctx.ss.srr0;
+ if (mctx.fs.fpscr & (1 << (31 - FPSCR_VX)))
+ sinfo.si_code = FPE_FLTINV;
+ else if (mctx.fs.fpscr & (1 << (31 - FPSCR_OX)))
+ sinfo.si_code = FPE_FLTOVF;
+ else if (mctx.fs.fpscr & (1 << (31 - FPSCR_UX)))
+ sinfo.si_code = FPE_FLTUND;
+ else if (mctx.fs.fpscr & (1 << (31 - FPSCR_ZX)))
+ sinfo.si_code = FPE_FLTDIV;
+ else if (mctx.fs.fpscr & (1 << (31 - FPSCR_XX)))
+ sinfo.si_code = FPE_FLTRES;
+ else
+ sinfo.si_code = FPE_NOOP;
+ break;
+
+ case SIGBUS:
+ sinfo.si_addr = (void *)mctx.ss.srr0;
+ /* on ppc we generate only if EXC_PPC_UNALIGNED */
+ sinfo.si_code = BUS_ADRALN;
+ break;
+
+ case SIGSEGV:
+ sinfo.si_addr = (void *)mctx.ss.srr0;
+ /* First check in srr1 and then in dsisr */
+ if (mctx.ss.srr1 & (1 << (31 - DSISR_PROT_BIT)))
+ sinfo.si_code = SEGV_ACCERR;
+ else if (mctx.es.dsisr & (1 << (31 - DSISR_PROT_BIT)))
+ sinfo.si_code = SEGV_ACCERR;
+ else
+ sinfo.si_code = SEGV_MAPERR;
+ break;
+ default:
+ break;
+ }
+