|
|
1.1 ! root 1: /* ! 2: * coh.386/exec.c ! 3: * ! 4: * The exec() system call. ! 5: * ! 6: * Revised: Fri Jun 4 10:41:40 1993 CDT ! 7: */ ! 8: #include <sys/coherent.h> ! 9: #include <sys/acct.h> ! 10: #include <sys/buf.h> ! 11: #include <canon.h> ! 12: #include <sys/con.h> ! 13: #include <errno.h> ! 14: #include <fcntl.h> ! 15: #include <sys/filsys.h> ! 16: #include <sys/ino.h> ! 17: #include <sys/inode.h> ! 18: #include <a.out.h> ! 19: #include <l.out.h> ! 20: #include <sys/proc.h> ! 21: #include <sys/sched.h> ! 22: #include <sys/seg.h> ! 23: #include <signal.h> ! 24: #include <sys/reg.h> ! 25: #include <sys/stat.h> ! 26: #include <sys/fd.h> ! 27: ! 28: /* ! 29: * Round section and segment start address to nearest lower click boundary. ! 30: */ ! 31: static void ! 32: xecrnd(xsp) ! 33: struct xecseg * xsp; ! 34: { ! 35: int diff; ! 36: ! 37: diff = xsp->fbase & (NBPC-1); ! 38: xsp->mbase -= diff; ! 39: xsp->fbase -= diff; ! 40: xsp->size += diff; ! 41: } ! 42: ! 43: /* ! 44: * Pass control to an image in a file. ! 45: * Make sure the format is acceptable. Release ! 46: * the old segments. Read in the new ones. Some special ! 47: * care is taken so that shared and (more important) shared ! 48: * and separated images can be run on the 8086. ! 49: */ ! 50: pexece(np, argp, envp) ! 51: char *np; ! 52: char *argp[]; ! 53: char *envp[]; ! 54: { ! 55: struct xechdr head; ! 56: register INODE *ip; /* Load file INODE */ ! 57: register PROC *pp; /* A cheap copy of SELF */ ! 58: register SEG *segp; ! 59: SEG *ssegp; ! 60: register int i; /* For looping over segments*/ ! 61: int roundup; ! 62: int shrdsize; ! 63: struct xecnode * xlist = NULL; /* list head */ ! 64: struct xecnode * xp; ! 65: struct xecseg tempseg; ! 66: unsigned int textSize; ! 67: ! 68: pp = SELF; ! 69: kclear(&head, sizeof(head)); ! 70: if ((ip=exlopen(&head, np, &shrdsize, &xlist)) == NULL) { ! 71: goto done; ! 72: } ! 73: ! 74: roundup = (shrdsize) & 0xf; ! 75: ssegp = exstack(&head,argp, envp, wdsize()); ! 76: ! 77: if (!ssegp) { ! 78: idetach(ip); ! 79: goto done; ! 80: } ! 81: ! 82: /* Release shared memory. */ ! 83: shmAllDt(); ! 84: ! 85: /* ! 86: * At this point the file has been ! 87: * validated as an object module, and the ! 88: * argument list has been built. Release all of ! 89: * the original segments. At this point we have ! 90: * committed to the new image. A "sys exec" that ! 91: * gets an I/O error is doomed. ! 92: * NOTE: User-area segment is NOT released. ! 93: * Segment pointer in proc is erased BEFORE invoking sfree(). ! 94: */ ! 95: for (i = 1; i < NUSEG; ++i) { ! 96: if ((segp = pp->p_segp[i])) { ! 97: pp->p_segp[i] = NULL; ! 98: sfree(segp); ! 99: } ! 100: } ! 101: pp->p_segp[SISTACK] = ssegp; ! 102: ! 103: /* ! 104: * Read in the loadable segments. ! 105: */ ! 106: switch (head.magic) { ! 107: case XMAGIC(I286MAGIC,I_MAGIC): ! 108: u.u_regl[CS] = SEG_286_UII | R_USR; ! 109: u.u_regl[DS] = SEG_286_UD | R_USR; ! 110: ! 111: if ((segp = ssalloc(ip,SFTEXT, head.segs[SISTEXT].size)) ! 112: == NULL) ! 113: goto out; ! 114: pp->p_segp[SISTEXT] = segp; ! 115: ! 116: if (!exsread(segp, ip, &head.segs[SISTEXT], 0)) ! 117: goto out; ! 118: ! 119: if ((segp = ssalloc(ip, 0, roundup + head.segs[SIPDATA].size ! 120: + head.segs[SIBSS].size)) == NULL) ! 121: goto out; ! 122: pp->p_segp[SIPDATA] = segp; ! 123: ! 124: if (!exsread(segp, ip, &head.segs[SIPDATA], shrdsize)) { ! 125: goto out; ! 126: } ! 127: head.segs[SIPDATA].size += roundup; ! 128: break; ! 129: case XMAGIC(I386MAGIC,Z_MAGIC): ! 130: u.u_regl[CS] = SEG_386_UI | R_USR; ! 131: u.u_regl[DS] = SEG_386_UD | R_USR; ! 132: ! 133: /* ! 134: * Round segment address down to nearest click boundary. ! 135: * Ciaran did this. I'm not sure why, but will preserve ! 136: * it for now. -hws- ! 137: */ ! 138: tempseg = head.segs[SISTEXT]; /* save pre-rounding value */ ! 139: xecrnd(head.segs + SISTEXT); ! 140: xecrnd(head.segs + SIPDATA); ! 141: ! 142: /* ! 143: * Compute text segment size by taking highest address ! 144: * seen in any text section. ! 145: */ ! 146: textSize = head.segs[SISTEXT].size + head.segs[SISTEXT].mbase; ! 147: for (xp = xlist; xp; xp = xp->xn) { ! 148: unsigned int tmpSize; ! 149: if (xp->segtype != SISTEXT) ! 150: continue; ! 151: tmpSize = xp->xseg.size + xp->xseg.mbase; ! 152: if (tmpSize > textSize) ! 153: textSize = tmpSize; ! 154: } ! 155: ! 156: /* Entry point must be within text segment. */ ! 157: if (head.entry >= textSize) { ! 158: goto out; ! 159: } ! 160: ! 161: if ((segp = ssalloc(ip, SFTEXT|SFSHRX, textSize)) ! 162: == NULL) ! 163: goto out; ! 164: pp->p_segp[SISTEXT] = segp; ! 165: ! 166: if (segp->s_ip==0) { ! 167: if (!exsread(segp, ip, &tempseg, 0)) { ! 168: goto out; ! 169: } ! 170: /* load additional text sections, if any */ ! 171: for (xp = xlist; xp; xp = xp->xn) { ! 172: if (xp->segtype != SISTEXT) ! 173: continue; ! 174: if (!exsread(segp, ip, &xlist->xseg, 0)) { ! 175: goto out; ! 176: } ! 177: } ! 178: ! 179: segp->s_ip = ip; ! 180: ip->i_refc++; ! 181: } ! 182: if ((segp = ssalloc(ip, 0, ! 183: head.segs[SIPDATA].size+head.segs[SIBSS].size)) == NULL) ! 184: goto out; ! 185: pp->p_segp[SIPDATA] = segp; ! 186: if (segp->s_ip==0 && ! 187: !exsread(segp, ip, &head.segs[SIPDATA], 0)) { ! 188: goto out; ! 189: } ! 190: ! 191: /* Deallocate nodes hooked into xlist by exlopen. */ ! 192: while (xlist) { ! 193: struct xecnode * tmp = xlist->xn; ! 194: kfree(xlist); ! 195: xlist = tmp; ! 196: } ! 197: break; ! 198: default: ! 199: panic("pexece"); ! 200: } ! 201: ! 202: u.u_regl[SS] = u.u_regl[ES] = u.u_regl[DS]; ! 203: if (sproto(&head) == 0) { ! 204: goto out; ! 205: } ! 206: ! 207: /* ! 208: * The new image is read in ! 209: * and mapped. Perform the final grunge ! 210: * (set-uid stuff, accounting, loading up ! 211: * registers, etc). ! 212: */ ! 213: u.u_flag &= ~AFORK; ! 214: kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm)); ! 215: if (iaccess(ip, IPR) == 0) { /* Can't read ? no dump or trace */ ! 216: pp->p_flags |= PFNDMP; ! 217: pp->p_flags &= ~PFTRAC; ! 218: } ! 219: ! 220: /* ! 221: * Norm says Frank says we need to drop this for db to work. ! 222: */ ! 223: #if 0 ! 224: if (iaccess(ip, IPW) == 0) { /* Can't write ? no trace */ ! 225: pp->p_flags &= ~PFTRAC; ! 226: printf("Can't write - no trace! "); ! 227: u.u_error = 0; ! 228: } ! 229: #endif ! 230: ! 231: if ((ip->i_mode&ISUID) != 0) { /* Set user id ? no trace */ ! 232: pp->p_uid = u.u_uid = u.u_euid = ip->i_uid; ! 233: pp->p_flags &= ~PFTRAC; ! 234: } ! 235: ! 236: if ((ip->i_mode&ISGID) != 0) { /* Set group id ? no trace */ ! 237: u.u_egid = u.u_gid = ip->i_gid; ! 238: pp->p_flags &= ~PFTRAC; ! 239: } ! 240: ! 241: for (i=0; i < NOFILE; i++) { ! 242: if (u.u_filep[i]!=NULL && (u.u_filep[i]->f_flag2&FD_CLOEXEC)) { ! 243: fdclose(i); /* close fd on exec bit set */ ! 244: } ! 245: } ! 246: ! 247: /* ! 248: * Default every signal that is not ignored. ! 249: */ ! 250: for (i = 1; i <= NSIG; ++i) { ! 251: if (u.u_sfunc[i - 1] != SIG_IGN) { ! 252: u.u_sfunc[i - 1] = SIG_DFL; ! 253: pp->p_dfsig |= SIG_BIT(i); ! 254: } ! 255: } ! 256: ! 257: if (pp->p_flags&PFTRAC) /* Being traced */ ! 258: sendsig(SIGTRAP, pp); ! 259: idetach(ip); ! 260: msetusr(head.entry, head.initsp); ! 261: ! 262: /* initialize u area ndp fields */ ! 263: ndpNewProc(); ! 264: ! 265: segload(); ! 266: goto done; ! 267: ! 268: /* ! 269: * Alas, exec() has failed.. ! 270: */ ! 271: out: ! 272: /* Deallocate nodes hooked into xlist by exlopen. */ ! 273: while (xlist) { ! 274: struct xecnode * tmp = xlist->xn; ! 275: kfree(xlist); ! 276: xlist = tmp; ! 277: } ! 278: ! 279: /* Release the INODE for the load file. */ ! 280: idetach(ip); ! 281: ! 282: /* If we allocated a text segment, let it go. */ ! 283: if (segp = pp->p_segp[SISTEXT]) { ! 284: pp->p_segp[SISTEXT] = NULL; ! 285: sfree(segp); ! 286: } ! 287: ! 288: /* If we allocated a data segment, let it go. */ ! 289: if (segp = pp->p_segp[SIPDATA]) { ! 290: pp->p_segp[SIPDATA] = NULL; ! 291: sfree(segp); ! 292: } ! 293: ! 294: /* ! 295: * Return through the "sys exit" code with a "SIGSYS", or with the ! 296: * signal actually received if we are aborting due to interrupted exec. ! 297: */ ! 298: if (u.u_error == EINTR) ! 299: pexit(nondsig()); ! 300: pexit(SIGSYS); ! 301: ! 302: done: ! 303: return 0; ! 304: } ! 305: ! 306: /* ! 307: * Open a file, make sure it is l.out, coff, or v86 as well as ! 308: * executable. ! 309: * ! 310: * "xhp" points to a cleared xechdr supplied by the caller. ! 311: * "np" is the file name. ! 312: * "shrds" points to an int that will be written by exlopen(). ! 313: * *shrds is set nonzero only for shared l.out. ! 314: * ! 315: * If file is COFF, there may be multiple text (or data?) sections. ! 316: * Use "xlist" linked structure to keep track of variably many sections ! 317: * after the first text and data sections. ! 318: * ! 319: * return NULL if failure, else return inode pointer for the file. ! 320: */ ! 321: INODE * ! 322: exlopen(xhp, np, shrds, xlist) ! 323: register struct xechdr *xhp; ! 324: char *np; ! 325: int *shrds; ! 326: struct xecnode ** xlist; ! 327: { ! 328: register INODE *ip; ! 329: int i, nscn, hdrsize; ! 330: register BUF *bp; ! 331: unsigned short magic; ! 332: struct ldheader head; ! 333: struct filehdr fhead; ! 334: struct aouthdr ahead; ! 335: struct scnhdr scnhdr; ! 336: ! 337: /* ! 338: * Make sure the file is executable and read the header. ! 339: */ ! 340: if (ftoi(np, 'r')) ! 341: return NULL; ! 342: ip = u.u_cdiri; ! 343: if (iaccess(ip, IPE) == 0) { ! 344: idetach(ip); ! 345: return NULL; ! 346: } ! 347: ! 348: if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) { ! 349: u.u_error = EACCES; ! 350: idetach(ip); ! 351: return NULL; ! 352: } ! 353: ! 354: if ((bp=vread(ip, (daddr_t)0)) == NULL) { ! 355: goto bad; ! 356: } ! 357: ! 358: /* ! 359: * Copy everything we need from the l.out header and check magic ! 360: * number and machine type. ! 361: */ ! 362: *shrds = 0; ! 363: kkcopy(bp->b_vaddr, &magic, sizeof(magic)); ! 364: canint(magic); ! 365: switch (magic) { ! 366: case L_MAGIC: /* Coherent 286 format */ ! 367: kkcopy(bp->b_vaddr, &head, sizeof(struct ldheader)); ! 368: canint(head.l_machine); ! 369: if (head.l_machine!=M_8086) { ! 370: goto bad; ! 371: } ! 372: ! 373: for (i=0; i<NXSEG; i++) { ! 374: cansize(head.l_ssize[i]); ! 375: } ! 376: canint(head.l_flag); ! 377: canvaddr(head.l_entry); ! 378: ! 379: /* ! 380: * If a shared and separated image ! 381: * has stuff in segments that makes it impossible ! 382: * to share, give an error immediately so that we don't ! 383: * lose the parent. ! 384: */ ! 385: head.l_flag &= LF_SHR|LF_SEP|LF_KER; ! 386: ! 387: if ((head.l_flag&LF_SEP==0) || (head.l_flag &LF_KER) ! 388: || head.l_ssize[L_PRVI] || head.l_ssize[L_BSSI]) { ! 389: goto bad; ! 390: } ! 391: xhp->magic = XMAGIC(I286MAGIC,I_MAGIC); ! 392: xhp->entry = head.l_entry; ! 393: ! 394: xhp->segs[SISTEXT].fbase = sizeof(struct ldheader); ! 395: xhp->segs[SISTEXT].mbase = NBPS; ! 396: xhp->segs[SISTEXT].size = head.l_ssize[L_SHRI]; ! 397: ! 398: xhp->segs[SIPDATA].fbase = sizeof(struct ldheader) + ! 399: xhp->segs[SISTEXT].size; ! 400: xhp->segs[SIPDATA].mbase = 0; ! 401: xhp->segs[SIPDATA].size = head.l_ssize[L_SHRD] + ! 402: head.l_ssize[L_PRVD]; ! 403: if (head.l_flag & LF_SHR) ! 404: *shrds = head.l_ssize[L_SHRD]; ! 405: ! 406: xhp->segs[SIBSS].fbase = 0; ! 407: xhp->segs[SIBSS].mbase = xhp->segs[SIPDATA].size; ! 408: xhp->segs[SIBSS].size = head.l_ssize[L_BSSD]; ! 409: ! 410: xhp->segs[SISTACK].mbase = ISP_286; /* size 0, fbase 0 */ ! 411: brelease(bp); ! 412: return ip; ! 413: ! 414: case I386MAGIC: /* ... COFF */ ! 415: kkcopy(bp->b_vaddr, &fhead, sizeof(struct filehdr)); ! 416: hdrsize = sizeof(ahead) + sizeof(fhead); ! 417: if(fhead.f_opthdr != sizeof (ahead) ! 418: || !(fhead.f_flags & F_EXEC) ! 419: || fhead.f_nscns * sizeof(scnhdr) > BSIZE) { ! 420: goto bad; ! 421: } ! 422: ! 423: kkcopy(bp->b_vaddr + sizeof(fhead), &ahead, sizeof(ahead)); ! 424: if (ahead.magic != Z_MAGIC) { ! 425: goto bad; ! 426: } ! 427: ! 428: xhp->magic = XMAGIC(I386MAGIC, ahead.magic); ! 429: xhp->entry = ahead.entry; ! 430: ! 431: for (i = 0; i < fhead.f_nscns; i++) { ! 432: kkcopy(bp->b_vaddr + hdrsize + sizeof(scnhdr)*i, ! 433: &scnhdr, sizeof(scnhdr)); ! 434: switch ((int)(scnhdr.s_flags)) { ! 435: case STYP_INFO: ! 436: continue; ! 437: case STYP_BSS: ! 438: nscn = SIBSS; ! 439: break; ! 440: case STYP_TEXT: ! 441: nscn = SISTEXT; ! 442: break; ! 443: case STYP_DATA: ! 444: nscn = SIPDATA; ! 445: break; ! 446: default: ! 447: goto bad; ! 448: } ! 449: ! 450: /* Text/data shouldn't collide with stack. */ ! 451: if ((unsigned)scnhdr.s_vaddr >= ISP_386) { ! 452: goto bad; ! 453: } ! 454: ! 455: /* Have we already seen a segment of this type? */ ! 456: if (xhp->segs[nscn].size) { ! 457: struct xecnode * tmp; ! 458: ! 459: if (nscn != SISTEXT) { ! 460: goto bad; ! 461: } ! 462: ! 463: /* insert new node at head of "xlist" */ ! 464: if (!(tmp = (struct xecnode *) ! 465: kalloc(sizeof (struct xecnode)))) { ! 466: printf("can't kalloc(xecnode)\n"); ! 467: goto bad; ! 468: } ! 469: tmp->xn = *xlist; ! 470: *xlist = tmp; ! 471: tmp->segtype = nscn; ! 472: tmp->xseg.mbase = scnhdr.s_vaddr; ! 473: tmp->xseg.fbase = scnhdr.s_scnptr; ! 474: tmp->xseg.size = scnhdr.s_size; ! 475: } else { ! 476: xhp->segs[nscn].mbase = scnhdr.s_vaddr; ! 477: xhp->segs[nscn].fbase = scnhdr.s_scnptr; ! 478: xhp->segs[nscn].size = scnhdr.s_size; ! 479: } ! 480: } ! 481: ! 482: /* Text and data segments must both be nonempty. */ ! 483: if (!xhp->segs[SISTEXT].size || !xhp->segs[SIPDATA].size) { ! 484: goto bad; ! 485: } ! 486: ! 487: xhp->entry = ahead.entry; ! 488: ! 489: xhp->segs[SISTACK].mbase = ISP_386; /* size 0, fbase 0 */ ! 490: xhp->magic = XMAGIC(I386MAGIC,ahead.magic); ! 491: brelease(bp); ! 492: return ip; ! 493: default: ! 494: bad: ! 495: brelease(bp); ! 496: u.u_error = ENOEXEC; ! 497: idetach(ip); ! 498: return NULL; ! 499: } ! 500: } ! 501: ! 502: static SEG * ! 503: exsread(sp, ip, xsp, shrdSz) ! 504: register SEG *sp; ! 505: INODE *ip; ! 506: struct xecseg *xsp; ! 507: int shrdSz; ! 508: { ! 509: register int sa, so; ! 510: ! 511: sa = xsp->fbase; ! 512: so = xsp->mbase & (NBPC - 1); ! 513: ! 514: u.u_io.io_seg = IOPHY; ! 515: u.u_io.io_seek = sa; ! 516: u.u_io.io.pbase = MAPIO(sp->s_vmem, so); ! 517: u.u_io.io_flag = 0; ! 518: ! 519: if (shrdSz) { /* shared l.out? */ ! 520: ! 521: /* Load SHRD. */ ! 522: u.u_io.io_ioc = shrdSz; ! 523: sp->s_lrefc++; ! 524: iread(ip, &u.u_io); ! 525: sp->s_lrefc--; ! 526: ! 527: if ((u.u_io.io_ioc = xsp->size - shrdSz) != 0) { ! 528: ! 529: /* Advance file and RAM offsets past SHRD. */ ! 530: sa += shrdSz; ! 531: so += shrdSz; ! 532: ! 533: /* Advance RAM offset to next 16-byte boundary. */ ! 534: so = (so + 15) & ~15; /* round up */ ! 535: ! 536: /* Load PRVD. */ ! 537: u.u_io.io_seg = IOPHY; ! 538: u.u_io.io_seek = sa; ! 539: u.u_io.io.pbase = MAPIO(sp->s_vmem, so); ! 540: u.u_io.io_flag = 0; ! 541: sp->s_lrefc++; ! 542: iread(ip, &u.u_io); ! 543: sp->s_lrefc--; ! 544: } ! 545: } else { /* NOT shared l.out */ ! 546: u.u_io.io_ioc = xsp->size; ! 547: ! 548: sp->s_lrefc++; ! 549: iread(ip, &u.u_io); ! 550: sp->s_lrefc--; ! 551: } ! 552: if (nondsig()) ! 553: u.u_error = EINTR; ! 554: ! 555: if (u.u_error == 0) ! 556: return (sp); ! 557: return NULL; ! 558: } ! 559: ! 560: struct adata { /* Storage for arg and env data */ ! 561: int np; /* Number of pointers in vector */ ! 562: int nc; /* Number of characters in strings */ ! 563: }; ! 564: ! 565: /* ! 566: * Given a pointer to a list of arguments and a pointer to a list of ! 567: * environments, return a stack with the arguments and environments on it. ! 568: */ ! 569: SEG * ! 570: exstack(xhp, argp, envp, wdin) ! 571: register struct xechdr *xhp; ! 572: caddr_t argp, envp; ! 573: { ! 574: register SEG *sp; /* Stack segment pointer */ ! 575: struct sdata { /* To keep segment pointers */ ! 576: caddr_t vp; /* Argv[i], envp[i] pointer */ ! 577: caddr_t cp; /* Argv[i][j], envp[i][j] pointer */ ! 578: } stk; ! 579: struct adata arg, env; ! 580: int chrsz, vecsz, stksz, wdmask, wdout, stkoff, stktop; ! 581: int stkenvp; ! 582: register int i; ! 583: ! 584: /* Validate and evaluate size of args and envs */ ! 585: if (!excount(argp, &arg, wdin) || !excount(envp, &env, wdin)) { ! 586: return NULL; ! 587: } ! 588: ! 589: /* Calculate stack size and allocate it */ ! 590: chrsz = roundu(arg.nc + env.nc, sizeof(int)); ! 591: vecsz = (arg.np+1 + env.np+1) * sizeof(long); ! 592: stksz = roundu(vecsz+chrsz+ISTSIZE, NBPC); ! 593: if (stksz > MADSIZE || !(sp = salloc(stksz, SFDOWN))) { ! 594: u.u_error = E2BIG; ! 595: return NULL; ! 596: } ! 597: ! 598: /* Set up target stack */ ! 599: stktop = xhp->segs[SISTACK].mbase; ! 600: stk.cp = stktop - chrsz; ! 601: stk.vp = stktop - chrsz - vecsz; ! 602: stkoff = MAPIO(sp->s_vmem, stksz - stktop); ! 603: u.u_argc = arg.np; ! 604: u.u_argp = stk.vp; ! 605: wdmask = -1; ! 606: if (wdin==sizeof(short)) ! 607: wdmask = (unsigned short)wdmask; ! 608: ! 609: switch (stktop) { ! 610: ! 611: case ISP_386: ! 612: wdout = sizeof(long); ! 613: xhp->initsp = stk.vp - sizeof(long); ! 614: dmaout(sizeof(long), xhp->initsp+stkoff, &arg.np); ! 615: break; ! 616: ! 617: case ISP_286: ! 618: wdout = sizeof(short); ! 619: xhp->initsp = stk.vp - 3*sizeof(short); ! 620: stkenvp = stk.vp + (arg.np+1) * sizeof(short); ! 621: dmaout(sizeof(short), xhp->initsp+stkoff, &arg.np); ! 622: dmaout(sizeof(short), xhp->initsp+sizeof(short)+stkoff, ! 623: &stk.vp); ! 624: dmaout(sizeof(short), xhp->initsp+2*sizeof(short)+stkoff, ! 625: &stkenvp); ! 626: break; ! 627: ! 628: default: ! 629: panic("exstack"); ! 630: ! 631: } ! 632: ! 633: /* Arguments */ ! 634: for (i = 0; i<arg.np; i++, argp += wdin, stk.vp += wdout) { ! 635: dmaout(wdout, stk.vp+stkoff, &stk.cp); ! 636: stk.cp += exarg(stk.cp+stkoff, getupd(argp) & wdmask); ! 637: } ! 638: ! 639: /* skip null word after arguments */ ! 640: stk.vp += wdout; ! 641: ! 642: /* Environments */ ! 643: for (i = 0; i<env.np; i++, envp += wdin, stk.vp += wdout) { ! 644: dmaout(wdout, stk.vp+stkoff, &stk.cp); ! 645: stk.cp += exarg(stk.cp+stkoff, getupd(envp) & wdmask); ! 646: } ! 647: ! 648: return sp; ! 649: } ! 650: ! 651: exarg(out, in) ! 652: caddr_t in, out; ! 653: { ! 654: char c; ! 655: caddr_t init_in; ! 656: ! 657: init_in = in; ! 658: do { ! 659: c = getubd(in++); ! 660: dmaout(sizeof(char), out++, &c); ! 661: } while (c); ! 662: return in - init_in; ! 663: } ! 664: ! 665: /* ! 666: * Given a pointer to a list of arguments, a pointer to an argument count ! 667: * and a pointer to a byte count, count the #characters/#strings ! 668: * in the arguments ! 669: */ ! 670: excount(usrvp, adp, wdin) ! 671: register caddr_t usrvp; ! 672: struct adata *adp; ! 673: { ! 674: register caddr_t usrcp; ! 675: register int c; ! 676: register unsigned nb; ! 677: register unsigned na; ! 678: int wdmask; ! 679: ! 680: wdmask = -1; ! 681: if (wdin==sizeof(short)) ! 682: wdmask = (unsigned short)wdmask; ! 683: na = nb = 0; ! 684: if (usrvp != NULL) { ! 685: for (;;) { ! 686: usrcp = getupd(usrvp) & wdmask; ! 687: usrvp += wdin; ! 688: if (u.u_error) ! 689: return (0); ! 690: if (usrcp == NULL) ! 691: break; ! 692: na++; ! 693: for (;;) { ! 694: c = getubd(usrcp++); ! 695: if (u.u_error) ! 696: return (0); ! 697: nb++; ! 698: if (c == '\0') ! 699: break; ! 700: } ! 701: } ! 702: } ! 703: adp->np = na; ! 704: adp->nc = nb; ! 705: return (1); ! 706: } ! 707: ! 708: /* ! 709: * Round up a size to a paragraph ! 710: * (mod 16) boundry. ! 711: * This is really mod 512 to make swapping work ! 712: */ ! 713: off_t ! 714: exround(s) ! 715: off_t s; ! 716: { ! 717: return ((s+15)&~0x0F); ! 718: } ! 719: ! 720: pload(np) ! 721: char * np; ! 722: { ! 723: return -1; ! 724: ! 725: } ! 726: /* ! 727: * Set up the first process, a small program which will exec ! 728: * the init program. ! 729: */ ! 730: extern char aicodep[]; ! 731: ! 732: eveinit() ! 733: { ! 734: SEG *sp; ! 735: register PROC *pp; ! 736: SELF = pp = eprocp; ! 737: /* static struct xechdr xecinit[NUSEG+1] = { {0},{0},{0},{ISP_386}}; */ ! 738: ! 739: /* ! 740: * Allocate, record, initialize code segment, make it executable. ! 741: */ ! 742: if ((sp = salloc(roundu(icodes, NBPC), 0)) == NULL) ! 743: panic("eveinit(code)"); ! 744: pp->p_segp[SIPDATA] = sp; ! 745: ! 746: /* ! 747: * Start process. ! 748: */ ! 749: u.u_argp = 0; ! 750: if (sproto(0) == 0) ! 751: panic("eveinit()"); ! 752: segload(); ! 753: kucopy(aicodep, 0, icodes); ! 754: } ! 755: ! 756: /* ! 757: * Given a major number, undo the previous function. ! 758: */ ! 759: puload(m) ! 760: int m; ! 761: { ! 762: register CON *cp; ! 763: register DRV *dp; ! 764: ! 765: dp = &drvl[m]; ! 766: lock(dp->d_gate); ! 767: if (m>=drvn || (cp=dp->d_conp)==NULL) { ! 768: u.u_error = ENXIO; ! 769: goto ret; ! 770: } ! 771: (*cp->c_uload)(); ! 772: if (! u.u_error) ! 773: dp->d_conp = NULL; ! 774: ret: ! 775: unlock(dp->d_gate); ! 776: return (0); ! 777: } ! 778:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.