summaryrefslogtreecommitdiffstats
path: root/sys
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
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')
-rw-r--r--sys/amd64/amd64/exception.S40
-rw-r--r--sys/amd64/amd64/exception.s40
-rw-r--r--sys/amd64/amd64/machdep.c12
-rw-r--r--sys/amd64/amd64/trap.c117
-rw-r--r--sys/amd64/include/segments.h4
-rw-r--r--sys/i386/i386/exception.s40
-rw-r--r--sys/i386/i386/machdep.c12
-rw-r--r--sys/i386/i386/trap.c117
-rw-r--r--sys/i386/include/segments.h4
-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
-rw-r--r--sys/sys/syscall-hide.h2
-rw-r--r--sys/sys/syscall.h2
-rw-r--r--sys/sys/sysent.h3
18 files changed, 518 insertions, 25 deletions
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index f6d6115..5d4f469 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.6 1994/12/03 10:02:19 bde Exp $
+ * $Id: exception.s,v 1.7 1995/01/14 13:20:05 bde Exp $
*/
#include "npx.h" /* NNPX */
@@ -245,6 +245,44 @@ IDTVEC(syscall)
MEXITCOUNT
jmp _doreti
+#ifdef COMPAT_LINUX
+/*
+ * Call gate entry for Linux syscall (int 0x80)
+ */
+ SUPERALIGN_TEXT
+IDTVEC(linux_syscall)
+ pushl $0
+ pushl $0
+ pushal
+ pushl %ds
+ pushl %es
+ movl $KDSEL,%eax
+ movl %ax,%ds
+ movl %ax,%es
+ FAKE_MCOUNT(12*4(%esp))
+ incl _cnt+V_SYSCALL
+ orl $SWI_AST_MASK,_cpl
+ call _linux_syscall
+ /*
+ * There was no place to save the cpl so we have to recover it
+ * indirectly. For traps from user mode it was 0, and for traps
+ * from kernel mode Oring SWI_AST_MASK into it didn't change it.
+ */
+ subl %eax,%eax
+ testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
+ jne 1f
+ movl _cpl,%eax
+1:
+ /*
+ * Return via _doreti to handle ASTs. Have to change trap frame
+ * to interrupt frame.
+ */
+ pushl %eax
+ subl $4,%esp
+ MEXITCOUNT
+ jmp _doreti
+#endif /* COMPAT_LINUX */
+
/*
* Include what was once config+isa-dependent code.
* XXX it should be in a stand-alone file. It's still icu-dependent and
diff --git a/sys/amd64/amd64/exception.s b/sys/amd64/amd64/exception.s
index f6d6115..5d4f469 100644
--- a/sys/amd64/amd64/exception.s
+++ b/sys/amd64/amd64/exception.s
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.6 1994/12/03 10:02:19 bde Exp $
+ * $Id: exception.s,v 1.7 1995/01/14 13:20:05 bde Exp $
*/
#include "npx.h" /* NNPX */
@@ -245,6 +245,44 @@ IDTVEC(syscall)
MEXITCOUNT
jmp _doreti
+#ifdef COMPAT_LINUX
+/*
+ * Call gate entry for Linux syscall (int 0x80)
+ */
+ SUPERALIGN_TEXT
+IDTVEC(linux_syscall)
+ pushl $0
+ pushl $0
+ pushal
+ pushl %ds
+ pushl %es
+ movl $KDSEL,%eax
+ movl %ax,%ds
+ movl %ax,%es
+ FAKE_MCOUNT(12*4(%esp))
+ incl _cnt+V_SYSCALL
+ orl $SWI_AST_MASK,_cpl
+ call _linux_syscall
+ /*
+ * There was no place to save the cpl so we have to recover it
+ * indirectly. For traps from user mode it was 0, and for traps
+ * from kernel mode Oring SWI_AST_MASK into it didn't change it.
+ */
+ subl %eax,%eax
+ testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
+ jne 1f
+ movl _cpl,%eax
+1:
+ /*
+ * Return via _doreti to handle ASTs. Have to change trap frame
+ * to interrupt frame.
+ */
+ pushl %eax
+ subl $4,%esp
+ MEXITCOUNT
+ jmp _doreti
+#endif /* COMPAT_LINUX */
+
/*
* Include what was once config+isa-dependent code.
* XXX it should be in a stand-alone file. It's still icu-dependent and
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index b82ecc0..3e07341 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.108 1995/02/11 04:21:24 phk Exp $
+ * $Id: machdep.c,v 1.109 1995/02/12 09:21:04 davidg Exp $
*/
#include "npx.h"
@@ -1125,6 +1125,11 @@ extern inthand_t
IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align),
IDTVEC(syscall);
+#ifdef COMPAT_LINUX
+extern inthand_t
+ IDTVEC(linux_syscall);
+#endif
+
void
sdtossd(sd, ssd)
struct segment_descriptor *sd;
@@ -1224,7 +1229,10 @@ init386(first)
setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL);
setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL);
setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL);
-
+#ifdef COMPAT_LINUX
+ setidt(0x80, &IDTVEC(linux_syscall), SDT_SYS386TGT, SEL_UPL);
+#endif
+
#include "isa.h"
#if NISA >0
isa_defaultirq();
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 5adff94..f98022b 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/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/amd64/include/segments.h b/sys/amd64/include/segments.h
index 6302599..0c236f5 100644
--- a/sys/amd64/include/segments.h
+++ b/sys/amd64/include/segments.h
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)segments.h 7.1 (Berkeley) 5/9/91
- * $Id: segments.h,v 1.6 1994/11/14 14:18:15 bde Exp $
+ * $Id: segments.h,v 1.7 1994/11/15 14:12:40 bde Exp $
*/
#ifndef _MACHINE_SEGMENTS_H_
@@ -194,7 +194,7 @@ struct region_descriptor {
* Size of IDT table
*/
-#define NIDT 48 /* 32 reserved, 16 h/w, 0 s/w */
+#define NIDT 129 /* 32 reserved, 16 h/w, 0 s/w, linux's 0x80 */
#define NRSVIDT 32 /* reserved entries for cpu exceptions */
/*
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index f6d6115..5d4f469 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.6 1994/12/03 10:02:19 bde Exp $
+ * $Id: exception.s,v 1.7 1995/01/14 13:20:05 bde Exp $
*/
#include "npx.h" /* NNPX */
@@ -245,6 +245,44 @@ IDTVEC(syscall)
MEXITCOUNT
jmp _doreti
+#ifdef COMPAT_LINUX
+/*
+ * Call gate entry for Linux syscall (int 0x80)
+ */
+ SUPERALIGN_TEXT
+IDTVEC(linux_syscall)
+ pushl $0
+ pushl $0
+ pushal
+ pushl %ds
+ pushl %es
+ movl $KDSEL,%eax
+ movl %ax,%ds
+ movl %ax,%es
+ FAKE_MCOUNT(12*4(%esp))
+ incl _cnt+V_SYSCALL
+ orl $SWI_AST_MASK,_cpl
+ call _linux_syscall
+ /*
+ * There was no place to save the cpl so we have to recover it
+ * indirectly. For traps from user mode it was 0, and for traps
+ * from kernel mode Oring SWI_AST_MASK into it didn't change it.
+ */
+ subl %eax,%eax
+ testb $SEL_RPL_MASK,TRAPF_CS_OFF(%esp)
+ jne 1f
+ movl _cpl,%eax
+1:
+ /*
+ * Return via _doreti to handle ASTs. Have to change trap frame
+ * to interrupt frame.
+ */
+ pushl %eax
+ subl $4,%esp
+ MEXITCOUNT
+ jmp _doreti
+#endif /* COMPAT_LINUX */
+
/*
* Include what was once config+isa-dependent code.
* XXX it should be in a stand-alone file. It's still icu-dependent and
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index b82ecc0..3e07341 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.108 1995/02/11 04:21:24 phk Exp $
+ * $Id: machdep.c,v 1.109 1995/02/12 09:21:04 davidg Exp $
*/
#include "npx.h"
@@ -1125,6 +1125,11 @@ extern inthand_t
IDTVEC(page), IDTVEC(rsvd), IDTVEC(fpu), IDTVEC(align),
IDTVEC(syscall);
+#ifdef COMPAT_LINUX
+extern inthand_t
+ IDTVEC(linux_syscall);
+#endif
+
void
sdtossd(sd, ssd)
struct segment_descriptor *sd;
@@ -1224,7 +1229,10 @@ init386(first)
setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL);
setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL);
setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL);
-
+#ifdef COMPAT_LINUX
+ setidt(0x80, &IDTVEC(linux_syscall), SDT_SYS386TGT, SEL_UPL);
+#endif
+
#include "isa.h"
#if NISA >0
isa_defaultirq();
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 5adff94..f98022b 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/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/i386/include/segments.h b/sys/i386/include/segments.h
index 6302599..0c236f5 100644
--- a/sys/i386/include/segments.h
+++ b/sys/i386/include/segments.h
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)segments.h 7.1 (Berkeley) 5/9/91
- * $Id: segments.h,v 1.6 1994/11/14 14:18:15 bde Exp $
+ * $Id: segments.h,v 1.7 1994/11/15 14:12:40 bde Exp $
*/
#ifndef _MACHINE_SEGMENTS_H_
@@ -194,7 +194,7 @@ struct region_descriptor {
* Size of IDT table
*/
-#define NIDT 48 /* 32 reserved, 16 h/w, 0 s/w */
+#define NIDT 129 /* 32 reserved, 16 h/w, 0 s/w, linux's 0x80 */
#define NRSVIDT 32 /* reserved entries for cpu exceptions */
/*
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[] = {
diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h
index b40f3d9..3447f9c 100644
--- a/sys/sys/syscall-hide.h
+++ b/sys/sys/syscall-hide.h
@@ -2,7 +2,7 @@
* System call hiders.
*
* 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 $
*/
HIDE_POSIX(fork)
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index ab6178c..8ebc58f 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -2,7 +2,7 @@
* System call numbers.
*
* 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 $
*/
#define SYS_syscall 0
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
index 8a0d939..64ac5bb 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sysent.h,v 1.1 1994/08/24 11:47:23 sos Exp $
+ * $Id: sysent.h,v 1.2 1994/10/09 21:53:05 sos Exp $
*/
#ifndef _SYS_SYSENT_H_
@@ -49,6 +49,7 @@ struct sysentvec {
int *sv_sigtbl; /* signal translation table */
int sv_errsize; /* size of signal translation table */
int *sv_errtbl; /* errno translation table */
+ int (*sv_fixup)(); /* stack fixup function */
};
#ifdef KERNEL
OpenPOWER on IntegriCloud