make links via ../machine for common dirs; hp300;
[unix-history] / usr / src / sys / kern / kern_exec.c
CommitLineData
da7c5cc6 1/*
c4ec2128
KM
2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3 * All rights reserved.
da7c5cc6 4 *
c4ec2128
KM
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 *
c9714ae3 17 * @(#)kern_exec.c 7.25 (Berkeley) %G%
da7c5cc6 18 */
28db9b87 19
94368568
JB
20#include "param.h"
21#include "systm.h"
22#include "map.h"
c9714ae3 23#include "syscontext.h"
94368568
JB
24#include "kernel.h"
25#include "proc.h"
c4ec2128
KM
26#include "mount.h"
27#include "ucred.h"
28#include "malloc.h"
94368568 29#include "buf.h"
c4ec2128 30#include "vnode.h"
94368568
JB
31#include "seg.h"
32#include "vm.h"
33#include "text.h"
34#include "file.h"
35#include "uio.h"
36#include "acct.h"
37#include "exec.h"
28db9b87 38
d301d150
KM
39#include "machine/reg.h"
40#include "machine/pte.h"
41#include "machine/psl.h"
42#include "machine/mtpr.h"
43
93422d4b
KM
44#ifdef HPUXCOMPAT
45#include "../hpux/hpux_exec.h"
46#endif
47
28db9b87
SL
48/*
49 * exec system call, with and without environments.
50 */
c9714ae3
KM
51execv(p, uap, retval)
52 struct proc *p;
53 struct args {
54 char *fname;
55 char **argp;
56 char **envp;
57 } *uap;
58 int *retval;
28db9b87 59{
c9714ae3
KM
60
61 uap->envp = NULL;
62 RETURN (execve(p, uap, retval));
28db9b87
SL
63}
64
c9714ae3
KM
65/* ARGSUSED */
66execve(p, uap, retval)
67 register struct proc *p;
68 register struct args {
69 char *fname;
70 char **argp;
71 char **envp;
72 } *uap;
73 int *retval;
28db9b87
SL
74{
75 register nc;
76 register char *cp;
77 register struct buf *bp;
c4ec2128 78 struct buf *tbp;
8011f5df
MK
79 int na, ne, ucp, ap, cc;
80 unsigned len;
28db9b87
SL
81 int indir, uid, gid;
82 char *sharg;
c4ec2128 83 struct vnode *vp;
28db9b87 84 swblk_t bno;
c4ec2128 85 struct vattr vattr;
28db9b87 86 char cfname[MAXCOMLEN + 1];
cb9392ae 87 char cfarg[MAXINTERP];
9fd50f35 88 union {
cb9392ae 89 char ex_shell[MAXINTERP]; /* #! and interpreter name */
9fd50f35 90 struct exec ex_exec;
93422d4b
KM
91#ifdef HPUXCOMPAT
92 struct hpux_exec ex_hexec;
93#endif
9fd50f35 94 } exdata;
93422d4b
KM
95#ifdef HPUXCOMPAT
96 struct hpux_exec hhead;
97#endif
c9714ae3 98 register struct ucred *cred = u.u_cred;
715baff1 99 register struct nameidata *ndp = &u.u_nd;
93422d4b 100 int resid, error, flags = 0;
ec67a3ce
MK
101#ifdef SECSIZE
102 extern long argdbsize; /* XXX */
103#endif SECSIZE
28db9b87 104
ba32f7c0 105 start:
c4ec2128 106 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
715baff1 107 ndp->ni_segflg = UIO_USERSPACE;
c9714ae3
KM
108 ndp->ni_dirp = uap->fname;
109 if (error = namei(ndp))
110 RETURN (error);
c4ec2128 111 vp = ndp->ni_vp;
28db9b87
SL
112 bno = 0;
113 bp = 0;
114 indir = 0;
c9714ae3
KM
115 uid = cred->cr_uid;
116 gid = cred->cr_gid;
117 if (error = VOP_GETATTR(vp, &vattr, cred))
c4ec2128 118 goto bad;
54fb9dc2 119 if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
c9714ae3 120 error = EACCES;
c4ec2128
KM
121 goto bad;
122 }
54fb9dc2 123 if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) {
c4ec2128
KM
124 if (vattr.va_mode & VSUID)
125 uid = vattr.va_uid;
126 if (vattr.va_mode & VSGID)
127 gid = vattr.va_gid;
128 }
28db9b87
SL
129
130 again:
c9714ae3 131 if (error = VOP_ACCESS(vp, VEXEC, cred))
28db9b87 132 goto bad;
c9714ae3 133 if ((p->p_flag & STRC) && (error = VOP_ACCESS(vp, VREAD, cred)))
28db9b87 134 goto bad;
c4ec2128
KM
135 if (vp->v_type != VREG ||
136 (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) {
c9714ae3 137 error = EACCES;
28db9b87
SL
138 goto bad;
139 }
140
141 /*
f3aaea26 142 * Read in first few bytes of file for segment sizes, magic number:
c4ec2128
KM
143 * OMAGIC = plain executable
144 * NMAGIC = RO text
145 * ZMAGIC = demand paged RO text
28db9b87
SL
146 * Also an ASCII line beginning with #! is
147 * the file name of a ``shell'' and arguments may be prepended
148 * to the argument list if given here.
149 *
150 * SHELL NAMES ARE LIMITED IN LENGTH.
151 *
152 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
153 * THE ASCII LINE.
154 */
9fd50f35 155 exdata.ex_shell[0] = '\0'; /* for zero length files */
c9714ae3
KM
156 error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata),
157 (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid);
158 if (error)
28db9b87 159 goto bad;
28db9b87 160#ifndef lint
ce66cb03 161 if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
9fd50f35 162 exdata.ex_shell[0] != '#') {
c9714ae3 163 error = ENOEXEC;
28db9b87
SL
164 goto bad;
165 }
93422d4b
KM
166#endif
167#if defined(hp300)
168 switch ((int)exdata.ex_exec.a_mid) {
169
170 /*
171 * An ancient hp200 or hp300 binary, shouldn't happen anymore.
172 * Mark as invalid.
173 */
174 case MID_ZERO:
175 exdata.ex_exec.a_magic = 0;
176 break;
177
178 /*
179 * HP200 series has a smaller page size so we cannot
180 * demand-load or even write protect text, so we just
181 * treat as OMAGIC.
182 */
183 case MID_HP200:
184 exdata.ex_exec.a_magic = OMAGIC;
185 break;
186
187 case MID_HP300:
188 break;
189
190#ifdef HPUXCOMPAT
191 case MID_HPUX:
192 /*
193 * Save a.out header. This is eventually saved in the pcb,
194 * but we cannot do that yet in case the exec fails before
195 * the image is overlayed.
196 */
197 bcopy((caddr_t)&exdata.ex_hexec,
198 (caddr_t)&hhead, sizeof hhead);
199 /*
200 * If version number is 0x2bad this is a native BSD
201 * binary created via the HPUX SGS. Should not be
202 * treated as an HPUX binary.
203 */
204 if (exdata.ex_hexec.ha_version != BSDVNUM)
205 flags |= SHPUX;
206 /*
207 * Shuffle important fields to their BSD locations.
208 * Note that the order in which this is done is important.
209 */
210 exdata.ex_exec.a_text = exdata.ex_hexec.ha_text;
211 exdata.ex_exec.a_data = exdata.ex_hexec.ha_data;
212 exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss;
213 exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry;
214 /*
215 * For ZMAGIC files, make sizes consistant with those
216 * generated by BSD ld.
217 */
218 if (exdata.ex_exec.a_magic == ZMAGIC) {
219 exdata.ex_exec.a_text =
220 ctob(btoc(exdata.ex_exec.a_text));
221 nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss;
222 exdata.ex_exec.a_data =
223 ctob(btoc(exdata.ex_exec.a_data));
224 nc -= (int)exdata.ex_exec.a_data;
225 exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc;
226 }
227 break;
228#endif
229 }
28db9b87 230#endif
aec7dd3b 231 switch ((int)exdata.ex_exec.a_magic) {
28db9b87 232
c4ec2128 233 case OMAGIC:
9fd50f35
SL
234 exdata.ex_exec.a_data += exdata.ex_exec.a_text;
235 exdata.ex_exec.a_text = 0;
28db9b87
SL
236 break;
237
c4ec2128 238 case ZMAGIC:
93422d4b 239 flags |= SPAGV;
c4ec2128 240 case NMAGIC:
9fd50f35 241 if (exdata.ex_exec.a_text == 0) {
c9714ae3 242 error = ENOEXEC;
28db9b87
SL
243 goto bad;
244 }
245 break;
246
247 default:
446115cb
MK
248 if (exdata.ex_shell[0] != '#' ||
249 exdata.ex_shell[1] != '!' ||
250 indir) {
c9714ae3 251 error = ENOEXEC;
28db9b87
SL
252 goto bad;
253 }
d26813a4 254 for (cp = &exdata.ex_shell[2];; ++cp) {
446115cb 255 if (cp >= &exdata.ex_shell[MAXINTERP]) {
c9714ae3 256 error = ENOEXEC;
d26813a4
KB
257 goto bad;
258 }
259 if (*cp == '\n') {
28db9b87
SL
260 *cp = '\0';
261 break;
262 }
d26813a4
KB
263 if (*cp == '\t')
264 *cp = ' ';
28db9b87 265 }
446115cb
MK
266 cp = &exdata.ex_shell[2];
267 while (*cp == ' ')
268 cp++;
715baff1 269 ndp->ni_dirp = cp;
446115cb
MK
270 while (*cp && *cp != ' ')
271 cp++;
e7db1101 272 cfarg[0] = '\0';
28db9b87 273 if (*cp) {
446115cb
MK
274 *cp++ = '\0';
275 while (*cp == ' ')
276 cp++;
ce66cb03 277 if (*cp)
cb9392ae 278 bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
e7db1101 279 }
446115cb 280 indir = 1;
c4ec2128
KM
281 vput(vp);
282 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
715baff1 283 ndp->ni_segflg = UIO_SYSSPACE;
c9714ae3
KM
284 if (error = namei(ndp))
285 RETURN (error);
c4ec2128 286 vp = ndp->ni_vp;
c9714ae3 287 if (error = VOP_GETATTR(vp, &vattr, cred))
c4ec2128 288 goto bad;
ce66cb03
MK
289 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
290 MAXCOMLEN);
291 cfname[MAXCOMLEN] = '\0';
c9714ae3
KM
292 uid = cred->cr_uid; /* shell scripts can't be setuid */
293 gid = cred->cr_gid;
28db9b87
SL
294 goto again;
295 }
ba32f7c0
KM
296 /*
297 * If the vnode has been modified since we last used it,
298 * then throw away all its pages and its text table entry.
299 */
300 if (vp->v_text && vp->v_text->x_mtime != vattr.va_mtime.tv_sec) {
301 /*
302 * Try once to release, if it is still busy
303 * take more drastic action.
304 */
305 xrele(vp);
306 if (vp->v_flag & VTEXT) {
307 vput(vp);
308 vgone(vp);
309 goto start;
310 }
311 }
28db9b87
SL
312
313 /*
314 * Collect arguments on "file" in swap space.
315 */
316 na = 0;
317 ne = 0;
318 nc = 0;
f3aaea26 319 cc = 0;
ec67a3ce
MK
320#ifdef SECSIZE
321 bno = rmalloc(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize);
322#else SECSIZE
9fd50f35 323 bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))));
ec67a3ce 324#endif SECSIZE
9fd50f35 325 if (bno == 0) {
c9714ae3 326 swkill(p, "exec: no swap space");
28db9b87
SL
327 goto bad;
328 }
329 if (bno % CLSIZE)
330 panic("execa rmalloc");
93422d4b
KM
331#ifdef GENERIC
332 if (rootdev == dumpdev)
333 bno += 4096;
334#endif
f3aaea26
SL
335 /*
336 * Copy arguments into file in argdev area.
337 */
28db9b87
SL
338 if (uap->argp) for (;;) {
339 ap = NULL;
ce66cb03
MK
340 sharg = NULL;
341 if (indir && na == 0) {
342 sharg = cfname;
343 ap = (int)sharg;
344 uap->argp++; /* ignore argv[0] */
345 } else if (indir && (na == 1 && cfarg[0])) {
346 sharg = cfarg;
347 ap = (int)sharg;
348 } else if (indir && (na == 1 || na == 2 && cfarg[0]))
28db9b87
SL
349 ap = (int)uap->fname;
350 else if (uap->argp) {
351 ap = fuword((caddr_t)uap->argp);
352 uap->argp++;
353 }
f3aaea26 354 if (ap == NULL && uap->envp) {
28db9b87 355 uap->argp = NULL;
f3aaea26
SL
356 if ((ap = fuword((caddr_t)uap->envp)) != NULL)
357 uap->envp++, ne++;
28db9b87
SL
358 }
359 if (ap == NULL)
360 break;
361 na++;
f3aaea26 362 if (ap == -1) {
c9714ae3 363 error = EFAULT;
93422d4b
KM
364 if (bp) {
365 brelse(bp);
366 bp = 0;
367 }
368 goto badarg;
f3aaea26 369 }
28db9b87 370 do {
f3aaea26
SL
371 if (cc <= 0) {
372 /*
373 * We depend on NCARGS being a multiple of
ec67a3ce 374 * CLBYTES. This way we need only check
f3aaea26
SL
375 * overflow before each buffer allocation.
376 */
377 if (nc >= NCARGS-1) {
378 error = E2BIG;
379 break;
380 }
28db9b87
SL
381 if (bp)
382 bdwrite(bp);
ec67a3ce
MK
383 cc = CLBYTES;
384#ifdef SECSIZE
385 bp = getblk(argdev, bno + nc / argdbsize, cc,
386 argdbsize);
387#else SECSIZE
c4ec2128 388 bp = getblk(argdev_vp, bno + ctod(nc/NBPG), cc);
ec67a3ce 389#endif SECSIZE
28db9b87
SL
390 cp = bp->b_un.b_addr;
391 }
ce66cb03 392 if (sharg) {
8011f5df 393 error = copystr(sharg, cp, (unsigned)cc, &len);
ce66cb03
MK
394 sharg += len;
395 } else {
8011f5df
MK
396 error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
397 &len);
ce66cb03
MK
398 ap += len;
399 }
f3aaea26
SL
400 cp += len;
401 nc += len;
402 cc -= len;
403 } while (error == ENOENT);
404 if (error) {
f3aaea26
SL
405 if (bp)
406 brelse(bp);
407 bp = 0;
408 goto badarg;
409 }
28db9b87
SL
410 }
411 if (bp)
412 bdwrite(bp);
413 bp = 0;
414 nc = (nc + NBPW-1) & ~(NBPW-1);
c9714ae3
KM
415 error = getxfile(p, vp, &exdata.ex_exec, flags, nc + (na+4)*NBPW,
416 uid, gid);
417 if (error) {
28db9b87 418badarg:
c4ec2128 419 for (cc = 0; cc < nc; cc += CLBYTES) {
2fd88d7d 420 (void) baddr(argdev_vp, bno + ctod(cc/NBPG),
9ad9d3f8 421 CLBYTES, NOCRED, &tbp);
c4ec2128 422 bp = tbp;
ec67a3ce 423#endif SECSIZE
28db9b87 424 if (bp) {
a4292a03 425 bp->b_flags |= B_INVAL; /* throw away */
28db9b87
SL
426 brelse(bp);
427 bp = 0;
428 }
429 }
430 goto bad;
431 }
ba32f7c0 432 vp->v_text->x_mtime = vattr.va_mtime.tv_sec;
c4ec2128
KM
433 vput(vp);
434 vp = NULL;
28db9b87 435
93422d4b
KM
436#ifdef HPUXCOMPAT
437 /*
438 * We are now committed to the exec so we can save the exec
439 * header in the pcb where we can dump it if necessary in core()
440 */
441 if (u.u_pcb.pcb_flags & PCB_HPUXBIN)
442 bcopy((caddr_t)&hhead,
443 (caddr_t)u.u_pcb.pcb_exec, sizeof hhead);
444#endif
445
28db9b87 446 /*
f3aaea26 447 * Copy back arglist.
28db9b87
SL
448 */
449 ucp = USRSTACK - nc - NBPW;
450 ap = ucp - na*NBPW - 3*NBPW;
451 u.u_ar0[SP] = ap;
452 (void) suword((caddr_t)ap, na-ne);
453 nc = 0;
72d4f41a 454 cc = 0;
28db9b87
SL
455 for (;;) {
456 ap += NBPW;
f3aaea26 457 if (na == ne) {
28db9b87
SL
458 (void) suword((caddr_t)ap, 0);
459 ap += NBPW;
460 }
461 if (--na < 0)
462 break;
463 (void) suword((caddr_t)ap, ucp);
464 do {
72d4f41a 465 if (cc <= 0) {
28db9b87
SL
466 if (bp)
467 brelse(bp);
ec67a3ce
MK
468 cc = CLBYTES;
469#ifdef SECSIZE
470 bp = bread(argdev, bno + nc / argdbsize, cc,
471 argdbsize);
472#else SECSIZE
c4ec2128 473 error = bread(argdev_vp,
9ad9d3f8
KM
474 (daddr_t)(bno + ctod(nc / NBPG)), cc,
475 NOCRED, &tbp);
c4ec2128 476 bp = tbp;
ec67a3ce 477#endif SECSIZE
a4292a03 478 bp->b_flags |= B_INVAL; /* throw away */
28db9b87
SL
479 cp = bp->b_un.b_addr;
480 }
8011f5df
MK
481 error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
482 &len);
72d4f41a
SL
483 ucp += len;
484 cp += len;
485 nc += len;
486 cc -= len;
487 } while (error == ENOENT);
488 if (error == EFAULT)
489 panic("exec: EFAULT");
28db9b87
SL
490 }
491 (void) suword((caddr_t)ap, 0);
ce66cb03 492
c9714ae3 493 execsigs(p);
ce66cb03
MK
494
495 for (nc = u.u_lastfile; nc >= 0; --nc) {
496 if (u.u_pofile[nc] & UF_EXCLOSE) {
69be5b7a 497 (void) closef(u.u_ofile[nc]);
ce66cb03
MK
498 u.u_ofile[nc] = NULL;
499 u.u_pofile[nc] = 0;
500 }
501 u.u_pofile[nc] &= ~UF_MAPPED;
502 }
503 while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL)
504 u.u_lastfile--;
9fd50f35 505 setregs(exdata.ex_exec.a_entry);
715baff1
KM
506 /*
507 * Remember file name for accounting.
508 */
509 u.u_acflag &= ~AFORK;
ce66cb03 510 if (indir)
c9714ae3 511 bcopy((caddr_t)cfname, (caddr_t)p->p_comm, MAXCOMLEN);
ce66cb03
MK
512 else {
513 if (ndp->ni_dent.d_namlen > MAXCOMLEN)
514 ndp->ni_dent.d_namlen = MAXCOMLEN;
c9714ae3 515 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)p->p_comm,
ce66cb03
MK
516 (unsigned)(ndp->ni_dent.d_namlen + 1));
517 }
28db9b87
SL
518bad:
519 if (bp)
520 brelse(bp);
521 if (bno)
ec67a3ce
MK
522#ifdef SECSIZE
523 rmfree(argmap, (clrnd((int)btoc(NCARGS))) * CLBYTES / argdbsize,
524 bno);
525#else SECSIZE
28db9b87 526 rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno);
ec67a3ce 527#endif SECSIZE
c4ec2128
KM
528 if (vp)
529 vput(vp);
c9714ae3 530 RETURN (error);
28db9b87
SL
531}
532
533/*
534 * Read in and set up memory for executed file.
535 */
c9714ae3
KM
536getxfile(p, vp, ep, flags, nargc, uid, gid)
537 register struct proc *p;
c4ec2128 538 register struct vnode *vp;
9fd50f35 539 register struct exec *ep;
93422d4b 540 int flags, nargc, uid, gid;
28db9b87 541{
e5b27ef1 542 segsz_t ts, ds, ids, uds, ss;
c9714ae3 543 register struct ucred *cred = u.u_cred;
93422d4b 544 off_t toff;
c9714ae3 545 int error;
28db9b87 546
93422d4b
KM
547#ifdef HPUXCOMPAT
548 if (ep->a_mid == MID_HPUX)
549 toff = sizeof (struct hpux_exec);
28db9b87 550 else
93422d4b
KM
551#endif
552 toff = sizeof (struct exec);
c9714ae3
KM
553 if (vp->v_text && (vp->v_text->x_flag & XTRC))
554 return (ETXTBSY);
c4ec2128 555 if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
c65056fe 556 vp->v_usecount != 1) {
28db9b87
SL
557 register struct file *fp;
558
559 for (fp = file; fp < fileNFILE; fp++) {
c4ec2128 560 if (fp->f_type == DTYPE_VNODE &&
28db9b87 561 fp->f_count > 0 &&
c4ec2128
KM
562 (struct vnode *)fp->f_data == vp &&
563 (fp->f_flag & FWRITE)) {
c9714ae3 564 return (ETXTBSY);
28db9b87
SL
565 }
566 }
567 }
568
569 /*
570 * Compute text and data sizes and make sure not too large.
0c48b03e
KM
571 * NB - Check data and bss separately as they may overflow
572 * when summed together.
28db9b87 573 */
9fd50f35 574 ts = clrnd(btoc(ep->a_text));
0c48b03e
KM
575 ids = clrnd(btoc(ep->a_data));
576 uds = clrnd(btoc(ep->a_bss));
f3aaea26 577 ds = clrnd(btoc(ep->a_data + ep->a_bss));
28db9b87 578 ss = clrnd(SSIZE + btoc(nargc));
c9714ae3
KM
579 if (error =
580 chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss))
581 return (error);
28db9b87
SL
582
583 /*
584 * Make sure enough space to start process.
585 */
586 u.u_cdmap = zdmap;
587 u.u_csmap = zdmap;
c9714ae3
KM
588 if (error = swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap))
589 return (error);
28db9b87
SL
590
591 /*
c4ec2128 592 * At this point, we are committed to the new image!
28db9b87
SL
593 * Release virtual memory resources of old process, and
594 * initialize the virtual memory of the new process.
595 * If we resulted from vfork(), instead wakeup our
596 * parent who will set SVFDONE when he has taken back
597 * our resources.
598 */
93422d4b
KM
599 if ((p->p_flag & SVFORK) == 0) {
600#ifdef MAPMEM
c9714ae3
KM
601 if (u.u_mmap && (error = mmexec(p)))
602 return (error);
93422d4b 603#endif
28db9b87 604 vrelvm();
93422d4b 605 } else {
ba7abd07
MK
606 p->p_flag &= ~SVFORK;
607 p->p_flag |= SKEEP;
608 wakeup((caddr_t)p);
609 while ((p->p_flag & SVFDONE) == 0)
610 sleep((caddr_t)p, PZERO - 1);
611 p->p_flag &= ~(SVFDONE|SKEEP);
28db9b87 612 }
93422d4b
KM
613#ifdef hp300
614 u.u_pcb.pcb_flags &= ~(PCB_AST|PCB_HPUXMMAP|PCB_HPUXBIN);
615#ifdef HPUXCOMPAT
616 /* remember that we were loaded from an HPUX format file */
617 if (ep->a_mid == MID_HPUX)
618 u.u_pcb.pcb_flags |= PCB_HPUXBIN;
619#endif
620#endif
621 p->p_flag &= ~(SPAGV|SSEQL|SUANOM|SHPUX);
622 p->p_flag |= flags | SEXEC;
28db9b87
SL
623 u.u_dmap = u.u_cdmap;
624 u.u_smap = u.u_csmap;
625 vgetvm(ts, ds, ss);
626
93422d4b 627 if ((flags & SPAGV) == 0)
c9714ae3 628 (void) vn_rdwr(UIO_READ, vp,
93422d4b 629 (char *)ctob(dptov(p, 0)),
9fd50f35 630 (int)ep->a_data,
93422d4b 631 (off_t)(toff + ep->a_text),
c4ec2128 632 UIO_USERSPACE, (IO_UNIT|IO_NODELOCKED), cred, (int *)0);
93422d4b 633 xalloc(vp, ep, toff, cred);
fb1db32c
MK
634#if defined(tahoe)
635 /*
636 * Define new keys.
637 */
ba7abd07
MK
638 if (p->p_textp == 0) { /* use existing code key if shared */
639 ckeyrelease(p->p_ckey);
640 p->p_ckey = getcodekey();
fb1db32c 641 }
ba7abd07
MK
642 mtpr(CCK, p->p_ckey);
643 dkeyrelease(p->p_dkey);
644 p->p_dkey = getdatakey();
645 mtpr(DCK, p->p_dkey);
fb1db32c 646#endif
93422d4b
KM
647 if ((flags & SPAGV) && p->p_textp)
648 vinifod(p, (struct fpte *)dptopte(p, 0),
ba7abd07 649 PG_FTEXT, p->p_textp->x_vptr,
e5b27ef1 650 (long)(1 + ts/CLSIZE), (segsz_t)btoc(ep->a_data));
28db9b87 651
fb1db32c 652#if defined(vax) || defined(tahoe)
28db9b87 653 /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
28db9b87
SL
654 mtpr(TBIA, 0);
655#endif
93422d4b
KM
656#ifdef hp300
657 TBIAU();
658#endif
28db9b87 659
28db9b87
SL
660 /*
661 * set SUID/SGID protections, if no tracing
662 */
ba7abd07 663 if ((p->p_flag&STRC)==0) {
c9714ae3
KM
664 if (uid != cred->cr_uid || gid != cred->cr_gid)
665 u.u_cred = cred = crcopy(cred);
666 cred->cr_uid = uid;
667 cred->cr_gid = gid;
ba7abd07 668 p->p_uid = uid;
28db9b87 669 } else
ba7abd07
MK
670 psignal(p, SIGTRAP);
671 p->p_svuid = p->p_uid;
c9714ae3 672 p->p_svgid = cred->cr_gid;
28db9b87
SL
673 u.u_tsize = ts;
674 u.u_dsize = ds;
675 u.u_ssize = ss;
d4a03a57 676 u.u_prof.pr_scale = 0;
fb1db32c
MK
677#if defined(tahoe)
678 u.u_pcb.pcb_savacc.faddr = (float *)NULL;
679#endif
c9714ae3 680 return (0);
28db9b87 681}