diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2003-06-21 00:42:59 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2003-06-21 00:42:59 +0000 |
commit | 544e5e6a2220a000f63bbb4669c3be396524a8ac (patch) | |
tree | 3882116a373bcc0bea029332459b1aca83d94b03 /sys/compat/linux | |
parent | b4f011dd3afccde0013e4cab893d0336b02f2bde (diff) |
add exec/fork/exit hooks per process for compat emulations.
use them to correctly emulate linux brk.
update to TNF copyright in linux_exec.c.
from netbsd, mostly from a diff by Kurt Miller in pr3318.
this should fix java. no regressions in testing by kurt and sturm@.
be prepared for "proc size mismatch" -- recompile ps and friends.
ok deraadt@
Diffstat (limited to 'sys/compat/linux')
-rw-r--r-- | sys/compat/linux/linux_emuldata.h | 16 | ||||
-rw-r--r-- | sys/compat/linux/linux_exec.c | 118 | ||||
-rw-r--r-- | sys/compat/linux/linux_misc.c | 18 |
3 files changed, 123 insertions, 29 deletions
diff --git a/sys/compat/linux/linux_emuldata.h b/sys/compat/linux/linux_emuldata.h new file mode 100644 index 00000000000..43e851f6f7a --- /dev/null +++ b/sys/compat/linux/linux_emuldata.h @@ -0,0 +1,16 @@ +/* $OpenBSD: linux_emuldata.h,v 1.1 2003/06/21 00:42:58 tedu Exp $ */ +/* $NetBSD: linux_emuldata.h,v 1.4 2002/02/15 16:48:02 christos Exp $ */ + +#ifndef _LINUX_EMULDATA_H +#define _LINUX_EMULDATA_H + +/* + * This is auxillary data the linux compat code + * needs to do its work. A pointer to it is + * stored in the emuldata field of the proc + * structure. + */ +struct linux_emuldata { + caddr_t p_break; /* Cached per-process break value */ +}; +#endif /* !_LINUX_EMULDATA_H */ diff --git a/sys/compat/linux/linux_exec.c b/sys/compat/linux/linux_exec.c index 457f4294e12..204eca3692a 100644 --- a/sys/compat/linux/linux_exec.c +++ b/sys/compat/linux/linux_exec.c @@ -1,11 +1,14 @@ -/* $OpenBSD: linux_exec.c,v 1.20 2002/03/14 01:26:50 millert Exp $ */ +/* $OpenBSD: linux_exec.c,v 1.21 2003/06/21 00:42:58 tedu Exp $ */ /* $NetBSD: linux_exec.c,v 1.13 1996/04/05 00:01:10 christos Exp $ */ -/* - * Copyright (c) 1995 Frank van der Linden - * Copyright (c) 1994 Christos Zoulas +/*- + * Copyright (c) 1994, 1995, 1998, 2000 The NetBSD Foundation, Inc. * All rights reserved. * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and + * Thor Lancelot Simon. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -14,21 +17,25 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * based on exec_aout.c, sunos_exec.c and svr4_exec.c + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/param.h> @@ -58,6 +65,7 @@ #include <compat/linux/linux_syscallargs.h> #include <compat/linux/linux_util.h> #include <compat/linux/linux_exec.h> +#include <compat/linux/linux_emuldata.h> static void *linux_aout_copyargs(struct exec_package *, struct ps_strings *, void *, void *); @@ -79,6 +87,11 @@ int exec_linux_aout_prep_nmagic(struct proc *, struct exec_package *); int exec_linux_aout_prep_omagic(struct proc *, struct exec_package *); int exec_linux_aout_prep_qmagic(struct proc *, struct exec_package *); +void linux_e_proc_exec(struct proc *, struct exec_package *); +void linux_e_proc_fork(struct proc *, struct proc *); +void linux_e_proc_exit(struct proc *); +void linux_e_proc_init(struct proc *, struct vmspace *); + struct emul emul_linux_aout = { "linux", linux_error, @@ -97,6 +110,10 @@ struct emul emul_linux_aout = { NULL, linux_sigcode, linux_esigcode, + NULL, + linux_e_proc_exec, + linux_e_proc_fork, + linux_e_proc_exit, }; struct emul emul_linux_elf = { @@ -117,8 +134,73 @@ struct emul emul_linux_elf = { exec_elf32_fixup, linux_sigcode, linux_esigcode, + NULL, + linux_e_proc_exec, + linux_e_proc_fork, + linux_e_proc_exit, }; +/* + * Allocate per-process structures. Called when executing Linux + * process. We can reuse the old emuldata - if it's not null, + * the executed process is of same emulation as original forked one. + */ +void +linux_e_proc_init(p, vmspace) + struct proc *p; + struct vmspace *vmspace; +{ + if (!p->p_emuldata) { + /* allocate new Linux emuldata */ + MALLOC(p->p_emuldata, void *, sizeof(struct linux_emuldata), + M_EMULDATA, M_WAITOK); + } + + memset(p->p_emuldata, '\0', sizeof(struct linux_emuldata)); + + /* Set the process idea of the break to the real value */ + ((struct linux_emuldata *)(p->p_emuldata))->p_break = + vmspace->vm_daddr + ctob(vmspace->vm_dsize); +} + +void +linux_e_proc_exec(p, epp) + struct proc *p; + struct exec_package *epp; +{ + /* exec, use our vmspace */ + linux_e_proc_init(p, p->p_vmspace); +} + +/* + * Emulation per-process exit hook. + */ +void +linux_e_proc_exit(p) + struct proc *p; +{ + /* free Linux emuldata and set the pointer to null */ + FREE(p->p_emuldata, M_EMULDATA); + p->p_emuldata = NULL; +} + +/* + * Emulation fork hook. + */ +void +linux_e_proc_fork(p, parent) + struct proc *p, *parent; +{ + /* + * It could be desirable to copy some stuff from parent's + * emuldata. We don't need anything like that for now. + * So just allocate new emuldata for the new process. + */ + p->p_emuldata = NULL; + + /* fork, use parent's vmspace (our vmspace may not be setup yet) */ + linux_e_proc_init(p, parent->p_vmspace); +} static void * linux_aout_copyargs(pack, arginfo, stack, argp) diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 988f9a5eca5..2f8a63b63b6 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_misc.c,v 1.48 2003/01/30 03:29:49 millert Exp $ */ +/* $OpenBSD: linux_misc.c,v 1.49 2003/06/21 00:42:58 tedu Exp $ */ /* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */ /* @@ -77,6 +77,7 @@ #include <compat/linux/linux_syscallargs.h> #include <compat/linux/linux_util.h> #include <compat/linux/linux_dirent.h> +#include <compat/linux/linux_emuldata.h> #include <compat/common/compat_dir.h> @@ -333,21 +334,16 @@ linux_sys_brk(p, v, retval) char *nbrk = SCARG(uap, nsize); struct sys_obreak_args oba; struct vmspace *vm = p->p_vmspace; - caddr_t oldbrk; + struct linux_emuldata *ed = (struct linux_emuldata*)p->p_emuldata; - oldbrk = vm->vm_daddr + ctob(vm->vm_dsize); - /* - * XXX inconsistent.. Linux always returns at least the old - * brk value, but it will be page-aligned if this fails, - * and possibly not page aligned if it succeeds (the user - * supplied pointer is returned). - */ SCARG(&oba, nsize) = nbrk; if ((caddr_t) nbrk > vm->vm_daddr && sys_obreak(p, &oba, retval) == 0) - retval[0] = (register_t)nbrk; + ed->p_break = (char*)nbrk; else - retval[0] = (register_t)oldbrk; + nbrk = ed->p_break; + + retval[0] = (register_t)nbrk; return 0; } |