summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>1995-02-14 19:23:22 +0000
committersos <sos@FreeBSD.org>1995-02-14 19:23:22 +0000
commit6deee3a45e9abcbe47f1e19b76c976658e2c5f26 (patch)
tree14e904cc9fa37485b1036478f5d4998f31c42a71 /sys/kern
parent7402b2152526539603dab9e8f1b64f404e3905e1 (diff)
downloadFreeBSD-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.c12
-rw-r--r--sys/kern/init_sysent.c3
-rw-r--r--sys/kern/kern_exec.c12
-rw-r--r--sys/kern/makesyscalls.sh4
-rw-r--r--sys/kern/subr_trap.c117
-rw-r--r--sys/kern/syscalls.c2
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[] = {
OpenPOWER on IntegriCloud