- register sep;
- register size_t ts, ds, ss;
- register int overlay;
- int pagi = 0;
-
- /*
- * read in first few bytes
- * of file for segment
- * sizes:
- * ux_mag = 407/410/411/405
- * 407 is plain executable
- * 410 is RO text
- * 411 is separated ID
- * 405 is overlaid text
- * 412 is demand paged plain executable (NOT IMPLEMENTED)
- * 413 is demand paged RO text
- */
-
- u.u_base = (caddr_t)&u.u_exdata;
- u.u_count = sizeof(u.u_exdata);
- u.u_offset = 0;
- u.u_segflg = 1;
- readi(ip);
- u.u_segflg = 0;
- if(u.u_error)
- goto bad;
- if (u.u_count!=0) {
- u.u_error = ENOEXEC;
- goto bad;
- }
- sep = 0;
- overlay = 0;
- switch (u.u_exdata.ux_mag) {
-
- case 0405:
- overlay++;
- break;
-
- case 0412:
- u.u_error = ENOEXEC;
- goto bad;
-
- case 0407:
- u.u_exdata.ux_dsize += u.u_exdata.ux_tsize;
- u.u_exdata.ux_tsize = 0;
- break;
-
- case 0413:
- pagi = SPAGI;
- /* fall into ... */
-
- case 0410:
- if (u.u_exdata.ux_tsize == 0) {
- u.u_error = ENOEXEC;
- goto bad;
- }
- break;
-
- case 0411:
- u.u_error = ENOEXEC;
- goto bad;
-
- default:
- u.u_error = ENOEXEC;
- goto bad;
- }
- if(u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) {
- u.u_error = ETXTBSY;
- goto bad;
- }
-
- /*
- * find text and data sizes
- * try them out for possible
- * exceed of max sizes
- */
-
- ts = clrnd(btoc(u.u_exdata.ux_tsize));
- ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize)));
- ss = clrnd(SSIZE + btoc(nargc));
- if (overlay) {
- if ((u.u_procp->p_flag & SPAGI) || u.u_sep==0 && ctos(ts) != ctos(u.u_tsize) || nargc) {
- u.u_error = ENOMEM;
- goto bad;
- }
- ds = u.u_dsize;
- ss = u.u_ssize;
- sep = u.u_sep;
- xfree();
- xalloc(ip, pagi);
- u.u_ar0[PC] = u.u_exdata.ux_entloc + 2; /* skip over entry mask */
- } else {
- if (chksize(ts, ds, ss))
- goto bad;
- u.u_cdmap = zdmap;
- u.u_csmap = zdmap;
- if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL)
- goto bad;
-
- /*
- * At this point, committed to the new image!
- * Release virtual memory resources of old process, and
- * initialize the virtual memory of the new process.
- * If we resulted from vfork(), instead wakeup our
- * parent who will set SVFDONE when he has taken back
- * our resources.
- */
- u.u_prof.pr_scale = 0;
- if ((u.u_procp->p_flag & SVFORK) == 0)
- vrelvm();
- else {
- u.u_procp->p_flag &= ~SVFORK;
- u.u_procp->p_flag |= SKEEP;
- wakeup((caddr_t)u.u_procp);
- while ((u.u_procp->p_flag & SVFDONE) == 0)
- sleep((caddr_t)u.u_procp, PZERO - 1);
- u.u_procp->p_flag &= ~(SVFDONE|SKEEP);
- }
- u.u_procp->p_flag &= ~(SPAGI|SANOM|SUANOM);
- u.u_procp->p_flag |= pagi;
- u.u_dmap = u.u_cdmap;
- u.u_smap = u.u_csmap;
- vgetvm(ts, ds, ss);
-
- if (pagi == 0) {
- /*
- * Read in data segment.
- */
- u.u_base = (char *)ctob(ts);
- u.u_offset = sizeof(u.u_exdata)+u.u_exdata.ux_tsize;
- u.u_count = u.u_exdata.ux_dsize;
- readi(ip);
- }
- xalloc(ip, pagi);
- if (pagi && u.u_procp->p_textp)
- vinifod((struct fpte *)dptopte(u.u_procp, 0),
- PG_FTEXT, u.u_procp->p_textp->x_iptr,
- 1 + ts/CLSIZE, (int)btoc(u.u_exdata.ux_dsize));
-
- /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */
- mtpr(TBIA,1);