1: /* 2: * checkobj 3: * checks if a file can be executed. 4: * looks at type, size, and requirements of floating point. 5: */ 6: 7: #include <sys/param.h> 8: #include <a.out.h> 9: #include <stdio.h> 10: 11: #define UNIX "/unix" /* for namelist (to get maxmem) */ 12: #define MEM "/dev/kmem" /* to read maxmem from */ 13: #define SSEG 8192 /* pdp 11 segment size (bytes) */ 14: #define MAXDATA (56*1024L) /* maximum process data size */ 15: #define MAXTEXT (64*1024L) /* maximum process text size */ 16: #define SETD 0170011 /* setd instruction */ 17: 18: #define fullseg(siz) ((((long)siz + (SSEG-1))/SSEG) * SSEG) 19: #define segs(siz) ((int)(((long)siz + (SSEG-1))/SSEG)) 20: #define lctob(cliks) ((long)(unsigned)cliks * ctob(1)) 21: 22: struct exec obj; 23: #ifdef MENLO_OVLY 24: struct ovlhdr ovlhdr; 25: #endif 26: 27: struct nlist nl[] = 28: { 29: "maxmem", 0, 0, 30: 0 31: }; 32: 33: struct nlist fpsim[] = 34: { 35: "fptrap", 0, 0, 36: "fltused", 0, 0, 37: "\0\0\0\0\0\0\0\0", 0, 0 38: }; 39: 40: int sflag; 41: int fflag; 42: 43: main(argc,argv) int argc;char **argv; 44: { 45: int x,fail=0; 46: char *myname; 47: 48: myname = argv[0]; 49: argc--,argv++; 50: while (argc > 1 && argv[0][0]=='-') { 51: while (*++*argv) 52: switch (**argv) { 53: case 'f': 54: fflag++; 55: break; 56: case 's': 57: sflag++; 58: break; 59: default: 60: if (atoi(*argv) == 40) { 61: sflag++; 62: fflag++; 63: goto nxt; 64: } else goto usage; 65: } 66: nxt: 67: argc--, argv++; 68: } 69: if (argc > 1) 70: for(x = 0 ; x<argc ; x++) 71: { 72: printf("%s:\t",argv[x]); 73: fail |= check(argv[x]); 74: printf("\n"); 75: } 76: else if (argc == 1) 77: fail = check(argv[0]); 78: else 79: { 80: usage: 81: printf("Usage: %s [-f] [-40] <obj-file> ...\n", myname); 82: exit(10); 83: } 84: exit(fail); 85: } 86: 87: 88: int check(file) char *file; 89: { 90: register i; 91: int fi, ins, fail, maxmem; 92: long size, tsize=0L, totsize, bytesmax; 93: 94: fail = 0; 95: if ((fi=open(file,0)) < 0) 96: { 97: perror(file); 98: return(1); 99: } 100: if (read(fi,&obj,sizeof(obj)) != sizeof(obj)) 101: { 102: printf("not an object file.\n"); 103: close(fi); 104: return(1); 105: } 106: #ifdef MENLO_OVLY 107: if (obj.a_magic == A_MAGIC5 || obj.a_magic == A_MAGIC6) 108: if (read(fi,&ovlhdr,sizeof(ovlhdr)) != sizeof(ovlhdr)) { 109: printf("not an object file.\n"); 110: close(fi); 111: return(1); 112: } 113: #endif 114: switch(obj.a_magic) 115: { 116: 117: case A_MAGIC1: 118: size = (long)obj.a_text + obj.a_data + obj.a_bss; 119: totsize = size; 120: break; 121: 122: case A_MAGIC2: 123: case A_MAGIC4: 124: size = fullseg(obj.a_text) + obj.a_data + obj.a_bss; 125: totsize = (long)obj.a_text + obj.a_data + obj.a_bss; 126: break; 127: 128: case A_MAGIC3: 129: tsize = fullseg(obj.a_text); 130: size = (long) obj.a_data + obj.a_bss; 131: totsize = (long)obj.a_text + obj.a_data + obj.a_bss; 132: break; 133: 134: #ifdef MENLO_OVLY 135: case A_MAGIC5: 136: size = fullseg(obj.a_text) + obj.a_data + obj.a_bss; 137: size += fullseg(ovlhdr.max_ovl); 138: totsize = (long)obj.a_text + obj.a_data + obj.a_bss; 139: for (i=0; i<NOVL; i++) 140: totsize += ovlhdr.ov_siz[i]; 141: break; 142: 143: case A_MAGIC6: 144: tsize = fullseg(obj.a_text) + fullseg(ovlhdr.max_ovl); 145: size = obj.a_data + obj.a_bss; 146: totsize = (long)obj.a_text + obj.a_data + obj.a_bss; 147: for (i=0; i<NOVL; i++) 148: totsize += ovlhdr.ov_siz[i]; 149: break; 150: #endif 151: 152: default: 153: printf("not an object file.\n"); 154: close(fi); 155: return(1); 156: } 157: 158: if (sflag) { 159: if (tsize>0) { 160: fail++; 161: printf("uses separate i/d\n"); 162: } 163: if (size > MAXDATA) { 164: fail++; 165: if (tsize) 166: printf("Data segment too big (limit %u)\n", 167: (unsigned)MAXDATA); 168: else { 169: printf("Too big"); 170: #ifdef MENLO_OVLY 171: if (ovlhdr.max_ovl != 0) 172: printf(": More than 8 segments used (%d base, %d overlay, %d data, 1 stack)\n", 173: segs(obj.a_text), segs(ovlhdr.max_ovl), 174: segs(obj.a_data+(long)obj.a_bss)); 175: else 176: #endif 177: if ((long)obj.a_text+obj.a_data+obj.a_bss <= MAXDATA) 178: printf(": try loading without -n\n"); 179: #ifdef MENLO_OVLY 180: /* 181: * Algorithm to determine if overlaying will work: 182: * assume one segment for base, rest of data divided into 183: * NOVL overlays, plus data and one segment for stack. 184: */ 185: else if (segs((obj.a_text-SSEG)/NOVL) 186: + segs((long)obj.a_data+obj.a_bss) + 2 <= 8) 187: printf(" (limit %u): Try overlaying\n", 188: (unsigned)MAXDATA); 189: #endif 190: else printf(" (limit %u bytes)\n", (unsigned)MAXDATA); 191: } 192: } else if (tsize) { 193: /* 194: * Was separate I/D. Offer helpful hints. 195: */ 196: if (((long)fullseg(obj.a_text) 197: + (long)obj.a_data + obj.a_bss) <= MAXDATA) 198: printf("Try loading with -n\n"); 199: else if (((long)obj.a_text + 200: (long)obj.a_data + obj.a_bss) <= MAXDATA) 201: printf("Try loading without -n or -i\n"); 202: #ifdef MENLO_OVLY 203: else if (ovlhdr.max_ovl==0 && segs((obj.a_text-SSEG)/NOVL) 204: + segs((long)obj.a_data+obj.a_bss) + 2 <= 8) 205: printf("Too big (limit %u bytes): try overlaying\n", 206: (unsigned)MAXDATA); 207: #endif 208: } 209: } else { 210: /* 211: * Not sflag. 212: */ 213: if (tsize > MAXTEXT) { 214: /* 215: * Can only happen when overlaid (text is 16 bits) 216: */ 217: fail++; 218: printf("More than 8 text segments: %d base, %d overlay\n", 219: segs(obj.a_text), segs(ovlhdr.max_ovl)); 220: } 221: if (size > MAXDATA) { 222: fail++; 223: printf("%s too big (limit %u bytes)\n", 224: tsize? "Data segment ": "", (unsigned)MAXDATA); 225: if (tsize == 0) 226: printf("Try loading with -i\n"); 227: 228: } 229: } 230: maxmem = MAXMEM; 231: nlist(UNIX, nl); 232: if (nl[0].n_value) { 233: int f = open(MEM, 0); 234: if (f>0) { 235: lseek(f, (off_t)nl[0].n_value, 0); 236: read(f, &maxmem, sizeof maxmem); 237: } 238: close(f); 239: } 240: bytesmax = lctob(maxmem); 241: if (totsize > bytesmax) { 242: fail++; 243: printf("Total size %D bytes, too large for this computer (%D maximum)\n", 244: totsize, bytesmax); 245: } 246: 247: if (fflag) { 248: /* 249: * fetch first instruction. 250: * if setd, then might require fpsim. 251: */ 252: 253: if ((read(fi,&ins,2)!=2)) 254: { 255: if (fail)printf(", "); 256: printf("not an object file.\n"); 257: close(fi); 258: return(1); 259: } 260: if ( ins == SETD ) 261: { 262: nlist(file,fpsim); 263: if (fpsim[1].n_type != N_UNDF && fpsim[0].n_type == N_UNDF) 264: { 265: printf("Uses floating point\n"); 266: fail = 1; 267: } 268: } 269: } 270: close(fi); 271: return(fail); 272: }