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