as discussed on tech-kern, put linux and ibcs2 syscall code to separate
files and change syscall() to call p->p_emul->e_syscall() if it's not NULL
This commit is contained in:
parent
d996722823
commit
6719ee1cf7
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.i386,v 1.175 2000/11/26 20:48:39 jdolecek Exp $
|
||||
# $NetBSD: files.i386,v 1.176 2000/12/02 16:03:23 jdolecek Exp $
|
||||
#
|
||||
# new style config file for i386 architecture
|
||||
#
|
||||
@ -312,13 +312,13 @@ file arch/i386/i386/svr4_sigcode.s compat_svr4
|
||||
include "compat/ibcs2/files.ibcs2"
|
||||
file arch/i386/i386/ibcs2_machdep.c compat_ibcs2
|
||||
file arch/i386/i386/ibcs2_sigcode.s compat_ibcs2
|
||||
#file arch/i386/i386/ibcs2_syscall.c compat_ibcs2
|
||||
file arch/i386/i386/ibcs2_syscall.c compat_ibcs2
|
||||
|
||||
# Linux binary compatibility (COMPAT_LINUX)
|
||||
include "compat/linux/files.linux"
|
||||
include "compat/linux/arch/i386/files.linux_i386"
|
||||
file arch/i386/i386/linux_sigcode.s compat_linux
|
||||
#file arch/i386/i386/linux_syscall.c compat_linux
|
||||
file arch/i386/i386/linux_syscall.c compat_linux
|
||||
|
||||
# FreeBSD binary compatibility (COMPAT_FREEBSD)
|
||||
include "compat/freebsd/files.freebsd"
|
||||
|
266
sys/arch/i386/i386/ibcs2_syscall.c
Normal file
266
sys/arch/i386/i386/ibcs2_syscall.c
Normal file
@ -0,0 +1,266 @@
|
||||
/* $NetBSD: ibcs2_syscall.c,v 1.1 2000/12/02 16:03:24 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Charles M. Hannum.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the University of Utah, and William Jolitz.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)trap.c 7.4 (Berkeley) 5/13/91
|
||||
*/
|
||||
|
||||
/*
|
||||
* 386 Trap and System call handling
|
||||
*/
|
||||
|
||||
#if defined(_KERNEL) && !defined(_LKM)
|
||||
#include "opt_syscall_debug.h"
|
||||
#include "opt_vm86.h"
|
||||
#include "opt_ktrace.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/acct.h>
|
||||
#include <sys/kernel.h>
|
||||
#ifdef KTRACE
|
||||
#include <sys/ktrace.h>
|
||||
#endif
|
||||
#include <sys/signal.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/trap.h>
|
||||
#ifdef DDB
|
||||
#include <machine/db_machdep.h>
|
||||
#endif
|
||||
|
||||
#include <compat/ibcs2/ibcs2_errno.h>
|
||||
#include <compat/ibcs2/ibcs2_exec.h>
|
||||
|
||||
static __inline void userret __P((struct proc *, int, u_quad_t));
|
||||
void ibcs2_syscall __P((struct trapframe *));
|
||||
|
||||
/*
|
||||
* Define the code needed before returning to user mode, for
|
||||
* trap and syscall.
|
||||
*/
|
||||
static __inline void
|
||||
userret(p, pc, oticks)
|
||||
register struct proc *p;
|
||||
int pc;
|
||||
u_quad_t oticks;
|
||||
{
|
||||
int sig;
|
||||
|
||||
/* take pending signals */
|
||||
while ((sig = CURSIG(p)) != 0)
|
||||
postsig(sig);
|
||||
p->p_priority = p->p_usrpri;
|
||||
if (want_resched) {
|
||||
/*
|
||||
* We are being preempted.
|
||||
*/
|
||||
preempt(NULL);
|
||||
while ((sig = CURSIG(p)) != 0)
|
||||
postsig(sig);
|
||||
}
|
||||
|
||||
/*
|
||||
* If profiling, charge recent system time to the trapped pc.
|
||||
*/
|
||||
if (p->p_flag & P_PROFIL) {
|
||||
extern int psratio;
|
||||
|
||||
addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio);
|
||||
}
|
||||
|
||||
curcpu()->ci_schedstate.spc_curpriority = p->p_priority;
|
||||
}
|
||||
|
||||
/*
|
||||
* syscall(frame):
|
||||
* System call request from POSIX system call gate interface to kernel.
|
||||
* Like trap(), argument is call by reference.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
ibcs2_syscall(frame)
|
||||
struct trapframe *frame;
|
||||
{
|
||||
register caddr_t params;
|
||||
register const struct sysent *callp;
|
||||
register struct proc *p;
|
||||
int error, opc, nsys;
|
||||
size_t argsize;
|
||||
register_t code, args[8], rval[2];
|
||||
u_quad_t sticks;
|
||||
|
||||
p = curproc;
|
||||
sticks = p->p_sticks;
|
||||
p->p_md.md_regs = frame;
|
||||
opc = frame->tf_eip;
|
||||
code = frame->tf_eax;
|
||||
|
||||
nsys = p->p_emul->e_nsysent;
|
||||
callp = p->p_emul->e_sysent;
|
||||
|
||||
if (IBCS2_HIGH_SYSCALL(code))
|
||||
code = IBCS2_CVT_HIGH_SYSCALL(code);
|
||||
|
||||
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;
|
||||
}
|
||||
if (code < 0 || code >= nsys)
|
||||
callp += p->p_emul->e_nosys; /* illegal */
|
||||
else
|
||||
callp += code;
|
||||
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 */
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(p, KTR_SYSCALL))
|
||||
ktrsyscall(p, code, argsize, args);
|
||||
#endif /* KTRACE */
|
||||
rval[0] = 0;
|
||||
rval[1] = frame->tf_edx;
|
||||
error = (*callp->sy_call)(p, args, rval);
|
||||
switch (error) {
|
||||
case 0:
|
||||
/*
|
||||
* Reinitialize proc pointer `p' as it may be different
|
||||
* if this is a child returning from fork syscall.
|
||||
*/
|
||||
p = curproc;
|
||||
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 = opc - frame->tf_err;
|
||||
break;
|
||||
case EJUSTRETURN:
|
||||
/* nothing to do */
|
||||
break;
|
||||
default:
|
||||
bad:
|
||||
if (p->p_emul->e_errno)
|
||||
error = p->p_emul->e_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, frame->tf_eip, sticks);
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(p, KTR_SYSRET))
|
||||
ktrsysret(p, code, error, rval[0]);
|
||||
#endif /* KTRACE */
|
||||
}
|
265
sys/arch/i386/i386/linux_syscall.c
Normal file
265
sys/arch/i386/i386/linux_syscall.c
Normal file
@ -0,0 +1,265 @@
|
||||
/* $NetBSD: linux_syscall.c,v 1.1 2000/12/02 16:03:24 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Charles M. Hannum.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the University of Utah, and William Jolitz.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)trap.c 7.4 (Berkeley) 5/13/91
|
||||
*/
|
||||
|
||||
/*
|
||||
* 386 Trap and System call handling
|
||||
*/
|
||||
|
||||
#if defined(_KERNEL) && !defined(_LKM)
|
||||
#include "opt_syscall_debug.h"
|
||||
#include "opt_vm86.h"
|
||||
#include "opt_ktrace.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/acct.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/signal.h>
|
||||
#ifdef KTRACE
|
||||
#include <sys/ktrace.h>
|
||||
#endif
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#include <uvm/uvm_extern.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/trap.h>
|
||||
|
||||
#include <compat/ibcs2/ibcs2_errno.h>
|
||||
#include <compat/ibcs2/ibcs2_exec.h>
|
||||
|
||||
static __inline void userret __P((struct proc *, int, u_quad_t));
|
||||
void linux_syscall __P((struct trapframe *));
|
||||
|
||||
/*
|
||||
* Define the code needed before returning to user mode, for
|
||||
* trap and syscall.
|
||||
*/
|
||||
static __inline void
|
||||
userret(p, pc, oticks)
|
||||
register struct proc *p;
|
||||
int pc;
|
||||
u_quad_t oticks;
|
||||
{
|
||||
int sig;
|
||||
|
||||
/* take pending signals */
|
||||
while ((sig = CURSIG(p)) != 0)
|
||||
postsig(sig);
|
||||
p->p_priority = p->p_usrpri;
|
||||
if (want_resched) {
|
||||
/*
|
||||
* We are being preempted.
|
||||
*/
|
||||
preempt(NULL);
|
||||
while ((sig = CURSIG(p)) != 0)
|
||||
postsig(sig);
|
||||
}
|
||||
|
||||
/*
|
||||
* If profiling, charge recent system time to the trapped pc.
|
||||
*/
|
||||
if (p->p_flag & P_PROFIL) {
|
||||
extern int psratio;
|
||||
|
||||
addupc_task(p, pc, (int)(p->p_sticks - oticks) * psratio);
|
||||
}
|
||||
|
||||
curcpu()->ci_schedstate.spc_curpriority = p->p_priority;
|
||||
}
|
||||
|
||||
/*
|
||||
* syscall(frame):
|
||||
* System call request from POSIX system call gate interface to kernel.
|
||||
* Like trap(), argument is call by reference.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
linux_syscall(frame)
|
||||
struct trapframe *frame;
|
||||
{
|
||||
register caddr_t params;
|
||||
register const struct sysent *callp;
|
||||
register struct proc *p;
|
||||
int error, opc, nsys;
|
||||
size_t argsize;
|
||||
register_t code, args[8], rval[2];
|
||||
u_quad_t sticks;
|
||||
|
||||
p = curproc;
|
||||
sticks = p->p_sticks;
|
||||
p->p_md.md_regs = frame;
|
||||
opc = frame->tf_eip;
|
||||
code = frame->tf_eax;
|
||||
|
||||
nsys = p->p_emul->e_nsysent;
|
||||
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 */
|
||||
|
||||
if (code < 0 || code >= nsys)
|
||||
callp += p->p_emul->e_nosys; /* illegal */
|
||||
else
|
||||
callp += code;
|
||||
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 */
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(p, KTR_SYSCALL))
|
||||
ktrsyscall(p, code, argsize, args);
|
||||
#endif /* KTRACE */
|
||||
rval[0] = 0;
|
||||
rval[1] = frame->tf_edx;
|
||||
error = (*callp->sy_call)(p, args, rval);
|
||||
switch (error) {
|
||||
case 0:
|
||||
/*
|
||||
* Reinitialize proc pointer `p' as it may be different
|
||||
* if this is a child returning from fork syscall.
|
||||
*/
|
||||
p = curproc;
|
||||
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 = opc - frame->tf_err;
|
||||
break;
|
||||
case EJUSTRETURN:
|
||||
/* nothing to do */
|
||||
break;
|
||||
default:
|
||||
if (p->p_emul->e_errno)
|
||||
error = p->p_emul->e_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, frame->tf_eip, sticks);
|
||||
#ifdef KTRACE
|
||||
if (KTRPOINT(p, KTR_SYSRET))
|
||||
ktrsysret(p, code, error, rval[0]);
|
||||
#endif /* KTRACE */
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: trap.c,v 1.142 2000/11/21 21:27:04 jdolecek Exp $ */
|
||||
/* $NetBSD: trap.c,v 1.143 2000/12/02 16:03:24 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
@ -80,15 +80,10 @@
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_syscall_debug.h"
|
||||
#include "opt_execfmt.h"
|
||||
#include "opt_math_emulate.h"
|
||||
#include "opt_vm86.h"
|
||||
#include "opt_ktrace.h"
|
||||
#include "opt_cputype.h"
|
||||
#include "opt_compat_freebsd.h"
|
||||
#include "opt_compat_linux.h"
|
||||
#include "opt_compat_ibcs2.h"
|
||||
#include "opt_compat_aout.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -124,27 +119,6 @@
|
||||
#include <sys/kgdb.h>
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_IBCS2
|
||||
#include <sys/exec_elf.h>
|
||||
#include <compat/ibcs2/ibcs2_errno.h>
|
||||
#include <compat/ibcs2/ibcs2_exec.h>
|
||||
extern struct emul emul_ibcs2;
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_LINUX
|
||||
# include <sys/exec.h>
|
||||
# include <compat/linux/linux_syscall.h>
|
||||
extern struct emul emul_linux;
|
||||
#endif /* COMPAT_LINUX */
|
||||
|
||||
#ifdef COMPAT_FREEBSD
|
||||
extern struct emul emul_freebsd;
|
||||
#endif /* COMPAT_FREEBSD */
|
||||
|
||||
#ifdef COMPAT_AOUT
|
||||
extern struct emul emul_netbsd_aout;
|
||||
#endif /* COMPAT_AOUT */
|
||||
|
||||
#include "npx.h"
|
||||
|
||||
static __inline void userret __P((struct proc *, int, u_quad_t));
|
||||
@ -605,17 +579,17 @@ syscall(frame)
|
||||
size_t argsize;
|
||||
register_t code, args[8], rval[2];
|
||||
u_quad_t sticks;
|
||||
#ifdef COMPAT_LINUX
|
||||
int linux;
|
||||
#endif /* COMPAT_LINUX */
|
||||
#ifdef COMPAT_FREEBSD
|
||||
int freebsd;
|
||||
#endif /* COMPAT_FREEBSD */
|
||||
|
||||
uvmexp.syscalls++;
|
||||
if (!USERMODE(frame.tf_cs, frame.tf_eflags))
|
||||
panic("syscall");
|
||||
|
||||
p = curproc;
|
||||
if (p->p_emul->e_syscall) {
|
||||
p->p_emul->e_syscall(&frame);
|
||||
return;
|
||||
}
|
||||
|
||||
sticks = p->p_sticks;
|
||||
p->p_md.md_regs = &frame;
|
||||
opc = frame.tf_eip;
|
||||
@ -624,20 +598,6 @@ syscall(frame)
|
||||
nsys = p->p_emul->e_nsysent;
|
||||
callp = p->p_emul->e_sysent;
|
||||
|
||||
#ifdef COMPAT_LINUX
|
||||
linux = (p->p_emul == &emul_linux);
|
||||
#endif /* COMPAT_LINUX */
|
||||
|
||||
#ifdef COMPAT_FREEBSD
|
||||
freebsd = (p->p_emul == &emul_freebsd);
|
||||
#endif /* COMPAT_FREEBSD */
|
||||
|
||||
#ifdef COMPAT_IBCS2
|
||||
if (p->p_emul == &emul_ibcs2) {
|
||||
if (IBCS2_HIGH_SYSCALL(code))
|
||||
code = IBCS2_CVT_HIGH_SYSCALL(code);
|
||||
}
|
||||
#endif /* COMPAT_IBCS2 */
|
||||
params = (caddr_t)frame.tf_esp + sizeof(int);
|
||||
|
||||
#ifdef VM86
|
||||
@ -653,11 +613,6 @@ syscall(frame)
|
||||
|
||||
switch (code) {
|
||||
case SYS_syscall:
|
||||
#ifdef COMPAT_LINUX
|
||||
/* Linux has a special system setup call as number 0 */
|
||||
if (linux)
|
||||
break;
|
||||
#endif /* COMPAT_LINUX */
|
||||
/*
|
||||
* Code is first argument, followed by actual args.
|
||||
*/
|
||||
@ -669,14 +624,7 @@ syscall(frame)
|
||||
* Like syscall, but code is a quad, so as to maintain
|
||||
* quad alignment for the rest of the arguments.
|
||||
*/
|
||||
if (callp == sysent /* Native */
|
||||
#ifdef COMPAT_FREEBSD
|
||||
|| freebsd /* FreeBSD has the same function */
|
||||
#endif
|
||||
#ifdef COMPAT_AOUT
|
||||
|| (p->p_emul == &emul_netbsd_aout) /* Our a.out */
|
||||
#endif
|
||||
) {
|
||||
if (p->p_emul->e_flags & EMUL_HAS_SYS___syscall) {
|
||||
code = fuword(params + _QUAD_LOWWORD * sizeof(int));
|
||||
params += sizeof(quad_t);
|
||||
}
|
||||
@ -690,37 +638,9 @@ syscall(frame)
|
||||
callp += code;
|
||||
argsize = callp->sy_argsize;
|
||||
if (argsize) {
|
||||
#ifdef COMPAT_LINUX
|
||||
if (linux) {
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* COMPAT_LINUX */
|
||||
{
|
||||
error = copyin(params, (caddr_t)args, argsize);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
error = copyin(params, (caddr_t)args, argsize);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
#ifdef SYSCALL_DEBUG
|
||||
scdebug_call(p, code, args);
|
||||
@ -740,10 +660,7 @@ syscall(frame)
|
||||
*/
|
||||
p = curproc;
|
||||
frame.tf_eax = rval[0];
|
||||
#ifdef COMPAT_LINUX
|
||||
if (!linux)
|
||||
#endif /* COMPAT_LINUX */
|
||||
frame.tf_edx = rval[1];
|
||||
frame.tf_edx = rval[1];
|
||||
frame.tf_eflags &= ~PSL_C; /* carry bit */
|
||||
break;
|
||||
case ERESTART:
|
||||
|
Loading…
Reference in New Issue
Block a user