/* Store registers needed to create the signal frame */ staticvoid store_sigregs(void)
{
save_access_regs(current->thread.acrs);
save_user_fpu_regs();
}
/* Load registers after signal return */ staticvoid load_sigregs(void)
{
restore_access_regs(current->thread.acrs);
}
/* Save high gprs to signal stack */ for (i = 0; i < NUM_GPRS; i++)
gprs_high[i] = regs->gprs[i] >> 32; if (__copy_to_user(&sregs_ext->gprs_high, &gprs_high, sizeof(sregs_ext->gprs_high))) return -EFAULT;
/* Save vector registers to signal stack */ if (cpu_has_vx()) { for (i = 0; i < __NUM_VXRS_LOW; i++)
vxrs[i] = current->thread.ufpu.vxrs[i].low; if (__copy_to_user(&sregs_ext->vxrs_low, vxrs, sizeof(sregs_ext->vxrs_low)) ||
__copy_to_user(&sregs_ext->vxrs_high,
current->thread.ufpu.vxrs + __NUM_VXRS_LOW, sizeof(sregs_ext->vxrs_high))) return -EFAULT;
} return 0;
}
/* Restore high gprs from signal stack */ if (__copy_from_user(&gprs_high, &sregs_ext->gprs_high, sizeof(sregs_ext->gprs_high))) return -EFAULT; for (i = 0; i < NUM_GPRS; i++)
*(__u32 *)®s->gprs[i] = gprs_high[i];
/* Restore vector registers from signal stack */ if (cpu_has_vx()) { if (__copy_from_user(vxrs, &sregs_ext->vxrs_low, sizeof(sregs_ext->vxrs_low)) ||
__copy_from_user(current->thread.ufpu.vxrs + __NUM_VXRS_LOW,
&sregs_ext->vxrs_high, sizeof(sregs_ext->vxrs_high))) return -EFAULT; for (i = 0; i < __NUM_VXRS_LOW; i++)
current->thread.ufpu.vxrs[i].low = vxrs[i];
} return 0;
}
/* Default to using normal stack */
sp = (unsignedlong) A(regs->gprs[15]);
/* Overflow on alternate signal stack gives SIGSEGV. */ if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL)) return (void __user *) -1UL;
/* This is the X/Open sanctioned signal stack switching. */ if (ka->sa.sa_flags & SA_ONSTACK) { if (! sas_ss_flags(sp))
sp = current->sas_ss_sp + current->sas_ss_size;
}
/* * gprs_high are always present for 31-bit compat tasks. * The space for vector registers is only allocated if * the machine supports it
*/
frame_size = sizeof(*frame) - sizeof(frame->sregs_ext.__reserved); if (!cpu_has_vx())
frame_size -= sizeof(frame->sregs_ext.vxrs_low) + sizeof(frame->sregs_ext.vxrs_high);
frame = get_sigframe(&ksig->ka, regs, frame_size); if (frame == (void __user *) -1UL) return -EFAULT;
/* Set up backchain. */ if (__put_user(regs->gprs[15], (unsignedint __user *) frame)) return -EFAULT;
/* Create struct sigcontext32 on the signal stack */ if (put_compat_sigset((compat_sigset_t __user *)frame->sc.oldmask,
set, sizeof(compat_sigset_t))) return -EFAULT; if (__put_user(ptr_to_compat(&frame->sregs), &frame->sc.sregs)) return -EFAULT;
/* Store registers needed to create the signal frame */
store_sigregs();
/* Create _sigregs32 on the signal stack */ if (save_sigregs32(regs, &frame->sregs)) return -EFAULT;
/* Place signal number on stack to allow backtrace from handler. */ if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo)) return -EFAULT;
/* Create _sigregs_ext32 on the signal stack */ if (save_sigregs_ext32(regs, &frame->sregs_ext)) return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
restorer = (unsignedlong __force)
ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
} else {
restorer = VDSO32_SYMBOL(current, sigreturn);
}
/* Set up registers for signal handler */
regs->gprs[14] = restorer;
regs->gprs[15] = (__force __u64) frame; /* Force 31 bit amode and default user address space control. */
regs->psw.mask = PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler;
/* We forgot to include these in the sigcontext.
To avoid breaking binary compatibility, they are passed as args. */ if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
sig == SIGTRAP || sig == SIGFPE) { /* set extra registers only for synchronous signals */
regs->gprs[4] = regs->int_code & 127;
regs->gprs[5] = regs->int_parm_long;
regs->gprs[6] = current->thread.last_break;
}
frame_size = sizeof(*frame) - sizeof(frame->uc.uc_mcontext_ext.__reserved); /* * gprs_high are always present for 31-bit compat tasks. * The space for vector registers is only allocated if * the machine supports it
*/
uc_flags = UC_GPRS_HIGH; if (cpu_has_vx()) {
uc_flags |= UC_VXRS;
} else {
frame_size -= sizeof(frame->uc.uc_mcontext_ext.vxrs_low) + sizeof(frame->uc.uc_mcontext_ext.vxrs_high);
}
frame = get_sigframe(&ksig->ka, regs, frame_size); if (frame == (void __user *) -1UL) return -EFAULT;
/* Set up backchain. */ if (__put_user(regs->gprs[15], (unsignedint __force __user *) frame)) return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
restorer = (unsignedlong __force)
ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
} else {
restorer = VDSO32_SYMBOL(current, rt_sigreturn);
}
/* Create siginfo on the signal stack */ if (copy_siginfo_to_user32(&frame->info, &ksig->info)) return -EFAULT;
/* Store registers needed to create the signal frame */
store_sigregs();
/* Create ucontext on the signal stack. */ if (__put_user(uc_flags, &frame->uc.uc_flags) ||
__put_user(0, &frame->uc.uc_link) ||
__compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
save_sigregs32(regs, &frame->uc.uc_mcontext) ||
put_compat_sigset(&frame->uc.uc_sigmask, set, sizeof(compat_sigset_t)) ||
save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext)) return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[14] = restorer;
regs->gprs[15] = (__force __u64) frame; /* Force 31 bit amode and default user address space control. */
regs->psw.mask = PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler;
/* Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame32(ksig, oldset, regs); else
ret = setup_frame32(ksig, oldset, regs);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.