|
|
1.1 root 1: static char sccsid[] = "@(#)runcompat.c 4.2 83/07/31";
2:
3: /*
4: * Compatability mode support
5: * written by Art Wetzel during August 1979
6: * at the Interdisciplinary Dept of Information Science
7: * Room 711, LIS Bldg
8: * University of Pittsburgh
9: * Pittsburgh, Pa 15260
10: *
11: * No claims are made on the completeness of the support of any
12: * of the systems simulated under this package
13: */
14:
15: #include <stdio.h>
16: #include <signal.h>
17: #include <sys/types.h>
18: #include <sys/stat.h>
19: #include <errno.h>
20: #include "defs.h"
21: #ifdef UNIX
22: #include "unixhdr.h"
23: #endif
24: #ifdef RT11
25: #include "rt11.h"
26: #endif
27:
28: struct stat stat32v;
29: u_short regs[8];
30: u_long psl;
31: u_short *pc;
32: int incompat;
33: char *progname;
34: char *nameend;
35:
36: main(argc, argv, envp)
37: int argc;
38: char **argv, **envp;
39: {
40:
41: if (argc < 2) {
42: fprintf(stderr,"Usage: %s [-rootdir] file args...\n",argv[0]);
43: exit(1);
44: }
45: /* remember where the program name etc should go for using ps */
46: progname = argv[0];
47: nameend = envp[0]-1;
48: argv++;
49: /* set up alternate root directory if flagged for */
50: if (*argv[0] == '-') {
51: if (chroot(argv[0]+1)) {
52: fprintf(stderr,"Can't change root to %s\n",argv[0]+1);
53: exit(-1);
54: }
55: argv++;
56: }
57: /* check out file stats of file to run */
58: if (stat(argv[0], &stat32v)) {
59: fprintf(stderr,"%s does not exist\n",argv[0]);
60: exit(1);
61: }
62: /* a version of SETUID and SETGID file executions */
63: /* the binary of this program should be SETUID root for this to work */
64: /* requires nonstandard seteuid and setegid sys calls */
65: if (!(stat32v.st_mode & S_ISGID) || setegid(stat32v.st_gid))
66: /* if not SETGID file or error, drop back to real group */
67: setgid(getgid());
68: if (!(stat32v.st_mode & S_ISUID) || seteuid(stat32v.st_uid))
69: /* if not SETUID file or error, drop back to real uid */
70: setuid(getuid());
71: #ifdef V6UNIX
72: /* no umasks in version 6 */
73: umask(0);
74: #endif
75: /* go try to execute , passing along args and environment */
76: execute(argv[0], argv, envp);
77: /* only get here if execute fails */
78: fprintf(stderr,"Execution failure on %s\n",argv[0]);
79: exit(1);
80: }
81:
82: execute(file, argv, envp)
83: char *file, **argv, **envp;
84: {
85: int fd, n, tloadpt, dloadpt, tloadsize, dloadsize, stacksize;
86: register short *p;
87: extern illtrap();
88: extern char **environ;
89:
90: /* file to run should be readable */
91: if ((fd = open(file, 0)) == -1) {
92: fprintf(stderr,"Can't open %s for read access\n",file);
93: return(-1);
94: }
95: #ifdef UNIX
96: if ((n = read(fd, &header, sizeof header)) != sizeof header)
97: return(ENOEXEC);
98: /* check to see if really unix file */
99: if (header.magic != MAGIC1 && header.magic != MAGIC2 &&
100: header.magic != MAGIC3 && header.magic != MAGIC4) {
101: return(ENOEXEC);
102: }
103: /* if a UNIX file run it */
104: if (header.textsize == 0) {
105: close(fd);
106: /* if no explicit env, pass along environ */
107: if (!envp || *envp == 0)
108: return(execve(file, argv, environ));
109: return(execve(file, argv, envp));
110: }
111: /* checks out OK as PDP-11 UNIX file */
112: if (header.magic == MAGIC3) {
113: fprintf(stderr,"%s compiled for separate I/D space\n",argv[0]);
114: return(-1);
115: }
116: /* unix text loads at 0 */
117: tloadpt = 0;
118: /* set starting pc value */
119: pc = (unsigned short *)header.entry;
120: /* figure out where to load initialized data */
121: dloadpt = tloadsize = header.textsize;
122: /* check if alignment of data segment to 8k byte boundary */
123: if (header.magic == MAGIC2)
124: dloadpt = (dloadpt+8191) & (~8191);
125: /* how much data */
126: dloadsize = header.datasize;
127: stacksize = header.bsssize;
128: #endif
129: #ifdef RT11
130: if ((n = read(fd, shortspace, RTHDRSIZ)) != RTHDRSIZ) {
131: fprintf(stderr,"Error reading 1st block\n");
132: return(-1);
133: }
134: /* rt11 files are 0 aligned including the header */
135: tloadpt = RTHDRSIZ;
136: /* set starting pc value */
137: pc = (unsigned short *)shortspace[RTPC];
138: /* initialize stack location */
139: regs[6] = shortspace[RTSP];
140: /* figure how much to load */
141: dloadpt = tloadsize = shortspace[RTHGH]-RTHDRSIZ;
142: /* no separate data as in unix */
143: dloadsize = 0;
144: stacksize = 0;
145: #endif
146: /* see if it all fits into available memory space */
147: if ((dloadpt+dloadsize+stacksize) > (int)memsiz) {
148: fprintf(stderr,"File too big to run\n");
149: return(-1);
150: }
151: /* read text segment */
152: if ((n = read(fd, tloadpt, tloadsize)) < tloadsize) {
153: fprintf(stderr,"Text read failure\n");
154: return(-1);
155: }
156: /* read data segment */
157: if ((n = read(fd, dloadpt, dloadsize)) < dloadsize) {
158: fprintf(stderr,"Data read failure\n");
159: return(-1);
160: }
161: /* clear out the rest of memory */
162: p = (short *)(dloadpt + dloadsize);
163: while (p < (short *)memsiz)
164: *p++ = 0;
165: /* close file before starting it */
166: close(fd);
167: /* set up illegal instruction trapping */
168: signal(SIGILL, illtrap);
169: /* lets give it a try */
170: start(argv, envp);
171: }
172:
173: illtrap(signum, faultcode, scp)
174: int signum, faultcode;
175: struct sigcontext *scp;
176: {
177: unsigned short *pcptr;
178: int instr;
179: register int i;
180: extern getregs();
181:
182: /* record the fact that we are not in compatability mode now */
183: incompat = 0;
184: /* get the register values before they get clobbered */
185: getregs();
186: /* figure out what the pc was */
187: pcptr = (unsigned short *) &scp->sc_pc;
188: pc = (unsigned short *) *pcptr;
189: /* get the instruction */
190: instr = *pc;
191: /* incriment the pc over this instruction */
192: pc++;
193: /* set register 7 as pc synonym */
194: regs[7] = (unsigned short)(int)pc;
195: /* set up psl with condition codes */
196: /* a UNIX-32V monitor patch is required to not clear condition codes */
197: psl = 0x83c00000 | (scp->sc_ps & 017);
198: sigsetmask(scp->sc_mask);
199: /* pick out the appropriate action for this illegal instruction */
200: switch(instr>>8){
201:
202: case TRAPS:
203: dotrap(instr & 0377);
204: break;
205:
206: case EMTS:
207: if (sigvals[SIGEMT] && ((sigvals[SIGEMT]%2) != 1)) {
208: dosig(SIGEMT, pc);
209: break;
210: }
211: doemt(instr & 0377);
212: break;
213:
214: default:
215: if (instr >= 075000 && instr < 075040) {
216: /* fis instructions */
217: if (dofloat(instr) == 0)
218: break;
219: }
220: if (instr >= 0170000) {
221: /* floating point unit instructions */
222: if (dofloat(instr) == 0)
223: break;
224: }
225: /* genuine illegal instruction */
226: /* if signal trap set go to user's trap location */
227: if (sigvals[SIGILL] && ((sigvals[SIGILL]%2) != 1)) {
228: dosig(SIGILL, pc);
229: break;
230: }
231: /* ignore uncaught setd instructions */
232: if (instr == SETD)
233: break;
234: /* otherwise put out a message and quit */
235: printf("Illegal instruction, psl 0x%08x, pc 0%04o\n",psl,pc-1);
236: for (i = 0; i < 7; i++)
237: printf("0x%04x ",regs[i]);
238: printf("0x%04x -> 0%o\n",pc-1,instr);
239: /* set up to dump on illegal instruction */
240: signal(SIGILL,SIG_DFL);
241: /* set pc back to bad instruction */
242: pc--;
243: /* go do it again for dump */
244: compat();
245: }
246: /* go back to compatability mode */
247: incompat++;
248: compat();
249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.