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

Defined functions

execute defined in line 82; used 2 times
illtrap defined in line 173; used 2 times
main defined in line 36; never used

Defined variables

nameend defined in line 34; used 1 times
  • in line 47
progname defined in line 33; used 1 times
  • in line 46
sccsid defined in line 1; never used
stat32v defined in line 28; used 49 times
Last modified: 1983-08-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1225
Valid CSS Valid XHTML 1.0 Strict