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
This commit is contained in:
parent
47ccef1936
commit
1e1e0b4463
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=6380
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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 @@ execve(p, uap, retval)
|
||||
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);
|
||||
|
@ -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
|
||||
} '
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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[] = {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user