Deleted Added
full compact
kern_sharedpage.c (32286) kern_sharedpage.c (32446)
1/*
2 * Copyright (c) 1993, David Greenman
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*
2 * Copyright (c) 1993, David Greenman
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: kern_exec.c,v 1.72 1997/12/27 02:56:21 bde Exp $
26 * $Id: kern_exec.c,v 1.73 1998/01/06 05:15:34 dyson Exp $
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/sysproto.h>
32#include <sys/signalvar.h>
33#include <sys/kernel.h>
34#include <sys/mount.h>

--- 14 unchanged lines hidden (view full) ---

49#include <sys/vnode.h>
50#include <sys/buf.h>
51
52#include <vm/vm.h>
53#include <vm/vm_param.h>
54#include <vm/vm_prot.h>
55#include <sys/lock.h>
56#include <vm/pmap.h>
27 */
28
29#include <sys/param.h>
30#include <sys/systm.h>
31#include <sys/sysproto.h>
32#include <sys/signalvar.h>
33#include <sys/kernel.h>
34#include <sys/mount.h>

--- 14 unchanged lines hidden (view full) ---

49#include <sys/vnode.h>
50#include <sys/buf.h>
51
52#include <vm/vm.h>
53#include <vm/vm_param.h>
54#include <vm/vm_prot.h>
55#include <sys/lock.h>
56#include <vm/pmap.h>
57#include <vm/vm_page.h>
57#include <vm/vm_map.h>
58#include <vm/vm_kern.h>
59#include <vm/vm_extern.h>
60#include <vm/vm_object.h>
61#include <vm/vm_zone.h>
58#include <vm/vm_map.h>
59#include <vm/vm_kern.h>
60#include <vm/vm_extern.h>
61#include <vm/vm_object.h>
62#include <vm/vm_zone.h>
63#include <vm/vm_pager.h>
64#include <vm/vm_pageout.h>
62
63#include <machine/reg.h>
64
65static int *exec_copyout_strings __P((struct image_params *));
66
65
66#include <machine/reg.h>
67
68static int *exec_copyout_strings __P((struct image_params *));
69
67static int exec_check_permissions(struct image_params *);
70static int exec_check_permissions __P((struct image_params *));
71static int exec_map_first_page __P((struct image_params *));
72static void exec_unmap_first_page __P((struct image_params *));
68
69/*
70 * XXX trouble here if sizeof(caddr_t) != sizeof(int), other parts
71 * of the sysctl code also assumes this, and sizeof(int) == sizeof(long).
72 */
73static struct ps_strings *ps_strings = PS_STRINGS;
74SYSCTL_INT(_kern, KERN_PS_STRINGS, ps_strings, 0, &ps_strings, 0, "");
75

--- 33 unchanged lines hidden (view full) ---

109 imgp = &image_params;
110
111 /*
112 * Initialize part of the common data
113 */
114 imgp->proc = p;
115 imgp->uap = uap;
116 imgp->attr = &attr;
73
74/*
75 * XXX trouble here if sizeof(caddr_t) != sizeof(int), other parts
76 * of the sysctl code also assumes this, and sizeof(int) == sizeof(long).
77 */
78static struct ps_strings *ps_strings = PS_STRINGS;
79SYSCTL_INT(_kern, KERN_PS_STRINGS, ps_strings, 0, &ps_strings, 0, "");
80

--- 33 unchanged lines hidden (view full) ---

114 imgp = &image_params;
115
116 /*
117 * Initialize part of the common data
118 */
119 imgp->proc = p;
120 imgp->uap = uap;
121 imgp->attr = &attr;
117 imgp->image_header = NULL;
118 imgp->argc = imgp->envc = 0;
119 imgp->argv0 = NULL;
120 imgp->entry_addr = 0;
121 imgp->vmspace_destroyed = 0;
122 imgp->interpreted = 0;
123 imgp->interpreter_name[0] = '\0';
124 imgp->auxargs = NULL;
122 imgp->argc = imgp->envc = 0;
123 imgp->argv0 = NULL;
124 imgp->entry_addr = 0;
125 imgp->vmspace_destroyed = 0;
126 imgp->interpreted = 0;
127 imgp->interpreter_name[0] = '\0';
128 imgp->auxargs = NULL;
129 imgp->vp = NULL;
130 imgp->firstpage = NULL;
125
126 /*
127 * Allocate temporary demand zeroed space for argument and
128 * environment strings
129 */
131
132 /*
133 * Allocate temporary demand zeroed space for argument and
134 * environment strings
135 */
130 imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX);
136 imgp->stringbase = (char *)kmem_alloc_wait(exec_map, ARG_MAX + PAGE_SIZE);
131 if (imgp->stringbase == NULL) {
132 error = ENOMEM;
133 goto exec_fail;
134 }
135 imgp->stringp = imgp->stringbase;
136 imgp->stringspace = ARG_MAX;
137 if (imgp->stringbase == NULL) {
138 error = ENOMEM;
139 goto exec_fail;
140 }
141 imgp->stringp = imgp->stringbase;
142 imgp->stringspace = ARG_MAX;
143 imgp->image_header = imgp->stringbase + ARG_MAX;
137
138 /*
139 * Translate the file name. namei() returns a vnode pointer
140 * in ni_vp amoung other things.
141 */
142 ndp = &nd;
143 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
144 UIO_USERSPACE, uap->fname, p);
145
146interpret:
147
148 error = namei(ndp);
149 if (error) {
144
145 /*
146 * Translate the file name. namei() returns a vnode pointer
147 * in ni_vp amoung other things.
148 */
149 ndp = &nd;
150 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
151 UIO_USERSPACE, uap->fname, p);
152
153interpret:
154
155 error = namei(ndp);
156 if (error) {
150 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
157 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase,
158 ARG_MAX + PAGE_SIZE);
151 goto exec_fail;
152 }
153
154 imgp->vp = ndp->ni_vp;
155
156 /*
157 * Check file permissions (also 'opens' file)
158 */
159 error = exec_check_permissions(imgp);
160 if (error) {
161 VOP_UNLOCK(imgp->vp, 0, p);
162 goto exec_fail_dealloc;
163 }
164
159 goto exec_fail;
160 }
161
162 imgp->vp = ndp->ni_vp;
163
164 /*
165 * Check file permissions (also 'opens' file)
166 */
167 error = exec_check_permissions(imgp);
168 if (error) {
169 VOP_UNLOCK(imgp->vp, 0, p);
170 goto exec_fail_dealloc;
171 }
172
165 /*
166 * Get the image header, which we define here as meaning the first
167 * page of the executable.
168 */
169 if (imgp->vp->v_object && imgp->vp->v_mount &&
170 imgp->vp->v_mount->mnt_stat.f_iosize >= PAGE_SIZE &&
171 imgp->vp->v_object->un_pager.vnp.vnp_size >=
172 imgp->vp->v_mount->mnt_stat.f_iosize) {
173 /*
174 * Get a buffer with (at least) the first page.
175 */
176 error = bread(imgp->vp, 0, imgp->vp->v_mount->mnt_stat.f_iosize,
177 p->p_ucred, &bp);
178 imgp->image_header = bp->b_data;
179 } else {
180 int resid;
181
182 /*
183 * The filesystem block size is too small, so do this the hard
184 * way. Malloc some space and read PAGE_SIZE worth of the image
185 * header into it.
186 */
187 imgp->image_header = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
188 error = vn_rdwr(UIO_READ, imgp->vp,
189 (void *)imgp->image_header, PAGE_SIZE, 0,
190 UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &resid, p);
191 /*
192 * Clear out any remaining junk.
193 */
194 if (!error && resid)
195 bzero((char *)imgp->image_header + PAGE_SIZE - resid, resid);
196 }
173 error = exec_map_first_page(imgp);
197 VOP_UNLOCK(imgp->vp, 0, p);
198 if (error)
199 goto exec_fail_dealloc;
200
201 /*
202 * Loop through list of image activators, calling each one.
203 * If there is no match, the activator returns -1. If there
204 * is a match, but there was an error during the activation,

--- 6 unchanged lines hidden (view full) ---

211 error = (*execsw[i]->ex_imgact)(imgp);
212 else
213 continue;
214 if (error == -1)
215 continue;
216 if (error)
217 goto exec_fail_dealloc;
218 if (imgp->interpreted) {
174 VOP_UNLOCK(imgp->vp, 0, p);
175 if (error)
176 goto exec_fail_dealloc;
177
178 /*
179 * Loop through list of image activators, calling each one.
180 * If there is no match, the activator returns -1. If there
181 * is a match, but there was an error during the activation,

--- 6 unchanged lines hidden (view full) ---

188 error = (*execsw[i]->ex_imgact)(imgp);
189 else
190 continue;
191 if (error == -1)
192 continue;
193 if (error)
194 goto exec_fail_dealloc;
195 if (imgp->interpreted) {
219 /* free old bp/image_header */
220 if (bp != NULL) {
221 brelse(bp);
222 bp = NULL;
223 } else
224 free((void *)imgp->image_header, M_TEMP);
225 imgp->image_header = NULL;
196 exec_unmap_first_page(imgp);
226 /* free old vnode and name buffer */
227 vrele(ndp->ni_vp);
228 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
229 /* set new name to that of the interpreter */
230 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
231 UIO_SYSSPACE, imgp->interpreter_name, p);
232 goto interpret;
233 }

--- 112 unchanged lines hidden (view full) ---

346 psignal(p, SIGTRAP);
347
348 /* clear "fork but no exec" flag, as we _are_ execing */
349 p->p_acflag &= ~AFORK;
350
351 /* Set entry address */
352 setregs(p, imgp->entry_addr, (u_long)stack_base);
353
197 /* free old vnode and name buffer */
198 vrele(ndp->ni_vp);
199 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
200 /* set new name to that of the interpreter */
201 NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME,
202 UIO_SYSSPACE, imgp->interpreter_name, p);
203 goto interpret;
204 }

--- 112 unchanged lines hidden (view full) ---

317 psignal(p, SIGTRAP);
318
319 /* clear "fork but no exec" flag, as we _are_ execing */
320 p->p_acflag &= ~AFORK;
321
322 /* Set entry address */
323 setregs(p, imgp->entry_addr, (u_long)stack_base);
324
325exec_fail_dealloc:
326
354 /*
355 * free various allocated resources
356 */
327 /*
328 * free various allocated resources
329 */
357 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
358 if (bp != NULL)
359 brelse(bp);
360 else if (imgp->image_header != NULL)
361 free((void *)imgp->image_header, M_TEMP);
362 vrele(ndp->ni_vp);
363 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
330 if (imgp->firstpage)
331 exec_unmap_first_page(imgp);
364
332
365 return (0);
366
367exec_fail_dealloc:
368 if (imgp->stringbase != NULL)
333 if (imgp->stringbase != NULL)
369 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase, ARG_MAX);
370 if (bp != NULL)
371 brelse(bp);
372 else if (imgp->image_header != NULL)
373 free((void *)imgp->image_header, M_TEMP);
334 kmem_free_wakeup(exec_map, (vm_offset_t)imgp->stringbase,
335 ARG_MAX + PAGE_SIZE);
336
374 if (ndp->ni_vp) {
375 vrele(ndp->ni_vp);
376 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
377 }
378
337 if (ndp->ni_vp) {
338 vrele(ndp->ni_vp);
339 zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
340 }
341
342 if (error == 0)
343 return (0);
344
379exec_fail:
380 if (imgp->vmspace_destroyed) {
381 /* sorry, no more process anymore. exit gracefully */
382 exit1(p, W_EXITCODE(0, SIGABRT));
383 /* NOT REACHED */
384 return(0);
385 } else {
386 return(error);
387 }
388}
389
345exec_fail:
346 if (imgp->vmspace_destroyed) {
347 /* sorry, no more process anymore. exit gracefully */
348 exit1(p, W_EXITCODE(0, SIGABRT));
349 /* NOT REACHED */
350 return(0);
351 } else {
352 return(error);
353 }
354}
355
356int
357exec_map_first_page(imgp)
358 struct image_params *imgp;
359{
360 int s;
361 vm_page_t m;
362 vm_object_t object;
363
364
365 if (imgp->firstpage) {
366 exec_unmap_first_page(imgp);
367 }
368
369 object = imgp->vp->v_object;
370 s = splvm();
371
372retry:
373 m = vm_page_lookup(object, 0);
374 if (m == NULL) {
375 m = vm_page_alloc(object, 0, VM_ALLOC_NORMAL);
376 if (m == NULL) {
377 VM_WAIT;
378 goto retry;
379 }
380 } else if ((m->flags & PG_BUSY) || m->busy) {
381 m->flags |= PG_WANTED;
382 tsleep(m, PVM, "execpw", 0);
383 goto retry;
384 }
385
386 m->flags |= PG_BUSY;
387
388 if ((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) {
389 int rv;
390 rv = vm_pager_get_pages(object, &m, 1, 0);
391 if (rv != VM_PAGER_OK) {
392 vm_page_protect(m, VM_PROT_NONE);
393 vm_page_deactivate(m);
394 PAGE_WAKEUP(m);
395 splx(s);
396 return EIO;
397 }
398 }
399
400 vm_page_wire(m);
401 PAGE_WAKEUP(m);
402 splx(s);
403
404 pmap_kenter((vm_offset_t) imgp->image_header, VM_PAGE_TO_PHYS(m));
405 imgp->firstpage = m;
406
407 return 0;
408}
409
410void
411exec_unmap_first_page(imgp)
412 struct image_params *imgp;
413{
414 if (imgp->firstpage) {
415 pmap_kremove((vm_offset_t) imgp->image_header);
416 vm_page_unwire(imgp->firstpage);
417 imgp->firstpage = NULL;
418 }
419}
420
390/*
391 * Destroy old address space, and allocate a new stack
392 * The new stack is only SGROWSIZ large because it is grown
393 * automatically in trap.c.
394 */
395int
396exec_new_vmspace(imgp)
397 struct image_params *imgp;

--- 17 unchanged lines hidden (view full) ---

415 vm_map_remove(map, 0, USRSTACK);
416 } else {
417 vmspace_exec(imgp->proc);
418 vmspace = imgp->proc->p_vmspace;
419 map = &vmspace->vm_map;
420 }
421
422 /* Allocate a new stack */
421/*
422 * Destroy old address space, and allocate a new stack
423 * The new stack is only SGROWSIZ large because it is grown
424 * automatically in trap.c.
425 */
426int
427exec_new_vmspace(imgp)
428 struct image_params *imgp;

--- 17 unchanged lines hidden (view full) ---

446 vm_map_remove(map, 0, USRSTACK);
447 } else {
448 vmspace_exec(imgp->proc);
449 vmspace = imgp->proc->p_vmspace;
450 map = &vmspace->vm_map;
451 }
452
453 /* Allocate a new stack */
423 error = vm_map_find(map, NULL, 0, (vm_offset_t *)&stack_addr,
424 SGROWSIZ, FALSE, VM_PROT_ALL, VM_PROT_ALL, 0);
454 error = vm_map_insert(&vmspace->vm_map, NULL, 0,
455 (vm_offset_t) stack_addr, (vm_offset_t) USRSTACK,
456 VM_PROT_ALL, VM_PROT_ALL, 0);
425 if (error)
457 if (error)
426 return(error);
458 return (error);
427
428 vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT;
429
430 /* Initialize maximum stack address */
431 vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ;
432
433 return(0);
434}

--- 235 unchanged lines hidden ---
459
460 vmspace->vm_ssize = SGROWSIZ >> PAGE_SHIFT;
461
462 /* Initialize maximum stack address */
463 vmspace->vm_maxsaddr = (char *)USRSTACK - MAXSSIZ;
464
465 return(0);
466}

--- 235 unchanged lines hidden ---