Source-Changes-HG archive

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

[src/trunk]: src/sys add infrastructure to load emulations and their executab...



details:   https://anonhg.NetBSD.org/src/rev/2c89fc4d63af
branches:  trunk
changeset: 500228:2c89fc4d63af
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Fri Dec 08 19:42:11 2000 +0000

description:
add infrastructure to load emulations and their executable support dynamically
via LKM

diffstat:

 sys/compat/netbsd32/netbsd32_netbsd.c |   23 +-
 sys/kern/exec_conf.c                  |    7 +-
 sys/kern/kern_exec.c                  |  439 ++++++++++++++++++++++++++++++++-
 sys/kern/kern_lkm.c                   |   87 +++---
 sys/sys/exec.h                        |   25 +-
 sys/sys/lkm.h                         |   35 ++-
 6 files changed, 514 insertions(+), 102 deletions(-)

diffs (truncated from 857 to 300 lines):

diff -r ee1b11931e82 -r 2c89fc4d63af sys/compat/netbsd32/netbsd32_netbsd.c
--- a/sys/compat/netbsd32/netbsd32_netbsd.c     Fri Dec 08 19:24:29 2000 +0000
+++ b/sys/compat/netbsd32/netbsd32_netbsd.c     Fri Dec 08 19:42:11 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_netbsd.c,v 1.43 2000/12/03 14:48:29 fvdl Exp $        */
+/*     $NetBSD: netbsd32_netbsd.c,v 1.44 2000/12/08 19:42:12 jdolecek Exp $    */
 
 /*
  * Copyright (c) 1998 Matthew R. Green
@@ -100,6 +100,7 @@
 
 /* this is provided by kern/kern_exec.c */
 extern int exec_maxhdrsz;
+extern struct lock exec_lock;
 
 static __inline void netbsd32_from_timeval __P((struct timeval *, struct netbsd32_timeval *));
 static __inline void netbsd32_to_timeval __P((struct netbsd32_timeval *, struct timeval *));
@@ -1808,18 +1809,6 @@
        sg = stackgap_init(p->p_emul);
        CHECK_ALT_EXIST(p, &sg, SCARG(&ua, path));
 
-       /*
-        * figure out the maximum size of an exec header, if necessary.
-        * XXX should be able to keep LKM code from modifying exec switch
-        * when we're still using it, but...
-        */
-       if (exec_maxhdrsz == 0) {
-               for (i = 0; i < nexecs; i++)
-                       if (execsw[i].es_check != NULL
-                           && execsw[i].es_hdrsz > exec_maxhdrsz)
-                               exec_maxhdrsz = execsw[i].es_hdrsz;
-       }
-
        /* init the namei data to point the file user's program name */
        /* XXX cgd 960926: why do this here?  most will be clobbered. */
        NDINIT(&nid, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(&ua, path), p);
@@ -1838,6 +1827,8 @@
        pack.ep_vap = &attr;
        pack.ep_flags = 0;
 
+       lockmgr(&exec_lock, LK_SHARED, NULL);
+
        /* see if we can run it. */
        if ((error = check_exec(p, &pack)) != 0)
                goto freehdr;
@@ -2142,6 +2133,8 @@
                ktremul(p);
 #endif
 
+       lockmgr(&exec_lock, LK_RELEASE, NULL);
+
        return (EJUSTRETURN);
 
 bad:
@@ -2160,10 +2153,14 @@
        uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
 
 freehdr:
+       lockmgr(&exec_lock, LK_RELEASE, NULL);
+
        free(pack.ep_hdr, M_EXEC);
        return error;
 
 exec_abort:
+       lockmgr(&exec_lock, LK_RELEASE, NULL);
+
        /*
         * the old process doesn't exist anymore.  exit gracefully.
         * get rid of the (new) address space we have created, if any, get rid
diff -r ee1b11931e82 -r 2c89fc4d63af sys/kern/exec_conf.c
--- a/sys/kern/exec_conf.c      Fri Dec 08 19:24:29 2000 +0000
+++ b/sys/kern/exec_conf.c      Fri Dec 08 19:42:11 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: exec_conf.c,v 1.50 2000/12/02 20:44:09 scw Exp $       */
+/*     $NetBSD: exec_conf.c,v 1.51 2000/12/08 19:42:11 jdolecek Exp $  */
 
 /*
  * Copyright (c) 1993, 1994 Christopher G. Demetriou
@@ -142,7 +142,7 @@
 extern const struct emul emul_netbsd_aoutm68k;
 #endif
 
-const struct execsw execsw[] = {
+const struct execsw execsw_builtin[] = {
 #ifdef EXEC_SCRIPT
        { MAXINTERP, exec_script_makecmds, { NULL },
          NULL, EXECSW_PRIO_ANY, }, /* shell scripts */
@@ -301,5 +301,4 @@
          pecoff_copyargs, setregs },   /* Win32/CE PE/COFF */
 #endif
 };
-int nexecs = (sizeof(execsw) / sizeof(*execsw));
-int exec_maxhdrsz = 0;
+int nexecs_builtin = (sizeof(execsw_builtin) / sizeof(struct execsw));
diff -r ee1b11931e82 -r 2c89fc4d63af sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c      Fri Dec 08 19:24:29 2000 +0000
+++ b/sys/kern/kern_exec.c      Fri Dec 08 19:42:11 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_exec.c,v 1.129 2000/12/07 16:14:35 jdolecek Exp $ */
+/*     $NetBSD: kern_exec.c,v 1.130 2000/12/08 19:42:12 jdolecek Exp $ */
 
 /*-
  * Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou
@@ -62,6 +62,48 @@
 #include <machine/cpu.h>
 #include <machine/reg.h>
 
+/*
+ * Exec function switch:
+ *
+ * Note that each makecmds function is responsible for loading the
+ * exec package with the necessary functions for any exec-type-specific
+ * handling.
+ *
+ * Functions for specific exec types should be defined in their own
+ * header file.
+ */
+extern const struct execsw execsw_builtin[];
+extern int nexecs_builtin;
+static const struct execsw **execsw = NULL;
+static int nexecs;
+int exec_maxhdrsz;             /* must not be static - netbsd32 needs it */
+
+#ifdef LKM
+/* list of supported emulations */
+static
+LIST_HEAD(emlist_head, emul_entry) el_head = LIST_HEAD_INITIALIZER(el_head);
+struct emul_entry {
+       LIST_ENTRY(emul_entry) el_list;
+       const struct emul *el_emul;
+       int ro_entry;
+};
+
+/* list of dynamically loaded execsw entries */
+static
+LIST_HEAD(execlist_head, exec_entry) ex_head = LIST_HEAD_INITIALIZER(ex_head);
+struct exec_entry {
+       LIST_ENTRY(exec_entry) ex_list;
+       const struct execsw *es;
+};
+
+/* structure used for building execw[] */
+struct execsw_entry {
+       struct execsw_entry *next;
+       const struct execsw *es;
+};
+#endif /* LKM */
+
+/* NetBSD emul struct */
 extern char sigcode[], esigcode[];
 #ifdef SYSCALL_DEBUG
 extern const char * const syscallnames[];
@@ -89,6 +131,17 @@
 };
 
 /*
+ * Exec lock. Used to control access to execsw[] structures.
+ * This must not be static so that netbsd32 can access it, too.
+ */
+struct lock exec_lock;
+ 
+#ifdef LKM
+static const struct emul *     emul_search __P((const char *));
+static void link_es __P((struct execsw_entry **, const struct execsw *));
+#endif /* LKM */
+
+/*
  * check exec:
  * given an "executable" described in the exec package's namei info,
  * see what we can do with it.
@@ -172,18 +225,15 @@
        for (i = 0; i < nexecs && error != 0; i++) {
                int newerror;
 
-               if (execsw[i].es_check == NULL)
-                       continue;
-
-               epp->ep_esch = &execsw[i];
-               newerror = (*execsw[i].es_check)(p, epp);
+               epp->ep_esch = execsw[i];
+               newerror = (*execsw[i]->es_check)(p, epp);
                /* make sure the first "interesting" error code is saved. */
                if (!newerror || error == ENOEXEC)
                        error = newerror;
 
                /* if es_check call was successful, update epp->ep_es */
                if (!newerror && (epp->ep_flags & EXEC_HASES) == 0)
-                       epp->ep_es = &execsw[i];
+                       epp->ep_es = execsw[i];
 
                if (epp->ep_flags & EXEC_DESTR && error != 0)
                        return error;
@@ -259,18 +309,6 @@
        struct exec_vmcmd *base_vcp = NULL;
 
        /*
-        * figure out the maximum size of an exec header, if necessary.
-        * XXX should be able to keep LKM code from modifying exec switch
-        * when we're still using it, but...
-        */
-       if (exec_maxhdrsz == 0) {
-               for (i = 0; i < nexecs; i++)
-                       if (execsw[i].es_check != NULL
-                           && execsw[i].es_hdrsz > exec_maxhdrsz)
-                               exec_maxhdrsz = execsw[i].es_hdrsz;
-       }
-
-       /*
         * Init the namei data to point the file user's program name.
         * This is done here rather than in check_exec(), so that it's
         * possible to override this settings if any of makecmd/probe
@@ -293,6 +331,8 @@
        pack.ep_vap = &attr;
        pack.ep_flags = 0;
 
+       lockmgr(&exec_lock, LK_SHARED, NULL);
+
        /* see if we can run it. */
        if ((error = check_exec(p, &pack)) != 0)
                goto freehdr;
@@ -596,6 +636,8 @@
                ktremul(p);
 #endif
 
+       lockmgr(&exec_lock, LK_RELEASE, NULL);
+
        return (EJUSTRETURN);
 
 bad:
@@ -614,10 +656,14 @@
        uvm_km_free_wakeup(exec_map, (vaddr_t) argp, NCARGS);
 
 freehdr:
+       lockmgr(&exec_lock, LK_RELEASE, NULL);
+
        free(pack.ep_hdr, M_EXEC);
        return error;
 
 exec_abort:
+       lockmgr(&exec_lock, LK_RELEASE, NULL);
+
        /*
         * the old process doesn't exist anymore.  exit gracefully.
         * get rid of the (new) address space we have created, if any, get rid
@@ -689,3 +735,358 @@
 
        return cpp;
 }
+
+#ifdef LKM
+/*
+ * Find an emulation of given name in list of emulations.
+ */
+static const struct emul *
+emul_search(name)
+       const char *name;
+{
+       struct emul_entry *it;
+
+       LIST_FOREACH(it, &el_head, el_list) {
+               if (strcmp(name, it->el_emul->e_name) == 0)
+                       return it->el_emul;
+       }
+
+       return NULL;
+}
+
+/*
+ * Add an emulation to list, if it's not there already.
+ */
+int
+emul_register(emul, ro_entry)
+       const struct emul *emul;
+       int ro_entry;
+{
+       struct emul_entry *ee;
+       int error = 0;
+
+       lockmgr(&exec_lock, LK_SHARED, NULL);
+
+       if (emul_search(emul->e_name)) {
+               error = EEXIST;
+               goto out;
+       }
+
+       MALLOC(ee, struct emul_entry *, sizeof(struct emul_entry),
+               M_EXEC, M_WAITOK);
+       ee->el_emul = emul;
+       ee->ro_entry = ro_entry;
+       LIST_INSERT_HEAD(&el_head, ee, el_list);
+
+    out:
+       lockmgr(&exec_lock, LK_RELEASE, NULL);
+       return error;
+}
+
+/*
+ * Remove emulation with name 'name' from list of supported emulations.
+ */
+int



Home | Main Index | Thread Index | Old Index