Annotation of 43BSD/games/compat/runcompat.c, revision 1.1

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

unix.superglobalmegacorp.com

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