|
|
1.1 root 1: /* symbols.c -symbol table-
2: Copyright (C) 1987 Free Software Foundation, Inc.
3:
4: This file is part of GAS, the GNU Assembler.
5:
6: GAS is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 1, or (at your option)
9: any later version.
10:
11: GAS is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GAS; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20: #include <stdlib.h>
21: #include <string.h>
22: #include "as.h"
23: #include "hash.h"
24: #include "obstack.h" /* For "symbols.h" */
25: #include "struc-symbol.h"
26: #include "symbols.h"
27: #include "frags.h"
28: #include "expr.h"
29: #include "sections.h"
30: #include "read.h"
31: #include "xmalloc.h"
32: #include "messages.h"
33: #include "fixes.h"
34: #include "input-scrub.h"
35:
36: /* symbol-name => struct symbol pointer */
37: struct hash_control *sy_hash = NULL;
38:
39: /* FixS & symbols live here */
40: struct obstack notes = { 0 };
41:
42: /* all the symbol nodes */
43: symbolS *symbol_rootP = NULL;
44: /* last struct symbol we made, or NULL */
45: symbolS *symbol_lastP = NULL;
46:
47: symbolS abs_symbol = { 0 };
48:
49: /*
50: * Un*x idea of local labels. They are made by "n:" where n
51: * is any decimal digit. Refer to them with
52: * "nb" for previous (backward) n:
53: * or "nf" for next (forward) n:.
54: *
55: * Like Un*x AS, we have one set of local label counters for entire assembly,
56: * not one set per (sub)segment like in most assemblers. This implies that
57: * one can refer to a label in another segment, and indeed some crufty
58: * compilers have done just that.
59: *
60: * I document the symbol names here to save duplicating words elsewhere.
61: * The mth occurence of label n: is turned into the symbol "Ln^Am" where
62: * n is a digit and m is a decimal number. "L" makes it a label discarded
63: * unless debugging and "^A"('\1') ensures no ordinary symbol SHOULD get the
64: * same name as a local label symbol. The first "4:" is "L4^A1" - the m
65: * numbers begin at 1.
66: */
67:
68: typedef short unsigned int local_label_countT;
69:
70: static local_label_countT local_label_counter[10];
71:
72: static /* Returned to caller, then copied. */
73: char symbol_name_build[12]; /* used for created names ("4f") */
74:
75: static void make_stab_for_symbol(
76: symbolS *symbolP);
77:
78:
79: void
80: symbol_begin(
81: void)
82: {
83: symbol_lastP = NULL;
84: symbol_rootP = NULL; /* In case we have 0 symbols (!!) */
85: sy_hash = hash_new();
86: memset((char *)(&abs_symbol), '\0', sizeof(abs_symbol));
87: abs_symbol.sy_type = N_ABS; /* Can't initialise a union. Sigh. */
88: memset((char *)(local_label_counter), '\0', sizeof(local_label_counter) );
89: }
90:
91: /*
92: * local_label_name()
93: *
94: * Caller must copy returned name: we re-use the area for the next name.
95: */
96: char * /* Return local label name. */
97: local_label_name(
98: int n, /* we just saw "n:", "nf" or "nb" : n a digit */
99: int augend) /* 0 for nb, 1 for n:, nf */
100: {
101: register char * p;
102: register char * q;
103: char symbol_name_temporary[10]; /* build up a number, BACKWARDS */
104:
105: know( n >= 0 );
106: know( augend == 0 || augend == 1 );
107: p = symbol_name_build;
108: * p ++ = 'L';
109: * p ++ = n + '0'; /* Make into ASCII */
110: * p ++ = 1; /* ^A */
111: n = local_label_counter [ n ] + augend;
112: /* version number of this local label */
113: /*
114: * Next code just does sprintf( {}, "%d", n);
115: * It is more elegant to do the next part recursively, but a procedure
116: * call for each digit emitted is considered too costly.
117: */
118: q = symbol_name_temporary;
119: for (*q++=0; n; q++) /* emits NOTHING if n starts as 0 */
120: {
121: know(n>0); /* We expect n > 0 always */
122: *q = n % 10 + '0';
123: n /= 10;
124: }
125: while (( * p ++ = * -- q ))
126: {
127: }
128: /* The label, as a '\0' ended string, starts at symbol_name_build. */
129: return (symbol_name_build);
130: }
131:
132: void
133: local_colon(
134: int n) /* just saw "n:" */
135: {
136: local_label_counter [n] ++;
137: colon (local_label_name (n, 0));
138: }
139:
140: /*
141: * symbol_new()
142: *
143: * Return a pointer to a new symbol.
144: * Die if we can't make a new symbol.
145: * Fill in the symbol's values.
146: * Add symbol to end of symbol chain.
147: *
148: *
149: * Please always call this to create a new symbol.
150: *
151: * Changes since 1985: Symbol names may not contain '\0'. Sigh.
152: */
153: symbolS *
154: symbol_new(
155: char *name, /* We copy this: OK to alter your copy. */
156: unsigned char type, /* As in <nlist.h>. */
157: char other, /* As in <nlist.h>. */
158: short desc, /* As in <nlist.h>. */
159: valueT value, /* As in <nlist.h>, often an address. */
160: /* Often used as offset from frag address. */
161: struct frag *frag) /* For sy_frag. */
162: {
163: register symbolS * symbolP;
164: register char * preserved_copy_of_name;
165: register unsigned int name_length;
166: char * p;
167:
168: name_length = strlen(name) + 1;
169: obstack_grow(¬es,name,name_length);
170: p=obstack_finish(¬es);
171: /* obstack_1done( ¬es, name, name_length, &p ); */
172: preserved_copy_of_name = p;
173: p=obstack_alloc(¬es,sizeof(struct symbol));
174: /* obstack_1blank( ¬es, sizeof(struct symbol), &p ); */
175: symbolP = (symbolS *) p;
176: symbolP -> sy_name = preserved_copy_of_name;
177: symbolP -> sy_type = type;
178: symbolP -> sy_other = other;
179: symbolP -> sy_desc = desc;
180: symbolP -> sy_value = value;
181: symbolP -> sy_frag = frag;
182: symbolP -> sy_next = NULL; /* End of chain. */
183: symbolP -> sy_forward = NULL; /* JF */
184: #ifdef SUSPECT
185: symbolP -> sy_name_offset = ~ 0; /* Impossible offset catches errors. */
186: symbolP -> sy_number = ~ 0; /* Ditto. */
187: #endif
188: /*
189: * Link to end of symbol chain.
190: */
191: if (symbol_lastP)
192: {
193: symbol_lastP -> sy_next = symbolP;
194: }
195: else
196: {
197: symbol_rootP = symbolP;
198: }
199: symbol_lastP = symbolP;
200:
201: return (symbolP);
202: }
203:
204: /*
205: * colon()
206: *
207: * We have just seen "<name>:".
208: * Creates a struct symbol unless it already exists.
209: *
210: * Gripes if we are redefining a symbol incompatibly (and ignores it).
211: *
212: */
213: void
214: colon( /* just seen "x:" - rattle symbols & frags */
215: char *sym_name) /* symbol name, as a cannonical string */
216: /* We copy this string: OK to alter later. */
217: {
218: register struct symbol * symbolP; /* symbol we are working with */
219:
220: if (frchain_now == NULL)
221: {
222: know(flagseen['n']);
223: as_fatal("with -n a section directive must be seen before assembly "
224: "can begin");
225: }
226: if ((symbolP = symbol_table_lookup( sym_name )))
227: {
228: /*
229: * Now check for undefined symbols
230: */
231: if ((symbolP -> sy_type & N_TYPE) == N_UNDF)
232: {
233: if( symbolP -> sy_other == 0
234: /* -O causes this not to work */
235: && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0
236: && symbolP -> sy_value == 0)
237: {
238: symbolP -> sy_frag = frag_now;
239: symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
240: know( N_UNDF == 0 );
241: symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */
242: symbolP -> sy_other = frchain_now->frch_nsect;
243: symbolP -> sy_desc &= ~REFERENCE_TYPE;
244: #ifdef NeXT /* generate stabs for debugging assembly code */
245: if(flagseen['g'])
246: make_stab_for_symbol(symbolP);
247: #endif
248: }
249: else
250: {
251: as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
252: sym_name,
253: seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]],
254: symbolP -> sy_other, symbolP -> sy_desc,
255: symbolP -> sy_value);
256: }
257: }
258: else
259: {
260: as_fatal("Symbol %s already defined.",sym_name);
261: }
262: }
263: else
264: {
265: symbolP = symbol_new (sym_name,
266: N_SECT,
267: frchain_now->frch_nsect,
268: 0,
269: (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
270: frag_now);
271: symbol_table_insert (symbolP);
272: #ifdef NeXT /* generate stabs for debugging assembly code */
273: if(flagseen['g'])
274: make_stab_for_symbol(symbolP);
275: #endif
276: }
277: }
278:
279:
280: /*
281: * symbol_table_insert()
282: *
283: * Die if we can't insert the symbol.
284: *
285: */
286: void
287: symbol_table_insert(
288: struct symbol *symbolP)
289: {
290: register char * error_string;
291:
292: know( symbolP );
293: know( symbolP -> sy_name );
294: if ( * (error_string = hash_jam (sy_hash, symbolP -> sy_name, (char *)symbolP)))
295: {
296: as_fatal( "Inserting \"%s\" into symbol table failed: %s",
297: symbolP -> sy_name, error_string);
298: }
299: }
300:
301: /*
302: * symbol_find_or_make()
303: *
304: * If a symbol name does not exist, create it as undefined, and insert
305: * it into the symbol table. Return a pointer to it.
306: */
307: symbolS *
308: symbol_find_or_make(
309: char *name)
310: {
311: register symbolS * symbolP;
312:
313: symbolP = symbol_table_lookup (name);
314: if (symbolP == NULL)
315: {
316: symbolP = symbol_new (name, N_UNDF, 0, 0, 0, & zero_address_frag);
317: symbol_table_insert (symbolP);
318: }
319: return (symbolP);
320: }
321:
322: /*
323: * symbol_find()
324: *
325: * Implement symbol table lookup.
326: * In: A symbol's name as a string: '\0' can't be part of a symbol name.
327: * Out: NULL if the name was not in the symbol table, else the address
328: * of a struct symbol associated with that name.
329: */
330: symbolS *
331: symbol_find(
332: char *name)
333: {
334: return ( (symbolS *) hash_find( sy_hash, name ));
335: }
336:
337: #ifdef NeXT /* generate stabs for debugging assembly code */
338: /*
339: * make_stab_for_symbol() is called when -g is present for a label that is
340: * being defined. If the label is a text label and in the (__TEXT,__text)
341: * section and not a local label create a stab for it.
342: *
343: * See the detailed comments about stabs in read_a_source_file() for a
344: * description of what is going on here.
345: */
346: static
347: void
348: make_stab_for_symbol(
349: symbolS *symbolP)
350: {
351: symbolS *stab;
352: int stabnamelen;
353: char *stabname;
354:
355: if(symbolP->sy_name[0] == 'L')
356: return;
357: if((symbolP->sy_type & N_TYPE) != N_SECT)
358: return;
359: if(symbolP->sy_other != text_nsect)
360: return;
361:
362: stabnamelen = strlen(symbolP->sy_name) + sizeof(":f3");
363: stabname = xmalloc(stabnamelen);
364: strcpy(stabname, symbolP->sy_name);
365: if(symbolP->sy_type & N_EXT)
366: strcat(stabname, ":F3");
367: else
368: strcat(stabname, ":f3");
369:
370: stab = symbol_new(
371: stabname,
372: 36, /* N_FUN */
373: text_nsect, /* n_sect */
374: logical_input_line, /* n_desc, line number */
375: symbolP->sy_value,
376: symbolP->sy_frag);
377: free(stabname);
378: }
379: #endif /* NeXT generate stabs for debugging assembly code */
380:
381: /*
382: * indirect_symbol_new()
383: *
384: * Return a pointer to a new indirect_symbol.
385: * Die if we can't make a new indirect_symbol.
386: * Fill in the indirect_symbol's values.
387: * Add symbol to end of section's indirect symbol chain.
388: */
389: isymbolS *
390: indirect_symbol_new(
391: char *name, /* We copy this: OK to alter your copy. */
392: struct frag *frag, /* For sy_frag. */
393: unsigned long offset) /* Offset from frag address. */
394: {
395: isymbolS *isymbolP;
396: char *preserved_copy_of_name;
397: unsigned long name_length;
398: char *p;
399: struct frag *fr_next;
400: #ifdef CHECK_INDIRECTS
401: unsigned long stride, fr_fix;
402: #endif
403:
404: /*
405: * First see if the last frag recorded for an indirect symbol turned
406: * out to be zero sized then changed that recorded frag to the next
407: * non-zero frag in the list. I think this happens because we record
408: * the frag before we fill it and if we run out of space that frag gets
409: * a zero size and a new one is created.
410: */
411: if(frchain_now->frch_isym_last != NULL &&
412: frchain_now->frch_isym_last->isy_frag->fr_fix == 0){
413: if(frchain_now->frch_isym_last->isy_frag->fr_next != NULL){
414: fr_next = frchain_now->frch_isym_last->isy_frag->fr_next;
415: while(fr_next->fr_fix == 0 &&
416: fr_next->fr_type == rs_fill &&
417: fr_next->fr_next != NULL)
418: fr_next = fr_next->fr_next;
419: frchain_now->frch_isym_last->isy_frag = fr_next;
420: }
421: }
422:
423: name_length = strlen(name) + 1;
424: obstack_grow(¬es, name, name_length);
425: p = obstack_finish(¬es);
426: preserved_copy_of_name = p;
427: p = obstack_alloc(¬es, sizeof(struct indirect_symbol));
428: isymbolP = (isymbolS *)p;
429: isymbolP->isy_name = preserved_copy_of_name;
430: isymbolP->isy_offset = offset;
431: isymbolP->isy_frag = frag;
432: isymbolP->isy_next = NULL; /* End of chain. */
433: isymbolP->isy_symbol = NULL;
434:
435: /*
436: * Link to end of indirect symbol chain and check for missing indirect
437: * symbols.
438: */
439: if(frchain_now->frch_isym_root == NULL){
440: #ifdef CHECK_INDIRECTS
441: if(offset != 0)
442: as_warn("missing or bad indirect symbol for section (%s,%s)",
443: frchain_now->frch_section.segname,
444: frchain_now->frch_section.sectname);
445: #endif
446: frchain_now->frch_isym_root = isymbolP;
447: frchain_now->frch_isym_last = isymbolP;
448: }
449: else{
450: #ifdef CHECK_INDIRECTS
451: if((frchain_now->frch_section.flags & SECTION_TYPE) ==
452: S_SYMBOL_STUBS)
453: stride = frchain_now->frch_section.reserved2;
454: else
455: stride = sizeof(unsigned long);
456: if(frag == frchain_now->frch_isym_last->isy_frag){
457: if(offset - frchain_now->frch_isym_last->isy_offset != stride)
458: as_warn("missing or bad indirect symbol for section "
459: "(%s,%s)", frchain_now->frch_section.segname,
460: frchain_now->frch_section.sectname);
461: }
462: else{
463: if(frchain_now->frch_isym_last->isy_frag->fr_fix < stride){
464: fr_fix = 0;
465: fr_next = frchain_now->frch_isym_last->isy_frag;
466: while(fr_fix + fr_next->fr_fix < stride &&
467: fr_next->fr_type == rs_fill &&
468: fr_next->fr_next != NULL){
469: fr_fix += fr_next->fr_fix;
470: fr_next = fr_next->fr_next;
471: }
472: if(frag != fr_next->fr_next ||
473: fr_fix + fr_next->fr_fix != stride ||
474: offset != 0)
475: as_warn("missing or bad indirect symbol for section "
476: "(%s,%s)", frchain_now->frch_section.segname,
477: frchain_now->frch_section.sectname);
478: }
479: else{
480: fr_next = frchain_now->frch_isym_last->isy_frag->fr_next;
481: /*
482: * Because of section changes there maybe some zero length
483: * frags after the last one that passed through here. So
484: * skip them and get to the last real one.
485: */
486: while(fr_next->fr_fix == 0 &&
487: fr_next->fr_type == rs_fill &&
488: fr_next->fr_next != NULL)
489: fr_next = fr_next->fr_next;
490: if(frag != fr_next || offset != 0)
491: as_warn("missing or bad indirect symbol for section "
492: "(%s,%s)", frchain_now->frch_section.segname,
493: frchain_now->frch_section.sectname);
494: }
495: }
496: #endif
497: frchain_now->frch_isym_last->isy_next = isymbolP;
498: frchain_now->frch_isym_last = isymbolP;
499: }
500: return(isymbolP);
501: }
502:
503: /* end: symbols.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.