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