|
From: <ai...@us...> - 2003-09-16 12:34:21
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel
In directory sc8-pr-cvs1:/tmp/cvs-serv16019
Modified Files:
signal.c
Log Message:
DA: this is better than what was there already - still not tested,
I'd say there is still some work left to do
Index: signal.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/signal.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- signal.c 16 Feb 2003 23:28:02 -0000 1.11
+++ signal.c 16 Sep 2003 12:34:15 -0000 1.12
@@ -32,7 +32,7 @@
#include <asm/ucontext.h>
#include <asm/uaccess.h>
-#undef DEBUG_SIG
+#undef DEBUG_SIG
/* FIXME: Check this & fixup other regs, like r0 */
#define RESTART_VAX_SYSCALL(regs) { (regs)->pc -= 4; }
@@ -188,12 +188,10 @@
/* FIXME: this dont work ... */
struct rt_sigframe {
- char *pretcode;
- struct siginfo *pinfo;
- void *puc;
+ int sig;
struct siginfo info;
struct ucontext uc;
- unsigned char retcode[8]; /* trampoline code */
+ unsigned char retcode[20]; /* trampoline code */
};
@@ -526,17 +524,14 @@
sigset_t *set, struct pt_regs * regs)
{
struct rt_sigframe *frame;
- unsigned long return_ip;
int err = 0;
- machine_halt();
+ // machine_halt();
frame = get_sigframe(ka, regs, sizeof(*frame));
if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
goto give_sigsegv;
- err |= __put_user(&frame->info, &frame->pinfo);
- err |= __put_user(&frame->uc, &frame->puc);
err |= copy_siginfo_to_user(&frame->info, info);
if (err)
goto give_sigsegv;
@@ -553,17 +548,54 @@
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+
+ /* We do this differently to other ports. Each function has a two byte RSM.
+ * (due to the calling convention). Each sighandler will expect to be
+ * CALLS'd and will RET from that. So we cant just muck about with PC's on the
+ * stack like the i386. So we use the trampoline code on the stack a bit more.
+ * The easiest way to skip around all this is to calls the signal
+ * handler, and then either calls the restorer, or chmk to sys_sigreturn */
+
+ /* CALLS $1, */
+ err |= __put_user(0xfb, (char *)(frame->retcode+0));
+ err |= __put_user(0x01, (char *)(frame->retcode+1));
+ /* (absolute address)*/
+ err |= __put_user(0x9f, (char *)(frame->retcode+2));
+ /* sighandler */
+ err |= __put_user(((unsigned long) ka->sa.sa_handler), (unsigned long *)(frame->retcode + 3));
+
if (ka->sa.sa_flags & SA_RESTORER) {
- return_ip = (unsigned long)ka->sa.sa_restorer;
+ /* CALLS $0,*/
+ err |= __put_user(0xfb, (char *)(frame->retcode+7));
+ err |= __put_user(0x00, (char *)(frame->retcode+8));
+ /* (absolute address)*/
+ err |= __put_user(0x9f, (char *)(frame->retcode+9));
+ /* restorer */
+ err |= __put_user(((unsigned long) ka->sa.sa_restorer), (unsigned long *)(frame->retcode + 10));
+ /* plus a halt */
+ err |= __put_user(0x00, (char *)(frame->retcode+14));
} else {
- /* trampoline - the desired return ip is the retcode itself */
- return_ip = (unsigned long)&frame->retcode;
- /* TODO: check byteorder */
- err |= __put_user(0xbc8f, (short *)(frame->retcode+0));
- err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
+ /* perform a syscall to sys_sigreturn. First set up the
+ * argument list to avoid confusing it */
+
+ /* pushl $0x0 */
+ err |= __put_user(0xdd, (char *)(frame->retcode+7));
+ err |= __put_user(0x00, (char *)(frame->retcode+8));
+ /* movl sp, ap */
+ err |= __put_user(0xd0, (char *)(frame->retcode+9));
+ err |= __put_user(0x5e, (char *)(frame->retcode+10));
+ err |= __put_user(0x5c, (char *)(frame->retcode+11));
+ /* chmk __NR_sigreturn; */
+ err |= __put_user(0xbc, (char *)(frame->retcode+12));
+ err |= __put_user(0x8f, (char *)(frame->retcode+13));
+ err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+14));
+ /* plus a halt */
+ err |= __put_user(0x00, (char *)(frame->retcode+16));
}
- err |= __put_user(return_ip, &frame->pretcode);
if (err)
goto give_sigsegv;
@@ -572,7 +604,9 @@
/* Set up registers for signal handler */
regs->pc = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */
- regs->sp = (unsigned int)frame; /* what we enter LATER */
+ regs->fp = regs->sp;
+ regs->sp = (unsigned int)frame; /* what we enter LATER */
+ __mtpr(frame, PR_USP);
return;
@@ -657,7 +691,7 @@
return 1;
/* FIXME: */
- canrestart=0;
+ canrestart=regs->r0;
#ifdef DEBUG_SIG
printk("do_signal: pid %d,canrestart %d, current->sigpending %d,current->blocked %d ", current->pid,canrestart,current->sigpending,current->blocked);
#endif
|