|
@@ -61,13 +61,19 @@ int restore_sigcontext(struct pt_regs *regs,
|
|
|
/* Always make any pending restarted system calls return -EINTR */
|
|
|
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
|
|
|
|
|
+ /*
|
|
|
+ * Enforce that sigcontext is like pt_regs, and doesn't mess
|
|
|
+ * up our stack alignment rules.
|
|
|
+ */
|
|
|
+ BUILD_BUG_ON(sizeof(struct sigcontext) != sizeof(struct pt_regs));
|
|
|
+ BUILD_BUG_ON(sizeof(struct sigcontext) % 8 != 0);
|
|
|
+
|
|
|
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
|
|
|
- err |= __get_user(((long *)regs)[i],
|
|
|
- &((long __user *)(&sc->regs))[i]);
|
|
|
+ err |= __get_user(regs->regs[i], &sc->gregs[i]);
|
|
|
|
|
|
regs->faultnum = INT_SWINT_1_SIGRETURN;
|
|
|
|
|
|
- err |= __get_user(*pr0, &sc->regs.regs[0]);
|
|
|
+ err |= __get_user(*pr0, &sc->gregs[0]);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
@@ -112,8 +118,7 @@ int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
|
|
|
int i, err = 0;
|
|
|
|
|
|
for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
|
|
|
- err |= __put_user(((long *)regs)[i],
|
|
|
- &((long __user *)(&sc->regs))[i]);
|
|
|
+ err |= __put_user(regs->regs[i], &sc->gregs[i]);
|
|
|
|
|
|
return err;
|
|
|
}
|
|
@@ -203,19 +208,17 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|
|
* 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 = (unsigned long) ka->sa.sa_handler;
|
|
|
regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
|
|
|
regs->sp = (unsigned long) frame;
|
|
|
regs->lr = restorer;
|
|
|
regs->regs[0] = (unsigned long) usig;
|
|
|
-
|
|
|
- if (ka->sa.sa_flags & SA_SIGINFO) {
|
|
|
- /* Need extra arguments, so mark to restore caller-saves. */
|
|
|
- regs->regs[1] = (unsigned long) &frame->info;
|
|
|
- regs->regs[2] = (unsigned long) &frame->uc;
|
|
|
- regs->flags |= PT_FLAGS_CALLER_SAVES;
|
|
|
- }
|
|
|
+ regs->regs[1] = (unsigned long) &frame->info;
|
|
|
+ regs->regs[2] = (unsigned long) &frame->uc;
|
|
|
+ regs->flags |= PT_FLAGS_CALLER_SAVES;
|
|
|
|
|
|
/*
|
|
|
* Notify any tracer that was single-stepping it.
|