struct compat_sigcontext { struct compat_user_regs_struct sc_regs; union __riscv_fp_state sc_fpregs;
};
struct compat_ucontext {
compat_ulong_t uc_flags; struct compat_ucontext *uc_link;
compat_stack_t uc_stack;
sigset_t uc_sigmask; /* There's some padding here to allow sigset_t to be expanded in the * future. Though this is unlikely, other architectures put uc_sigmask * at the end of this structure and explicitly state it can be
* expanded, so we didn't want to box ourselves in here. */
__u8 __unused[1024 / 8 - sizeof(sigset_t)]; /* We can't put uc_sigmask at the end of this structure because we need * to be able to expand sigcontext in the future. For example, the * vector ISA extension will almost certainly add ISA state. We want * to ensure all user-visible ISA state can be saved and restored via a * ucontext, so we're putting this at the end in order to allow for * infinite extensibility. Since we know this will be extended and we * assume sigset_t won't be extended an extreme amount, we're
* prioritizing this. */ struct compat_sigcontext uc_mcontext;
};
/* We support no other extension state at this time. */ for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
err = __put_user(0, &sc_fpregs->q.reserved[i]); if (unlikely(err)) break;
}
/* sc_regs is structured the same as the start of pt_regs */
err = __copy_to_user(&sc->sc_regs, &cregs, sizeof(sc->sc_regs)); /* Save the floating-point state. */ if (has_fpu())
err |= compat_save_fp_state(regs, &sc->sc_fpregs); return err;
}
staticinlinevoid __user *compat_get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t framesize)
{ unsignedlong sp; /* Default to using normal stack */
sp = regs->sp;
/* * 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;
/* Align the stack frame. */
sp &= ~0xfUL;
return (void __user *)sp;
}
int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{ struct compat_rt_sigframe __user *frame; long err = 0;
frame = compat_get_sigframe(ksig, regs, sizeof(*frame)); if (!access_ok(frame, sizeof(*frame))) return -EFAULT;
/* * 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->epc = (unsignedlong)ksig->ka.sa.sa_handler;
regs->sp = (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 */
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.