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