diff options
author | sos <sos@FreeBSD.org> | 1996-03-10 08:42:54 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 1996-03-10 08:42:54 +0000 |
commit | 7d151a09c3f9613590f35dad81c77959e4f34381 (patch) | |
tree | ab85b2b967b056b586d4e20e909a63357cd88185 /sys/i386/linux | |
parent | bfb211a9a540fa804c574162f720bebded3fcddf (diff) | |
download | FreeBSD-src-7d151a09c3f9613590f35dad81c77959e4f34381.zip FreeBSD-src-7d151a09c3f9613590f35dad81c77959e4f34381.tar.gz |
First attempt at FreeBSD & Linux ELF support.
Compile and link a new kernel, that will give native ELF support, and
provide the hooks for other ELF interpreters as well.
To make native ELF binaries use John Polstras elf-kit-1.0.1..
For the time being also use his ld-elf.so.1 and put it in
/usr/libexec.
The Linux emulator has been enhanced to also run ELF binaries, it
is however in its very first incarnation.
Just get some Linux ELF libs (Slackware-3.0) and put them in the
prober place (/compat/linux/...).
I've ben able to run all the Slackware-3.0 binaries I've tried
so far.
(No it won't run quake yet :)
Diffstat (limited to 'sys/i386/linux')
-rw-r--r-- | sys/i386/linux/imgact_linux.c | 6 | ||||
-rw-r--r-- | sys/i386/linux/linux.h | 14 | ||||
-rw-r--r-- | sys/i386/linux/linux_sysvec.c | 166 | ||||
-rw-r--r-- | sys/i386/linux/linux_util.h | 4 |
4 files changed, 119 insertions, 71 deletions
diff --git a/sys/i386/linux/imgact_linux.c b/sys/i386/linux/imgact_linux.c index 9d6906d..e070aa2 100644 --- a/sys/i386/linux/imgact_linux.c +++ b/sys/i386/linux/imgact_linux.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1994-1995 Søren Schmidt + * Copyright (c) 1994-1996 Søren Schmidt * All rights reserved. * * Based heavily on /sys/kern/imgact_aout.c which is: @@ -28,7 +28,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: imgact_linux.c,v 1.8 1996/02/16 18:40:48 peter Exp $ + * $Id: imgact_linux.c,v 1.9 1996/03/02 19:37:47 peter Exp $ */ #include <sys/param.h> @@ -227,6 +227,6 @@ exec_linux_imgact(imgp) * Since `const' objects end up in the text segment, TEXT_SET is the * correct directive to use. */ -const struct execsw linux_execsw = { exec_linux_imgact, "linux" }; +const struct execsw linux_execsw = { exec_linux_imgact, "linux a.out" }; TEXT_SET(execsw_set, linux_execsw); diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index af0eb04..cf97265 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1994-1995 Søren Schmidt + * Copyright (c) 1994-1996 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,11 +25,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux.h,v 1.5 1996/03/02 19:37:47 peter Exp $ + * $Id: linux.h,v 1.6 1996/03/03 19:07:49 peter Exp $ */ #ifndef _I386_LINUX_LINUX_H_ #define _I386_LINUX_LINUX_H_ +#include "i386/linux/linux_syscall.h" typedef unsigned short linux_uid_t; typedef unsigned short linux_gid_t; @@ -97,13 +98,20 @@ struct linux_sigframe { sig_t sf_handler; }; +extern int bsd_to_linux_errno[]; extern int bsd_to_linux_signal[]; extern int linux_to_bsd_signal[]; +extern char linux_sigcode[]; +extern int linux_szsigcode; +extern const char linux_emul_path[]; +extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; extern struct sysentvec linux_sysvec; +extern struct sysentvec elf_linux_sysvec; +/* dummy struct definitions */ struct image_params; -int linux_fixup __P((int **stack_base, struct image_params *iparams)); +struct trapframe; /* misc defines */ #define LINUX_NAME_MAX 255 diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 9278102..e7a72ae 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1994-1995 Søren Schmidt + * Copyright (c) 1994-1996 Søren Schmidt * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: linux_sysent.c,v 1.4 1996/01/14 10:59:57 sos Exp $ + * $Id: linux_sysvec.c,v 1.1 1996/03/02 19:38:01 peter Exp $ */ /* XXX we use functions that might not exist. */ @@ -36,7 +36,9 @@ #include <sys/sysproto.h> #include <sys/sysent.h> #include <sys/imgact.h> +#include <sys/imgact_elf.h> #include <sys/signalvar.h> +#include <sys/malloc.h> #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/vm_prot.h> @@ -59,62 +61,93 @@ #include <i386/linux/linux.h> #include <i386/linux/linux_proto.h> -#include <i386/linux/linux_syscall.h> + +int linux_fixup __P((int **stack_base, struct image_params *iparams)); +int elf_linux_fixup __P((int **stack_base, struct image_params *iparams)); +void linux_prepsyscall __P((struct trapframe *tf, int *args, u_int *code, caddr_t *params)); +void linux_sendsig __P((sig_t catcher, int sig, int mask, unsigned code)); /* * Linux syscalls return negative errno's, we do positive and map them */ int bsd_to_linux_errno[ELAST] = { - -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, - -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, - -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, - -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, - -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, - -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, - -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, - -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, - -6, + -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, + -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, + -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, + -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, + -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, + -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, + -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, + -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, + -6, }; int bsd_to_linux_signal[NSIG] = { - 0, LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, - LINUX_SIGILL, LINUX_SIGTRAP, LINUX_SIGABRT, 0, - LINUX_SIGFPE, LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, - 0, LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, - LINUX_SIGURG, LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, - LINUX_SIGCHLD, LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, - LINUX_SIGXCPU, LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, - LINUX_SIGWINCH, 0, LINUX_SIGUSR1, LINUX_SIGUSR2 + 0, LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, + LINUX_SIGILL, LINUX_SIGTRAP, LINUX_SIGABRT, 0, + LINUX_SIGFPE, LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, + 0, LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, + LINUX_SIGURG, LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, + LINUX_SIGCHLD, LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, + LINUX_SIGXCPU, LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, + LINUX_SIGWINCH, 0, LINUX_SIGUSR1, LINUX_SIGUSR2 }; int linux_to_bsd_signal[LINUX_NSIG] = { - 0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT, - SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, - SIGBUS, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGIO, - SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGURG, SIGURG, 0 + 0, SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGEMT, + SIGFPE, SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2, SIGPIPE, SIGALRM, SIGTERM, + SIGBUS, SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU, SIGIO, + SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGURG, SIGURG, 0 }; int linux_fixup(int **stack_base, struct image_params *imgp) { - int *argv, *envp; - - argv = *stack_base; - envp = *stack_base + (imgp->argc + 1); - (*stack_base)--; - **stack_base = (int)envp; - (*stack_base)--; - **stack_base = (int)argv; - (*stack_base)--; - **stack_base = (int)imgp->argc; - return 0; /* XXX */ + int *argv, *envp; + + argv = *stack_base; + envp = *stack_base + (imgp->argc + 1); + (*stack_base)--; + **stack_base = (int)envp; + (*stack_base)--; + **stack_base = (int)argv; + (*stack_base)--; + **stack_base = (int)imgp->argc; + return 0; } -extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL]; +int elf_linux_fixup(int **stack_base, struct image_params *imgp) +{ + Elf32_Auxargs *args = (Elf32_Auxargs *)imgp->auxargs; + int *pos; + + pos = *stack_base + (imgp->argc + imgp->envc + 2); + + if (args->trace) { + AUXARGS_ENTRY(pos, AT_DEBUG, 1); + } + if (args->execfd != -1) { + AUXARGS_ENTRY(pos, AT_EXECFD, args->execfd); + } + AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); + AUXARGS_ENTRY(pos, AT_PHENT, args->phent); + AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); + AUXARGS_ENTRY(pos, AT_PAGESZ, args->pagesz); + AUXARGS_ENTRY(pos, AT_FLAGS, args->flags); + AUXARGS_ENTRY(pos, AT_ENTRY, args->entry); + AUXARGS_ENTRY(pos, AT_BASE, args->base); + AUXARGS_ENTRY(pos, AT_UID, imgp->proc->p_cred->p_ruid); + AUXARGS_ENTRY(pos, AT_EUID, imgp->proc->p_cred->p_svuid); + AUXARGS_ENTRY(pos, AT_GID, imgp->proc->p_cred->p_rgid); + AUXARGS_ENTRY(pos, AT_EGID, imgp->proc->p_cred->p_svgid); + AUXARGS_ENTRY(pos, AT_NULL, 0); + + free(imgp->auxargs, M_TEMP); + imgp->auxargs = NULL; -static void linux_sendsig(sig_t action, - int sig, - int returnmask, - unsigned code); + (*stack_base)--; + **stack_base = (int)imgp->argc; + return 0; +} extern int _ucodesel, _udatasel; @@ -129,12 +162,8 @@ extern int _ucodesel, _udatasel; * specified pc, psl. */ -static void -linux_sendsig(catcher, sig, mask, code) - sig_t catcher; - int sig; - int mask; - unsigned code; +void +linux_sendsig(sig_t catcher, int sig, int mask, unsigned code) { register struct proc *p = curproc; register int *regs; @@ -327,7 +356,7 @@ linux_sigreturn(p, args, retval) return (EJUSTRETURN); } -static void +void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params) { int i; @@ -339,20 +368,33 @@ linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params) *params = NULL; /* no copyin */ } -extern char linux_sigcode[]; -extern int linux_szsigcode; - struct sysentvec linux_sysvec = { - sizeof (linux_sysent) / sizeof(linux_sysent[0]), - linux_sysent, - 0xff, - NSIG, - bsd_to_linux_signal, - ELAST, - bsd_to_linux_errno, - linux_fixup, - linux_sendsig, - linux_sigcode, - &linux_szsigcode, - linux_prepsyscall, + LINUX_SYS_MAXSYSCALL, + linux_sysent, + 0xff, + NSIG, + bsd_to_linux_signal, + ELAST, + bsd_to_linux_errno, + linux_fixup, + linux_sendsig, + linux_sigcode, + &linux_szsigcode, + linux_prepsyscall, +}; + +struct sysentvec elf_linux_sysvec = { + LINUX_SYS_MAXSYSCALL, + linux_sysent, + 0xff, + NSIG, + bsd_to_linux_signal, + ELAST, + bsd_to_linux_errno, + elf_linux_fixup, + linux_sendsig, + linux_sigcode, + &linux_szsigcode, + linux_prepsyscall, }; + diff --git a/sys/i386/linux/linux_util.h b/sys/i386/linux/linux_util.h index 46edfc5..6a09cf3 100644 --- a/sys/i386/linux/linux_util.h +++ b/sys/i386/linux/linux_util.h @@ -28,7 +28,7 @@ * * from: svr4_util.h,v 1.5 1994/11/18 02:54:31 christos Exp * from: linux_util.h,v 1.2 1995/03/05 23:23:50 fvdl Exp - * $Id$ + * $Id: linux_util.h,v 1.1 1996/03/02 19:38:02 peter Exp $ */ /* @@ -78,8 +78,6 @@ stackgap_alloc(sgp, sz) #define DPRINTF(a) #endif -extern const char linux_emul_path[]; - int linux_emul_find __P((struct proc *, caddr_t *, const char *, char *, char **, int)); |