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