/* These symbols are defined with the addresses in the vsyscall page.
See vsyscall-trapa.S. */ externvoid __kernel_sigreturn(void); externvoid __kernel_rt_sigreturn(void);
if (_NSIG_WORDS > 1)
err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask));
/* Set up to return from userspace. If provided, use a stub
already in userspace. */ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
regs->pr = (unsignedlong) ksig->ka.sa.sa_restorer; #ifdef CONFIG_VSYSCALL
} elseif (likely(current->mm->context.vdso)) {
regs->pr = VDSO_SYM(&__kernel_sigreturn); #endif
} else { /* Generate return code (system call to sigreturn) */
err |= __put_user(MOVW(7), &frame->retcode[0]);
err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
err |= __put_user(OR_R0_R0, &frame->retcode[2]);
err |= __put_user(OR_R0_R0, &frame->retcode[3]);
err |= __put_user(OR_R0_R0, &frame->retcode[4]);
err |= __put_user(OR_R0_R0, &frame->retcode[5]);
err |= __put_user(OR_R0_R0, &frame->retcode[6]);
err |= __put_user((__NR_sigreturn), &frame->retcode[7]);
regs->pr = (unsignedlong) frame->retcode;
flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
}
if (err) return -EFAULT;
/* Set up registers for signal handler */
regs->regs[15] = (unsignedlong) frame;
regs->regs[4] = sig; /* Arg for signal handler */
regs->regs[5] = 0;
regs->regs[6] = (unsignedlong) &frame->sc;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */ if (ksig->ka.sa.sa_flags & SA_RESTORER) {
regs->pr = (unsignedlong) ksig->ka.sa.sa_restorer; #ifdef CONFIG_VSYSCALL
} elseif (likely(current->mm->context.vdso)) {
regs->pr = VDSO_SYM(&__kernel_rt_sigreturn); #endif
} else { /* Generate return code (system call to rt_sigreturn) */
err |= __put_user(MOVW(7), &frame->retcode[0]);
err |= __put_user(TRAP_NOARG, &frame->retcode[1]);
err |= __put_user(OR_R0_R0, &frame->retcode[2]);
err |= __put_user(OR_R0_R0, &frame->retcode[3]);
err |= __put_user(OR_R0_R0, &frame->retcode[4]);
err |= __put_user(OR_R0_R0, &frame->retcode[5]);
err |= __put_user(OR_R0_R0, &frame->retcode[6]);
err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]);
regs->pr = (unsignedlong) frame->retcode;
flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
}
if (err) return -EFAULT;
/* Set up registers for signal handler */
regs->regs[15] = (unsignedlong) frame;
regs->regs[4] = sig; /* Arg for signal handler */
regs->regs[5] = (unsignedlong) &frame->info;
regs->regs[6] = (unsignedlong) &frame->uc;
staticinlinevoid
handle_syscall_restart(unsignedlong save_r0, struct pt_regs *regs, struct sigaction *sa)
{ /* If we're not from a syscall, bail out */ if (regs->tra < 0) return;
/* check for system call restart.. */ switch (regs->regs[0]) { case -ERESTART_RESTARTBLOCK: case -ERESTARTNOHAND:
no_system_call_restart:
regs->regs[0] = -EINTR; break;
case -ERESTARTSYS: if (!(sa->sa_flags & SA_RESTART)) goto no_system_call_restart;
fallthrough; case -ERESTARTNOINTR:
regs->regs[0] = save_r0;
regs->pc -= instruction_size(__raw_readw(regs->pc - 4)); break;
}
}
/* Set up the stack frame */ if (ksig->ka.sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame(ksig, oldset, regs); else
ret = setup_frame(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.