Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add initial (but unfinished) COMPAT_LINUX32 for amd64. This ...
details: https://anonhg.NetBSD.org/src/rev/67d0c3f7171b
branches: trunk
changeset: 588145:67d0c3f7171b
user: manu <manu%NetBSD.org@localhost>
date: Thu Feb 09 19:18:56 2006 +0000
description:
Add initial (but unfinished) COMPAT_LINUX32 for amd64. This is good enough so
that the i386 license manager part of amd64 version of Fluent works.
While I'm here, add SysV IPC to COMPAT_LINUX/amd64
diffstat:
doc/CHANGES | 3 +-
sys/arch/amd64/amd64/genassym.cf | 17 +-
sys/arch/amd64/amd64/linux32_sigcode.S | 28 +
sys/arch/amd64/amd64/linux32_syscall.c | 307 +++
sys/arch/amd64/conf/GENERIC | 6 +-
sys/arch/amd64/conf/files.amd64 | 8 +-
sys/arch/amd64/include/Makefile | 4 +-
sys/arch/amd64/include/linux32_machdep.h | 15 +
sys/compat/linux/arch/amd64/linux_commons.c | 11 +-
sys/compat/linux/arch/amd64/linux_syscall.h | 53 +-
sys/compat/linux/arch/amd64/linux_syscallargs.h | 88 +-
sys/compat/linux/arch/amd64/linux_syscalls.c | 32 +-
sys/compat/linux/arch/amd64/linux_sysent.c | 43 +-
sys/compat/linux/arch/amd64/syscalls.master | 35 +-
sys/compat/linux/common/linux_exec.h | 28 +-
sys/compat/linux/common/linux_exec_elf32.c | 21 +-
sys/compat/linux/common/linux_file64.c | 21 +-
sys/compat/linux/common/linux_ipc.c | 11 +-
sys/compat/linux/common/linux_limit.h | 98 +
sys/compat/linux/common/linux_misc.c | 134 +-
sys/compat/linux/common/linux_misc_notalpha.c | 12 +-
sys/compat/linux/common/linux_msg.h | 4 +-
sys/compat/linux/common/linux_oldmmap.c | 12 +-
sys/compat/linux/common/linux_sem.h | 4 +-
sys/compat/linux/common/linux_shm.h | 4 +-
sys/compat/linux/common/linux_socket.c | 8 +-
sys/compat/linux/common/linux_socketcall.h | 5 +-
sys/compat/linux32/Makefile.inc | 11 +
sys/compat/linux32/arch/amd64/Makefile | 4 +
sys/compat/linux32/arch/amd64/files.linux32_amd64 | 10 +
sys/compat/linux32/arch/amd64/linux32_errno.h | 10 +
sys/compat/linux32/arch/amd64/linux32_exec.h | 77 +
sys/compat/linux32/arch/amd64/linux32_machdep.c | 505 +++++
sys/compat/linux32/arch/amd64/linux32_machdep.h | 14 +
sys/compat/linux32/arch/amd64/linux32_missing.c | 26 +
sys/compat/linux32/arch/amd64/linux32_missing.h | 100 +
sys/compat/linux32/arch/amd64/linux32_signal.h | 299 +++
sys/compat/linux32/arch/amd64/linux32_syscall.h | 403 ++++
sys/compat/linux32/arch/amd64/linux32_syscallargs.h | 598 ++++++
sys/compat/linux32/arch/amd64/linux32_syscalls.c | 324 +++
sys/compat/linux32/arch/amd64/linux32_sysent.c | 1065 +++++++++++
sys/compat/linux32/arch/amd64/linux32_types.h | 95 +
sys/compat/linux32/arch/amd64/syscalls.conf | 16 +
sys/compat/linux32/arch/amd64/syscalls.master | 411 ++++
sys/compat/linux32/common/linux32_dirent.c | 113 +
sys/compat/linux32/common/linux32_emuldata.h | 69 +
sys/compat/linux32/common/linux32_errno.h | 10 +
sys/compat/linux32/common/linux32_exec.c | 329 +++
sys/compat/linux32/common/linux32_exec.h | 58 +
sys/compat/linux32/common/linux32_exec_elf32.c | 269 ++
sys/compat/linux32/common/linux32_fcntl.c | 131 +
sys/compat/linux32/common/linux32_ioctl.c | 74 +
sys/compat/linux32/common/linux32_machdep.h | 55 +
sys/compat/linux32/common/linux32_misc.c | 1716 +++++++++++++++++++
sys/compat/linux32/common/linux32_mman.c | 107 +
sys/compat/linux32/common/linux32_resource.c | 149 +
sys/compat/linux32/common/linux32_sched.c | 113 +
sys/compat/linux32/common/linux32_signal.c | 396 ++++
sys/compat/linux32/common/linux32_signal.h | 55 +
sys/compat/linux32/common/linux32_socket.c | 406 ++++
sys/compat/linux32/common/linux32_socketcall.c | 105 +
sys/compat/linux32/common/linux32_socketcall.h | 199 ++
sys/compat/linux32/common/linux32_stat.c | 229 ++
sys/compat/linux32/common/linux32_sysctl.c | 177 +
sys/compat/linux32/common/linux32_sysctl.h | 65 +
sys/compat/linux32/common/linux32_time.c | 248 ++
sys/compat/linux32/common/linux32_types.h | 83 +
sys/compat/linux32/common/linux32_unistd.c | 698 +++++++
sys/compat/linux32/common/linux32_utsname.c | 119 +
sys/compat/linux32/common/linux32_wait.c | 114 +
sys/compat/linux32/files.linux32 | 25 +
sys/compat/linux32/linux32_syscall.h | 12 +
sys/compat/linux32/linux32_syscallargs.h | 12 +
sys/compat/linux32/linux32_syscalls.c | 10 +
sys/compat/netbsd32/netbsd32_netbsd.c | 6 +-
sys/conf/files | 3 +-
sys/kern/exec_conf.c | 23 +-
sys/kern/kern_exec.c | 9 +-
sys/sys/sysctl.h | 6 +-
usr.bin/kdump/setemul.c | 10 +-
80 files changed, 11012 insertions(+), 171 deletions(-)
diffs (truncated from 12402 to 300 lines):
diff -r e00dc3e26a63 -r 67d0c3f7171b doc/CHANGES
--- a/doc/CHANGES Thu Feb 09 18:03:12 2006 +0000
+++ b/doc/CHANGES Thu Feb 09 19:18:56 2006 +0000
@@ -1,4 +1,4 @@
-LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.583 $>
+LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.584 $>
[Note: This file does not mention every change made to the NetBSD source tree.
@@ -197,3 +197,4 @@
iscsi-target(8): Add the NetBSD iSCSI target [agc 20060208]
evbmips: Add support Alchemy Au15XX PCI host. (DBAu1500/DBAu1550).
[gdamore 20060208]
+ amd64: Add initial COMPAT_LINUX32 support [manu 20060209]
diff -r e00dc3e26a63 -r 67d0c3f7171b sys/arch/amd64/amd64/genassym.cf
--- a/sys/arch/amd64/amd64/genassym.cf Thu Feb 09 18:03:12 2006 +0000
+++ b/sys/arch/amd64/amd64/genassym.cf Thu Feb 09 19:18:56 2006 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.4 2005/12/11 12:16:21 christos Exp $
+# $NetBSD: genassym.cf,v 1.5 2006/02/09 19:18:56 manu Exp $
#
# Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -76,6 +76,7 @@
if defined(_KERNEL_OPT)
include "opt_compat_netbsd32.h"
+include "opt_compat_linux32.h"
include "opt_multiprocessor.h"
endif
@@ -102,6 +103,10 @@
include <machine/netbsd32_machdep.h>
endif
+if defined(COMPAT_LINUX32)
+include <machine/linux32_machdep.h>
+endif
+
if defined(_KERNEL) && !defined(_LKM)
include "isa.h"
include "ioapic.h"
@@ -239,6 +244,16 @@
define SC_GS32 offsetof(struct netbsd32_sigcontext, sc_gs)
endif
+ifdef COMPAT_LINUX32
+define LINUX32_SF_HANDLER offsetof(struct linux32_sigframe, sf_handler)
+define LINUX32_SF_SC offsetof(struct linux32_sigframe, sf_sc)
+define LINUX32_RT_SF_HANDLER offsetof(struct linux32_rt_sigframe, sf_handler)
+define LINUX32_RT_SF_UC offsetof(struct linux32_rt_sigframe, sf_uc)
+define LINUX32_SYS_rt_sigreturn LINUX32_SYS_rt_sigreturn
+define LINUX32_SYS_sigreturn LINUX32_SYS_sigreturn
+define LINUX32_SYS_exit LINUX32_SYS_exit
+endif
+
define IS_RECURSE offsetof(struct intrsource, is_recurse)
define IS_RESUME offsetof(struct intrsource, is_resume)
define IS_EVCNT offsetof(struct intrsource, is_evcnt.ev_count)
diff -r e00dc3e26a63 -r 67d0c3f7171b sys/arch/amd64/amd64/linux32_sigcode.S
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/amd64/amd64/linux32_sigcode.S Thu Feb 09 19:18:56 2006 +0000
@@ -0,0 +1,28 @@
+/* $NetBSD: linux32_sigcode.S,v 1.1 2006/02/09 19:18:56 manu Exp $ */
+
+#include "assym.h"
+#include <machine/asm.h>
+
+ .code32
+NENTRY(linux32_sigcode)
+ call *LINUX32_SF_HANDLER(%esp)
+ leal LINUX32_SF_SC(%esp),%ebx # scp
+ pushl %eax
+ movl $LINUX32_SYS_sigreturn,%eax
+ int $0x80
+ movl $LINUX32_SYS_exit,%eax
+ int $0x80
+
+ .balign 16,,
+NENTRY(linux32_rt_sigcode)
+ call *LINUX32_RT_SF_HANDLER(%esp)
+ leal LINUX32_RT_SF_UC(%esp),%ebx # scp
+ pushl %eax
+ movl $LINUX32_SYS_rt_sigreturn,%eax
+ int $0x80
+ movl $LINUX32_SYS_exit,%eax
+ int $0x80
+ .balign 16,,
+ .globl _C_LABEL(linux32_esigcode)
+_C_LABEL(linux32_esigcode):
+
diff -r e00dc3e26a63 -r 67d0c3f7171b sys/arch/amd64/amd64/linux32_syscall.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/amd64/amd64/linux32_syscall.c Thu Feb 09 19:18:56 2006 +0000
@@ -0,0 +1,307 @@
+/* $NetBSD: linux32_syscall.c,v 1.1 2006/02/09 19:18:56 manu Exp $ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: linux32_syscall.c,v 1.1 2006/02/09 19:18:56 manu Exp $");
+
+#include "opt_syscall_debug.h"
+#include "opt_ktrace.h"
+#include "opt_systrace.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/sa.h>
+#include <sys/savar.h>
+#include <sys/signal.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
+#ifdef SYSTRACE
+#include <sys/systrace.h>
+#endif
+#include <sys/syscall.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/cpu.h>
+#include <machine/psl.h>
+#include <machine/userret.h>
+
+#include <compat/linux32/arch/amd64/linux32_errno.h>
+
+void linux32_syscall_intern(struct proc *);
+void linux32_syscall_plain(struct trapframe *);
+void linux32_syscall_fancy(struct trapframe *);
+
+void
+linux32_syscall_intern(p)
+ struct proc *p;
+{
+#ifdef KTRACE
+ if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET)) {
+ p->p_md.md_syscall = linux32_syscall_fancy;
+ return;
+ }
+#endif
+#ifdef SYSTRACE
+ if (ISSET(p->p_flag, P_SYSTRACE)) {
+ p->p_md.md_syscall = linux32_syscall_fancy;
+ return;
+ }
+#endif
+ p->p_md.md_syscall = linux32_syscall_plain;
+}
+
+void
+linux32_syscall_plain(frame)
+ struct trapframe *frame;
+{
+ caddr_t params;
+ const struct sysent *callp;
+ struct proc *p;
+ struct lwp *l;
+ int error;
+ size_t argsize;
+ register32_t code, args[8];
+ register_t rval[2];
+
+ uvmexp.syscalls++;
+ l = curlwp;
+ p = l->l_proc;
+
+ code = frame->tf_rax;
+ callp = p->p_emul->e_sysent;
+ params = (caddr_t)frame->tf_rsp + sizeof(int);
+
+ switch (code) {
+ case SYS_syscall:
+ /*
+ * Code is first argument, followed by actual args.
+ */
+ code = fuword(params);
+ params += sizeof(int);
+ break;
+ case SYS___syscall:
+ /*
+ * Like syscall, but code is a quad, so as to maintain
+ * quad alignment for the rest of the arguments.
+ */
+ code = fuword(params + _QUAD_LOWWORD * sizeof(int));
+ params += sizeof(quad_t);
+ break;
+ default:
+ break;
+ }
+
+ code &= (SYS_NSYSENT - 1);
+ callp += code;
+ argsize = callp->sy_argsize;
+ if (argsize) {
+ /*
+ * Linux passes the args in ebx, ecx, edx, esi, edi, ebp, in
+ * increasing order.
+ */
+ switch (argsize >> 2) {
+ case 6:
+ args[5] = frame->tf_rbp & 0xffffffff;
+ case 5:
+ args[4] = frame->tf_rdi & 0xffffffff;
+ case 4:
+ args[3] = frame->tf_rsi & 0xffffffff;
+ case 3:
+ args[2] = frame->tf_rdx & 0xffffffff;
+ case 2:
+ args[1] = frame->tf_rcx & 0xffffffff;
+ case 1:
+ args[0] = frame->tf_rbx & 0xffffffff;
+ break;
+ default:
+ printf("linux syscall %d bogus argument size %ld",
+ code, argsize);
+ error = ENOSYS;
+ goto out;
+ break;
+ }
+ }
+#ifdef SYSCALL_DEBUG
+ scdebug_call(p, code, args);
+#endif /* SYSCALL_DEBUG */
+
+ rval[0] = 0;
+ rval[1] = 0;
+#if 0
+ printf("linux32: syscall %d (%x %x %x %x %x %x, %x)\n", code,
+ args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
+#endif
+ KERNEL_PROC_LOCK(l);
+ error = (*callp->sy_call)(l, args, rval);
+ KERNEL_PROC_UNLOCK(l);
+
+out:
+ switch (error) {
+ case 0:
+ frame->tf_rax = rval[0];
+ frame->tf_rflags &= ~PSL_C; /* carry bit */
+ break;
+ case ERESTART:
+ /*
+ * The offset to adjust the PC by depends on whether we entered
+ * the kernel through the trap or call gate. We pushed the
+ * size of the instruction into tf_err on entry.
+ */
+ frame->tf_rip -= frame->tf_err;
+ break;
+ case EJUSTRETURN:
+ /* nothing to do */
+ break;
+ default:
+ frame->tf_rax = native_to_linux32_errno[error];
+ frame->tf_rflags |= PSL_C; /* carry bit */
+ break;
+ }
+
+#ifdef SYSCALL_DEBUG
+ scdebug_ret(p, code, error, rval);
+#endif /* SYSCALL_DEBUG */
+ userret(l);
+}
+
+void
+linux32_syscall_fancy(frame)
+ struct trapframe *frame;
+{
+ caddr_t params;
+ const struct sysent *callp;
+ struct proc *p;
+ struct lwp *l;
+ int error;
+ size_t argsize;
+ register32_t code, args[8];
+ register_t rval[2];
+#if defined(KTRACE) || defined(SYSTRACE)
+ int i;
+ register_t args64[8];
+#endif
+
+ uvmexp.syscalls++;
+ l = curlwp;
+ p = l->l_proc;
+
+ code = frame->tf_rax;
+ callp = p->p_emul->e_sysent;
+ params = (caddr_t)frame->tf_rsp + sizeof(int);
+
+ switch (code) {
+ case SYS_syscall:
+ /*
+ * Code is first argument, followed by actual args.
+ */
+ code = fuword(params);
+ params += sizeof(int);
+ break;
+ case SYS___syscall:
+ /*
+ * Like syscall, but code is a quad, so as to maintain
Home |
Main Index |
Thread Index |
Old Index