Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/i386/i386 Separate the syscall handlers into two ve...



details:   https://anonhg.NetBSD.org/src/rev/12d2e25f4f06
branches:  trunk
changeset: 500411:12d2e25f4f06
user:      mycroft <mycroft%NetBSD.org@localhost>
date:      Mon Dec 11 16:49:15 2000 +0000

description:
Separate the syscall handlers into two versions -- one which does ktrace, and
one which doesn't.  Dynamically switch.
There's more to do on this, but I have to go to work.

diffstat:

 sys/arch/i386/i386/ibcs2_syscall.c |  108 +++++++++++++++++++++++++++++++++---
 sys/arch/i386/i386/linux_syscall.c |  110 +++++++++++++++++++++++++++++++++---
 sys/arch/i386/i386/svr4_syscall.c  |  105 ++++++++++++++++++++++++++++++++---
 sys/arch/i386/i386/syscall.c       |   67 +++++++++++++++-------
 4 files changed, 341 insertions(+), 49 deletions(-)

diffs (truncated from 573 to 300 lines):

diff -r fe22c7a72008 -r 12d2e25f4f06 sys/arch/i386/i386/ibcs2_syscall.c
--- a/sys/arch/i386/i386/ibcs2_syscall.c        Mon Dec 11 16:39:01 2000 +0000
+++ b/sys/arch/i386/i386/ibcs2_syscall.c        Mon Dec 11 16:49:15 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ibcs2_syscall.c,v 1.8 2000/12/11 05:37:01 mycroft Exp $        */
+/*     $NetBSD: ibcs2_syscall.c,v 1.9 2000/12/11 16:49:15 mycroft Exp $        */
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -68,7 +68,8 @@
 #include <compat/ibcs2/ibcs2_syscall.h>
 #include <machine/ibcs2_machdep.h>
 
-void ibcs2_syscall __P((struct trapframe));
+void ibcs2_syscall_plain __P((struct trapframe));
+void ibcs2_syscall_fancy __P((struct trapframe));
 extern struct sysent ibcs2_sysent[];
 
 void
@@ -76,7 +77,10 @@
        struct proc *p;
 {
 
-       p->p_md.md_syscall = ibcs2_syscall;
+       if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET))
+               p->p_md.md_syscall = ibcs2_syscall_fancy;
+       else
+               p->p_md.md_syscall = ibcs2_syscall_plain;
 }
 
 /*
@@ -84,9 +88,8 @@
  *     System call request from POSIX system call gate interface to kernel.
  * Like trap(), argument is call by reference.
  */
-/*ARGSUSED*/
 void
-ibcs2_syscall(frame)
+ibcs2_syscall_plain(frame)
        struct trapframe frame;
 {
        register caddr_t params;
@@ -97,11 +100,98 @@
        register_t code, args[8], rval[2];
 
        uvmexp.syscalls++;
-#ifdef DEBUG
-       if (!USERMODE(frame.tf_cs, frame.tf_eflags))
-               panic("ibcs2_syscall");
-#endif
+       p = curproc;
+
+       code = frame.tf_eax;
+       if (IBCS2_HIGH_SYSCALL(code))
+               code = IBCS2_CVT_HIGH_SYSCALL(code);
+       callp = ibcs2_sysent;
+       params = (caddr_t)frame.tf_esp + sizeof(int);
+
+#ifdef VM86
+       /*
+        * VM86 mode application found our syscall trap gate by accident; let
+        * it get a SIGSYS and have the VM86 handler in the process take care
+        * of it.
+        */
+       if (frame.tf_eflags & PSL_VM)
+               code = -1;
+       else
+#endif /* VM86 */
+
+       switch (code) {
+       case SYS_syscall:
+               /*
+                * Code is first argument, followed by actual args.
+                */
+               code = fuword(params);
+               params += sizeof(int);
+               break;
+       default:
+               break;
+       }
 
+       callp += (code & (IBCS2_SYS_NSYSENT - 1));
+       argsize = callp->sy_argsize;
+       if (argsize) {
+               error = copyin(params, (caddr_t)args, argsize);
+               if (error)
+                       goto bad;
+       }
+#ifdef SYSCALL_DEBUG
+       scdebug_call(p, code, args);
+#endif /* SYSCALL_DEBUG */
+       rval[0] = 0;
+       rval[1] = 0;
+       error = (*callp->sy_call)(p, args, rval);
+       switch (error) {
+       case 0:
+               frame.tf_eax = rval[0];
+               frame.tf_edx = rval[1];
+               frame.tf_eflags &= ~PSL_C;      /* carry bit */
+               break;
+       case ERESTART:
+               /*
+                * The offset to adjust the PC by depends on whether we entered
+                * the kernel through the trap or call gate.  We pushed the
+                * size of the instruction into tf_err on entry.
+                */
+               frame.tf_eip -= frame.tf_err;
+               break;
+       case EJUSTRETURN:
+               /* nothing to do */
+               break;
+       default:
+       bad:
+               error = native_to_ibcs2_errno[error];
+               frame.tf_eax = error;
+               frame.tf_eflags |= PSL_C;       /* carry bit */
+               break;
+       }
+
+#ifdef SYSCALL_DEBUG
+       scdebug_ret(p, code, error, rval);
+#endif /* SYSCALL_DEBUG */
+       userret(p);
+}
+
+/*
+ * syscall(frame):
+ *     System call request from POSIX system call gate interface to kernel.
+ * Like trap(), argument is call by reference.
+ */
+void
+ibcs2_syscall_fancy(frame)
+       struct trapframe frame;
+{
+       register caddr_t params;
+       register const struct sysent *callp;
+       register struct proc *p;
+       int error;
+       size_t argsize;
+       register_t code, args[8], rval[2];
+
+       uvmexp.syscalls++;
        p = curproc;
 
        code = frame.tf_eax;
diff -r fe22c7a72008 -r 12d2e25f4f06 sys/arch/i386/i386/linux_syscall.c
--- a/sys/arch/i386/i386/linux_syscall.c        Mon Dec 11 16:39:01 2000 +0000
+++ b/sys/arch/i386/i386/linux_syscall.c        Mon Dec 11 16:49:15 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_syscall.c,v 1.8 2000/12/11 05:37:01 mycroft Exp $        */
+/*     $NetBSD: linux_syscall.c,v 1.9 2000/12/11 16:49:15 mycroft Exp $        */
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -68,7 +68,8 @@
 #include <compat/linux/arch/i386/linux_signal.h>
 #include <compat/linux/arch/i386/linux_machdep.h>
 
-void linux_syscall __P((struct trapframe));
+void linux_syscall_plain __P((struct trapframe));
+void linux_syscall_fancy __P((struct trapframe));
 extern struct sysent linux_sysent[];
 
 void
@@ -76,7 +77,10 @@
        struct proc *p;
 {
 
-       p->p_md.md_syscall = linux_syscall;
+       if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET))
+               p->p_md.md_syscall = linux_syscall_fancy;
+       else
+               p->p_md.md_syscall = linux_syscall_plain;
 }
 
 /*
@@ -84,9 +88,8 @@
  *     System call request from POSIX system call gate interface to kernel.
  * Like trap(), argument is call by reference.
  */
-/*ARGSUSED*/
 void
-linux_syscall(frame)
+linux_syscall_plain(frame)
        struct trapframe frame;
 {
        register const struct sysent *callp;
@@ -96,11 +99,98 @@
        register_t code, args[8], rval[2];
 
        uvmexp.syscalls++;
-#ifdef DEBUG
-       if (!USERMODE(frame.tf_cs, frame.tf_eflags))
-               panic("linux_syscall");
-#endif
-       
+       p = curproc;
+
+       code = frame.tf_eax;
+       callp = linux_sysent;
+
+#ifdef VM86
+       /*
+        * VM86 mode application found our syscall trap gate by accident; let
+        * it get a SIGSYS and have the VM86 handler in the process take care
+        * of it.
+        */
+       if (frame.tf_eflags & PSL_VM)
+               code = -1;
+       else
+#endif /* VM86 */
+
+       callp += (code & (LINUX_SYS_NSYSENT - 1));
+       argsize = callp->sy_argsize;
+       if (argsize) {
+               /*
+                * Linux passes the args in ebx, ecx, edx, esi, edi, in
+                * increasing order.
+                */
+               switch (argsize >> 2) {
+               case 5:
+                       args[4] = frame.tf_edi;
+               case 4:
+                       args[3] = frame.tf_esi;
+               case 3:
+                       args[2] = frame.tf_edx;
+               case 2:
+                       args[1] = frame.tf_ecx;
+               case 1:
+                       args[0] = frame.tf_ebx;
+                       break;
+               default:
+                       panic("linux syscall bogus argument size %d",
+                               argsize);
+                       break;
+               }
+       }
+#ifdef SYSCALL_DEBUG
+       scdebug_call(p, code, args);
+#endif /* SYSCALL_DEBUG */
+       rval[0] = 0;
+       rval[1] = 0;
+       error = (*callp->sy_call)(p, args, rval);
+       switch (error) {
+       case 0:
+               frame.tf_eax = rval[0];
+               frame.tf_eflags &= ~PSL_C;      /* carry bit */
+               break;
+       case ERESTART:
+               /*
+                * The offset to adjust the PC by depends on whether we entered
+                * the kernel through the trap or call gate.  We pushed the
+                * size of the instruction into tf_err on entry.
+                */
+               frame.tf_eip -= frame.tf_err;
+               break;
+       case EJUSTRETURN:
+               /* nothing to do */
+               break;
+       default:
+               error = native_to_linux_errno[error];
+               frame.tf_eax = error;
+               frame.tf_eflags |= PSL_C;       /* carry bit */
+               break;
+       }
+
+#ifdef SYSCALL_DEBUG
+       scdebug_ret(p, code, error, rval);
+#endif /* SYSCALL_DEBUG */
+       userret(p);
+}
+
+/*
+ * syscall(frame):
+ *     System call request from POSIX system call gate interface to kernel.
+ * Like trap(), argument is call by reference.
+ */
+void
+linux_syscall_fancy(frame)
+       struct trapframe frame;
+{
+       register const struct sysent *callp;
+       register struct proc *p;
+       int error;
+       size_t argsize;
+       register_t code, args[8], rval[2];
+
+       uvmexp.syscalls++;
        p = curproc;
 
        code = frame.tf_eax;
diff -r fe22c7a72008 -r 12d2e25f4f06 sys/arch/i386/i386/svr4_syscall.c
--- a/sys/arch/i386/i386/svr4_syscall.c Mon Dec 11 16:39:01 2000 +0000
+++ b/sys/arch/i386/i386/svr4_syscall.c Mon Dec 11 16:49:15 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: svr4_syscall.c,v 1.7 2000/12/11 05:37:01 mycroft Exp $ */
+/*     $NetBSD: svr4_syscall.c,v 1.8 2000/12/11 16:49:15 mycroft Exp $ */
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.



Home | Main Index | Thread Index | Old Index