Annotation of 40BSD/games/compat/runcompat.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.