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