- bzero((caddr_t)&sinfo64, sizeof(user_siginfo_t));
- sinfo64.si_signo = sig;
-
- if (proc_is64bit(p)) {
- x86_thread_state64_t *tstate64;
- struct user_ucontext64 uctx64;
-
- flavor = x86_THREAD_STATE64;
- state_count = x86_THREAD_STATE64_COUNT;
- state = (void *)&mctx.mctx64.ss;
- if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
- goto bad;
-
- flavor = x86_FLOAT_STATE64;
- state_count = x86_FLOAT_STATE64_COUNT;
- state = (void *)&mctx.mctx64.fs;
- if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
- goto bad;
-
- flavor = x86_EXCEPTION_STATE64;
- state_count = x86_EXCEPTION_STATE64_COUNT;
- state = (void *)&mctx.mctx64.es;
- if (thread_getstatus(thread, flavor, (thread_state_t)state, &state_count) != KERN_SUCCESS)
- goto bad;
-
- tstate64 = &mctx.mctx64.ss;
-
- if (altstack && !oonstack && (ps->ps_sigonstack & sigmask(sig))) {
- if (uthsigaltstack != 0) {
- ua_sp = ut->uu_sigstk.ss_sp;
- stack_size = ut->uu_sigstk.ss_size;
- ua_sp += stack_size;
- ut->uu_sigstk.ss_flags |= SA_ONSTACK;
- } else {
- ua_sp = ps->ps_sigstk.ss_sp;
- stack_size = ps->ps_sigstk.ss_size;
- ua_sp += stack_size;
- ps->ps_sigstk.ss_flags |= SA_ONSTACK;
- }
- } else
- ua_sp = tstate64->rsp;
- ua_cr2 = mctx.mctx64.es.faultvaddr;
-
- /* The x86_64 ABI defines a 128-byte red zone. */
- ua_sp -= C_64_REDZONE_LEN;
-
- ua_sp -= sizeof (struct user_ucontext64);
- ua_uctxp = ua_sp; // someone tramples the first word!
-
- ua_sp -= sizeof (user_siginfo_t);
- ua_sip = ua_sp;
-
- ua_sp -= sizeof (struct mcontext64);
- ua_mctxp = ua_sp;
-
- /*
- * Align the frame and stack pointers to 16 bytes for SSE.
- * (Note that we use 'ua_fp' as the base of the stack going forward)
- */
- ua_fp = TRUNC_DOWN64(ua_sp, C_64_STK_ALIGN);
-
- /*
- * But we need to account for the return address so the alignment is
- * truly "correct" at _sigtramp
- */
- ua_fp -= sizeof(user_addr_t);
-
- /*
- * Build the signal context to be used by sigreturn.
- */
- bzero(&uctx64, sizeof(uctx64));
-
- uctx64.uc_onstack = oonstack;
- uctx64.uc_sigmask = mask;
- uctx64.uc_stack.ss_sp = ua_fp;
- uctx64.uc_stack.ss_size = stack_size;
-
- if (oonstack)
- uctx64.uc_stack.ss_flags |= SS_ONSTACK;
- uctx64.uc_link = 0;
-
- uctx64.uc_mcsize = sizeof(struct mcontext64);
- uctx64.uc_mcontext64 = ua_mctxp;
-
- if (copyout((caddr_t)&uctx64, ua_uctxp, sizeof (uctx64)))
- goto bad;
-
- if (copyout((caddr_t)&mctx.mctx64, ua_mctxp, sizeof (struct mcontext64)))
- goto bad;
-
- sinfo64.pad[0] = tstate64->rsp;
- sinfo64.si_addr = tstate64->rip;
-
- tstate64->rip = ps->ps_trampact[sig];
- tstate64->rsp = ua_fp;
- tstate64->rflags = get_eflags_exportmask();
- /*
- * JOE - might not need to set these
- */
- tstate64->cs = USER64_CS;
- tstate64->fs = NULL_SEG;
- tstate64->gs = USER_CTHREAD;
-
- /*
- * Build the argument list for the signal handler.
- * Handler should call sigreturn to get out of it
- */
- tstate64->rdi = ua_catcher;
- tstate64->rsi = infostyle;
- tstate64->rdx = sig;
- tstate64->rcx = ua_sip;
- tstate64->r8 = ua_uctxp;
-
+ context.sc_onstack = oonstack;
+ context.sc_mask = mask;
+ context.sc_eax = saved_state->eax;
+ context.sc_ebx = saved_state->ebx;
+ context.sc_ecx = saved_state->ecx;
+ context.sc_edx = saved_state->edx;
+ context.sc_edi = saved_state->edi;
+ context.sc_esi = saved_state->esi;
+ context.sc_ebp = saved_state->ebp;
+ context.sc_esp = saved_state->uesp;
+ context.sc_ss = saved_state->ss;
+ context.sc_eflags = saved_state->efl;
+ context.sc_eip = saved_state->eip;
+ context.sc_cs = saved_state->cs;
+ if (saved_state->efl & EFL_VM) {
+ context.sc_ds = saved_state->v86_segs.v86_ds;
+ context.sc_es = saved_state->v86_segs.v86_es;
+ context.sc_fs = saved_state->v86_segs.v86_fs;
+ context.sc_gs = saved_state->v86_segs.v86_gs;
+
+ saved_state->efl &= ~EFL_VM;