|
|
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.