1: /* 2: * checksys 3: * checks the system size and reports any limits exceeded. 4: */ 5: 6: #include "param.h" 7: #include <a.out.h> 8: #include <stdio.h> 9: #include <sys/tty.h> 10: 11: #define KB * 1024 12: 13: /* 14: * Round up to a click boundary. 15: */ 16: #define cround(bytes) ((bytes + ctob(1) - 1) / ctob(1) * ctob(1)); 17: 18: struct exec obj; 19: struct ovlhdr ovlhdr; 20: 21: struct nlist nl[] = 22: { 23: "_end", 0, 0, 24: #define N_END 0 25: "_remap_a", 0, 0, 26: #define N_REMAPAREA 1 27: "NOKA5", 0, 0, 28: #define N_NOKA5 2 29: "_nbuf", 0, 0, 30: #define N_NBUF 3 31: "_bsize", 0, 0, 32: #define N_BSIZE 4 33: "UCB_CLIST", 0, 0, 34: #define N_CLIST 5 35: "_nclist", 0, 0, 36: #define N_NCLIST 6 37: 0 38: }; 39: 40: char *file; 41: int fi; 42: 43: main(argc,argv) 44: int argc; 45: char **argv; 46: { 47: register i; 48: long size, totsize; 49: int errs = 0; 50: int texterrs = 0; 51: 52: if (argc != 2) { 53: fprintf(stderr, "Usage: %s unix-binary\n", argv[0]); 54: exit(20); 55: } 56: file = argv[1]; 57: if ((fi=open(file,0)) < 0) 58: { 59: perror(file); 60: exit(20); 61: } 62: if (read(fi,&obj,sizeof(obj)) != sizeof(obj)) 63: { 64: printf("%s is not an object file.\n", file); 65: close(fi); 66: exit(20); 67: } 68: if (obj.a_magic == A_MAGIC5 || obj.a_magic == A_MAGIC6) 69: if (read(fi,&ovlhdr,sizeof(ovlhdr)) != sizeof(ovlhdr)) { 70: printf("%s is not an object file.\n", file); 71: close(fi); 72: exit(20); 73: } 74: switch(obj.a_magic) 75: { 76: 77: /* 78: * 0407-- nonseparate I/D "vanilla" 79: */ 80: case A_MAGIC1: 81: size = (long)obj.a_text + obj.a_data + obj.a_bss; 82: if (size > (unsigned) 48 KB) { 83: printf("Total size too large by %D bytes.\n", 84: size - (unsigned) 48 KB); 85: errs++; 86: } 87: totsize = cround(size); 88: break; 89: 90: /* 91: * 0411-- separate I/D 92: */ 93: case A_MAGIC3: 94: size = (long) obj.a_data + obj.a_bss; 95: if (size > (unsigned) 48 KB) { 96: printf("Data too large by %D bytes.\n", 97: size - (unsigned) 48 KB); 98: errs++; 99: } 100: totsize = obj.a_text + cround(size); 101: break; 102: 103: /* 104: * 0430-- overlaid nonseparate I/D 105: */ 106: case A_MAGIC5: 107: if (obj.a_text > 16 KB) { 108: printf("Base segment too large by %u bytes.\n", 109: obj.a_text - 16 KB); 110: errs++; 111: texterrs++; 112: } 113: if (obj.a_text <= 8 KB) { 114: printf("Base segment too small by %u bytes.\n", 115: 8 KB - obj.a_text); 116: errs++; 117: } 118: size = (long) obj.a_data + obj.a_bss; 119: if (size > 24 KB) { 120: printf("Data too large by %D bytes.\n", size - 24 KB); 121: errs++; 122: } 123: /* 124: * Base and overlay 1 occupy 16K and 8K of physical 125: * memory, respectively, regardless of actual size. 126: */ 127: totsize = 24 KB + cround(size); 128: /* 129: * Subtract the first overlay, it will be added below 130: * and it has already been included. 131: */ 132: totsize -= ovlhdr.ov_siz[0]; 133: goto checkov; 134: break; 135: 136: /* 137: * 0431-- overlaid separate I/D 138: */ 139: case A_MAGIC6: 140: if (obj.a_text > (unsigned) 56 KB) { 141: printf("Base segment too large by %u bytes.\n", 142: obj.a_text - (unsigned) 56 KB); 143: errs++; 144: } 145: if (obj.a_text <= (unsigned) 48 KB) { 146: printf("Base segment too small by %u bytes.\n", 147: (unsigned) 48 KB - obj.a_text); 148: errs++; 149: } 150: size = (long)obj.a_data + obj.a_bss; 151: if (size > (unsigned) 48 KB) { 152: printf("Data too large by %D bytes.\n", 153: size - (unsigned) 48 KB); 154: errs++; 155: } 156: totsize = (long)obj.a_text + cround(size); 157: checkov: 158: for (i=0; i<NOVL; i++) { 159: totsize += ovlhdr.ov_siz[i]; 160: if (ovlhdr.ov_siz[i] > 8 KB) { 161: printf("Overlay %d too large by %u bytes.\n", 162: i+1, ovlhdr.ov_siz[i] - 8 KB); 163: errs++; 164: texterrs++; 165: } 166: } 167: break; 168: 169: default: 170: printf("Magic number not recognized.\n"); 171: close(fi); 172: exit(20); 173: } 174: 175: nlist(file, nl); 176: if (nl[N_NOKA5].n_type == 0) { 177: fprintf(stderr, "Symbols not found in namelist\n"); 178: exit(20); 179: } 180: if (texterrs == 0) { 181: if (nl[N_NOKA5].n_value == 0) { 182: if (nl[N_REMAPAREA].n_value >= 0120000) { 183: printf("The remapping area (0120000-0140000, KDSD5)\n"); 184: printf("contains data other than the proc, text and file tables.\n"); 185: printf("Reduce other data by %u bytes.\n", nl[N_REMAPAREA].n_value - 0120000); 186: errs++; 187: } 188: } else { 189: if (nl[N_END].n_value >= 0120000) { 190: printf("Data extends into the remapping area (0120000-0140000, KDSD5)\n"); 191: printf("by %u bytes; undefine NOKA5 or reduce data size.\n", 192: nl[N_END].n_value - 0120000); 193: errs++; 194: } 195: } 196: } 197: 198: totsize += cround((long) getval(N_NBUF) * (long) getval(N_BSIZE)); 199: if (nl[N_CLIST].n_value) 200: totsize += cround((long) getval(N_NCLIST) 201: * (long) sizeof(struct cblock)); 202: totsize += ctob(USIZE); 203: printf("System will occupy %D bytes of memory (including buffers and clists).\n", 204: totsize); 205: 206: close(fi); 207: if (errs) 208: printf("**** SYSTEM IS NOT BOOTABLE.\n"); 209: exit(errs); 210: } 211: 212: #define round(x) (ctob(stoc(ctos(btoc(x))))) 213: /* 214: * Get the value of an initialized variable from the object file. 215: */ 216: getval(index) 217: { 218: int ret; 219: off_t offst; 220: 221: offst = (off_t)nl[index].n_value 222: + (off_t) obj.a_text + sizeof(obj); 223: if (obj.a_magic == A_MAGIC2 || obj.a_magic == A_MAGIC5) 224: offst -= (off_t)round(obj.a_text); 225: if (obj.a_magic == A_MAGIC5 || obj.a_magic == A_MAGIC6) { 226: register i; 227: offst += sizeof ovlhdr; 228: if (obj.a_magic == A_MAGIC5) 229: offst -= (off_t)round(ovlhdr.max_ovl); 230: for(i=0; i<NOVL; i++) 231: offst += (off_t)ovlhdr.ov_siz[i]; 232: } 233: lseek(fi, offst, 0); 234: read(fi, &ret, sizeof(ret)); 235: return(ret); 236: }