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