diff options
| author | dsl <dsl@NetBSD.org> | 2007-04-22 08:29:55 +0000 |
|---|---|---|
| committer | dsl <dsl@NetBSD.org> | 2007-04-22 08:29:55 +0000 |
| commit | b8fbaf8c4be690d029da1be20006f487e2f81b17 (patch) | |
| tree | 68186d3317175dfd95f7baa39a60030c8364e661 /sys/kern/exec_elf32.c | |
| parent | 98e922db67056a5d00e1de9d956eb8f21f649172 (diff) | |
Change the way that emulations locate files within the emulation root to
avoid having to allocate space in the 'stackgap'
- which is very LWP unfriendly.
The additional code for non-emulation namei() is trivial, the reduction for
the emulations is massive.
The vnode for a processes emulation root is saved in the cwdi structure
during process exec.
If the emulation root the TRYEMULROOT flag are set, namei() will do an initial
search for absolute pathnames in the emulation root, if that fails it will
retry from the normal root.
".." at the emulation root will always go to the real root, even in the middle
of paths and when expanding symlinks.
Absolute symlinks found using absolute paths in the emulation root will be
relative to the emulation root (so /usr/lib/xxx.so -> /lib/xxx.so links
inside the emulation root don't need changing).
If the root of the emulation would be returned (for an emulation lookup), then
the real root is returned instead (matching the behaviour of emul_lookup,
but being a cheap comparison here) so that programs that scan "../.."
looking for the root dircetory don't loop forever.
The target for symbolic links is no longer mangled (it used to get the
CHECK_ALT_xxx() treatment, so could get /emul/xxx prepended).
CHECK_ALT_xxx() are no more. Most of the change is deleting them, and adding
TRYEMULROOT to the flags to NDINIT().
A lot of the emulation system call stubs could now be deleted.
Diffstat (limited to 'sys/kern/exec_elf32.c')
| -rw-r--r-- | sys/kern/exec_elf32.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/sys/kern/exec_elf32.c b/sys/kern/exec_elf32.c index eb9bb5b8694..0f1b441332a 100644 --- a/sys/kern/exec_elf32.c +++ b/sys/kern/exec_elf32.c @@ -1,4 +1,4 @@ -/* $NetBSD: exec_elf32.c,v 1.122 2007/03/05 09:22:02 yamt Exp $ */ +/* $NetBSD: exec_elf32.c,v 1.123 2007/04/22 08:30:00 dsl Exp $ */ /*- * Copyright (c) 1994, 2000, 2005 The NetBSD Foundation, Inc. @@ -64,7 +64,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: exec_elf32.c,v 1.122 2007/03/05 09:22:02 yamt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: exec_elf32.c,v 1.123 2007/04/22 08:30:00 dsl Exp $"); /* If not included by exec_elf64.c, ELFSIZE won't be defined. */ #ifndef ELFSIZE @@ -91,6 +91,8 @@ __KERNEL_RCSID(1, "$NetBSD: exec_elf32.c,v 1.122 2007/03/05 09:22:02 yamt Exp $" #include <machine/cpu.h> #include <machine/reg.h> +#include <compat/common/compat_util.h> + #if defined(PAX_MPROTECT) || defined(PAX_SEGVGUARD) #include <sys/pax.h> #endif /* PAX_MPROTECT || PAX_SEGVGUARD */ @@ -341,7 +343,6 @@ elf_load_file(struct lwp *l, struct exec_package *epp, char *path, Elf_Addr *last) { int error, i; - struct nameidata nd; struct vnode *vp; struct vattr attr; Elf_Ehdr eh; @@ -360,10 +361,16 @@ elf_load_file(struct lwp *l, struct exec_package *epp, char *path, * 2. read filehdr * 3. map text, data, and bss out of it using VM_* */ - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, path, l); - if ((error = namei(&nd)) != 0) - return error; - vp = nd.ni_vp; + vp = epp->ep_interp; + if (vp == NULL) { + error = emul_find_interp(l, epp, path); + if (error != 0) + return error; + vp = epp->ep_interp; + } + /* We'll tidy this ourselves - otherwise we have locking issues */ + epp->ep_interp = NULL; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* * Similarly, if it's not marked as executable, or it's not a regular |
