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