|
|
1.1 root 1: /* $Header: /newbits/286_KERNEL/USRSRC/coh/RCS/exec.c,v 1.1 92/01/09 13:26:47 bin Exp Locker: bin $ */
2: /* (lgl-
3: * The information contained herein is a trade secret of Mark Williams
4: * Company, and is confidential information. It is provided under a
5: * license agreement, and may be copied or disclosed only under the
6: * terms of that agreement. Any reproduction or disclosure of this
7: * material without the express written authorization of Mark Williams
8: * Company or persuant to the license agreement is unlawful.
9: *
10: * COHERENT Version 2.3.37
11: * Copyright (c) 1982, 1983, 1984.
12: * An unpublished work by Mark Williams Company, Chicago.
13: * All rights reserved.
14: -lgl) */
15: /*
16: * Coherent.
17: * Exec and driver load code.
18: *
19: * $Log: exec.c,v $
20: * Revision 1.1 92/01/09 13:26:47 bin
21: * Initial revision
22: *
23: * Revision 1.1 88/03/24 16:13:39 src
24: * Initial revision
25: *
26: * 86/11/19 Allan Cornish /usr/src/sys/coh/exec.c
27: * Exsread() initializes the (new) (IO).io_flag field to 0.
28: */
29: #include <sys/coherent.h>
30: #include <acct.h>
31: #include <sys/buf.h>
32: #include <canon.h>
33: #include <sys/con.h>
34: #include <errno.h>
35: #include <sys/filsys.h>
36: #include <sys/ino.h>
37: #include <sys/inode.h>
38: #include <l.out.h>
39: #include <sys/proc.h>
40: #include <sys/seg.h>
41: #include <signal.h>
42: #include <sys/uproc.h>
43:
44: /*
45: * Sizes.
46: */
47: #define sh ((fsize_t)sizeof(struct ldheader))
48: #define si lssize[L_SHRI]
49: #define pi lssize[L_PRVI]
50: #define bi lssize[L_BSSI]
51: #define sd lssize[L_SHRD]
52: #define pd lssize[L_PRVD]
53: #define bd lssize[L_BSSD]
54:
55: /*
56: * Segments.
57: */
58: #define upsp pp->p_segp[SIUSERP]
59: #define sssp pp->p_segp[SISTACK]
60: #define sisp pp->p_segp[SISTEXT]
61: #define pisp pp->p_segp[SIPTEXT]
62: #define sdsp pp->p_segp[SISDATA]
63: #define pdsp pp->p_segp[SIPDATA]
64:
65: /*
66: * Set up the first process, a small programme which will exec
67: * the init programme.
68: */
69: eveinit(sp)
70: SEG *sp;
71: {
72: register PROC *pp;
73:
74: SELF = pp = eprocp;
75: pp->p_segp[SIUSERP] = sp;
76: if ((sp=salloc((fsize_t)icodes, 0)) == NULL)
77: panic("eveinit()");
78: pp->p_segp[SIPDATA] = sp;
79: kscopy(icodep, sp, 0, icodes);
80: if ((sp=salloc((fsize_t)UPASIZE, SFDOWN)) == NULL)
81: panic("eveinit()");
82: pp->p_segp[SISTACK] = sp;
83: u.u_argp = 0;
84: if (sproto() == 0)
85: panic("eveinit()");
86: segload();
87: }
88:
89: /*
90: * Given a major number, a file containing a device driver and a configuration
91: * pointer, load the driver on the major number.
92: */
93: pload(m, np, cp)
94: char *np;
95: CON *cp;
96: {
97: register INODE *ip;
98: register SEG *sp;
99: register DRV *dp;
100: register fsize_t ss;
101: dold_t dold;
102: int lflag;
103: int r;
104: vaddr_t pc;
105: fsize_t lssize[NUSEG];
106:
107: if (m >= drvn) {
108: u.u_error = ENXIO;
109: return;
110: }
111: if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
112: return;
113: ss = pi+si+pd+sd;
114: sp = ssalloc(&r, ip, SFSHRX, ss+bi+bd, sh, ss);
115: idetach(ip);
116: if (r < 0)
117: return;
118: dp = &drvl[m];
119: lock(dp->d_gate);
120: if (dp->d_conp != NULL) {
121: unlock(dp->d_gate);
122: sfree(sp);
123: u.u_error = EDBUSY;
124: return;
125: }
126: dp->d_time = 0;
127: dp->d_conp = cp;
128: dp->d_segp = sp;
129: dp->d_map = sp->s_mbase;
130: dsave(dold);
131: dmapv(dp->d_map);
132: (*cp->c_load)();
133: drest(dold);
134: unlock(dp->d_gate);
135: }
136:
137: /*
138: * Given a major number, undo the previous function.
139: */
140: puload(m)
141: int m;
142: {
143: register CON *cp;
144: register DRV *dp;
145: dold_t dold;
146:
147: dp = &drvl[m];
148: lock(dp->d_gate);
149: if (m>=drvn || dp->d_segp==NULL || (cp=dp->d_conp)==NULL) {
150: u.u_error = ENXIO;
151: goto ret;
152: }
153: dsave(dold);
154: dmapv(dp->d_map);
155: (*cp->c_uload)();
156: drest(dold);
157: if (u.u_error)
158: goto ret;
159: sfree(dp->d_segp);
160: dp->d_conp = NULL;
161: dp->d_segp = NULL;
162: dp->d_map = 0;
163: ret:
164: unlock(dp->d_gate);
165: return (0);
166: }
167:
168: /*
169: * Given the name of an executable l.out, a null terminated argument
170: * list and a null terminated environment list, execute the l.out with the
171: * given arguments and environments.
172: */
173: pexece(np, argp, envp)
174: char *np;
175: char *argp[];
176: char *envp[];
177: {
178: register INODE *ip; /* Load file INODE */
179: register PROC *pp; /* A cheap copy of SELF */
180: register SEG *ssp; /* New stack segment */
181: register fsize_t ss; /* Segment size temp. */
182: register int kprocflag; /* Set if kernal process */
183: register int i; /* For looping over segments */
184: int r; /* Flag for "exload" */
185: int lflag; /* l_flags from l.out */
186: vaddr_t pc; /* l_entry from l.out */
187: vaddr_t sp; /* Initial stack pointer */
188: fsize_t lssize[NUSEG]; /* Segment sizes */
189:
190: pp = SELF;
191: if ((ip=exlopen(np, lssize, &lflag, &pc)) == NULL)
192: return;
193: if ((lflag&LF_KER) != 0) {
194: pp->p_flags |= PFKERN;
195: kprocflag = 1;
196: ssp = NULL;
197: if (super() == 0) {
198: idetach(ip);
199: return;
200: }
201: } else {
202: kprocflag = 0;
203: if ((ssp=exstack(&sp, argp, envp)) == NULL) {
204: idetach(ip);
205: return;
206: }
207: }
208: /*
209: * At this point the file has been
210: * validated as an object module, and the
211: * argument list has been build. Release all of
212: * the original segments. At this point we have
213: * committed to the new image. A "sys exec" that
214: * gets an I/O error is doomed.
215: */
216: for (i=1; i<NUSEG; ++i) {
217: if (pp->p_segp[i] != NULL) {
218: sfree(pp->p_segp[i]);
219: pp->p_segp[i] = NULL;
220: }
221: }
222: sssp = ssp;
223: /*
224: * Read in load module.
225: */
226: switch (lflag&(LF_SHR|LF_SEP)) {
227: case 0:
228: ss = si+pi+sd+pd;
229: pdsp = ssalloc(&r, ip, kprocflag?SFHIGH:0, ss+bi+bd, sh, ss);
230: if (r < 0)
231: goto out;
232: break;
233:
234: case LF_SHR:
235: sdsp = ssalloc(&r, ip, SFSHRX, si+sd, sh, si);
236: if (r < 0)
237: goto out;
238: if (r == 0) {
239: if (exsread(sdsp, ip, sd, sh+si+pi, si) == 0)
240: goto out;
241: }
242: pdsp = ssalloc(&r, ip, 0, pi+pd+bi+bd, sh+si, pi);
243: if (r < 0)
244: goto out;
245: if (r == 0) {
246: if (exsread(pdsp, ip, pd, sh+si+pi+sd, pi) == 0)
247: goto out;
248: }
249: break;
250:
251: case LF_SEP:
252: pisp = ssalloc(&r, ip, SFTEXT, si+pi+bi, sh, si+pi);
253: if (r < 0)
254: goto out;
255: pdsp = ssalloc(&r, ip, 0, sd+pd+bd, sh+si+bi, sd+pd);
256: if (r < 0)
257: goto out;
258: break;
259:
260: case LF_SHR|LF_SEP:
261: sisp = ssalloc(&r, ip, SFSHRX|SFTEXT, si, sh, si);
262: if (r < 0)
263: goto out;
264: pisp = ssalloc(&r, ip, SFTEXT, pi+bi, sh+si, pi);
265: if (r < 0)
266: goto out;
267: sdsp = ssalloc(&r, ip, SFSHRX, sd, sh+si+pi, sd);
268: if (r < 0)
269: goto out;
270: pdsp = ssalloc(&r, ip, 0, pd+bd, sh+si+pi+pd, pd);
271: if (r < 0)
272: goto out;
273: }
274: if (sproto() == 0)
275: goto out;
276: /*
277: * The new image is read in
278: * and mapped. Perform the final grunge
279: * (set-uid stuff, accounting, loading up
280: * registers, etc).
281: */
282: u.u_flag &= ~AFORK;
283: kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm));
284: if (iaccess(ip, IPR) == 0)
285: pp->p_flags |= PFNDMP;
286: if ((ip->i_mode&ISUID) != 0)
287: pp->p_uid = u.u_uid = ip->i_uid;
288: if ((ip->i_mode&ISGID) != 0)
289: u.u_gid = ip->i_gid;
290: for (i=0; i<NSIG; ++i) {
291: if (u.u_sfunc[i] != SIG_IGN)
292: u.u_sfunc[i] = SIG_DFL;
293: }
294: if ((pp->p_flags&PFTRAC) != 0)
295: sendsig(SIGTRAP, pp);
296: idetach(ip);
297: msetusr(pc, sp);
298: segload();
299: return (0);
300:
301: /*
302: * We did not make it.
303: * Release the INODE for the load
304: * file, and return through the "sys exit"
305: * code. A better exit status should be
306: * chosen!
307: */
308: out:
309: idetach(ip);
310: pexit(0);
311: }
312:
313: /*
314: * Open an l.out, make sure it is an l.out and executable and return the
315: * appropriate information.
316: */
317: INODE *
318: exlopen(np, ssizep, flagp, pcp)
319: char *np;
320: fsize_t *ssizep;
321: int *flagp;
322: vaddr_t *pcp;
323: {
324: register INODE *ip;
325: register struct ldheader *ldp;
326: register int n;
327: register BUF *bp;
328: int m;
329:
330: /*
331: * Make sure the file is really an executable l.out and read the
332: * header in.
333: */
334: if (ftoi(np, 'r') != 0)
335: return (NULL);
336: ip = u.u_cdiri;
337: if (iaccess(ip, IPE) == 0) {
338: idetach(ip);
339: return (NULL);
340: }
341: if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) {
342: u.u_error = EACCES;
343: idetach(ip);
344: return (NULL);
345: }
346: if ((bp=vread(ip, (daddr_t)0)) == NULL) {
347: u.u_error = EBADFMT;
348: idetach(ip);
349: return (NULL);
350: }
351:
352: /*
353: * Copy everything we need from the l.out header and check magic
354: * number and machine type.
355: */
356: ldp = bp->b_vaddr;
357: m = ldp->l_magic;
358: canint(m);
359: if (m != L_MAGIC) {
360: u.u_error = ENOEXEC;
361: brelease(bp);
362: idetach(ip);
363: return (NULL);
364: }
365: m = ldp->l_machine;
366: canint(m);
367: if (m != mactype) {
368: u.u_error = EBADFMT;
369: brelease(bp);
370: idetach(ip);
371: return (NULL);
372: }
373: kkcopy(ldp->l_ssize, ssizep, NXSEG*sizeof(fsize_t));
374: for (n=0; n<NXSEG; n++)
375: cansize(ssizep[n]);
376: *flagp = ldp->l_flag;
377: canint(*flagp);
378: *pcp = ldp->l_entry;
379: canvaddr(*pcp);
380: brelease(bp);
381: return (ip);
382: }
383:
384: /*
385: * Given a segment `sp', read `ss' bytes from the inode `ip' starting
386: * at seek address `sa' into offset `so' in the segment.
387: */
388: SEG *
389: exsread(sp, ip, ss, sa, so)
390: register SEG *sp;
391: INODE *ip;
392: fsize_t sa;
393: fsize_t ss;
394: fsize_t so;
395: {
396: u.u_io.io_seg = IOPHY;
397: u.u_io.io_ioc = ss;
398: u.u_io.io_seek = sa;
399: u.u_io.io_phys = ctob((paddr_t)sp->s_mbase) + so;
400: u.u_io.io_flag = 0;
401: iread(ip, &u.u_io);
402: return (u.u_error==0);
403: }
404:
405: /*
406: * Given a pointer to a list of arguments and a pointer to a list of
407: * environments, return a stack with the arguments and environments on it.
408: */
409: SEG *
410: exstack(iusp, argp, envp)
411: char **iusp; /* Back patch sp value */
412: char *argp[]; /* Arguments for new process */
413: char *envp[]; /* Environments for new process */
414: {
415: SEG *sp; /* Stack segment pointer */
416: struct adata { /* Storage for arg and env data */
417: char **up; /* User vector pointer */
418: int np; /* Number of pointers in vector */
419: int nc; /* Number of characters in strings */
420: } arg, env;
421: struct sdata { /* To keep segment pointers */
422: vaddr_t base; /* Top of segment virtual */
423: vaddr_t ap; /* Argc, argv, envp pointer */
424: vaddr_t vp; /* Argv[i], envp[i] pointer */
425: vaddr_t cp; /* Argv[i][j], envp[i][j] pointer */
426: } aux, stk;
427: aold_t aold; /* Auxiliary map storage */
428: register char **usrvp; /* Vector pointer into user seg */
429: register char *usrcp; /* Character pointer into user seg */
430: register int c; /* Character fetched from user */
431: register int chrsz; /* Size of strings */
432: register struct adata *adp; /* Arg and env scanner */
433: register int vecsz; /* Size of vectors */
434: register int stksz; /* Size of stack argument region */
435:
436: /* Validate and evaluate size of args and envs */
437: arg.up = argp;
438: env.up = envp;
439: chrsz = 0;
440: vecsz = 0;
441: for (adp = &arg; ; adp = &env) {
442: adp->np = 0;
443: adp->nc = 0;
444: if (excount(adp->up, &adp->np, &adp->nc) == 0)
445: return (NULL);
446: chrsz += adp->nc * sizeof(char);
447: vecsz += adp->np * sizeof(char *);
448: if (adp == &env)
449: break;
450: }
451:
452: /* Calculate stack size and allocate it */
453: chrsz = roundu(chrsz, sizeof(int));
454: stksz = sizeof(int) /* argc */
455: + sizeof(char **) /* argv */
456: + sizeof(char **) /* envp */
457: + vecsz /* argv[i] and envp[i] */
458: + chrsz /* *argv[i] and *envp[i] */
459: + sizeof(int) /* Mystery zero word */
460: + sizeof(char *) /* Splimit for z8000 */
461: + sizeof(int); /* errno */
462: stksz += ISTSIZE;
463: if (stksz > MADSIZE) {
464: u.u_error = E2BIG;
465: return (NULL);
466: }
467: if ((sp=salloc((fsize_t)stksz, SFDOWN)) == NULL)
468: return (NULL);
469: stksz -= ISTSIZE;
470:
471: /*
472: * Initialize segment data.
473: */
474: asave(aold);
475:
476: aux.base = abase(sp->s_mbase) + ctob(sp->s_size);
477: aux.ap = aux.base - stksz;
478: aux.vp = aux.ap + sizeof(int) + 2*sizeof(char **);
479: aux.cp = aux.vp + vecsz;
480:
481: stk.base = ISTVIRT;
482: stk.ap = stk.base - stksz;
483: stk.vp = stk.ap + sizeof(int) + 2*sizeof(char **);
484: stk.cp = stk.vp + vecsz;
485:
486: /*
487: * Write argc.
488: */
489: aputi((int *)aux.ap, arg.np-1);
490: aux.ap += sizeof(int);
491:
492: /*
493: * Arguments and environments.
494: */
495: for (adp = &arg; ; adp = &env) {
496:
497: /* Write argv or envp */
498: aputp((char ***)aux.ap, (char **)stk.vp);
499: aux.ap += sizeof(char **);
500: if ((usrvp = adp->up) != NULL) {
501:
502: /* Write argv[i] or envp[i] */
503: while ((usrcp = getupd(usrvp++)) != NULL) {
504: aputp((char **)aux.vp, (char *)stk.cp);
505: aux.vp += sizeof(char *);
506: stk.vp += sizeof(char *);
507:
508: /* Write argv[i][j] or envp[i][j] */
509: do {
510: c = getubd(usrcp++);
511: aputc((char *)aux.cp, c);
512: aux.cp += sizeof(char);
513: stk.cp += sizeof(char);
514: } while (c != '\0');
515: }
516: }
517:
518: /* Write argv[argc] or envp[envc] */
519: aputp((char **)aux.vp, NULL);
520: aux.vp += sizeof(char *);
521: stk.vp += sizeof(char *);
522: if (adp == &env)
523: break;
524: }
525:
526: /*
527: * Clear out the slop.
528: */
529: aux.base -= sizeof(int);
530: aputi((int *) aux.base, 0); /* errno */
531: aux.base -= sizeof(char *);
532: aputp((char **) aux.base, (char *)stk.base-ctob(sp->s_size)+SOVSIZE);
533: aux.base -= sizeof(int);
534: aputi((int *) aux.base, 0); /* mystery word */
535:
536: arest(aold);
537:
538: /*
539: * Patch some values and return.
540: */
541: *iusp = stk.ap; /* Patch initial usp */
542: u.u_argc = arg.np-1;
543: u.u_argp = stk.vp; /* Points after NULL of envs */
544: return (sp);
545: }
546:
547: /*
548: * Given a pointer to a list of arguments, a pointer to an argument count
549: * and a pointer to a byte count, update incrementally the argument count
550: * and the byte count.
551: */
552: excount(usrvp, nap, nbp)
553: register char **usrvp;
554: int *nap;
555: int *nbp;
556: {
557: register char *usrcp;
558: register int c;
559: register unsigned nb;
560: register unsigned na;
561:
562: na = 1;
563: nb = 0;
564: if (usrvp != NULL) {
565: for (;;) {
566: usrcp = getupd(usrvp++);
567: if (u.u_error)
568: return (0);
569: if (usrcp == NULL)
570: break;
571: na++;
572: for (;;) {
573: c = getubd(usrcp++);
574: if (u.u_error)
575: return (0);
576: nb++;
577: if (c == '\0')
578: break;
579: }
580: }
581: }
582: *nap += na;
583: *nbp += nb;
584: return (1);
585: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.