fix so it compiles
[unix-history] / usr / src / sys / kern / kern_exec.c
CommitLineData
8c0dbd1c
KB
1/*-
2 * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
3 * All rights reserved.
da7c5cc6 4 *
8c0dbd1c
KB
5 * %sccs.include.proprietary.c%
6 *
d59f854f 7 * @(#)kern_exec.c 7.53 (Berkeley) %G%
da7c5cc6 8 */
28db9b87 9
94368568
JB
10#include "param.h"
11#include "systm.h"
5e00df3b 12#include "filedesc.h"
94368568
JB
13#include "kernel.h"
14#include "proc.h"
c4ec2128 15#include "mount.h"
c4ec2128 16#include "malloc.h"
f254ddb7 17#include "namei.h"
c4ec2128 18#include "vnode.h"
94368568 19#include "file.h"
94368568
JB
20#include "acct.h"
21#include "exec.h"
7c9a1d1f 22#include "ktrace.h"
605f1ab4 23#include "resourcevar.h"
28db9b87 24
75a969a7 25#include "machine/cpu.h"
d301d150 26#include "machine/reg.h"
d301d150 27
9d4095a1 28#include "mman.h"
8429d022
MK
29#include "vm/vm.h"
30#include "vm/vm_param.h"
31#include "vm/vm_map.h"
32#include "vm/vm_kern.h"
33#include "vm/vm_pager.h"
9d4095a1 34
605f1ab4
MK
35#include "signalvar.h"
36#include "kinfo_proc.h"
605f1ab4 37
93422d4b 38#ifdef HPUXCOMPAT
75a969a7 39#include "user.h" /* for pcb */
90153171 40#include "hp300/hpux/hpux_exec.h"
93422d4b
KM
41#endif
42
75a969a7
MK
43#ifdef COPY_SIGCODE
44extern char sigcode[], esigcode[];
45#define szsigcode (esigcode - sigcode)
46#else
47#define szsigcode 0
48#endif
49
8429d022
MK
50/*
51 * exec system call
52 */
c9714ae3
KM
53/* ARGSUSED */
54execve(p, uap, retval)
55 register struct proc *p;
56 register struct args {
57 char *fname;
58 char **argp;
59 char **envp;
60 } *uap;
61 int *retval;
28db9b87 62{
8429d022 63 register struct ucred *cred = p->p_ucred;
5e00df3b 64 register struct filedesc *fdp = p->p_fd;
0a5745b2 65 int na, ne, ucp, ap, cc, ssize;
5e00df3b
KM
66 register char *cp;
67 register int nc;
8011f5df 68 unsigned len;
28db9b87
SL
69 int indir, uid, gid;
70 char *sharg;
c4ec2128 71 struct vnode *vp;
34dc7acb 72 int resid, error, paged = 0;
f0729cac 73 vm_offset_t execargs = 0;
c4ec2128 74 struct vattr vattr;
cb9392ae 75 char cfarg[MAXINTERP];
9fd50f35 76 union {
cb9392ae 77 char ex_shell[MAXINTERP]; /* #! and interpreter name */
9fd50f35 78 struct exec ex_exec;
93422d4b
KM
79#ifdef HPUXCOMPAT
80 struct hpux_exec ex_hexec;
81#endif
9fd50f35 82 } exdata;
93422d4b
KM
83#ifdef HPUXCOMPAT
84 struct hpux_exec hhead;
85#endif
8429d022 86 struct nameidata nd;
ec67a3ce
MK
87#ifdef SECSIZE
88 extern long argdbsize; /* XXX */
89#endif SECSIZE
28db9b87 90
62ce54a4
KM
91 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | SAVENAME, UIO_USERSPACE,
92 uap->fname, p);
93 if (error = namei(&nd))
d9c2f47f 94 return (error);
62ce54a4 95 vp = nd.ni_vp;
28db9b87 96 indir = 0;
c9714ae3
KM
97 uid = cred->cr_uid;
98 gid = cred->cr_gid;
f254ddb7 99 if (error = VOP_GETATTR(vp, &vattr, cred, p))
c4ec2128 100 goto bad;
54fb9dc2 101 if (vp->v_mount->mnt_flag & MNT_NOEXEC) {
c9714ae3 102 error = EACCES;
c4ec2128
KM
103 goto bad;
104 }
54fb9dc2 105 if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) {
c4ec2128
KM
106 if (vattr.va_mode & VSUID)
107 uid = vattr.va_uid;
108 if (vattr.va_mode & VSGID)
109 gid = vattr.va_gid;
110 }
28db9b87
SL
111
112 again:
f254ddb7 113 if (error = VOP_ACCESS(vp, VEXEC, cred, p))
28db9b87 114 goto bad;
f254ddb7 115 if ((p->p_flag & STRC) && (error = VOP_ACCESS(vp, VREAD, cred, p)))
28db9b87 116 goto bad;
c4ec2128
KM
117 if (vp->v_type != VREG ||
118 (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) {
c9714ae3 119 error = EACCES;
28db9b87
SL
120 goto bad;
121 }
122
123 /*
f3aaea26 124 * Read in first few bytes of file for segment sizes, magic number:
c4ec2128
KM
125 * OMAGIC = plain executable
126 * NMAGIC = RO text
127 * ZMAGIC = demand paged RO text
28db9b87
SL
128 * Also an ASCII line beginning with #! is
129 * the file name of a ``shell'' and arguments may be prepended
130 * to the argument list if given here.
131 *
132 * SHELL NAMES ARE LIMITED IN LENGTH.
133 *
134 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM
135 * THE ASCII LINE.
136 */
9fd50f35 137 exdata.ex_shell[0] = '\0'; /* for zero length files */
c9714ae3 138 error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata),
f254ddb7
KM
139 (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid,
140 (struct proc *)0);
c9714ae3 141 if (error)
28db9b87 142 goto bad;
28db9b87 143#ifndef lint
ce66cb03 144 if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) &&
9fd50f35 145 exdata.ex_shell[0] != '#') {
c9714ae3 146 error = ENOEXEC;
28db9b87
SL
147 goto bad;
148 }
93422d4b
KM
149#endif
150#if defined(hp300)
151 switch ((int)exdata.ex_exec.a_mid) {
152
153 /*
154 * An ancient hp200 or hp300 binary, shouldn't happen anymore.
155 * Mark as invalid.
156 */
157 case MID_ZERO:
158 exdata.ex_exec.a_magic = 0;
159 break;
160
161 /*
162 * HP200 series has a smaller page size so we cannot
163 * demand-load or even write protect text, so we just
164 * treat as OMAGIC.
165 */
166 case MID_HP200:
167 exdata.ex_exec.a_magic = OMAGIC;
168 break;
169
170 case MID_HP300:
171 break;
172
173#ifdef HPUXCOMPAT
174 case MID_HPUX:
175 /*
176 * Save a.out header. This is eventually saved in the pcb,
177 * but we cannot do that yet in case the exec fails before
178 * the image is overlayed.
179 */
180 bcopy((caddr_t)&exdata.ex_hexec,
181 (caddr_t)&hhead, sizeof hhead);
182 /*
183 * If version number is 0x2bad this is a native BSD
184 * binary created via the HPUX SGS. Should not be
185 * treated as an HPUX binary.
186 */
187 if (exdata.ex_hexec.ha_version != BSDVNUM)
34dc7acb 188 paged |= SHPUX; /* XXX */
93422d4b
KM
189 /*
190 * Shuffle important fields to their BSD locations.
191 * Note that the order in which this is done is important.
192 */
193 exdata.ex_exec.a_text = exdata.ex_hexec.ha_text;
194 exdata.ex_exec.a_data = exdata.ex_hexec.ha_data;
195 exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss;
196 exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry;
197 /*
198 * For ZMAGIC files, make sizes consistant with those
199 * generated by BSD ld.
200 */
201 if (exdata.ex_exec.a_magic == ZMAGIC) {
202 exdata.ex_exec.a_text =
203 ctob(btoc(exdata.ex_exec.a_text));
204 nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss;
205 exdata.ex_exec.a_data =
206 ctob(btoc(exdata.ex_exec.a_data));
207 nc -= (int)exdata.ex_exec.a_data;
208 exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc;
209 }
210 break;
211#endif
212 }
28db9b87 213#endif
aec7dd3b 214 switch ((int)exdata.ex_exec.a_magic) {
28db9b87 215
c4ec2128 216 case OMAGIC:
f0729cac
RC
217#ifdef COFF
218 if (exdata.ex_exec.ex_fhdr.magic != COFF_MAGIC) {
219 error = ENOEXEC;
220 goto bad;
221 }
0a5745b2
CT
222#endif
223#ifdef sparc
224 if (exdata.ex_exec.a_mid != MID_SUN_SPARC) {
225 error = ENOEXEC;
226 goto bad;
227 }
f0729cac 228#endif
9fd50f35
SL
229 exdata.ex_exec.a_data += exdata.ex_exec.a_text;
230 exdata.ex_exec.a_text = 0;
28db9b87
SL
231 break;
232
c4ec2128 233 case ZMAGIC:
d59f854f
KM
234#ifdef HPUXCOMPAT
235 paged |= 1; /* XXX fix me */
236#else
0a5745b2 237 paged = 1;
d59f854f 238#endif
34dc7acb 239 /* FALLTHROUGH */
0a5745b2 240
c4ec2128 241 case NMAGIC:
f0729cac
RC
242#ifdef COFF
243 if (exdata.ex_exec.ex_fhdr.magic != COFF_MAGIC) {
244 error = ENOEXEC;
245 goto bad;
246 }
0a5745b2
CT
247#endif
248#ifdef sparc
249 if (exdata.ex_exec.a_mid != MID_SUN_SPARC) {
250 error = ENOEXEC;
251 goto bad;
252 }
f0729cac 253#endif
9fd50f35 254 if (exdata.ex_exec.a_text == 0) {
c9714ae3 255 error = ENOEXEC;
28db9b87
SL
256 goto bad;
257 }
258 break;
259
260 default:
446115cb
MK
261 if (exdata.ex_shell[0] != '#' ||
262 exdata.ex_shell[1] != '!' ||
263 indir) {
c9714ae3 264 error = ENOEXEC;
28db9b87
SL
265 goto bad;
266 }
d26813a4 267 for (cp = &exdata.ex_shell[2];; ++cp) {
446115cb 268 if (cp >= &exdata.ex_shell[MAXINTERP]) {
c9714ae3 269 error = ENOEXEC;
d26813a4
KB
270 goto bad;
271 }
272 if (*cp == '\n') {
28db9b87
SL
273 *cp = '\0';
274 break;
275 }
d26813a4
KB
276 if (*cp == '\t')
277 *cp = ' ';
28db9b87 278 }
446115cb
MK
279 cp = &exdata.ex_shell[2];
280 while (*cp == ' ')
281 cp++;
62ce54a4 282 nd.ni_dirp = cp;
446115cb
MK
283 while (*cp && *cp != ' ')
284 cp++;
e7db1101 285 cfarg[0] = '\0';
28db9b87 286 if (*cp) {
446115cb
MK
287 *cp++ = '\0';
288 while (*cp == ' ')
289 cp++;
ce66cb03 290 if (*cp)
cb9392ae 291 bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP);
e7db1101 292 }
446115cb 293 indir = 1;
c4ec2128 294 vput(vp);
62ce54a4
KM
295 nd.ni_segflg = UIO_SYSSPACE;
296 if (error = namei(&nd))
d9c2f47f 297 return (error);
62ce54a4 298 vp = nd.ni_vp;
f254ddb7 299 if (error = VOP_GETATTR(vp, &vattr, cred, p))
c4ec2128 300 goto bad;
c9714ae3
KM
301 uid = cred->cr_uid; /* shell scripts can't be setuid */
302 gid = cred->cr_gid;
28db9b87
SL
303 goto again;
304 }
305
306 /*
307 * Collect arguments on "file" in swap space.
308 */
309 na = 0;
310 ne = 0;
311 nc = 0;
9d4095a1
KM
312 cc = NCARGS;
313 execargs = kmem_alloc_wait(exec_map, NCARGS);
f0729cac
RC
314#ifdef DIAGNOSTIC
315 if (execargs == (vm_offset_t)0)
316 panic("execve: kmem_alloc_wait");
317#endif
9d4095a1 318 cp = (char *) execargs;
f3aaea26
SL
319 /*
320 * Copy arguments into file in argdev area.
321 */
28db9b87
SL
322 if (uap->argp) for (;;) {
323 ap = NULL;
ce66cb03
MK
324 sharg = NULL;
325 if (indir && na == 0) {
62ce54a4 326 sharg = nd.ni_cnd.cn_nameptr;
ce66cb03
MK
327 ap = (int)sharg;
328 uap->argp++; /* ignore argv[0] */
329 } else if (indir && (na == 1 && cfarg[0])) {
330 sharg = cfarg;
331 ap = (int)sharg;
332 } else if (indir && (na == 1 || na == 2 && cfarg[0]))
28db9b87
SL
333 ap = (int)uap->fname;
334 else if (uap->argp) {
335 ap = fuword((caddr_t)uap->argp);
336 uap->argp++;
337 }
f3aaea26 338 if (ap == NULL && uap->envp) {
28db9b87 339 uap->argp = NULL;
f3aaea26
SL
340 if ((ap = fuword((caddr_t)uap->envp)) != NULL)
341 uap->envp++, ne++;
28db9b87
SL
342 }
343 if (ap == NULL)
344 break;
345 na++;
f3aaea26 346 if (ap == -1) {
c9714ae3 347 error = EFAULT;
9d4095a1 348 goto bad;
f3aaea26 349 }
28db9b87 350 do {
9d4095a1
KM
351 if (nc >= NCARGS-1) {
352 error = E2BIG;
353 break;
28db9b87 354 }
ce66cb03 355 if (sharg) {
8011f5df 356 error = copystr(sharg, cp, (unsigned)cc, &len);
ce66cb03
MK
357 sharg += len;
358 } else {
8011f5df
MK
359 error = copyinstr((caddr_t)ap, cp, (unsigned)cc,
360 &len);
ce66cb03
MK
361 ap += len;
362 }
f3aaea26
SL
363 cp += len;
364 nc += len;
365 cc -= len;
9e73a4eb 366 } while (error == ENAMETOOLONG);
9d4095a1
KM
367 if (error)
368 goto bad;
28db9b87 369 }
0a5745b2
CT
370
371 /*
372 * XXX the following is excessively bogus
373 *
374 * Compute initial process stack size and location of argc
375 * and character strings. `nc' is currently just the number
376 * of characters of arg and env strings.
377 *
378 * nc = size of signal code + 4 bytes of NULL pointer + nc,
379 * rounded to nearest integer;
380 * ucp = USRSTACK - nc; [user characters pointer]
381 * apsize = padding (if any) +
382 * 4 bytes of NULL pointer +
383 * ne 4-byte pointers to env strings +
384 * 4 bytes of NULL pointer +
385 * (na-ne) 4-byte pointers to arg strings +
386 * 4 bytes of argc;
387 * (this is the same as nc + (na+3)*4)
388 * ap = ucp - apsize; [user address of argc]
389 * ssize = ssize + nc + machine-dependent space;
390 */
391 nc = (szsigcode + 4 + nc + NBPW-1) & ~(NBPW - 1);
392#ifdef sparc
393 ucp = USRSTACK;
394 ssize = (nc + (na + 3) * NBPW + 7) & ~7;
395 ap = ucp - ssize;
396 ucp -= nc;
397 ssize += sizeof(struct rwindow);
398#else
399 ssize = (na + 3) * NBPW;
400 ucp = USRSTACK - nc;
401 ap = ucp - ssize;
402 ssize += nc;
403#endif
404 error = getxfile(p, vp, &exdata.ex_exec, paged, ssize, uid, gid);
9d4095a1 405 if (error)
28db9b87 406 goto bad;
c4ec2128
KM
407 vput(vp);
408 vp = NULL;
28db9b87 409
93422d4b
KM
410#ifdef HPUXCOMPAT
411 /*
412 * We are now committed to the exec so we can save the exec
413 * header in the pcb where we can dump it if necessary in core()
414 */
75a969a7 415 if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXBIN)
93422d4b 416 bcopy((caddr_t)&hhead,
75a969a7 417 (caddr_t)p->p_addr->u_pcb.pcb_exec, sizeof hhead);
93422d4b
KM
418#endif
419
28db9b87 420 /*
f3aaea26 421 * Copy back arglist.
28db9b87 422 */
09936ccc 423 cpu_setstack(p, ap);
28db9b87
SL
424 (void) suword((caddr_t)ap, na-ne);
425 nc = 0;
9d4095a1
KM
426 cp = (char *) execargs;
427 cc = NCARGS;
28db9b87
SL
428 for (;;) {
429 ap += NBPW;
f3aaea26 430 if (na == ne) {
28db9b87
SL
431 (void) suword((caddr_t)ap, 0);
432 ap += NBPW;
433 }
434 if (--na < 0)
435 break;
436 (void) suword((caddr_t)ap, ucp);
437 do {
8011f5df
MK
438 error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc,
439 &len);
72d4f41a
SL
440 ucp += len;
441 cp += len;
442 nc += len;
443 cc -= len;
9e73a4eb 444 } while (error == ENAMETOOLONG);
72d4f41a
SL
445 if (error == EFAULT)
446 panic("exec: EFAULT");
28db9b87
SL
447 }
448 (void) suword((caddr_t)ap, 0);
ce66cb03 449
c9714ae3 450 execsigs(p);
ce66cb03 451
5e00df3b 452 for (nc = fdp->fd_lastfile; nc >= 0; --nc) {
605f1ab4
MK
453 if (fdp->fd_ofileflags[nc] & UF_EXCLOSE) {
454 (void) closef(fdp->fd_ofiles[nc], p);
455 fdp->fd_ofiles[nc] = NULL;
456 fdp->fd_ofileflags[nc] = 0;
8429d022
MK
457 if (nc < fdp->fd_freefile)
458 fdp->fd_freefile = nc;
ce66cb03 459 }
605f1ab4 460 fdp->fd_ofileflags[nc] &= ~UF_MAPPED;
ce66cb03 461 }
605f1ab4
MK
462 /*
463 * Adjust fd_lastfile to account for descriptors closed above.
464 * Don't decrement fd_lastfile past 0, as it's unsigned.
465 */
466 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
5e00df3b 467 fdp->fd_lastfile--;
54955369 468 setregs(p, exdata.ex_exec.a_entry, retval);
75a969a7 469#ifdef COPY_SIGCODE
9d4095a1
KM
470 /*
471 * Install sigcode at top of user stack.
472 */
75a969a7
MK
473 copyout((caddr_t)sigcode, (caddr_t)(USRSTACK - szsigcode), szsigcode);
474#endif
715baff1
KM
475 /*
476 * Remember file name for accounting.
477 */
8429d022 478 p->p_acflag &= ~AFORK;
62ce54a4
KM
479 if (nd.ni_cnd.cn_namelen > MAXCOMLEN)
480 nd.ni_cnd.cn_namelen = MAXCOMLEN;
481 bcopy((caddr_t)nd.ni_cnd.cn_nameptr, (caddr_t)p->p_comm,
0a5745b2 482 (unsigned)nd.ni_cnd.cn_namelen);
62ce54a4 483 p->p_comm[nd.ni_cnd.cn_namelen] = '\0';
75a969a7 484 cpu_exec(p);
28db9b87 485bad:
62ce54a4 486 FREE(nd.ni_cnd.cn_pnbuf, M_NAMEI);
9d4095a1
KM
487 if (execargs)
488 kmem_free_wakeup(exec_map, execargs, NCARGS);
ec67a3ce 489#endif SECSIZE
c4ec2128
KM
490 if (vp)
491 vput(vp);
d9c2f47f 492 return (error);
28db9b87
SL
493}
494
495/*
496 * Read in and set up memory for executed file.
497 */
0a5745b2 498getxfile(p, vp, ep, paged, ssize, uid, gid)
c9714ae3 499 register struct proc *p;
c4ec2128 500 register struct vnode *vp;
9fd50f35 501 register struct exec *ep;
0a5745b2 502 int paged, ssize, uid, gid;
28db9b87 503{
8429d022 504 register struct ucred *cred = p->p_ucred;
0a5745b2
CT
505 register struct vmspace *vm = p->p_vmspace;
506 vm_offset_t addr;
507 vm_size_t xts, size;
508 segsz_t ds;
93422d4b 509 off_t toff;
9d4095a1 510 int error = 0;
28db9b87 511
93422d4b 512#ifdef HPUXCOMPAT
34dc7acb
MK
513 int hpux = (paged & SHPUX);
514 paged &= ~SHPUX;
d59f854f
KM
515 if (ep->a_mid == MID_HPUX)
516 toff = paged ? CLBYTES : sizeof(struct hpux_exec);
517 else
93422d4b 518#endif
f0729cac
RC
519#ifdef COFF
520 toff = N_TXTOFF(*ep);
521#else
0a5745b2
CT
522#ifdef sparc
523 if (ep->a_mid == MID_SUN_SPARC)
524 toff = paged ? 0 : sizeof(struct exec);
525 else
526#endif
34dc7acb 527 if (paged)
9d4095a1
KM
528 toff = CLBYTES;
529 else
530 toff = sizeof (struct exec);
f0729cac 531#endif
c4ec2128 532 if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 &&
82177e7b
KM
533 vp->v_writecount != 0)
534 return (ETXTBSY);
28db9b87
SL
535
536 /*
537 * Compute text and data sizes and make sure not too large.
0a5745b2
CT
538 * Text size is rounded to an ``ld page''; data+bss is left
539 * in machine pages. Check data and bss separately as they
540 * may overflow when summed together. (XXX not done yet)
28db9b87 541 */
0a5745b2 542 xts = roundup(ep->a_text, __LDPGSZ);
f3aaea26 543 ds = clrnd(btoc(ep->a_data + ep->a_bss));
605f1ab4
MK
544
545 /*
546 * If we're sharing the address space, allocate a new space
547 * and release our reference to the old one. Otherwise,
548 * empty out the existing vmspace.
549 */
0a5745b2
CT
550#ifdef sparc
551 kill_user_windows(p); /* before addrs go away */
552#endif
605f1ab4 553 if (vm->vm_refcnt > 1) {
54955369
WN
554 p->p_vmspace = vmspace_alloc(VM_MIN_ADDRESS,
555 VM_MAXUSER_ADDRESS, 1);
605f1ab4
MK
556 vmspace_free(vm);
557 vm = p->p_vmspace;
558 } else {
9d4095a1 559#ifdef SYSVSHM
605f1ab4
MK
560 if (vm->vm_shm)
561 shmexit(p);
9d4095a1 562#endif
54955369
WN
563 (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS,
564 VM_MAXUSER_ADDRESS);
605f1ab4 565 }
28db9b87 566 /*
8429d022
MK
567 * If parent is waiting for us to exec or exit,
568 * SPPWAIT will be set; clear it and wakeup parent.
28db9b87 569 */
8429d022
MK
570 if (p->p_flag & SPPWAIT) {
571 p->p_flag &= ~SPPWAIT;
572 wakeup((caddr_t) p->p_pptr);
28db9b87 573 }
93422d4b 574#ifdef HPUXCOMPAT
75a969a7 575 p->p_addr->u_pcb.pcb_flags &= ~(PCB_HPUXMMAP|PCB_HPUXBIN);
93422d4b
KM
576 /* remember that we were loaded from an HPUX format file */
577 if (ep->a_mid == MID_HPUX)
75a969a7 578 p->p_addr->u_pcb.pcb_flags |= PCB_HPUXBIN;
34dc7acb
MK
579 if (hpux)
580 p->p_flag |= SHPUX;
581 else
582 p->p_flag &= ~SHPUX;
f0729cac
RC
583#endif
584#ifdef ULTRIXCOMPAT
585 /*
586 * Always start out as an ULTRIX process.
587 * A system call in crt0.o will change us to BSD system calls later.
588 */
589 p->p_md.md_flags |= MDP_ULTRIX;
93422d4b 590#endif
34dc7acb 591 p->p_flag |= SEXEC;
f0729cac 592#ifndef COFF
9d4095a1 593 addr = VM_MIN_ADDRESS;
0a5745b2 594 if (vm_allocate(&vm->vm_map, &addr, xts + ctob(ds), FALSE)) {
9d4095a1
KM
595 uprintf("Cannot allocate text+data space\n");
596 error = ENOMEM; /* XXX */
597 goto badmap;
598 }
f0729cac 599 vm->vm_taddr = (caddr_t)VM_MIN_ADDRESS;
0a5745b2 600 vm->vm_daddr = (caddr_t)(VM_MIN_ADDRESS + xts);
f0729cac
RC
601#else /* COFF */
602 addr = (vm_offset_t)ep->ex_aout.codeStart;
603 vm->vm_taddr = (caddr_t)addr;
0a5745b2 604 if (vm_allocate(&vm->vm_map, &addr, xts, FALSE)) {
f0729cac
RC
605 uprintf("Cannot allocate text space\n");
606 error = ENOMEM; /* XXX */
607 goto badmap;
608 }
609 addr = (vm_offset_t)ep->ex_aout.heapStart;
610 vm->vm_daddr = (caddr_t)addr;
611 if (vm_allocate(&vm->vm_map, &addr, round_page(ctob(ds)), FALSE)) {
612 uprintf("Cannot allocate data space\n");
613 error = ENOMEM; /* XXX */
614 goto badmap;
615 }
616#endif /* COFF */
9d4095a1 617 size = round_page(MAXSSIZ); /* XXX */
4021f565
WN
618#ifdef i386
619 addr = trunc_page(USRSTACK - size) - NBPG; /* XXX */
620#else
54955369 621 addr = trunc_page(USRSTACK - size);
4021f565 622#endif
8429d022 623 if (vm_allocate(&vm->vm_map, &addr, size, FALSE)) {
9d4095a1
KM
624 uprintf("Cannot allocate stack space\n");
625 error = ENOMEM; /* XXX */
626 goto badmap;
627 }
54955369
WN
628 size -= round_page(p->p_rlimit[RLIMIT_STACK].rlim_cur);
629 if (vm_map_protect(&vm->vm_map, addr, addr+size, VM_PROT_NONE, FALSE)) {
630 uprintf("Cannot protect stack space\n");
631 error = ENOMEM;
632 goto badmap;
633 }
8429d022 634 vm->vm_maxsaddr = (caddr_t)addr;
28db9b87 635
34dc7acb 636 if (paged == 0) {
605f1ab4
MK
637 /*
638 * Read in data segment.
639 */
8429d022
MK
640 (void) vn_rdwr(UIO_READ, vp, vm->vm_daddr, (int) ep->a_data,
641 (off_t)(toff + ep->a_text), UIO_USERSPACE,
f254ddb7 642 (IO_UNIT|IO_NODELOCKED), cred, (int *)0, p);
605f1ab4
MK
643 /*
644 * Read in text segment if necessary (0410),
645 * and read-protect it.
646 */
9d4095a1 647 if (ep->a_text > 0) {
8429d022
MK
648 error = vn_rdwr(UIO_READ, vp, vm->vm_taddr,
649 (int)ep->a_text, toff, UIO_USERSPACE,
f254ddb7 650 (IO_UNIT|IO_NODELOCKED), cred, (int *)0, p);
f0729cac
RC
651 (void) vm_map_protect(&vm->vm_map, vm->vm_taddr,
652 vm->vm_taddr + trunc_page(ep->a_text),
8429d022 653 VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
9d4095a1
KM
654 }
655 } else {
656 /*
657 * Allocate a region backed by the exec'ed vnode.
658 */
f0729cac 659#ifndef COFF
9d4095a1 660 addr = VM_MIN_ADDRESS;
0a5745b2 661 size = round_page(xts + ep->a_data);
8429d022
MK
662 error = vm_mmap(&vm->vm_map, &addr, size, VM_PROT_ALL,
663 MAP_FILE|MAP_COPY|MAP_FIXED,
664 (caddr_t)vp, (vm_offset_t)toff);
0a5745b2 665 (void) vm_map_protect(&vm->vm_map, addr, addr + xts,
8429d022 666 VM_PROT_READ|VM_PROT_EXECUTE, FALSE);
f0729cac
RC
667#else /* COFF */
668 addr = (vm_offset_t)vm->vm_taddr;
0a5745b2 669 size = xts;
f0729cac
RC
670 error = vm_mmap(&vm->vm_map, &addr, size,
671 VM_PROT_READ|VM_PROT_EXECUTE,
672 MAP_FILE|MAP_COPY|MAP_FIXED,
673 (caddr_t)vp, (vm_offset_t)toff);
674 toff += size;
675 addr = (vm_offset_t)vm->vm_daddr;
676 size = round_page(ep->a_data);
677 error = vm_mmap(&vm->vm_map, &addr, size, VM_PROT_ALL,
678 MAP_FILE|MAP_COPY|MAP_FIXED,
679 (caddr_t)vp, (vm_offset_t)toff);
680#endif /* COFF */
605f1ab4 681 vp->v_flag |= VTEXT;
9d4095a1 682 }
9d4095a1 683 if (error) {
0a5745b2 684badmap:
9d4095a1
KM
685 printf("pid %d: VM allocation failure\n", p->p_pid);
686 uprintf("sorry, pid %d was killed in exec: VM allocation\n",
687 p->p_pid);
688 psignal(p, SIGKILL);
34dc7acb 689 p->p_flag |= SKEEP;
9d4095a1 690 return(error);
fb1db32c 691 }
28db9b87 692
28db9b87
SL
693 /*
694 * set SUID/SGID protections, if no tracing
695 */
ba7abd07 696 if ((p->p_flag&STRC)==0) {
7c9a1d1f 697 if (uid != cred->cr_uid || gid != cred->cr_gid) {
8429d022 698 p->p_ucred = cred = crcopy(cred);
7c9a1d1f
MT
699 /*
700 * If process is being ktraced, turn off - unless
701 * root set it.
702 */
703 if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {
704 vrele(p->p_tracep);
705 p->p_tracep = NULL;
706 p->p_traceflag = 0;
707 }
0a5745b2
CT
708 cred->cr_uid = uid;
709 cred->cr_gid = gid;
7c9a1d1f 710 }
28db9b87 711 } else
ba7abd07 712 psignal(p, SIGTRAP);
8429d022
MK
713 p->p_cred->p_svuid = cred->cr_uid;
714 p->p_cred->p_svgid = cred->cr_gid;
0a5745b2 715 vm->vm_tsize = btoc(xts);
8429d022 716 vm->vm_dsize = ds;
0a5745b2 717 vm->vm_ssize = ssize;
8429d022 718 p->p_stats->p_prof.pr_scale = 0;
fb1db32c 719#if defined(tahoe)
75a969a7
MK
720 /* move this when tahoe cpu_exec is created */
721 p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL;
fb1db32c 722#endif
c9714ae3 723 return (0);
28db9b87 724}