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