Annotation of 40BSD/games/compat/runcompat.c, revision 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.