Subject: Re: Emulations as LKMs
To: Matthew Orgass <darkstar@pgh.net>
From: Jaromír Dolecek <dolecek@ibis.cz>
List: tech-kern
Date: 11/08/2000 19:22:50
Matthew Orgass wrote:
>   No, that is not fine.  This limits you to emulations the kernel already
> knows about and keeps emulation code spread accross the kernel.  The right
> thing to do is to separate the syscall and signal code for each emulation
> and just call the correct function for the current emulation.

I'll think about this. It's not particularily wise to separate the
syscall/signal code - the emulation-specific code is minimal, only kind of
quirks. Making the thing a separate function would probably duplicate
too much code. I'd probably go just with some kind of flags, like
EMUL_SYSCALL_ARGS_IN_REGS, and making the code something like:

	if (p->p_emul->e_flags & EMUL_SOME_FLAG)
		do_something;

This could be sufficient.

Anyway, I made some preliminary changes to struct emul, struct
execsw and struct exec_package, so that all exec-related stuff is in execsw
and there is only single emulation struct for every emulation type. I'm
including a (incomplete) patch. Incomplete in that only couple of
emulations were fixed to new format so far (namely linux and NetBSD, on
i386). I'd appreciate comments if anything should be done better or is
incorrect. I'm not terribly sure if the check for (newerror != ENOEXEC)
is correct, for example.

Note that for now, an execsw entry is not marked busy when used -
it will be later, so that it's possible to find out if it's
safe to unload the appropriate executable format.

A bit of problem is the probe_funcs[] array in exec_elf32.c. Problem
in that it's one more structure which needs to be patched to add
emulation-specific hooks. This is probably unavoidable, though :(

Jaromir

XXXX
Index: sys/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/proc.h,v
retrieving revision 1.106
diff -u -r1.106 proc.h
--- sys/proc.h	2000/11/07 12:41:53	1.106
+++ sys/proc.h	2000/11/08 18:00:22
@@ -91,16 +91,8 @@
 	void	(*e_sendsig) __P((sig_t, int, sigset_t *, u_long));
 	int	e_nosys;		/* Offset of the nosys() syscall */
 	int	e_nsysent;		/* Number of system call entries */
-	struct sysent *e_sysent;	/* System call array */
-	char	**e_syscallnames;	/* System call name array */
-	int	e_arglen;		/* Extra argument size in words */
-					/* Copy arguments on the new stack */
-	void	*(*e_copyargs) __P((struct exec_package *, struct ps_strings *,
-				    void *, void *));
-					/* Set registers before execution */
-	void	(*e_setregs) __P((struct proc *, struct exec_package *,
-				  u_long));
-
+	const struct sysent *e_sysent;	/* System call array */
+	const char * const *e_syscallnames;	/* System call name array */
 	char	*e_sigcode;		/* Start of sigcode */
 	char	*e_esigcode;		/* End of sigcode */
 
@@ -187,7 +179,7 @@
 	int	p_locks;		/* DEBUG: lockmgr count of held locks */
 
 	int	p_holdcnt;		/* If non-zero, don't swap. */
-	struct	emul *p_emul;		/* Emulation information */
+	const struct emul *p_emul;	/* Emulation information */
 	void	*p_emuldata;		/* Per-process emulation data, or NULL.
 					 * Malloc type M_EMULDATA */
 
Index: sys/exec.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/exec.h,v
retrieving revision 1.72
diff -u -r1.72 exec.h
--- sys/exec.h	2000/09/28 19:05:07	1.72
+++ sys/exec.h	2000/11/08 18:00:24
@@ -107,6 +107,15 @@
 struct execsw {
 	u_int	es_hdrsz;		/* size of header for this format */
 	exec_makecmds_fcn es_check;	/* function to check exec format */
+	int	es_arglen;		/* Extra argument size in words */
+					/* Copy arguments on the new stack */
+	void	*(*es_copyargs) __P((struct exec_package *, struct ps_strings *,
+				    void *, void *));
+					/* Set registers before execution */
+	void	(*es_setregs) __P((struct proc *, struct exec_package *,
+				  u_long));
+	
+	pid_t	es_busy;		/* one if currently used */
 };
 
 /* exec vmspace-creation command set; see below */
@@ -138,8 +147,9 @@
 	u_int	ep_flags;		/* flags; see below. */
 	char	**ep_fa;		/* a fake args vector for scripts */
 	int	ep_fd;			/* a file descriptor we're holding */
-	struct  emul *ep_emul;		/* os emulation */
+	const struct  emul *ep_emul;	/* os emulation */
 	void	*ep_emul_arg;		/* emulation argument */
+	struct	execsw *ep_es;		/* appropriate execsw entry */
 };
 #define	EXEC_INDIR	0x0001		/* script handling already done */
 #define	EXEC_HASFD	0x0002		/* holding a shell script */
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_exec.c,v
retrieving revision 1.122
diff -u -r1.122 kern_exec.c
--- kern/kern_exec.c	2000/11/07 12:41:52	1.122
+++ kern/kern_exec.c	2000/11/08 18:00:25
@@ -33,6 +33,7 @@
  */
 
 #include "opt_ktrace.h"
+#include "opt_syscall_debug.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -52,6 +53,7 @@
 #include <sys/mman.h>
 #include <sys/signalvar.h>
 #include <sys/stat.h>
+#include <sys/syscall.h>
 
 #include <sys/syscallargs.h>
 
@@ -60,6 +62,27 @@
 #include <machine/cpu.h>
 #include <machine/reg.h>
 
+extern char sigcode[], esigcode[];
+#ifdef SYSCALL_DEBUG
+extern char *syscallnames[];
+#endif
+
+const struct emul emul_netbsd = {
+	"netbsd",
+	NULL,
+	sendsig,
+	SYS_syscall,
+	SYS_MAXSYSCALL,
+	sysent,
+#ifdef SYSCALL_DEBUG
+	syscallnames,
+#else
+	NULL,
+#endif
+	sigcode,
+	esigcode,
+};
+
 /*
  * check exec:
  * given an "executable" described in the exec package's namei info,
@@ -152,6 +175,10 @@
 			error = newerror;
 		if (epp->ep_flags & EXEC_DESTR && error != 0)
 			return error;
+
+		/* if es_check call was successful, update epp->ep_es */
+		if (newerror == ENOEXEC)
+			epp->ep_es = &execsw[i];
 	}
 	if (!error) {
 		/* check that entry point is sane */
@@ -339,11 +366,11 @@
 
 	/* Now check if args & environ fit into new stack */
 	if (pack.ep_flags & EXEC_32)
-		len = ((argc + envc + 2 + pack.ep_emul->e_arglen) * sizeof(int) +
+		len = ((argc + envc + 2 + pack.ep_es->es_arglen) * sizeof(int) +
 		       sizeof(int) + dp + STACKGAPLEN + szsigcode +
 		       sizeof(struct ps_strings)) - argp;
 	else
-		len = ((argc + envc + 2 + pack.ep_emul->e_arglen) * sizeof(char *) +
+		len = ((argc + envc + 2 + pack.ep_es->es_arglen) * sizeof(char *) +
 		       sizeof(int) + dp + STACKGAPLEN + szsigcode +
 		       sizeof(struct ps_strings)) - argp;
 
@@ -424,7 +451,7 @@
 
 	stack = (char *) (vm->vm_minsaddr - len);
 	/* Now copy argc, args & environ to new stack */
-	if (!(*pack.ep_emul->e_copyargs)(&pack, &arginfo, stack, argp)) {
+	if (!(*pack.ep_es->es_copyargs)(&pack, &arginfo, stack, argp)) {
 #ifdef DEBUG
 		printf("execve: copyargs failed\n");
 #endif
@@ -450,7 +477,7 @@
 	/* copy out the process's signal trapoline code */
 	if (szsigcode) {
 		if (copyout((char *)pack.ep_emul->e_sigcode,
-		    p->p_sigacts->ps_sigcode = (char *)p->p_psstr - szsigcode,
+		    p->p_sigacts.ps_sigcode = (char *)p->p_psstr - szsigcode,
 		    szsigcode)) {
 #ifdef DEBUG
 			printf("execve: sig trampoline copyout failed\n");
@@ -521,7 +548,7 @@
 	vput(pack.ep_vp);
 
 	/* setup new registers and do misc. setup. */
-	(*pack.ep_emul->e_setregs)(p, &pack, (u_long) stack);
+	(*pack.ep_es->es_setregs)(p, &pack, (u_long) stack);
 
 	if (p->p_flag & P_TRACED)
 		psignal(p, SIGTRAP);
@@ -619,7 +646,7 @@
 	argc >>= 32;
 #endif
 
-	dp = (char *) (cpp + argc + envc + 2 + pack->ep_emul->e_arglen);
+	dp = (char *) (cpp + argc + envc + 2 + pack->ep_es->es_arglen);
 	sp = argp;
 
 	/* XXX don't copy them out, remap them! */
Index: kern/exec_conf.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/exec_conf.c,v
retrieving revision 1.43
diff -u -r1.43 exec_conf.c
--- kern/exec_conf.c	2000/06/09 22:38:57	1.43
+++ kern/exec_conf.c	2000/11/08 18:00:25
@@ -114,61 +114,66 @@
 
 struct execsw execsw[] = {
 #ifdef LKM
-	{ 0, NULL, },					/* entries for LKMs */
-	{ 0, NULL, },
-	{ 0, NULL, },
-	{ 0, NULL, },
-	{ 0, NULL, },
+	{ 0, NULL, 0 },					/* entries for LKMs */
+	{ 0, NULL, 0 },
+	{ 0, NULL, 0 },
+	{ 0, NULL, 0 },
+	{ 0, NULL, 0 },
 #endif
 #ifdef EXEC_SCRIPT
-	{ MAXINTERP, exec_script_makecmds, },		/* shell scripts */
+	{ MAXINTERP, exec_script_makecmds, 0 },	/* shell scripts */
 #endif
 #ifdef EXEC_AOUT
 #ifdef COMPAT_NETBSD32
-	{ sizeof(struct netbsd32_exec), exec_netbsd32_makecmds, }, /* sparc 32 bit */
+	{ sizeof(struct netbsd32_exec), exec_netbsd32_makecmds, 0 }, /* sparc 32 bit */
 #endif
 # ifdef COMPAT_AOUT
-	{ sizeof(struct exec), exec_aoutcompat_makecmds, },/* compat a.out */
+	{ sizeof(struct exec), exec_aoutcompat_makecmds, 0 },/* compat a.out */
 # else
-	{ sizeof(struct exec), exec_aout_makecmds, },	/* a.out binaries */
+	{ sizeof(struct exec), exec_aout_makecmds, 0 },	/* a.out binaries */
 # endif
 #endif
 #ifdef EXEC_COFF
-	{ COFF_HDR_SIZE, exec_coff_makecmds, },		/* coff binaries */
+	{ COFF_HDR_SIZE, exec_coff_makecmds, 0 },	/* coff binaries */
 #endif
 #ifdef EXEC_ECOFF
-	{ ECOFF_HDR_SIZE, exec_ecoff_makecmds, },	/* ecoff binaries */
+	{ ECOFF_HDR_SIZE, exec_ecoff_makecmds, 0 },	/* ecoff binaries */
 #endif
 #ifdef EXEC_ELF32
-	{ sizeof (Elf32_Ehdr), exec_elf32_makecmds, },	/* 32bit ELF bins */
+	{ sizeof (Elf32_Ehdr), exec_elf32_makecmds,
+	  howmany(ELF_AUX_ENTRIES * sizeof(Aux32Info), sizeof (Elf32_Addr)),
+	  elf32_copyargs, setregs },	/* 32bit ELF bins */
 #endif
 #ifdef EXEC_ELF64
-	{ sizeof (Elf64_Ehdr), exec_elf64_makecmds, },	/* 64bit ELF bins */
+	{ sizeof (Elf64_Ehdr), exec_elf64_makecmds,
+	  howmany(ELF_AUX_ENTRIES * sizeof(Aux64Info), sizeof (Elf64_Addr)),
+	  elf64_copyargs, setregs },	/* 64bit ELF bins */
 #endif
 #ifdef COMPAT_SUNOS
-	{ SUNOS_AOUT_HDR_SIZE, exec_sunos_aout_makecmds, }, /* SunOS a.out */
+	{ SUNOS_AOUT_HDR_SIZE, exec_sunos_aout_makecmds, 0 }, /* SunOS a.out */
 #endif
 #if defined(COMPAT_LINUX) && defined(EXEC_AOUT)
-	{ LINUX_AOUT_HDR_SIZE, exec_linux_aout_makecmds, }, /* linux a.out */
+	{ LINUX_AOUT_HDR_SIZE, exec_linux_aout_makecmds, LINUX_AOUT_AUX_ARGSIZ,
+		linux_aout_copyargs, linux_setregs, 0 }, /* linux a.out */
 #endif
 #ifdef COMPAT_IBCS2
-	{ COFF_HDR_SIZE, exec_ibcs2_coff_makecmds, },	/* coff binaries */
-	{ XOUT_HDR_SIZE, exec_ibcs2_xout_makecmds, },	/* x.out binaries */
+	{ COFF_HDR_SIZE, exec_ibcs2_coff_makecmds, 0 },	/* coff binaries */
+	{ XOUT_HDR_SIZE, exec_ibcs2_xout_makecmds, 0 },	/* x.out binaries */
 #endif
 #if defined(COMPAT_FREEBSD) && defined(EXEC_AOUT)
-	{ FREEBSD_AOUT_HDR_SIZE, exec_freebsd_aout_makecmds, },	/* a.out */
+	{ FREEBSD_AOUT_HDR_SIZE, exec_freebsd_aout_makecmds, 0 },	/* a.out */
 #endif
 #ifdef COMPAT_HPUX
-	{ HPUX_EXEC_HDR_SIZE, exec_hpux_makecmds, },	/* HP-UX a.out */
+	{ HPUX_EXEC_HDR_SIZE, exec_hpux_makecmds, 0 },	/* HP-UX a.out */
 #endif
 #ifdef COMPAT_M68K4K
-	{ sizeof(struct exec), exec_m68k4k_makecmds, },	/* m68k4k a.out */
+	{ sizeof(struct exec), exec_m68k4k_makecmds, 0 },	/* m68k4k a.out */
 #endif
 #ifdef COMPAT_VAX1K
-	{ sizeof(struct exec), exec_vax1k_makecmds, },	/* vax1k a.out */
+	{ sizeof(struct exec), exec_vax1k_makecmds, 0 },	/* vax1k a.out */
 #endif
 #ifdef COMPAT_PECOFF
-	{ sizeof(struct exec), exec_pecoff_makecmds, },	/* Win32/CE PE/COFF */
+	{ sizeof(struct exec), exec_pecoff_makecmds, 0 },	/* Win32/CE PE/COFF */
 #endif
 };
 int nexecs = (sizeof(execsw) / sizeof(*execsw));
Index: kern/exec_elf32.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/exec_elf32.c,v
retrieving revision 1.54
diff -u -r1.54 exec_elf32.c
--- kern/exec_elf32.c	2000/08/01 04:57:28	1.54
+++ kern/exec_elf32.c	2000/11/08 18:00:26
@@ -73,7 +73,6 @@
 #include "opt_compat_svr4.h"
 #include "opt_compat_freebsd.h"
 #include "opt_compat_netbsd32.h"
-#include "opt_syscall_debug.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -85,7 +84,6 @@
 #include <sys/exec.h>
 #include <sys/exec_elf.h>
 #include <sys/fcntl.h>
-#include <sys/syscall.h>
 #include <sys/signalvar.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
@@ -115,6 +113,8 @@
 #include <compat/freebsd/freebsd_exec.h>
 #endif
 
+extern struct emul emul_netbsd;
+
 int	ELFNAME(check_header)(Elf_Ehdr *, int);
 int	ELFNAME(load_file)(struct proc *, struct exec_package *, char *,
 	    struct exec_vmcmd_set *, u_long *, struct elf_args *, Elf_Addr *);
@@ -126,30 +126,6 @@
 static int ELFNAME2(netbsd,probe)(struct proc *, struct exec_package *,
     Elf_Ehdr *, char *, Elf_Addr *);
 
-extern char sigcode[], esigcode[];
-#ifdef SYSCALL_DEBUG
-extern char *syscallnames[];
-#endif
-
-struct emul ELFNAMEEND(emul_netbsd) = {
-	"netbsd",
-	NULL,
-	sendsig,
-	SYS_syscall,
-	SYS_MAXSYSCALL,
-	sysent,
-#ifdef SYSCALL_DEBUG
-	syscallnames,
-#else
-	NULL,
-#endif
-	howmany(ELF_AUX_ENTRIES * sizeof(AuxInfo), sizeof (Elf_Addr)),
-	ELFNAME(copyargs),
-	setregs,
-	sigcode,
-	esigcode,
-};
-
 int (*ELFNAME(probe_funcs)[])(struct proc *, struct exec_package *,
     Elf_Ehdr *, char *, Elf_Addr *) = {
 #if defined(COMPAT_NETBSD32) && (ELFSIZE == 32)
@@ -578,7 +554,7 @@
 	/*
 	 * Setup things for native emulation.
 	 */
-	epp->ep_emul = &ELFNAMEEND(emul_netbsd);
+	epp->ep_emul = &emul_netbsd;
 	pos = ELFDEFNNAME(NO_ADDR);
 
 	/*
@@ -790,7 +766,7 @@
 
 	if ((error = ELFNAME2(netbsd,signature)(p, epp, eh)) != 0)
 		return error;
-	epp->ep_emul = &ELFNAMEEND(emul_netbsd);
+	epp->ep_emul = &emul_netbsd;
 	*pos = ELFDEFNNAME(NO_ADDR);
 	return 0;
 }
Index: arch/i386/i386/trap.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/trap.c,v
retrieving revision 1.140
diff -u -r1.140 trap.c
--- arch/i386/i386/trap.c	2000/06/29 08:44:54	1.140
+++ arch/i386/i386/trap.c	2000/11/08 18:00:28
@@ -134,16 +134,7 @@
 #ifdef COMPAT_LINUX
 # include <sys/exec.h>
 # include <compat/linux/linux_syscall.h>
-
-# ifdef EXEC_AOUT
-extern struct emul emul_linux_aout;
-# endif
-# ifdef EXEC_ELF32
-extern struct emul emul_linux_elf32;
-# endif
-# ifdef EXEC_ELF64
-extern struct emul emul_linux_elf64;
-# endif
+extern struct emul emul_linux;
 #endif /* COMPAT_LINUX */
 
 #ifdef COMPAT_FREEBSD
@@ -613,7 +604,7 @@
 	struct trapframe frame;
 {
 	register caddr_t params;
-	register struct sysent *callp;
+	register const struct sysent *callp;
 	register struct proc *p;
 	int error, opc, nsys;
 	size_t argsize;
@@ -639,17 +630,7 @@
 	callp = p->p_emul->e_sysent;
 
 #ifdef COMPAT_LINUX
-	linux = 0
-# ifdef EXEC_AOUT
-	    || (p->p_emul == &emul_linux_aout)
-# endif /* EXEC_AOUT */
-# ifdef EXEC_ELF32
-	    || (p->p_emul == &emul_linux_elf32)
-# endif /* EXEC_ELF32 */
-# ifdef EXEC_ELF64
-	    || (p->p_emul == &emul_linux_elf64)
-# endif /* EXEC_ELF64 */
-	    ;
+	linux = (p->p_emul == &emul_linux);
 #endif /* COMPAT_LINUX */
 
 #ifdef COMPAT_FREEBSD
Index: compat/linux/common/linux_exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_exec.c,v
retrieving revision 1.37
diff -u -r1.37 linux_exec.c
--- compat/linux/common/linux_exec.c	2000/06/29 02:40:38	1.37
+++ compat/linux/common/linux_exec.c	2000/11/08 18:00:28
@@ -62,10 +62,15 @@
 
 #include <compat/linux/linux_syscallargs.h>
 #include <compat/linux/linux_syscall.h>
+#include <compat/linux/common/linux_misc.h>
+#include <compat/linux/common/linux_errno.h>
 
-
 const char linux_emul_path[] = "/emul/linux";
 
+extern struct sysent linux_sysent[];
+extern const char * const linux_syscallnames[];
+extern char linux_sigcode[], linux_esigcode[];
+
 /*
  * Execve(2). Just check the alternate emulation path, and pass it on
  * to the NetBSD execve().
@@ -93,3 +98,21 @@
 
 	return sys_execve(p, &ap, retval);
 }
+
+/*
+ * Emulation switch.
+ */
+const struct emul emul_linux = {
+	"linux",
+	native_to_linux_errno,
+	linux_sendsig,
+	LINUX_SYS_syscall,
+	LINUX_SYS_MAXSYSCALL,
+	linux_sysent,
+	linux_syscallnames,
+	linux_sigcode,
+	linux_esigcode,
+	linux_e_proc_exec,
+	linux_e_proc_fork,
+	linux_e_proc_exit,
+};
Index: compat/linux/common/linux_exec_aout.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_exec_aout.c,v
retrieving revision 1.40
diff -u -r1.40 linux_exec_aout.c
--- compat/linux/common/linux_exec_aout.c	2000/06/29 02:40:39	1.40
+++ compat/linux/common/linux_exec_aout.c	2000/11/08 18:00:28
@@ -62,42 +62,25 @@
 #include <compat/linux/common/linux_util.h>
 #include <compat/linux/common/linux_exec.h>
 #include <compat/linux/common/linux_machdep.h>
-#include <compat/linux/common/linux_errno.h>
 
 #include <compat/linux/linux_syscallargs.h>
 #include <compat/linux/linux_syscall.h>
 
+extern const struct emul emul_linux;
 
-static void *linux_aout_copyargs __P((struct exec_package *,
+void *linux_aout_copyargs __P((struct exec_package *,
     struct ps_strings *, void *, void *));
 
-#define	LINUX_AOUT_AUX_ARGSIZ	2
+static int exec_linux_aout_prep_zmagic __P((struct proc *,
+	struct exec_package *));
+static int exec_linux_aout_prep_nmagic __P((struct proc *,
+	struct exec_package *));
+static int exec_linux_aout_prep_omagic __P((struct proc *,
+	struct exec_package *));
+static int exec_linux_aout_prep_qmagic __P((struct proc *,
+	struct exec_package *));
 
-extern char linux_sigcode[], linux_esigcode[];
-extern struct sysent linux_sysent[];
-extern char *linux_syscallnames[];
-
-int exec_linux_aout_prep_zmagic __P((struct proc *, struct exec_package *));
-int exec_linux_aout_prep_nmagic __P((struct proc *, struct exec_package *));
-int exec_linux_aout_prep_omagic __P((struct proc *, struct exec_package *));
-int exec_linux_aout_prep_qmagic __P((struct proc *, struct exec_package *));
-
-struct emul emul_linux_aout = {
-	"linux",
-	native_to_linux_errno,
-	linux_sendsig,
-	LINUX_SYS_syscall,
-	LINUX_SYS_MAXSYSCALL,
-	linux_sysent,
-	linux_syscallnames,
-	LINUX_AOUT_AUX_ARGSIZ,
-	linux_aout_copyargs,
-	linux_setregs,
-	linux_sigcode,
-	linux_esigcode,
-};
-
-static void *
+void *
 linux_aout_copyargs(pack, arginfo, stack, argp)
 	struct exec_package *pack;
 	struct ps_strings *arginfo;
@@ -181,7 +164,7 @@
 		break;
 	}
 	if (error == 0)
-		epp->ep_emul = &emul_linux_aout;
+		epp->ep_emul = &emul_linux;
 	return error;
 }
 
@@ -191,7 +174,7 @@
  * as an NMAGIC here. XXX
  */
 
-int
+static int
 exec_linux_aout_prep_zmagic(p, epp)
 	struct proc *p;
 	struct exec_package *epp;
@@ -227,7 +210,7 @@
  * Not different from the normal stuff.
  */
 
-int
+static int
 exec_linux_aout_prep_nmagic(p, epp)
 	struct proc *p;
 	struct exec_package *epp;
@@ -266,7 +249,7 @@
  * Business as usual.
  */
 
-int
+static int
 exec_linux_aout_prep_omagic(p, epp)
 	struct proc *p;
 	struct exec_package *epp;
@@ -305,7 +288,7 @@
 	return exec_aout_setup_stack(p, epp);
 }
 
-int
+static int
 exec_linux_aout_prep_qmagic(p, epp)
 	struct proc *p;
 	struct exec_package *epp;
Index: compat/linux/common/linux_exec_elf32.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_exec_elf32.c,v
retrieving revision 1.45
diff -u -r1.45 linux_exec_elf32.c
--- compat/linux/common/linux_exec_elf32.c	2000/06/29 02:40:39	1.45
+++ compat/linux/common/linux_exec_elf32.c	2000/11/08 18:00:29
@@ -66,11 +66,12 @@
 #include <compat/linux/common/linux_util.h>
 #include <compat/linux/common/linux_exec.h>
 #include <compat/linux/common/linux_machdep.h>
-#include <compat/linux/common/linux_errno.h>
 
 #include <compat/linux/linux_syscallargs.h>
 #include <compat/linux/linux_syscall.h>
 
+extern const struct emul emul_linux;
+
 static int ELFNAME2(linux,signature) __P((struct proc *, struct exec_package *,
 	Elf_Ehdr *));
 #ifdef LINUX_GCC_SIGNATURE
@@ -78,29 +79,6 @@
 	struct exec_package *, Elf_Ehdr *));
 #endif
 
-#define LINUX_ELF_AUX_ARGSIZ howmany(sizeof(AuxInfo) * 8, sizeof(char *))
-
-
-extern char linux_sigcode[], linux_esigcode[];
-extern struct sysent linux_sysent[];
-extern char *linux_syscallnames[];
-
-struct emul ELFNAMEEND(emul_linux) = {
-	"linux",
-	native_to_linux_errno,
-	linux_sendsig,
-	LINUX_SYS_syscall,
-	LINUX_SYS_MAXSYSCALL,
-	linux_sysent,
-	linux_syscallnames,
-	LINUX_ELF_AUX_ARGSIZ,
-	ELFNAME(copyargs),
-	linux_setregs,
-	linux_sigcode,
-	linux_esigcode,
-};
-
-
 #ifdef LINUX_GCC_SIGNATURE
 /*
  * Take advantage of the fact that all the linux binaries are compiled
@@ -211,7 +189,7 @@
 			goto out3;
 		}
 #ifdef DEBUG_LINUX
-		printf("linux_signature: interp=%s\n", notep);
+		printf("linux_signature: interp=%s\n", (char *)notep);
 #endif
 		if (strncmp(&((char *)notep)[8], "linux", 5) == 0 ||
 		    strncmp((char *)notep, "/lib/ld.so.", 11) == 0) {
@@ -295,7 +273,7 @@
 			return error;
 		free((void *)bp, M_TEMP);
 	}
-	epp->ep_emul = &ELFNAMEEND(emul_linux);
+	epp->ep_emul = &emul_linux;
 	*pos = ELF_NO_ADDR;
 #ifdef DEBUG_LINUX
 	printf("linux_probe: returning 0\n");
XXXX
-- 
Jaromir Dolecek <jdolecek@NetBSD.org>      http://www.ics.muni.cz/~dolecek/
@@@@  Wanna a real operating system ? Go and get NetBSD, damn!  @@@@