|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)sym.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 <a.out.h>
10: #include "as.h"
11: #include "scan.h"
12:
13: /* Allocation increments for symbol buckets and character blocks */
14: #define SYM_INCR 50
15: #define CBLOCK_INCR 512
16:
17: extern struct stab_sym_bkt *stabkt_head;
18:
19: struct sym_bkt *last_symbol; /* last symbol defined */
20: struct sym_bkt *sym_hash_tab[HASH_MAX]; /* Symbol hash table */
21: struct sym_bkt *sym_free = NULL; /* head of free list */
22: char *cblock = NULL; /* storage for symbol names */
23: int ccnt = 0; /* number of chars left in c block */
24: int ntlabels = 0;
25:
26: /* grab a new symbol bucket off of the free list; allocate space
27: * for a new free list if necessary
28: */
29: struct sym_bkt *
30: gsbkt()
31: { register struct sym_bkt *sbp;
32: register int i;
33:
34: if ((sbp = sym_free) != NULL) sym_free = sbp->next_s;
35: else {
36: sbp = (struct sym_bkt *)calloc(SYM_INCR,sizeof(struct sym_bkt));
37: if (sbp == NULL) sys_error("Symbol storage exceeded\n",0);
38: for (i = SYM_INCR-1; i--;) {
39: sbp->next_s = sym_free;
40: sym_free = sbp++;
41: }
42: }
43:
44: return(sbp);
45: }
46:
47: /* initialize hash table */
48: sym_init()
49: { register int i;
50:
51: for (i=0; i<HASH_MAX; i++) sym_hash_tab[i] = NULL;
52: } /* end Sym_Init */
53:
54: char *sstring(string)
55: register char *string;
56: { register char *p,*q; /* working char string */
57: register int i;
58:
59: i = strlen(string); /* get length of string */
60:
61: if (++i > ccnt) { /* if not enough room get more */
62: if ((cblock = (char *)calloc(CBLOCK_INCR,1)) == NULL)
63: sys_error("Symbol storage exceeded\n",0);
64: ccnt = CBLOCK_INCR;
65: }
66:
67: p = q = cblock; /* copy string into permanent storage */
68: while (*p++ = *string++);
69: cblock = p;
70: ccnt -= i;
71: return(q);
72: } /* end sstring */
73:
74: /* lookup symbol in symbol table */
75: struct sym_bkt *
76: lookup(s)
77: register char *s;
78: { register struct sym_bkt *sbp; /* general purpose ptr */
79: register int Save; /* save subscript in sym_hash_tab */
80: register char *p;
81: static char local[250]; /* used for constructing local sym */
82: extern char *ll_format;
83:
84: if (*s>='0' && *s<='9') { /* local symbol hackery */
85: /* we hope no-one uses really long local symbols */
86: p = local;
87: while ((*p++ = *s++) && (p < &local[sizeof local-1]));/* copy local symbol */
88: p--;
89: s = last_symbol->name_s; /* add last symbol defined as suffix */
90: while ((*p++ = *s++) && (p < &local[sizeof local-1]));
91: s = local; /* this becomes name to deal with */
92: }
93:
94: /* if the symbol is already in here, return a ptr to it */
95: for (sbp = sym_hash_tab[Save=hash(s)]; sbp != NULL ; sbp = sbp->next_s)
96: if (strcmp(sbp->name_s,s) == 0) return(sbp);
97:
98: /* Since it's not, make a bucket for it, and put the bucket in the symbol table */
99: sbp = gsbkt(); /* get the bucket */
100: sbp->name_s = sstring(s); /* Store it's name */
101: sbp->value_s = sbp->id_s = sbp->attr_s = 0;
102: sbp->csect_s = C_UNDEF;
103: sbp->next_s = sym_hash_tab[Save]; /* and insert on top of list */
104: if (s == local || *s == *ll_format) sbp->attr_s |= S_LOCAL;
105: return(sym_hash_tab[Save] = sbp);
106: }
107:
108: /* Sym_Fix - Assigns index numbers to the symbols. Also performs
109: relocation of the symbols assuming data segment follows
110: text and bss follows the data. If global flag, make all
111: undefined symbols defined to be externals.
112: */
113:
114: /* symbol value compare -- for sorting */
115: static int
116: symvc( a, b )
117: struct sym_bkt **a, **b;
118: {
119: return ((*a)->value_s - (*b)->value_s);
120: }
121:
122: sym_fix()
123: {
124: register struct sym_bkt **sbp1, *sbp2;
125: int i = 0;
126: register int t;
127: struct sym_bkt **symlistlist;
128: register struct sym_bkt **syml;
129:
130: symlistlist = syml = (struct sym_bkt **)calloc( ntlabels, sizeof *symlistlist );
131: for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
132: for (sbp2 = *sbp1; sbp2; sbp2 = sbp2->next_s) {
133: if ((sbp2->attr_s & (S_DEC|S_DEF)) == 0) {
134: sbp2->attr_s |= S_EXT | S_DEC;
135: sbp2->csect_s = C_UNDEF;
136: }
137: switch (sbp2->csect_s) {
138: case C_TEXT:
139: if (sbp2 != dot_bkt && !(sbp2->attr_s & S_PERM))
140: *syml++ = sbp2;
141: break;
142: case C_DATA:
143: sbp2->value_s += tsize; break;
144: case C_DATA1:
145: sbp2->value_s += tsize + dsize; break;
146: case C_DATA2:
147: sbp2->value_s += tsize + dsize + d1size; break;
148: case C_BSS:
149: sbp2->value_s += tsize + dsize + d1size + d2size; break;
150: }
151: if (sbp2==dot_bkt || sbp2->attr_s & (S_REG|S_LOCAL|S_PERM))
152: sbp2->id_s = -1;
153: else
154: sbp2->id_s = i++;
155: }
156: /* consistancy check */
157: if (syml - symlistlist != ntlabels)
158: sys_error("wrong number of text labels: %d found\n", syml-symlistlist);
159: /* sort C_TEXT symbols on value */
160: qsort( symlistlist, ntlabels, sizeof *symlistlist, symvc );
161: /* and go update those labels using the sdi information */
162: sdi_sym_update( symlistlist, ntlabels );
163: free( symlistlist );
164: }
165:
166:
167: /* sym_write - Write out the symbols to the specified
168: file in b.out format, while computing size
169: of the symbol segment in output file.
170: */
171:
172: redosyms()
173: {
174: /* Go through the symbol table and get rid of "L" syms if
175: we are supposed to. */
176: long size = 0;
177: register struct sym_bkt **sbp1, *sbp2;
178:
179: for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
180: if (sbp2 = *sbp1)
181: for (; sbp2; sbp2 = sbp2->next_s)
182: {
183: if (sbp2->id_s != -1 && chkname(sbp2)) {
184: sbp2->final = size++;
185: }
186: }
187: }
188:
189: long sym_write(file)
190: FILE *file;
191: { register struct sym_bkt **sbp1, *sbp2;
192: long size = 0;
193: struct nlist s;
194: int strcount = 4;
195: struct stab_sym_bkt *t;
196:
197: for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
198: if (sbp2 = *sbp1) for (; sbp2; sbp2 = sbp2->next_s)
199: if (sbp2->id_s != -1 && chkname(sbp2)) {
200: /* Write out the symbol table using the VAX a.out format */
201: if ((sbp2->attr_s&S_DEF)== 0) {
202: s.n_type = N_UNDF;
203: if (*(sbp2->name_s) == 'L' ) {
204: prog_warning( E_UNDEFINED_L ); /* Undefined L-symbol */
205: }
206: } else {
207: switch (sbp2->csect_s){
208: case C_TEXT:
209: s.n_type = N_TEXT; break;
210: case C_UNDEF:
211: s.n_type = N_ABS; break;
212: case C_BSS:
213: s.n_type = N_BSS; break;
214: default:
215: s.n_type = (rflag)?N_TEXT:N_DATA; break;
216: }
217: }
218: if (sbp2->attr_s & S_EXT) s.n_type |= N_EXT;
219: s.n_value = sbp2->value_s;
220: /* For right now, just stuff these with 0 */
221: s.n_other = s.n_desc = 0;
222: s.n_un.n_strx = strcount;
223: strcount += strlen(sbp2->name_s)+1;
224: size += sizeof(s);
225: fwrite(&s,sizeof(s),1,file);
226: } else if (!(sbp2->attr_s & S_DEF)){
227: PROG_ERROR( E_UNDEFINED_L );
228: }
229:
230: /* This is to write out the .stabs and .stabd symbols onto the */
231: /* a.out file. This is only being written after the regular */
232: /* symbols have been put out (the prior section of the function). */
233: t = stabkt_head; /* obtain head of stabs/stabd symbol table */
234: while (t != NULL)
235: { s.n_type = t->type;
236: s.n_other = t->other;
237: s.n_desc = t->desc;
238: s.n_value = t->value; /* zero for testing now */
239: if (t->id)
240: { s.n_un.n_strx = strcount; /* assign string offset */
241: strcount += t->id + 1; /* increment str location */
242: } /* in string table. */
243: else s.n_un.n_strx = 0; /* else if no string is */
244: /* present, assign 0. */
245: size += sizeof(s);
246: fwrite(&s, sizeof(s), 1, file);
247: t = t->next_stab;
248: } /* end while */
249: return(size);
250: }
251:
252: long
253: str_write(file)
254: FILE *file;
255: {
256: long size = 0;
257: long strcount = 4;
258: register struct sym_bkt **sbp1, *sbp2;
259: struct stab_sym_bkt *t;
260:
261:
262: fwrite(&strcount,sizeof(long),1,file);
263: for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
264: if (sbp2 = *sbp1) for (; sbp2; sbp2 = sbp2->next_s)
265: if (chkname(sbp2))
266: {
267: if (sbp2->id_s != -1) {
268: register i;
269: strcount += i = strlen(sbp2->name_s)+1;
270: fwrite(sbp2->name_s,i,1,file);
271: }
272: }
273:
274: /* This is to write out all the symbols (strings) generated by */
275: /* .stabs and .stabd directives. They are being written onto the */
276: /* string table only after all the regular symbol tables have been */
277: /* written out (by the prior section of this function. */
278: t = stabkt_head; /* head of stabs/stabd link list */
279: while (t != NULL)
280: { register i;
281: if (t->id)
282: { strcount += i = t->id + 1;
283: fwrite(t->ch,i,1,file);
284: }
285: t = t->next_stab;
286: } /* end while */
287: return(strcount);
288: }
289:
290: chkname(name)
291: struct sym_bkt *name;
292: {
293: extern char o_lflag;
294:
295: if(o_lflag) return (1);
296: if ( *(name->name_s)!='L') return(1);
297: if ( (name->attr_s&S_DEF) == 0) return(1); /* don't zap undef L's */
298: return(0);
299: }
300:
301: /*
302: * Perm Flags all currently defined symbols as permanent (and therefore
303: * ineligible for redefinition. Also prevents them from being output
304: * in the object file).
305: */
306: perm()
307: { register struct sym_bkt **sbp1, *sbp2;
308:
309: for (sbp1 = sym_hash_tab; sbp1 < &sym_hash_tab[HASH_MAX]; sbp1++)
310: for (sbp2 = *sbp1; sbp2; sbp2 = sbp2->next_s)
311: sbp2->attr_s |= S_PERM;
312: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.