|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)incl.c 1.1 86/02/03 Copyr 1984 Sun Micro"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1984 by Sun Microsystems, Inc. ! 7: */ ! 8: ! 9: #include <stdio.h> ! 10: #include <a.out.h> ! 11: #include <stab.h> ! 12: #include <ctype.h> ! 13: ! 14: /* ! 15: * Info about each include file ! 16: */ ! 17: struct incl { ! 18: char *name; /* Name of header file */ ! 19: int nstatic; /* # of statics in the file */ ! 20: int nsymbols; /* # of symbols in header file */ ! 21: int checksum; /* Checksum for header file */ ! 22: int ord; /* Ordinal # of header file */ ! 23: int exclude; /* Flag: include/exclude syms */ ! 24: struct incl *next; /* Linked Hash list */ ! 25: }; ! 26: ! 27: #define NINCL_STACK 10 /* Size of the include stack */ ! 28: #define INCL_HASH 64 /* Size of header file hash table */ ! 29: ! 30: static struct incl **incl_stack; /* Include file stack */ ! 31: static int stack_size; /* Size of incl_stack */ ! 32: static struct incl **stkp; /* Stack pointer */ ! 33: static struct incl *incl_table[INCL_HASH]; /* Table saved for pass 2 */ ! 34: static struct incl *cur_incl; /* Current header file */ ! 35: static int obj_ord; /* Saved value of header_num */ ! 36: ! 37: extern int ssize; /* Size of symbol section */ ! 38: extern int header_num; /* Ordinal value of next header file */ ! 39: ! 40: struct incl *find_ord(); ! 41: char *strcpy(); ! 42: char *malloc(); ! 43: ! 44: /* ! 45: * Allocate the intial include file stack. ! 46: * The stack will grow if necessary. ! 47: */ ! 48: alloc_inclstack() ! 49: { ! 50: incl_stack = (struct incl **) malloc(NINCL_STACK*sizeof(struct incl *)); ! 51: stkp = incl_stack; ! 52: stack_size = NINCL_STACK; ! 53: } ! 54: ! 55: /* ! 56: * Beginning a new object file. Remember the ordinal number ! 57: * of the next header file in case this object file is not ! 58: * used and everything needs to be ripped out and thrown away. ! 59: */ ! 60: new_obj1() ! 61: { ! 62: obj_ord = header_num; ! 63: } ! 64: ! 65: /* ! 66: * Enter a new include file. ! 67: * Stack the current one, if it is active. ! 68: * Allocate a structure and initialize it. ! 69: */ ! 70: start_incl1(sym, ord) ! 71: struct nlist *sym; ! 72: int ord; ! 73: { ! 74: char *name; ! 75: int n; ! 76: ! 77: if (stkp > &incl_stack[stack_size]) { ! 78: n = stkp - incl_stack; ! 79: stack_size += NINCL_STACK; ! 80: incl_stack = (struct incl **) realloc(incl_stack, ! 81: stack_size * sizeof(struct incl *)); ! 82: stkp = &incl_stack[n]; ! 83: } ! 84: *stkp++ = cur_incl; ! 85: name = sym->n_un.n_name; ! 86: cur_incl = (struct incl *) malloc(sizeof(struct incl)); ! 87: cur_incl->name = strcpy(malloc(strlen(name) + 1), name); ! 88: cur_incl->nstatic = 0; ! 89: cur_incl->nsymbols = 0; ! 90: cur_incl->checksum = 0; ! 91: cur_incl->ord = ord; ! 92: cur_incl->exclude = 0; ! 93: cur_incl->next = NULL; ! 94: } ! 95: ! 96: /* ! 97: * Found the end of an include file. ! 98: * Hash on its name and enter it into the ! 99: * has table. Pass two will find it by ! 100: * its name and ordinal number. ! 101: * Also, pop one off of the stack. ! 102: */ ! 103: end_incl1() ! 104: { ! 105: int h; ! 106: ! 107: h = hash(cur_incl->name); ! 108: cur_incl->next = incl_table[h]; ! 109: incl_table[h] = cur_incl; ! 110: cur_incl = *--stkp; ! 111: } ! 112: ! 113: /* ! 114: * Found a dbx symbol in pass one. ! 115: * If there is an active header file, include the info. ! 116: * The checksum is the summation of all the letters, underscores, ! 117: * and equals signs in the n_name field of the nlist ! 118: * structure. ! 119: * ! 120: * The equals signs are counted because they are present whenever ! 121: * new type is defined. We want to insure that each inclusion of ! 122: * a header file defines the same number of types. ! 123: */ ! 124: stab1(sym) ! 125: struct nlist *sym; ! 126: { ! 127: register char *cp; ! 128: ! 129: if (cur_incl == NULL) { ! 130: return; ! 131: } ! 132: cur_incl->nsymbols++; ! 133: if (sym->n_type == N_STSYM || sym->n_type == N_LCSYM) { ! 134: cur_incl->nstatic++; ! 135: } ! 136: cp = sym->n_un.n_name; ! 137: if (sym->n_type != N_EXCL && cp != NULL) { ! 138: while (*cp != '\0') { ! 139: if (isalpha(*cp) || *cp == '_' || *cp == '=') { ! 140: cur_incl->checksum += *cp; ! 141: } ! 142: cp++; ! 143: } ! 144: } ! 145: } ! 146: ! 147: /* ! 148: * An object file was not used. ! 149: * Must remove any header files it had from the hash table. ! 150: */ ! 151: incl_free() ! 152: { ! 153: struct incl *ip; ! 154: struct incl *next; ! 155: struct incl **ipp; ! 156: struct incl **bpatch; ! 157: int nhdrs; ! 158: int removed; ! 159: ! 160: if (obj_ord == header_num) { ! 161: return; ! 162: } ! 163: removed = 0; ! 164: nhdrs = header_num - obj_ord; ! 165: for (ipp = incl_table; ipp < &incl_table[INCL_HASH]; ipp++) { ! 166: bpatch = ipp; ! 167: for (ip = *ipp; ip != NULL; ip = next) { ! 168: next = ip->next; ! 169: if (ip->ord >= obj_ord) { ! 170: *bpatch = ip->next; ! 171: free((char *) ip); ! 172: removed++; ! 173: } else { ! 174: bpatch = &ip->next; ! 175: } ! 176: } ! 177: } ! 178: if (removed != nhdrs) { ! 179: fprintf(stderr, "incl_free removed %d nhdrs %d\n", ! 180: removed, nhdrs); ! 181: } ! 182: header_num = obj_ord; ! 183: } ! 184: ! 185: /* ! 186: * See what header files can be excluded from the final output. ! 187: * The important goal here is to determine how many symbols ! 188: * will be excluded so that "ssize" can be adjusted. "Ssize" ! 189: * determines the value that will be stored into the a_syms ! 190: * field of the a.out header and also determines where the ! 191: * string table will begin. ! 192: */ ! 193: merge_headers() ! 194: { ! 195: register struct incl *ip; ! 196: register struct incl **ipp; ! 197: ! 198: for (ipp = incl_table; ipp < &incl_table[INCL_HASH]; ipp++) { ! 199: for (ip = *ipp; ip != NULL; ip = ip->next) { ! 200: ip->exclude = find_prev(ip); ! 201: if (ip->exclude) { ! 202: ssize -= (ip->nsymbols + 1) * ! 203: sizeof(struct nlist); ! 204: } ! 205: } ! 206: } ! 207: cur_incl = NULL; ! 208: } ! 209: ! 210: /* ! 211: * Found the beginning of a header file in pass2. ! 212: * Find the struct for the header file created in pass1. ! 213: * See if there is an identical struct for a header file ! 214: * with a lower ordinal value. If so, the symbols in this ! 215: * file can be discarded. ! 216: */ ! 217: start_incl2(sym, ord) ! 218: struct nlist *sym; ! 219: int ord; ! 220: { ! 221: struct incl *ip; ! 222: int r; ! 223: ! 224: if (stkp > &incl_stack[NINCL_STACK]) { ! 225: error(1, "include stack too deep"); ! 226: } ! 227: *stkp++ = cur_incl; ! 228: cur_incl = find_ord(sym, ord); ! 229: sym->n_value = cur_incl->checksum; ! 230: if (cur_incl->exclude) { ! 231: sym->n_type = N_EXCL; ! 232: } ! 233: return(cur_incl->exclude); ! 234: } ! 235: ! 236: end_incl2() ! 237: { ! 238: cur_incl = *--stkp; ! 239: return(cur_incl != NULL && cur_incl->exclude); ! 240: } ! 241: ! 242: /* ! 243: * Find a header file with a given ordinal number. ! 244: */ ! 245: struct incl * ! 246: find_ord(sym, ord) ! 247: struct nlist *sym; ! 248: int ord; ! 249: { ! 250: register struct incl *ip; ! 251: int h; ! 252: ! 253: h = hash(sym->n_un.n_name); ! 254: for (ip = incl_table[h]; ip != NULL; ip = ip->next) { ! 255: if (ip->ord == ord) { ! 256: return(ip); ! 257: } ! 258: } ! 259: error(1, "no include table entry for header file '%s'", ! 260: sym->n_un.n_name); ! 261: } ! 262: ! 263: /* ! 264: * Try to find an identical header file with a lower ordinal number. ! 265: */ ! 266: find_prev(incl) ! 267: register struct incl *incl; ! 268: { ! 269: register struct incl *ip; ! 270: int h; ! 271: ! 272: if (incl->nstatic > 0) { ! 273: return(0); ! 274: } ! 275: h = hash(incl->name); ! 276: for (ip = incl_table[h]; ip != NULL; ip = ip->next) { ! 277: if (ip->nsymbols == incl->nsymbols && ! 278: ip->nstatic == 0 && ! 279: ip->checksum == incl->checksum && ! 280: ip->ord < incl->ord && ! 281: strcmp(incl->name, ip->name) == 0) { ! 282: return(1); ! 283: } ! 284: } ! 285: return(0); ! 286: } ! 287: ! 288: /* ! 289: * Compute a hash from a string. ! 290: * Simply sum the characters and mod. ! 291: */ ! 292: hash(str) ! 293: char *str; ! 294: { ! 295: register int sum; ! 296: register char *cp; ! 297: ! 298: sum = 0; ! 299: for (cp = str; *cp; cp++) { ! 300: sum += *cp; ! 301: } ! 302: return(sum % INCL_HASH); ! 303: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.