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