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.
This commit is contained in:
parent
11fcbfe7a6
commit
1ef2795be9
|
@ -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 @@ ibcs2_syscall_intern(p)
|
|||
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 @@ ibcs2_syscall_intern(p)
|
|||
* 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 @@ ibcs2_syscall(frame)
|
|||
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;
|
||||
|
|
|
@ -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 @@ linux_syscall_intern(p)
|
|||
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,100 @@ linux_syscall_intern(p)
|
|||
* 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;
|
||||
register struct proc *p;
|
||||
int error;
|
||||
size_t argsize;
|
||||
register_t code, args[8], rval[2];
|
||||
|
||||
uvmexp.syscalls++;
|
||||
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;
|
||||
|
@ -96,11 +191,6 @@ linux_syscall(frame)
|
|||
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;
|
||||
|
|
|
@ -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.
|
||||
|
@ -67,7 +67,8 @@
|
|||
#include <compat/svr4/svr4_syscall.h>
|
||||
#include <machine/svr4_machdep.h>
|
||||
|
||||
void svr4_syscall __P((struct trapframe));
|
||||
void svr4_syscall_plain __P((struct trapframe));
|
||||
void svr4_syscall_fancy __P((struct trapframe));
|
||||
extern struct sysent svr4_sysent[];
|
||||
|
||||
void
|
||||
|
@ -75,7 +76,10 @@ svr4_syscall_intern(p)
|
|||
struct proc *p;
|
||||
{
|
||||
|
||||
p->p_md.md_syscall = svr4_syscall;
|
||||
if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET))
|
||||
p->p_md.md_syscall = svr4_syscall_fancy;
|
||||
else
|
||||
p->p_md.md_syscall = svr4_syscall_plain;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -83,9 +87,8 @@ svr4_syscall_intern(p)
|
|||
* System call request from POSIX system call gate interface to kernel.
|
||||
* Like trap(), argument is call by reference.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
svr4_syscall(frame)
|
||||
svr4_syscall_plain(frame)
|
||||
struct trapframe frame;
|
||||
{
|
||||
register caddr_t params;
|
||||
|
@ -96,11 +99,95 @@ svr4_syscall(frame)
|
|||
register_t code, args[8], rval[2];
|
||||
|
||||
uvmexp.syscalls++;
|
||||
#ifdef DEBUG
|
||||
if (!USERMODE(frame.tf_cs, frame.tf_eflags))
|
||||
panic("svr4_syscall");
|
||||
#endif
|
||||
p = curproc;
|
||||
|
||||
code = frame.tf_eax;
|
||||
callp = svr4_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 & (SVR4_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_svr4_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
|
||||
svr4_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;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: syscall.c,v 1.2 2000/12/11 05:37:01 mycroft Exp $ */
|
||||
/* $NetBSD: syscall.c,v 1.3 2000/12/11 16:49:15 mycroft Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -62,14 +62,18 @@
|
|||
#include <machine/userret.h>
|
||||
|
||||
void syscall_intern __P((struct proc *));
|
||||
void syscall __P((struct trapframe));
|
||||
void syscall_plain __P((struct trapframe));
|
||||
void syscall_fancy __P((struct trapframe));
|
||||
|
||||
void
|
||||
syscall_intern(p)
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
p->p_md.md_syscall = syscall;
|
||||
if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET))
|
||||
p->p_md.md_syscall = syscall_fancy;
|
||||
else
|
||||
p->p_md.md_syscall = syscall_plain;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -77,10 +81,8 @@ syscall_intern(p)
|
|||
* System call request from POSIX system call gate interface to kernel.
|
||||
* Like trap(), argument is call by reference.
|
||||
*/
|
||||
#if 0
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
syscall(frame)
|
||||
syscall_plain(frame)
|
||||
struct trapframe frame;
|
||||
{
|
||||
register caddr_t params;
|
||||
|
@ -91,17 +93,43 @@ syscall(frame)
|
|||
register_t code, args[8], rval[2];
|
||||
|
||||
uvmexp.syscalls++;
|
||||
#ifdef DEBUG
|
||||
if (!USERMODE(frame.tf_cs, frame.tf_eflags))
|
||||
panic("syscall");
|
||||
#endif
|
||||
|
||||
p = curproc;
|
||||
|
||||
code = frame.tf_eax;
|
||||
callp = p->p_emul->e_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;
|
||||
case SYS___syscall:
|
||||
/*
|
||||
* Like syscall, but code is a quad, so as to maintain
|
||||
* quad alignment for the rest of the arguments.
|
||||
*/
|
||||
code = fuword(params + _QUAD_LOWWORD * sizeof(int));
|
||||
params += sizeof(quad_t);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
callp += (code & (SYS_NSYSENT - 1));
|
||||
argsize = callp->sy_argsize;
|
||||
if (argsize) {
|
||||
|
@ -109,6 +137,9 @@ syscall(frame)
|
|||
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);
|
||||
|
@ -136,14 +167,14 @@ syscall(frame)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef SYSCALL_DEBUG
|
||||
scdebug_ret(p, code, error, rval);
|
||||
#endif /* SYSCALL_DEBUG */
|
||||
userret(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
syscall(frame)
|
||||
syscall_fancy(frame)
|
||||
struct trapframe frame;
|
||||
{
|
||||
register caddr_t params;
|
||||
|
@ -154,11 +185,6 @@ syscall(frame)
|
|||
register_t code, args[8], rval[2];
|
||||
|
||||
uvmexp.syscalls++;
|
||||
#ifdef DEBUG
|
||||
if (!USERMODE(frame.tf_cs, frame.tf_eflags))
|
||||
panic("syscall");
|
||||
#endif
|
||||
|
||||
p = curproc;
|
||||
|
||||
code = frame.tf_eax;
|
||||
|
@ -246,7 +272,6 @@ syscall(frame)
|
|||
ktrsysret(p, code, error, rval[0]);
|
||||
#endif /* KTRACE */
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
child_return(arg)
|
||||
|
|
Loading…
Reference in New Issue