Annotation of researchv9/cmd/sun/ld/incl.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.