Annotation of src/sys/compat/linux/common/linux_exec.c, Revision 1.64.2.4
1.64.2.4! skrll 1: /* $NetBSD: linux_exec.c,v 1.72 2004/08/08 19:52:37 jdolecek Exp $ */
1.29 christos 2:
3: /*-
1.44 mycroft 4: * Copyright (c) 1994, 1995, 1998, 2000 The NetBSD Foundation, Inc.
1.29 christos 5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
1.33 fvdl 8: * by Christos Zoulas, Frank van der Linden, Eric Haszlakiewicz and
9: * Thor Lancelot Simon.
1.29 christos 10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
1.1 fvdl 38: */
1.54 lukem 39:
40: #include <sys/cdefs.h>
1.64.2.4! skrll 41: __KERNEL_RCSID(0, "$NetBSD: linux_exec.c,v 1.72 2004/08/08 19:52:37 jdolecek Exp $");
1.1 fvdl 42:
43: #include <sys/param.h>
44: #include <sys/systm.h>
45: #include <sys/kernel.h>
46: #include <sys/proc.h>
47: #include <sys/malloc.h>
48: #include <sys/namei.h>
49: #include <sys/vnode.h>
1.13 christos 50: #include <sys/mount.h>
1.25 christos 51: #include <sys/exec.h>
1.8 fvdl 52: #include <sys/exec_elf.h>
1.1 fvdl 53:
54: #include <sys/mman.h>
1.61 thorpej 55: #include <sys/sa.h>
1.13 christos 56: #include <sys/syscallargs.h>
1.1 fvdl 57:
58: #include <machine/cpu.h>
59: #include <machine/reg.h>
60:
1.32 christos 61: #include <compat/linux/common/linux_types.h>
62: #include <compat/linux/common/linux_signal.h>
63: #include <compat/linux/common/linux_util.h>
64: #include <compat/linux/common/linux_exec.h>
65: #include <compat/linux/common/linux_machdep.h>
66:
67: #include <compat/linux/linux_syscallargs.h>
1.4 christos 68: #include <compat/linux/linux_syscall.h>
1.38 jdolecek 69: #include <compat/linux/common/linux_misc.h>
70: #include <compat/linux/common/linux_errno.h>
1.39 jdolecek 71: #include <compat/linux/common/linux_emuldata.h>
1.8 fvdl 72:
1.38 jdolecek 73: extern struct sysent linux_sysent[];
74: extern const char * const linux_syscallnames[];
75: extern char linux_sigcode[], linux_esigcode[];
1.1 fvdl 76:
1.39 jdolecek 77: static void linux_e_proc_exec __P((struct proc *, struct exec_package *));
1.64.2.3 skrll 78: static void linux_e_proc_fork __P((struct proc *, struct proc *, int));
1.39 jdolecek 79: static void linux_e_proc_exit __P((struct proc *));
1.64.2.3 skrll 80: static void linux_e_proc_init __P((struct proc *, struct proc *, int));
1.39 jdolecek 81:
1.1 fvdl 82: /*
83: * Execve(2). Just check the alternate emulation path, and pass it on
84: * to the NetBSD execve().
85: */
86: int
1.61 thorpej 87: linux_sys_execve(l, v, retval)
88: struct lwp *l;
1.11 thorpej 89: void *v;
90: register_t *retval;
91: {
1.12 mycroft 92: struct linux_sys_execve_args /* {
1.35 christos 93: syscallarg(const char *) path;
1.1 fvdl 94: syscallarg(char **) argv;
95: syscallarg(char **) envp;
1.11 thorpej 96: } */ *uap = v;
1.61 thorpej 97: struct proc *p = l->l_proc;
1.16 mycroft 98: struct sys_execve_args ap;
1.1 fvdl 99: caddr_t sg;
100:
1.57 christos 101: sg = stackgap_init(p, 0);
1.64.2.4! skrll 102: CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
1.1 fvdl 103:
1.16 mycroft 104: SCARG(&ap, path) = SCARG(uap, path);
105: SCARG(&ap, argp) = SCARG(uap, argp);
106: SCARG(&ap, envp) = SCARG(uap, envp);
107:
1.61 thorpej 108: return sys_execve(l, &ap, retval);
1.1 fvdl 109: }
1.38 jdolecek 110:
111: /*
112: * Emulation switch.
113: */
1.64.2.2 skrll 114:
115: struct uvm_object *emul_linux_object;
116:
1.38 jdolecek 117: const struct emul emul_linux = {
118: "linux",
1.40 jdolecek 119: "/emul/linux",
1.44 mycroft 120: #ifndef __HAVE_MINIMAL_EMUL
1.51 manu 121: 0,
1.45 manu 122: (int*)native_to_linux_errno,
1.38 jdolecek 123: LINUX_SYS_syscall,
1.60 jdolecek 124: LINUX_SYS_NSYSENT,
1.44 mycroft 125: #endif
1.38 jdolecek 126: linux_sysent,
127: linux_syscallnames,
1.44 mycroft 128: linux_sendsig,
1.52 christos 129: linux_trapsignal,
1.64.2.2 skrll 130: NULL,
1.38 jdolecek 131: linux_sigcode,
132: linux_esigcode,
1.64.2.2 skrll 133: &emul_linux_object,
1.53 jdolecek 134: linux_setregs,
1.39 jdolecek 135: linux_e_proc_exec,
136: linux_e_proc_fork,
137: linux_e_proc_exit,
1.64.2.2 skrll 138: NULL,
139: NULL,
1.44 mycroft 140: #ifdef __HAVE_SYSCALL_INTERN
141: linux_syscall_intern,
1.42 jdolecek 142: #else
1.62 thorpej 143: #error Implement __HAVE_SYSCALL_INTERN for this platform
1.41 jdolecek 144: #endif
1.64.2.2 skrll 145: NULL,
1.59 manu 146: NULL,
1.38 jdolecek 147: };
1.39 jdolecek 148:
149: static void
1.64.2.3 skrll 150: linux_e_proc_init(p, parent, forkflags)
151: struct proc *p, *parent;
152: int forkflags;
1.39 jdolecek 153: {
1.64.2.3 skrll 154: struct linux_emuldata *e = p->p_emuldata;
155: struct linux_emuldata_shared *s;
156:
157: if (!e) {
1.39 jdolecek 158: /* allocate new Linux emuldata */
1.64.2.3 skrll 159: MALLOC(e, void *, sizeof(struct linux_emuldata),
160: M_EMULDATA, M_WAITOK);
161: } else {
162: e->s->refs--;
163: if (e->s->refs == 0)
164: FREE(e->s, M_EMULDATA);
165: }
166:
167: memset(e, '\0', sizeof(struct linux_emuldata));
168:
169: if (forkflags & FORK_SHAREVM) {
170: struct linux_emuldata *e2 = parent->p_emuldata;
171: s = e2->s;
172: s->refs++;
173: } else {
174: struct vmspace *vm;
175:
176: MALLOC(s, void *, sizeof(struct linux_emuldata_shared),
1.39 jdolecek 177: M_EMULDATA, M_WAITOK);
1.64.2.3 skrll 178: s->refs = 1;
179:
180: /*
181: * Set the process idea of the break to the real value.
182: * For fork, we use parent's vmspace since our's
183: * is not setup at the time of this call and is going
184: * to be copy of parent's anyway. For exec, just
185: * use our own vmspace.
186: */
187: vm = (parent) ? parent->p_vmspace : p->p_vmspace;
188: s->p_break = vm->vm_daddr + ctob(vm->vm_dsize);
189:
1.39 jdolecek 190: }
191:
1.64.2.3 skrll 192: e->s = s;
193: p->p_emuldata = e;
1.48 jdolecek 194: }
195:
196: /*
1.64.2.3 skrll 197: * Allocate new per-process structures. Called when executing Linux
1.48 jdolecek 198: * process. We can reuse the old emuldata - if it's not null,
199: * the executed process is of same emulation as original forked one.
200: */
201: static void
202: linux_e_proc_exec(p, epp)
203: struct proc *p;
204: struct exec_package *epp;
205: {
206: /* exec, use our vmspace */
1.64.2.3 skrll 207: linux_e_proc_init(p, NULL, 0);
1.39 jdolecek 208: }
209:
210: /*
211: * Emulation per-process exit hook.
212: */
213: static void
214: linux_e_proc_exit(p)
215: struct proc *p;
216: {
1.64.2.3 skrll 217: struct linux_emuldata *e = p->p_emuldata;
218:
1.39 jdolecek 219: /* free Linux emuldata and set the pointer to null */
1.64.2.3 skrll 220: e->s->refs--;
221: if (e->s->refs == 0)
222: FREE(e->s, M_EMULDATA);
223: FREE(e, M_EMULDATA);
1.39 jdolecek 224: p->p_emuldata = NULL;
225: }
226:
227: /*
228: * Emulation fork hook.
229: */
230: static void
1.64.2.3 skrll 231: linux_e_proc_fork(p, parent, forkflags)
1.39 jdolecek 232: struct proc *p, *parent;
1.64.2.3 skrll 233: int forkflags;
1.39 jdolecek 234: {
235: /*
1.64.2.3 skrll 236: * The new process might share some vmspace-related stuff
237: * with parent, depending on fork flags (CLONE_VM et.al).
238: * Force allocation of new base emuldata, and share the
239: * VM-related parts only if necessary.
1.39 jdolecek 240: */
241: p->p_emuldata = NULL;
1.64.2.3 skrll 242: linux_e_proc_init(p, parent, forkflags);
1.39 jdolecek 243: }
CVSweb <webmaster@jp.NetBSD.org>