Source-Changes-HG archive

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

[src/trunk]: src/sys/compat/netbsd32 PR/55547: Dan Plassche: Fix BSD/OS binar...



details:   https://anonhg.NetBSD.org/src/rev/06292d55d68c
branches:  trunk
changeset: 974686:06292d55d68c
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Aug 08 19:08:48 2020 +0000

description:
PR/55547: Dan Plassche: Fix BSD/OS binary emulation.
Centralize lcall sniffer and recognize the BSD/OS flavor.

diffstat:

 sys/arch/i386/i386/trap.c          |  18 +++++++-----------
 sys/arch/x86/include/cpu.h         |   3 ++-
 sys/arch/x86/x86/cpu.c             |  27 +++++++++++++++++++++++++--
 sys/compat/netbsd32/netbsd32_mod.c |  27 +++++++++++++--------------
 4 files changed, 47 insertions(+), 28 deletions(-)

diffs (165 lines):

diff -r cde8ee1ad6fc -r 06292d55d68c sys/arch/i386/i386/trap.c
--- a/sys/arch/i386/i386/trap.c Sat Aug 08 19:04:58 2020 +0000
+++ b/sys/arch/i386/i386/trap.c Sat Aug 08 19:08:48 2020 +0000
@@ -1,5 +1,5 @@
 
-/*     $NetBSD: trap.c,v 1.304 2020/07/14 00:45:52 yamaguchi Exp $     */
+/*     $NetBSD: trap.c,v 1.305 2020/08/08 19:08:48 christos Exp $      */
 
 /*-
  * Copyright (c) 1998, 2000, 2005, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.304 2020/07/14 00:45:52 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.305 2020/08/08 19:08:48 christos Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -447,19 +447,15 @@
                /* NOTREACHED */
 
        case T_PROTFLT|T_USER:          /* protection fault */
-#if defined(COMPAT_10)
+#if defined(COMPAT_10) || defined(COMPAT_NOMID)
        {
-               static const char lcall[7] = { 0x9a, 0, 0, 0, 0, 7, 0 };
-               const size_t sz = sizeof(lcall);
-               char tmp[sizeof(lcall)];
-
+#define LCALLSZ 7
                /* Check for the osyscall lcall instruction. */
-               if (frame->tf_eip < VM_MAXUSER_ADDRESS - sz &&
-                   copyin((void *)frame->tf_eip, tmp, sz) == 0 &&
-                   memcmp(tmp, lcall, sz) == 0) {
+               if (frame->tf_eip < VM_MAXUSER_ADDRESS - LCALLSZ &&
+                   x86_cpu_is_lcall((const void *)frame->tf_eip)) {
 
                        /* Advance past the lcall. */
-                       frame->tf_eip += sz;
+                       frame->tf_eip += LCALLSZ;
 
                        /* Do the syscall. */
                        p->p_md.md_syscall(frame);
diff -r cde8ee1ad6fc -r 06292d55d68c sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h        Sat Aug 08 19:04:58 2020 +0000
+++ b/sys/arch/x86/include/cpu.h        Sat Aug 08 19:08:48 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.128 2020/07/19 13:55:09 maxv Exp $   */
+/*     $NetBSD: cpu.h,v 1.129 2020/08/08 19:08:48 christos Exp $       */
 
 /*
  * Copyright (c) 1990 The Regents of the University of California.
@@ -564,6 +564,7 @@
 
 /* cpu.c */
 void   cpu_probe_features(struct cpu_info *);
+int    x86_cpu_is_lcall(const void *);
 
 /* vm_machdep.c */
 void   cpu_proc_fork(struct proc *, struct proc *);
diff -r cde8ee1ad6fc -r 06292d55d68c sys/arch/x86/x86/cpu.c
--- a/sys/arch/x86/x86/cpu.c    Sat Aug 08 19:04:58 2020 +0000
+++ b/sys/arch/x86/x86/cpu.c    Sat Aug 08 19:08:48 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.c,v 1.196 2020/07/28 14:49:55 fcambus Exp $        */
+/*     $NetBSD: cpu.c,v 1.197 2020/08/08 19:08:48 christos Exp $       */
 
 /*
  * Copyright (c) 2000-2020 NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.196 2020/07/28 14:49:55 fcambus Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.197 2020/08/08 19:08:48 christos Exp $");
 
 #include "opt_ddb.h"
 #include "opt_mpbios.h"                /* for MPDEBUG */
@@ -1451,3 +1451,26 @@
 {
        x86_send_ipi(ci, X86_IPI_AST);
 }
+
+int
+x86_cpu_is_lcall(const void *ip)
+{
+        static const uint8_t lcall[] = { 0x9a, 0, 0, 0, 0 };
+       int error;
+        const size_t sz = sizeof(lcall) + 2;
+        uint8_t tmp[sizeof(lcall) + 2];
+
+       if ((error = copyin(ip, tmp, sz)) != 0)
+               return error;
+
+       if (memcmp(tmp, lcall, sizeof(lcall)) != 0 || tmp[sz - 1] != 0)
+               return EINVAL;
+
+       switch (tmp[sz - 2]) {
+        case (uint8_t)0x07: /* NetBSD */
+       case (uint8_t)0x87: /* BSD/OS */
+               return 0;
+       default:
+               return EINVAL;
+        }
+}
diff -r cde8ee1ad6fc -r 06292d55d68c sys/compat/netbsd32/netbsd32_mod.c
--- a/sys/compat/netbsd32/netbsd32_mod.c        Sat Aug 08 19:04:58 2020 +0000
+++ b/sys/compat/netbsd32/netbsd32_mod.c        Sat Aug 08 19:08:48 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_mod.c,v 1.22 2020/03/21 16:17:08 pgoyette Exp $       */
+/*     $NetBSD: netbsd32_mod.c,v 1.23 2020/08/08 19:08:48 christos Exp $       */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -59,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_mod.c,v 1.22 2020/03/21 16:17:08 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_mod.c,v 1.23 2020/08/08 19:08:48 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_execfmt.h"
@@ -131,29 +131,28 @@
 };
 
 #if defined(__amd64__)
+#include <x86/cpu.h>
 
 /* This code was moved here, from $SRC/arch/amd64/amd64/trap.c */
 
 static int
 amd64_oosyscall_handle(struct proc *p, struct trapframe *frame)
 {
-
-       static const char lcall[7] = { 0x9a, 0, 0, 0, 0, 7, 0 };
-       const size_t sz = sizeof(lcall);
-       char tmp[sizeof(lcall) /* Avoids VLA */];
+       int error = EPASSTHROUGH;
+#define LCALLSZ        7
 
        /* Check for the oosyscall lcall instruction. */
        if (p->p_emul == &emul_netbsd32 &&
-           frame->tf_rip < VM_MAXUSER_ADDRESS32 - sz &&
-           copyin((void *)frame->tf_rip, tmp, sz) == 0 &&
-           memcmp(tmp, lcall, sz) == 0) {
-
+           frame->tf_rip < VM_MAXUSER_ADDRESS32 - LCALLSZ && 
+           (error = x86_cpu_is_lcall((void *)frame->tf_rip)) == 0)
+       {
                /* Advance past the lcall and save instruction size. */
-               frame->tf_rip += sz;
-               frame->tf_err = sz;
+               frame->tf_rip += LCALLSZ;
+               frame->tf_err = LCALLSZ;
                return 0;
-       } else
-               return EPASSTHROUGH;
+       }
+
+       return error;
 }
 #endif /* defined(__amd64__) */
 



Home | Main Index | Thread Index | Old Index