summaryrefslogtreecommitdiff
path: root/sys/compat/linux
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2003-06-21 00:42:59 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2003-06-21 00:42:59 +0000
commit544e5e6a2220a000f63bbb4669c3be396524a8ac (patch)
tree3882116a373bcc0bea029332459b1aca83d94b03 /sys/compat/linux
parentb4f011dd3afccde0013e4cab893d0336b02f2bde (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.h16
-rw-r--r--sys/compat/linux/linux_exec.c118
-rw-r--r--sys/compat/linux/linux_misc.c18
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;
}