Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/compat/linux Make the linux compatibilty code work on th...



details:   https://anonhg.NetBSD.org/src/rev/83005403f29e
branches:  trunk
changeset: 499321:83005403f29e
user:      erh <erh%NetBSD.org@localhost>
date:      Fri Nov 17 03:55:17 2000 +0000

description:
Make the linux compatibilty code work on the alpha.  (horay!) (at last!)
Two main changes:
        Create a linux_elf64_copyargs that uses the linux specific LinuxAuxInfo
        structure.  This is only used on the alpha.  i386 and m68k use the
        standard elf copyargs function.

        Since linux's approach to binary compatibilty is to look as much
        like osf1 as possible, add all the osf1 syscalls that we have
        implemented to the linux syscall table.  This includes get/setsysinfo,
        ported from FreeBSD.

In order for linux compat to work you must have COMPAT_OSF1, COMPAT_43,
COMPAT_09, COMPAT_12 and COMPAT_13 on also.

diffstat:

 sys/compat/linux/arch/alpha/files.linux_alpha  |    4 +-
 sys/compat/linux/arch/alpha/linux_exec.h       |   50 ++++++++++-
 sys/compat/linux/arch/alpha/linux_exec_alpha.c |  112 +++++++++++++++++++++++++
 sys/compat/linux/arch/alpha/syscalls.master    |   90 ++++++++++++-------
 sys/compat/linux/arch/i386/linux_exec.h        |    6 +-
 sys/compat/linux/arch/m68k/linux_exec.h        |    6 +-
 sys/compat/linux/common/linux_exec_elf32.c     |    8 +-
 7 files changed, 233 insertions(+), 43 deletions(-)

diffs (truncated from 508 to 300 lines):

diff -r 3d6b75ebaa05 -r 83005403f29e sys/compat/linux/arch/alpha/files.linux_alpha
--- a/sys/compat/linux/arch/alpha/files.linux_alpha     Fri Nov 17 03:47:43 2000 +0000
+++ b/sys/compat/linux/arch/alpha/files.linux_alpha     Fri Nov 17 03:55:17 2000 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.linux_alpha,v 1.3 1998/10/07 23:48:04 erh Exp $
+#      $NetBSD: files.linux_alpha,v 1.4 2000/11/17 03:55:17 erh Exp $
 #
 # Config file description for alpha-dependent Linux compat code.
 
@@ -7,6 +7,6 @@
 file   compat/linux/arch/alpha/linux_sysent.c          compat_linux
 file   compat/linux/arch/alpha/linux_pipe.c            compat_linux
 file   compat/linux/arch/alpha/linux_sigarray.c        compat_linux
+file   compat/linux/arch/alpha/linux_exec_alpha.c      compat_linux
 file   compat/linux/common/linux_sigaction.c           compat_linux
-# XXX olduname = osf_utsname on Linux.  Possibly not used.
 file   compat/linux/common/linux_olduname.c            compat_linux
diff -r 3d6b75ebaa05 -r 83005403f29e sys/compat/linux/arch/alpha/linux_exec.h
--- a/sys/compat/linux/arch/alpha/linux_exec.h  Fri Nov 17 03:47:43 2000 +0000
+++ b/sys/compat/linux/arch/alpha/linux_exec.h  Fri Nov 17 03:55:17 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_exec.h,v 1.1 1998/09/30 21:36:23 erh Exp $       */
+/*     $NetBSD: linux_exec.h,v 1.2 2000/11/17 03:55:18 erh Exp $       */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -44,4 +44,52 @@
 #define LINUX_M_ALPHA          MID_ALPHA
 #define LINUX_MID_MACHINE      LINUX_M_ALPHA
 
+#define LINUX_COPYARGS_FUNCTION        ELFNAME2(linux,copyargs)
+
+/*
+ * Alpha specific ELF defines.
+ *
+ * If this is common to more than one linux port move it
+ * to common/linux_exec.h.
+ */
+#define LINUX_AT_NOTELF        10
+#define        LINUX_AT_UID            11
+#define LINUX_AT_EUID          12
+#define LINUX_AT_GID           13
+#define        LINUX_AT_EGID           14
+#define LINUX_AT_PLATFORM      15
+#define LINUX_AT_HWCAP         16
+
+#define LINUX_ELF_AUX_ENTRIES 12
+
+#define LINUX_ELF_AUX_ARGSIZ howmany(sizeof(LinuxAuxInfo) * LINUX_ELF_AUX_ENTRIES, sizeof(char *))
+
+typedef struct {
+       Elf32_Sword     a_type;
+       Elf32_Word      a_v;
+} LinuxAux32Info;
+
+typedef struct {
+       Elf64_Word      a_type;
+       Elf64_Word      a_v;
+} LinuxAux64Info;
+
+#if defined(ELFSIZE) && (ELFSIZE == 32)
+#define LinuxAuxInfo   LinuxAux32Info
+#else
+#define LinuxAuxInfo   LinuxAux64Info
+#endif
+
+
+#ifdef _KERNEL
+__BEGIN_DECLS
+#ifdef EXEC_ELF32
+void *linux_elf32_copyargs __P((struct exec_package *, struct ps_strings *, void *, void *));
+#endif
+#ifdef EXEC_ELF64
+void *linux_elf64_copyargs __P((struct exec_package *, struct ps_strings *, void *, void *));
+#endif
+__END_DECLS
+#endif /* !_KERNEL */
+
 #endif /* !_ALPHA_LINUX_EXEC_H */
diff -r 3d6b75ebaa05 -r 83005403f29e sys/compat/linux/arch/alpha/linux_exec_alpha.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/compat/linux/arch/alpha/linux_exec_alpha.c    Fri Nov 17 03:55:17 2000 +0000
@@ -0,0 +1,112 @@
+/* $Id: linux_exec_alpha.c,v 1.1 2000/11/17 03:55:18 erh Exp $ */
+
+#define ELFSIZE 64
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/exec.h>
+#include <sys/exec_elf.h>
+
+#include <compat/linux/common/linux_exec.h>
+
+/*
+ * Alpha specific linux copyargs function.
+ *
+ * XXX Figure out if this is common to more than one linux
+ * XXX port.  If so, move it to common/linux_exec_elf32.c
+ * XXX included based on some define.
+ */
+void *
+ELFNAME2(linux,copyargs)(struct exec_package *pack, struct ps_strings *arginfo,        
+                        void *stack, void *argp)
+{
+       size_t len;
+       LinuxAuxInfo ai[LINUX_ELF_AUX_ENTRIES], *a;
+       struct elf_args *ap;
+
+       stack = copyargs(pack, arginfo, stack, argp);
+       if (!stack)
+               return(NULL);
+
+       memset(ai, 0, sizeof(LinuxAuxInfo) * LINUX_ELF_AUX_ENTRIES);
+
+       a = ai;
+
+       /*
+        * Push extra arguments on the stack needed by dynamically
+        * linked binaries.
+        */
+       if ((ap = (struct elf_args *)pack->ep_emul_arg)) {
+
+               a->a_type = AT_PHDR;
+               a->a_v = ap->arg_phaddr;
+               a++;
+
+               a->a_type = AT_PHENT;
+               a->a_v = ap->arg_phentsize;
+               a++;
+
+               a->a_type = AT_PHNUM;
+               a->a_v = ap->arg_phnum;
+               a++;
+
+               a->a_type = AT_PAGESZ;
+               a->a_v = NBPG;
+               a++;
+
+               a->a_type = AT_BASE;
+               a->a_v = ap->arg_interp;
+               a++;
+
+               a->a_type = AT_FLAGS;
+               a->a_v = 0;
+               a++;
+
+               a->a_type = AT_ENTRY;
+               a->a_v = ap->arg_entry;
+               a++;
+
+               a->a_type = AT_BASE;
+               a->a_v = ap->arg_interp;
+               a++;
+
+#if 0
+/*
+ * The exec_package doesn't have a proc pointer and it's not
+ * exactly trivial to add one since the credentials are changing.
+ */
+               a->a_type = LINUX_AT_UID;
+               a->a_v = pack->p->p_cred->p_ruid;
+               a++;
+
+               a->a_type = LINUX_AT_EUID;
+               a->a_v = pack->p->p_ucred->cr_uid;
+               a++;
+
+               a->a_type = LINUX_AT_GID;
+               a->a_v = pack->p->p_cred->p_rgid;
+               a++;
+
+               a->a_type = LINUX_AT_EGID;
+               a->a_v = pack->p->p_ucred->cr_gid;
+               a++;
+#endif
+
+               free((char *)ap, M_TEMP);
+               pack->ep_emul_arg = NULL;
+       }
+
+       a->a_type = AT_NULL;
+       a->a_v = 0;
+       a++;
+
+       len = (a - ai) * sizeof(LinuxAuxInfo);
+       if (copyout(ai, stack, len))
+               return NULL;
+       stack = (caddr_t)stack + len;
+
+       return(stack);
+}
diff -r 3d6b75ebaa05 -r 83005403f29e sys/compat/linux/arch/alpha/syscalls.master
--- a/sys/compat/linux/arch/alpha/syscalls.master       Fri Nov 17 03:47:43 2000 +0000
+++ b/sys/compat/linux/arch/alpha/syscalls.master       Fri Nov 17 03:55:17 2000 +0000
@@ -1,4 +1,4 @@
-       $NetBSD: syscalls.master,v 1.21 2000/11/08 04:19:01 erh Exp $
+       $NetBSD: syscalls.master,v 1.22 2000/11/17 03:55:18 erh Exp $
 ;
 ;      @(#)syscalls.master     8.1 (Berkeley) 7/19/93
 
@@ -59,6 +59,7 @@
 
 #include "opt_sysv.h"
 #include "opt_compat_43.h"
+#include "opt_compat_osf1.h"
 
 #include <sys/param.h>
 #include <sys/poll.h>
@@ -86,8 +87,9 @@
 4      NOARGS          { int sys_write(int fd, const void *buf, size_t nbyte); }
 5      UNIMPL
 6      NOARGS          { int sys_close(int fd); }
-7      UNIMPL          osf_wait4
-;8     OBSOL           osf_old_creat, NOT USED
+7      NODEF           { int osf1_sys_wait4(int pid, int *status, \
+                           int options, struct osf1_rusage *rusage); }
+;8     ALIAS           osf1_sys_old_creat, NOT USED
 8      STD             { int linux_sys_creat(const char *path, mode_t mode); }
 9      NOARGS          { int sys_link(const char *path, const char *link); }
 10     STD             { int linux_sys_unlink(const char *path); }
@@ -97,13 +99,14 @@
 14     STD             { int linux_sys_mknod(const char *path, int mode, int dev); }
 15     STD             { int linux_sys_chmod(const char *path, int mode); }
 16     STD             { int linux_sys_chown(const char *path, int uid, int gid); }
-;17    ALIAS           osf_brk
+;17    ALIAS           osf1_sys_brk
 17     STD             { int linux_sys_brk(char *nsize); }
 18     UNIMPL
 19     NOARGS          { long compat_43_sys_lseek(int fd, long offset, \
                            int whence); }
 20     NOARGS          { pid_t sys_getpid(void); }
-21     UNIMPL          osf_mount
+21     NODEF           { int osf1_sys_mount(int type, const char *path, \
+                           int flags, caddr_t data); }
 22     UNIMPL          umount
 23     NOARGS          { int sys_setuid(uid_t uid); }
 24     NOARGS          { uid_t sys_getuid(void); }
@@ -126,12 +129,17 @@
 40     UNIMPL
 41     NOARGS          { int sys_dup(int fd); }
 42     NOARGS          { int linux_sys_pipe(void); }
-43     UNIMPL          osf_set_program_attributes
+43     NODEF           { int osf1_sys_set_program_attributes( \
+                           caddr_t taddr, unsigned long tsize, \
+                           caddr_t daddr, unsigned long dsize); }
 44     UNIMPL
 45     STD             { int linux_sys_open(const char *path, int flags, int mode); }
 46     UNIMPL
 47     NOARGS          { gid_t sys_getgid(void); }
-48     UNIMPL          osf_sigprocmask
+; ALIAS osf1_sys_sigprocmask(int how, unsigned long mask);
+; XXX <- copied from osf1/syscalls.master
+48     NOARGS          { int compat_13_sys_sigprocmask(int how, \
+                           sigset13_t mask); }
 49     UNIMPL
 50     UNIMPL
 51     NOARGS          { int sys_acct(const char *path); }
@@ -159,7 +167,7 @@
                            struct linux_stat *sp); }
 69     UNIMPL 
 70     UNIMPL
-;71    ALIAS           osf_mmap
+;71    ALIAS           osf1_sys_mmap
 71     NOARGS          { int linux_sys_mmap(unsigned long addr, size_t len, \
                            int prot, int flags, int fd, off_t offset); }
 72     UNIMPL
@@ -174,10 +182,12 @@
 80     NOARGS          { int sys_setgroups(int gidsetsize, const gid_t *gidset); }
 81     UNIMPL
 82     UNIMPL          setpgrp
-83     UNIMPL          osf_setitimer
+83     NODEF           { int osf1_sys_setitimer(u_int which, \
+                           struct osf1_itimerval *itv, \
+                           struct osf1_itimerval *oitv); }
 84     UNIMPL
 85     UNIMPL  
-86     UNIMPL          osf_getitimer
+86     UNIMPL          osf1_sys_getitimer
 87     NOARGS          { int compat_43_sys_gethostname(char *hostname, \
                            u_int len); }
 88     NOARGS          { int compat_43_sys_sethostname(char *hostname, \
@@ -186,7 +196,8 @@
 90     NOARGS          { int sys_dup2(int from, int to); }
 91     STD             { int linux_sys_fstat(int fd, struct linux_stat *sp); }
 92     STD             { int linux_sys_fcntl(int fd, int cmd, void *arg); }
-93     UNIMPL          osf_select
+93     NODEF           { int osf1_sys_select(u_int nd, fd_set *in, \
+                           fd_set *ou, fd_set *ex, struct osf1_timeval *tv); }
 94     NOARGS          { int sys_poll(struct pollfd *fds, u_int nfds, \
                            int timeout); }
 95     NOARGS          { int sys_fsync(int fd); }
@@ -198,7 +209,7 @@
                            unsigned int namelen); }
 99     NOARGS          { int compat_43_sys_accept(int s, \
                                caddr_t name, int *anamelen); }
-;100   ALIAS           osf_getpriority



Home | Main Index | Thread Index | Old Index