|
|
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.