void __longjmp14(jmp_buf env, int val) { struct sigcontext *sc = (void *)env; ucontext_t uc; /* Ensure non-zero SP */ if (sc->sc_sp == 0 || sc->sc_regs[R_ZERO] != 0xacedbade) goto err; /* Ensure non-zero return value */ if (val == 0) val = -1; /* Set _UC_SIGMASK and _UC_CPU */ uc.uc_flags = _UC_SIGMASK | _UC_CPU; /* Clear uc_link */ uc.uc_link = 0; /* Save return value in context */ uc.uc_mcontext.__gregs[_REG_V0] = val; /* Copy saved registers */ uc.uc_mcontext.__gregs[_REG_S0] = sc->sc_regs[R_S0]; uc.uc_mcontext.__gregs[_REG_S1] = sc->sc_regs[R_S1]; uc.uc_mcontext.__gregs[_REG_S2] = sc->sc_regs[R_S2]; uc.uc_mcontext.__gregs[_REG_S3] = sc->sc_regs[R_S3]; uc.uc_mcontext.__gregs[_REG_S4] = sc->sc_regs[R_S4]; uc.uc_mcontext.__gregs[_REG_S5] = sc->sc_regs[R_S5]; uc.uc_mcontext.__gregs[_REG_S6] = sc->sc_regs[R_S6]; uc.uc_mcontext.__gregs[_REG_RA] = sc->sc_regs[R_RA]; uc.uc_mcontext.__gregs[_REG_SP] = sc->sc_sp; uc.uc_mcontext.__gregs[_REG_PC] = sc->sc_pc; uc.uc_mcontext.__gregs[_REG_PS] = (sc->sc_ps | ALPHA_PSL_USERSET) & ~ALPHA_PSL_USERCLR; /* Copy FP state */ if (sc->sc_ownedfp) { memcpy(&uc.uc_mcontext.__fpregs.__fp_fr, &sc->sc_fpregs, 31 * sizeof(unsigned long)); uc.uc_mcontext.__fpregs.__fp_fpcr = sc->sc_fpcr; /* XXX sc_fp_control */ uc.uc_flags |= _UC_FPU; } /* Copy signal mask */ uc.uc_sigmask = sc->sc_mask; setcontext(&uc); err: longjmperror(); abort(); /* NOTREACHED */ }
void __longjmp14(jmp_buf env, int val) { struct _jmp_buf *jb = (void *)env; ucontext_t uc; /* Ensure non-zero SP */ if (jb->jb_sc.sc_sp == 0) goto err; /* Ensure non-zero return value */ if (val == 0) val = -1; /* Set _UC_SIGMASK and _UC_CPU */ uc.uc_flags = _UC_SIGMASK | _UC_CPU; /* Clear uc_link */ uc.uc_link = 0; /* Save return value in context */ uc.uc_mcontext.__gregs[_REG_R0] = val; /* Copy saved registers */ uc.uc_mcontext.__gregs[_REG_AP] = jb->jb_sc.sc_ap; uc.uc_mcontext.__gregs[_REG_SP] = jb->jb_sc.sc_sp; uc.uc_mcontext.__gregs[_REG_FP] = jb->jb_sc.sc_fp; uc.uc_mcontext.__gregs[_REG_PC] = jb->jb_sc.sc_pc; uc.uc_mcontext.__gregs[_REG_PSL] = jb->jb_sc.sc_ps; uc.uc_mcontext.__gregs[_REG_R6] = jb->jb_regs[0]; uc.uc_mcontext.__gregs[_REG_R7] = jb->jb_regs[1]; uc.uc_mcontext.__gregs[_REG_R8] = jb->jb_regs[2]; uc.uc_mcontext.__gregs[_REG_R9] = jb->jb_regs[3]; uc.uc_mcontext.__gregs[_REG_R10] = jb->jb_regs[4]; uc.uc_mcontext.__gregs[_REG_R11] = jb->jb_regs[5]; /* Copy signal mask */ uc.uc_sigmask = jb->jb_sc.sc_mask; setcontext(&uc); err: longjmperror(); abort(); /* NOTREACHED */ }
void __longjmp14(jmp_buf env, int val) { struct sigcontext *sc = (void *)env; ucontext_t uc; /* Ensure non-zero SP and sigcontext magic number is present */ if (sc->sc_regs[_R_SP] == 0 || sc->sc_regs[_R_ZERO] != 0xACEDBADE) goto err; /* Ensure non-zero return value */ if (val == 0) val = 1; /* * Set _UC_{SET,CLR}STACK according to SS_ONSTACK. * * Restore the signal mask with sigprocmask() instead of _UC_SIGMASK, * since libpthread may want to interpose on signal handling. */ uc.uc_flags = _UC_CPU | (sc->sc_onstack ? _UC_SETSTACK : _UC_CLRSTACK); sigprocmask(SIG_SETMASK, &sc->sc_mask, NULL); /* Clear uc_link */ uc.uc_link = 0; /* Save return value in context */ uc.uc_mcontext.__gregs[_R_V0] = val; /* Copy saved registers */ uc.uc_mcontext.__gregs[_REG_S0] = sc->sc_regs[_R_S0]; uc.uc_mcontext.__gregs[_REG_S1] = sc->sc_regs[_R_S1]; uc.uc_mcontext.__gregs[_REG_S2] = sc->sc_regs[_R_S2]; uc.uc_mcontext.__gregs[_REG_S3] = sc->sc_regs[_R_S3]; uc.uc_mcontext.__gregs[_REG_S4] = sc->sc_regs[_R_S4]; uc.uc_mcontext.__gregs[_REG_S5] = sc->sc_regs[_R_S5]; uc.uc_mcontext.__gregs[_REG_S6] = sc->sc_regs[_R_S6]; uc.uc_mcontext.__gregs[_REG_S7] = sc->sc_regs[_R_S7]; uc.uc_mcontext.__gregs[_REG_S8] = sc->sc_regs[_R_S8]; uc.uc_mcontext.__gregs[_REG_SP] = sc->sc_regs[_R_SP]; uc.uc_mcontext.__gregs[_REG_RA] = sc->sc_regs[_R_RA]; uc.uc_mcontext.__gregs[_REG_EPC] = sc->sc_pc; /* Copy FP state */ if (sc->sc_fpused) { /* FP saved regs are $f20 .. $f31 */ memcpy(&uc.uc_mcontext.__fpregs.__fp_r.__fp_regs[20], &sc->sc_fpregs[20], 32 - 20); uc.uc_mcontext.__fpregs.__fp_csr = sc->sc_fpregs[_R_FSR - _FPBASE]; /* XXX sc_fp_control */ uc.uc_flags |= _UC_FPU; } setcontext(&uc); err: longjmperror(); abort(); /* NOTREACHED */ }
void __longjmp14(jmp_buf env, int val) { ucontext_t uc; struct sigcontext *sc = (void *)env; register_t *regs = (void *)(sc + 1); register register_t dp __asm("r27"); /* Ensure non-zero SP */ if (sc->sc_sp == 0) goto err; /* Make return value non-zero */ if (val == 0) val = 1; /* Copy callee-saved regs */ regs -= 3; uc.uc_mcontext.__gregs[3] = regs[3]; uc.uc_mcontext.__gregs[4] = regs[4]; uc.uc_mcontext.__gregs[5] = regs[5]; uc.uc_mcontext.__gregs[6] = regs[6]; uc.uc_mcontext.__gregs[7] = regs[7]; uc.uc_mcontext.__gregs[8] = regs[8]; uc.uc_mcontext.__gregs[9] = regs[9]; uc.uc_mcontext.__gregs[10] = regs[10]; uc.uc_mcontext.__gregs[11] = regs[11]; uc.uc_mcontext.__gregs[12] = regs[12]; uc.uc_mcontext.__gregs[13] = regs[13]; uc.uc_mcontext.__gregs[14] = regs[14]; uc.uc_mcontext.__gregs[15] = regs[15]; uc.uc_mcontext.__gregs[16] = regs[16]; uc.uc_mcontext.__gregs[17] = regs[17]; uc.uc_mcontext.__gregs[18] = regs[18]; /* Preserve the current value of DP */ /* LINTED dp is r27, so is "initialized" */ uc.uc_mcontext.__gregs[27] = dp; /* Set the desired return value. */ uc.uc_mcontext.__gregs[_REG_RET0] = val; /* * Set _UC_{SET,CLR}STACK according to SS_ONSTACK. * * Restore the signal mask with sigprocmask() instead of _UC_SIGMASK, * since libpthread may want to interpose on signal handling. */ uc.uc_flags = _UC_CPU | (sc->sc_onstack ? _UC_SETSTACK : _UC_CLRSTACK); sigprocmask(SIG_SETMASK, &sc->sc_mask, NULL); /* Clear uc_link */ uc.uc_link = 0; /* Copy signal mask */ uc.uc_sigmask = sc->sc_mask; /* Copy special regs */ uc.uc_mcontext.__gregs[_REG_PSW] = sc->sc_ps; uc.uc_mcontext.__gregs[_REG_SP] = sc->sc_sp; uc.uc_mcontext.__gregs[_REG_PCSQH] = sc->sc_pcsqh; uc.uc_mcontext.__gregs[_REG_PCOQH] = sc->sc_pcoqh; uc.uc_mcontext.__gregs[_REG_PCSQT] = sc->sc_pcsqt; uc.uc_mcontext.__gregs[_REG_PCOQT] = sc->sc_pcoqt; setcontext(&uc); err: longjmperror(); abort(); /* NOTREACHED */ }