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