diff options
author | sos <sos@FreeBSD.org> | 1995-02-14 19:23:22 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 1995-02-14 19:23:22 +0000 |
commit | 6deee3a45e9abcbe47f1e19b76c976658e2c5f26 (patch) | |
tree | 14e904cc9fa37485b1036478f5d4998f31c42a71 /sys/kern | |
parent | 7402b2152526539603dab9e8f1b64f404e3905e1 (diff) | |
download | FreeBSD-src-6deee3a45e9abcbe47f1e19b76c976658e2c5f26.zip FreeBSD-src-6deee3a45e9abcbe47f1e19b76c976658e2c5f26.tar.gz |
First attempt to run linux binaries. This is only the changes needed to
the generic kernel. The actual emulator is a separate LKM. (not finished
yet, sorry).
Submitted by: sos@freebsd.org & sef@kithrup.com
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/imgact_aout.c | 12 | ||||
-rw-r--r-- | sys/kern/init_sysent.c | 3 | ||||
-rw-r--r-- | sys/kern/kern_exec.c | 12 | ||||
-rw-r--r-- | sys/kern/makesyscalls.sh | 4 | ||||
-rw-r--r-- | sys/kern/subr_trap.c | 117 | ||||
-rw-r--r-- | sys/kern/syscalls.c | 2 |
6 files changed, 141 insertions, 9 deletions
diff --git a/sys/kern/imgact_aout.c b/sys/kern/imgact_aout.c index c700c26..5d6454c 100644 --- a/sys/kern/imgact_aout.c +++ b/sys/kern/imgact_aout.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: imgact_aout.c,v 1.8 1994/09/24 21:36:50 davidg Exp $ + * $Id: imgact_aout.c,v 1.9 1994/09/25 19:33:31 phk Exp $ */ #include <sys/param.h> @@ -54,6 +54,16 @@ exec_aout_imgact(iparams) int error; extern struct sysentvec aout_sysvec; +#ifdef COMPAT_LINUX + /* + * Linux and *BSD binaries look very much alike, + * only the machine id is different: + * 0x64 for Linux, 0x86 for *BSD. + */ + if (((a_out->a_magic >> 16) & 0xff) != 0x86) + return -1; +#endif /* COMPAT_LINUX */ + /* * Set file/virtual offset based on a.out variant. * We do two cases: host byte order and network byte order diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 8c68240..bd77750 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -2,7 +2,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from $Id: syscalls.master,v 1.11 1994/10/02 04:45:52 davidg Exp $ + * created from $Id: syscalls.master,v 1.12 1994/12/14 17:57:23 wollman Exp $ */ #include <sys/param.h> @@ -520,5 +520,6 @@ struct sysentvec aout_sysvec = { 0, 0, 0, + 0, 0 }; diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index b35343b..94b5dc2 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kern_exec.c,v 1.10 1994/10/02 17:35:13 phk Exp $ + * $Id: kern_exec.c,v 1.11 1995/01/09 16:04:49 davidg Exp $ */ #include <sys/param.h> @@ -46,6 +46,7 @@ #include <sys/wait.h> #include <sys/mman.h> #include <sys/malloc.h> +#include <sys/sysent.h> #include <sys/syslog.h> #include <sys/shm.h> @@ -214,9 +215,14 @@ interpret: p->p_vmspace->vm_minsaddr = (char *)stack_base; /* - * Stuff argument count as first item on stack + * If custom stack fixup routine present for this process + * let it do the stack setup. + * Else stuff argument count as first item on stack */ - *(--stack_base) = iparams->argc; + if (p->p_sysent->sv_fixup) + (*p->p_sysent->sv_fixup)(&stack_base, iparams); + else + *(--stack_base) = iparams->argc; /* close files on exec */ fdcloseexec(p); diff --git a/sys/kern/makesyscalls.sh b/sys/kern/makesyscalls.sh index 50de7d2..a4875fb 100644 --- a/sys/kern/makesyscalls.sh +++ b/sys/kern/makesyscalls.sh @@ -1,6 +1,6 @@ #! /bin/sh - # @(#)makesyscalls.sh 8.1 (Berkeley) 6/10/93 -# $Id: makesyscalls.sh,v 1.9 1994/10/09 22:07:37 sos Exp $ +# $Id: makesyscalls.sh,v 1.10 1994/11/06 21:57:16 ats Exp $ set -e @@ -183,7 +183,7 @@ awk < $1 " printf ("struct sysentvec aout_sysvec = {\n") > sysent printf ("\tsizeof (sysent) / sizeof (sysent[0]),\n") > sysent printf ("\tsysent,\n") > sysent - printf ("\t0,\n\t0,\n\t0,\n\t0,\n\t0\n};\n") > sysent + printf ("\t0,\n\t0,\n\t0,\n\t0,\n\t0,\n\t0\n};\n") > sysent printf("};\n") > sysnames } ' diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 5adff94..f98022b 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -35,7 +35,7 @@ * SUCH DAMAGE. * * from: @(#)trap.c 7.4 (Berkeley) 5/13/91 - * $Id: trap.c,v 1.46 1995/02/10 06:25:14 davidg Exp $ + * $Id: trap.c,v 1.47 1995/02/10 06:43:47 davidg Exp $ */ /* @@ -747,3 +747,118 @@ syscall(frame) ktrsysret(p->p_tracep, code, error, rval[0]); #endif } + +#ifdef COMPAT_LINUX +/* + * linux_syscall(frame): + */ +/*ARGSUSED*/ +void +linux_syscall(frame) + struct trapframe frame; +{ + caddr_t params; + int i; + struct proc *p = curproc; + struct sysent *callp; + u_quad_t sticks; + int error, opc; + int rval[2]; + int code; + struct linux_syscall_args { + int ebx; + int ecx; + int edx; + int esi; + int edi; + int ebp; + int eax; + } args; + + args.ebx = frame.tf_ebx; + args.ecx = frame.tf_ecx; + args.edx = frame.tf_edx; + args.esi = frame.tf_esi; + args.edi = frame.tf_edi; + args.ebp = frame.tf_ebp; + args.eax = frame.tf_eax; + + sticks = p->p_sticks; + if (ISPL(frame.tf_cs) != SEL_UPL) + panic("linux syscall"); + + code = frame.tf_eax; + p->p_md.md_regs = (int *)&frame; + params = (caddr_t)frame.tf_esp + sizeof (int) ; + + /* + * Reconstruct pc, assuming lcall $X,y is 7 bytes, as it is always. + * THIS IS WRONG FOR LINUX XXX SOS + * SIZE OF INT 0x80 (2??) NEEDED HERE !!! + */ + opc = frame.tf_eip - 2; /* was 7 */ + if (code == 0) { + code = fuword(params); + params += sizeof (int); + } + if (p->p_sysent->sv_mask) + code = code & p->p_sysent->sv_mask; + + if (code < 0 || code >= p->p_sysent->sv_size) + callp = &p->p_sysent->sv_table[0]; + else + callp = &p->p_sysent->sv_table[code]; + +#ifdef KTRACE + if (KTRPOINT(p, KTR_SYSCALL)) + ktrsyscall(p->p_tracep, code, callp->sy_narg, &args); +#endif + +#ifdef KTRACE + if (KTRPOINT(p, KTR_SYSCALL)) + ktrsyscall(p->p_tracep, code, callp->sy_narg, &args); +#endif + 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: + frame.tf_eip = opc; + break; + + case EJUSTRETURN: + break; + + default: + bad: + if (p->p_sysent->sv_errsize) + if (error >= p->p_sysent->sv_errsize) + error = -1; /* XXX */ + else + error = p->p_sysent->sv_errtbl[error]; + frame.tf_eax = -error; + frame.tf_eflags |= PSL_C; /* carry bit */ + break; + } + + userret(p, &frame, sticks); + +#ifdef KTRACE + if (KTRPOINT(p, KTR_SYSRET)) + ktrsysret(p->p_tracep, code, error, rval[0]); +#endif +} +#endif /* COMPAT_LINUX */ diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 247b928..d880f18 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -2,7 +2,7 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * created from $Id: syscalls.master,v 1.11 1994/10/02 04:45:52 davidg Exp $ + * created from $Id: syscalls.master,v 1.12 1994/12/14 17:57:23 wollman Exp $ */ char *syscallnames[] = { |