struct rt_sigframe { /* * pad[3] is compatible with the same struct defined in * gcc/libgcc/config/csky/linux-unwind.h
*/ int pad[3]; struct siginfo info; struct ucontext uc;
};
staticlong restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
{ int err = 0; unsignedlong sr = regs->sr;
/* sc_pt_regs is structured the same as the start of pt_regs */
err |= __copy_from_user(regs, &sc->sc_pt_regs, sizeof(struct pt_regs));
/* BIT(0) of regs->sr is Condition Code/Carry bit */
regs->sr = (sr & ~1) | (regs->sr & 1);
/* Restore the floating-point state. */
err |= restore_fpu_state(sc);
staticinlinevoid __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t framesize)
{ unsignedlong sp; /* Default to using normal stack */
sp = regs->usp;
/* * If we are on the alternate signal stack and would overflow it, don't. * Return an always-bogus address instead so we will die with SIGSEGV.
*/ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) return (void __user __force *)(-1UL);
/* This is the X/Open sanctioned signal stack switching. */
sp = sigsp(sp, ksig) - framesize;
/* Set up to return from userspace. */
regs->lr = (unsignedlong)VDSO_SYMBOL(
current->mm->context.vdso, rt_sigreturn);
/* * Set up registers for signal handler. * Registers that we don't modify keep the value they had from * user-space at the time we took the signal. * We always pass siginfo and mcontext, regardless of SA_SIGINFO, * since some things rely on this (e.g. glibc's debug/segfault.c).
*/
regs->pc = (unsignedlong)ksig->ka.sa.sa_handler;
regs->usp = (unsignedlong)frame;
regs->a0 = ksig->sig; /* a0: signal number */
regs->a1 = (unsignedlong)(&(frame->info)); /* a1: siginfo pointer */
regs->a2 = (unsignedlong)(&(frame->uc)); /* a2: ucontext pointer */
if (get_signal(&ksig)) { /* Actually deliver the signal */
handle_signal(&ksig, regs); return;
}
/* Did we come from a system call? */ if (in_syscall(regs)) { /* Avoid additional syscall restarting via ret_from_exception */
forget_syscall(regs);
/* Restart the system call - no handlers present */ switch (regs->a0) { case -ERESTARTNOHAND: case -ERESTARTSYS: case -ERESTARTNOINTR:
regs->a0 = regs->orig_a0;
regs->pc -= TRAP0_SIZE; break; case -ERESTART_RESTARTBLOCK:
regs->a0 = regs->orig_a0;
regs_syscallid(regs) = __NR_restart_syscall;
regs->pc -= TRAP0_SIZE; break;
}
}
/* * If there is no signal to deliver, we just put the saved * sigmask back.
*/
restore_saved_sigmask();
}
/* * notification of userspace execution resumption * - triggered by the _TIF_WORK_MASK flags
*/
asmlinkage void do_notify_resume(struct pt_regs *regs, unsignedlong thread_info_flags)
{ if (thread_info_flags & _TIF_UPROBE)
uprobe_notify_resume(regs);
/* Handle pending signal delivery */ if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
do_signal(regs);
if (thread_info_flags & _TIF_NOTIFY_RESUME)
resume_user_mode_work(regs);
}
Messung V0.5
¤ 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.0.0Bemerkung:
(vorverarbeitet)
¤
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.