Annotation of researchv9/cmd/sun/ld/incl.c, revision 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.