* stack.c (print_frame_info): When checking PC_IN_CALL_DUMMY,
[deliverable/binutils-gdb.git] / gas / symbols.c
CommitLineData
fecd2382 1/* symbols.c -symbol table-
6efd877d 2
2b68b820 3 Copyright (C) 1987, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
6efd877d 4
a39116f1 5 This file is part of GAS, the GNU Assembler.
6efd877d 6
a39116f1
RP
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
6efd877d 11
a39116f1
RP
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
6efd877d 16
a39116f1
RP
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
fecd2382 20
2b68b820
KR
21#define DEBUG
22
6efd877d
KR
23#include <ctype.h>
24
fecd2382
RP
25#include "as.h"
26
27#include "obstack.h" /* For "symbols.h" */
28#include "subsegs.h"
29
30#ifndef WORKING_DOT_WORD
31extern int new_broken_words;
32#endif
fecd2382 33
2b68b820
KR
34/* symbol-name => struct symbol pointer */
35static struct hash_control *sy_hash;
fecd2382 36
a39116f1 37/* Below are commented in "symbols.h". */
6efd877d
KR
38symbolS *symbol_rootP;
39symbolS *symbol_lastP;
40symbolS abs_symbol;
fecd2382 41
6efd877d
KR
42symbolS *dot_text_symbol;
43symbolS *dot_data_symbol;
44symbolS *dot_bss_symbol;
fecd2382 45
6efd877d 46struct obstack notes;
fecd2382 47
85825401 48static void fb_label_init PARAMS ((void));
fecd2382 49
fecd2382 50void
6efd877d 51symbol_begin ()
fecd2382 52{
6efd877d
KR
53 symbol_lastP = NULL;
54 symbol_rootP = NULL; /* In case we have 0 symbols (!!) */
55 sy_hash = hash_new ();
56 memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
2b68b820
KR
57#ifdef BFD_ASSEMBLER
58 abs_symbol.bsym = bfd_abs_section.symbol;
59#else
60 /* Can't initialise a union. Sigh. */
61 S_SET_SEGMENT (&abs_symbol, absolute_section);
62#endif
6efd877d
KR
63#ifdef LOCAL_LABELS_FB
64 fb_label_init ();
65#endif /* LOCAL_LABELS_FB */
fecd2382 66}
fecd2382 67
fecd2382
RP
68/*
69 * symbol_new()
70 *
71 * Return a pointer to a new symbol.
72 * Die if we can't make a new symbol.
73 * Fill in the symbol's values.
74 * Add symbol to end of symbol chain.
75 *
76 *
77 * Please always call this to create a new symbol.
78 *
79 * Changes since 1985: Symbol names may not contain '\0'. Sigh.
80 * 2nd argument is now a SEG rather than a TYPE. The mapping between
81 * segments and types is mostly encapsulated herein (actually, we inherit it
82 * from macros in struc-symbol.h).
83 */
84
6efd877d
KR
85symbolS *
86symbol_new (name, segment, value, frag)
2b68b820 87 CONST char *name; /* It is copied, the caller can destroy/modify */
6efd877d 88 segT segment; /* Segment identifier (SEG_<something>) */
2b68b820 89 valueT value; /* Symbol value */
6efd877d 90 fragS *frag; /* Associated fragment */
fecd2382 91{
6efd877d
KR
92 unsigned int name_length;
93 char *preserved_copy_of_name;
94 symbolS *symbolP;
95
96 name_length = strlen (name) + 1; /* +1 for \0 */
97 obstack_grow (&notes, name, name_length);
98 preserved_copy_of_name = obstack_finish (&notes);
2b68b820
KR
99#ifdef STRIP_UNDERSCORE
100 if (preserved_copy_of_name[0] == '_')
101 preserved_copy_of_name++;
102#endif
6efd877d
KR
103 symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
104
105 /* symbol must be born in some fixed state. This seems as good as any. */
106 memset (symbolP, 0, sizeof (symbolS));
107
2b68b820
KR
108
109#ifdef BFD_ASSEMBLER
110 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
111 assert (symbolP->bsym != 0);
112 symbolP->bsym->udata = (PTR) symbolP;
113#endif
6efd877d 114 S_SET_NAME (symbolP, preserved_copy_of_name);
6efd877d
KR
115
116 S_SET_SEGMENT (symbolP, segment);
117 S_SET_VALUE (symbolP, value);
2b68b820 118 symbol_clear_list_pointers(symbolP);
6efd877d
KR
119
120 symbolP->sy_frag = frag;
2b68b820 121#ifndef BFD_ASSEMBLER
6efd877d
KR
122 symbolP->sy_number = ~0;
123 symbolP->sy_name_offset = ~0;
2b68b820 124#endif
6efd877d
KR
125
126 /*
2b68b820
KR
127 * Link to end of symbol chain.
128 */
6efd877d
KR
129 symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
130
131 obj_symbol_new_hook (symbolP);
132
fecd2382 133#ifdef DEBUG
2b68b820 134 verify_symbol_chain(symbol_rootP, symbol_lastP);
fecd2382 135#endif /* DEBUG */
fecd2382 136
2b68b820
KR
137 return symbolP;
138}
fecd2382 139\f
6efd877d 140
fecd2382
RP
141/*
142 * colon()
143 *
144 * We have just seen "<name>:".
145 * Creates a struct symbol unless it already exists.
146 *
147 * Gripes if we are redefining a symbol incompatibly (and ignores it).
148 *
149 */
6efd877d
KR
150void
151colon (sym_name) /* just seen "x:" - rattle symbols & frags */
152 register char *sym_name; /* symbol name, as a cannonical string */
153 /* We copy this string: OK to alter later. */
fecd2382 154{
6efd877d
KR
155 register symbolS *symbolP; /* symbol we are working with */
156
fecd2382 157#ifdef LOCAL_LABELS_DOLLAR
2b68b820
KR
158 /* Sun local labels go out of scope whenever a non-local symbol is
159 defined. */
6efd877d
KR
160
161 if (*sym_name != 'L')
162 dollar_label_clear ();
163#endif /* LOCAL_LABELS_DOLLAR */
164
fecd2382 165#ifndef WORKING_DOT_WORD
6efd877d
KR
166 if (new_broken_words)
167 {
168 struct broken_word *a;
169 int possible_bytes;
170 fragS *frag_tmp;
171 char *frag_opcode;
172
2b68b820
KR
173 extern const int md_short_jump_size;
174 extern const int md_long_jump_size;
175 possible_bytes = (md_short_jump_size
176 + new_broken_words * md_long_jump_size);
6efd877d
KR
177
178 frag_tmp = frag_now;
179 frag_opcode = frag_var (rs_broken_word,
180 possible_bytes,
181 possible_bytes,
182 (relax_substateT) 0,
183 (symbolS *) broken_words,
184 0L,
185 NULL);
186
187 /* We want to store the pointer to where to insert the jump table in the
2b68b820
KR
188 fr_opcode of the rs_broken_word frag. This requires a little
189 hackery. */
190 while (frag_tmp
191 && (frag_tmp->fr_type != rs_broken_word
192 || frag_tmp->fr_opcode))
6efd877d
KR
193 frag_tmp = frag_tmp->fr_next;
194 know (frag_tmp);
195 frag_tmp->fr_opcode = frag_opcode;
196 new_broken_words = 0;
197
198 for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
199 a->dispfrag = frag_tmp;
200 }
201#endif /* WORKING_DOT_WORD */
202
203 if ((symbolP = symbol_find (sym_name)) != 0)
204 {
2b68b820
KR
205#ifdef RESOLVE_SYMBOL_REDEFINITION
206 if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
6efd877d 207 return;
2b68b820 208#endif
6efd877d 209 /*
2b68b820
KR
210 * Now check for undefined symbols
211 */
6efd877d
KR
212 if (!S_IS_DEFINED (symbolP))
213 {
214 if (S_GET_VALUE (symbolP) == 0)
215 {
216 symbolP->sy_frag = frag_now;
2b68b820
KR
217#ifdef OBJ_VMS
218 S_GET_OTHER(symbolP) = const_flag;
fecd2382 219#endif
2b68b820 220 S_SET_VALUE (symbolP, (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal));
6efd877d 221 S_SET_SEGMENT (symbolP, now_seg);
fecd2382 222#ifdef N_UNDF
6efd877d 223 know (N_UNDF == 0);
fecd2382 224#endif /* if we have one, it better be zero. */
6efd877d
KR
225
226 }
227 else
228 {
229 /*
2b68b820
KR
230 * There are still several cases to check:
231 * A .comm/.lcomm symbol being redefined as
232 * initialized data is OK
233 * A .comm/.lcomm symbol being redefined with
234 * a larger size is also OK
235 *
236 * This only used to be allowed on VMS gas, but Sun cc
237 * on the sparc also depends on it.
238 */
239
240 if (((!S_IS_DEBUG (symbolP)
241 && !S_IS_DEFINED (symbolP)
242 && S_IS_EXTERNAL (symbolP))
243 || S_GET_SEGMENT (symbolP) == bss_section)
244 && (now_seg == data_section
245 || now_seg == S_GET_SEGMENT (symbolP)))
6efd877d
KR
246 {
247 /*
2b68b820
KR
248 * Select which of the 2 cases this is
249 */
250 if (now_seg != data_section)
6efd877d
KR
251 {
252 /*
2b68b820
KR
253 * New .comm for prev .comm symbol.
254 * If the new size is larger we just
255 * change its value. If the new size
256 * is smaller, we ignore this symbol
257 */
6efd877d 258 if (S_GET_VALUE (symbolP)
2b68b820 259 < ((unsigned) frag_now_fix ()))
6efd877d 260 {
2b68b820 261 S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
6efd877d
KR
262 }
263 }
264 else
265 {
85825401
ILT
266 /* It is a .comm/.lcomm being converted to initialized
267 data. */
6efd877d 268 symbolP->sy_frag = frag_now;
2b68b820
KR
269#ifdef OBJ_VMS
270 S_GET_OTHER(symbolP) = const_flag;
271#endif /* OBJ_VMS */
272 S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
6efd877d
KR
273 S_SET_SEGMENT (symbolP, now_seg); /* keep N_EXT bit */
274 }
275 }
276 else
277 {
2b68b820
KR
278#if defined (S_GET_OTHER) && defined (S_GET_DESC)
279 as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
6efd877d
KR
280 sym_name,
281 segment_name (S_GET_SEGMENT (symbolP)),
2b68b820
KR
282 S_GET_OTHER (symbolP), S_GET_DESC (symbolP),
283 (long) S_GET_VALUE (symbolP));
284#else
285 as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.",
6efd877d
KR
286 sym_name,
287 segment_name (S_GET_SEGMENT (symbolP)),
6efd877d 288 S_GET_VALUE (symbolP));
2b68b820 289#endif
6efd877d
KR
290 }
291 } /* if the undefined symbol has no value */
292 }
293 else
294 {
295 /* Don't blow up if the definition is the same */
296 if (!(frag_now == symbolP->sy_frag
2b68b820 297 && S_GET_VALUE (symbolP) == (char*)obstack_next_free (&frags) - frag_now->fr_literal
6efd877d
KR
298 && S_GET_SEGMENT (symbolP) == now_seg))
299 as_fatal ("Symbol %s already defined.", sym_name);
300 } /* if this symbol is not yet defined */
301
302 }
303 else
304 {
305 symbolP = symbol_new (sym_name,
306 now_seg,
2b68b820 307 (valueT) ((char*)obstack_next_free (&frags) - frag_now->fr_literal),
6efd877d 308 frag_now);
2b68b820 309#ifdef OBJ_VMS
6efd877d 310 S_SET_OTHER (symbolP, const_flag);
2b68b820 311#endif /* OBJ_VMS */
fecd2382 312
6efd877d
KR
313 symbol_table_insert (symbolP);
314 } /* if we have seen this symbol before */
2b68b820
KR
315#ifdef TC_HPPA
316 pa_define_label(symbolP);
317#endif
6efd877d
KR
318
319 return;
320} /* colon() */
fecd2382 321\f
6efd877d 322
fecd2382
RP
323/*
324 * symbol_table_insert()
325 *
326 * Die if we can't insert the symbol.
327 *
328 */
329
6efd877d
KR
330void
331symbol_table_insert (symbolP)
332 symbolS *symbolP;
fecd2382 333{
6efd877d
KR
334 register char *error_string;
335
336 know (symbolP);
337 know (S_GET_NAME (symbolP));
338
339 if (*(error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (char *) symbolP)))
340 {
341 as_fatal ("Inserting \"%s\" into symbol table failed: %s",
342 S_GET_NAME (symbolP), error_string);
343 } /* on error */
344} /* symbol_table_insert() */
fecd2382
RP
345\f
346/*
347 * symbol_find_or_make()
348 *
349 * If a symbol name does not exist, create it as undefined, and insert
350 * it into the symbol table. Return a pointer to it.
351 */
6efd877d
KR
352symbolS *
353symbol_find_or_make (name)
354 char *name;
fecd2382 355{
6efd877d
KR
356 register symbolS *symbolP;
357
358 symbolP = symbol_find (name);
359
360 if (symbolP == NULL)
361 {
362 symbolP = symbol_make (name);
363
364 symbol_table_insert (symbolP);
365 } /* if symbol wasn't found */
366
367 return (symbolP);
368} /* symbol_find_or_make() */
369
370symbolS *
371symbol_make (name)
2b68b820 372 CONST char *name;
fecd2382 373{
6efd877d
KR
374 symbolS *symbolP;
375
376 /* Let the machine description default it, e.g. for register names. */
2b68b820 377 symbolP = md_undefined_symbol ((char *) name);
6efd877d
KR
378
379 if (!symbolP)
2b68b820 380 symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
6efd877d
KR
381
382 return (symbolP);
383} /* symbol_make() */
fecd2382
RP
384
385/*
386 * symbol_find()
6efd877d 387 *
fecd2382
RP
388 * Implement symbol table lookup.
389 * In: A symbol's name as a string: '\0' can't be part of a symbol name.
390 * Out: NULL if the name was not in the symbol table, else the address
391 * of a struct symbol associated with that name.
392 */
393
6efd877d
KR
394symbolS *
395symbol_find (name)
2b68b820 396 CONST char *name;
fecd2382 397{
a6c6eaf8 398#ifdef STRIP_UNDERSCORE
6efd877d 399 return (symbol_find_base (name, 1));
a6c6eaf8 400#else /* STRIP_UNDERSCORE */
6efd877d 401 return (symbol_find_base (name, 0));
fecd2382 402#endif /* STRIP_UNDERSCORE */
6efd877d 403} /* symbol_find() */
fecd2382 404
6efd877d
KR
405symbolS *
406symbol_find_base (name, strip_underscore)
2b68b820 407 CONST char *name;
6efd877d 408 int strip_underscore;
fecd2382 409{
6efd877d
KR
410 if (strip_underscore && *name == '_')
411 name++;
412 return ((symbolS *) hash_find (sy_hash, name));
fecd2382
RP
413}
414
415/*
416 * Once upon a time, symbols were kept in a singly linked list. At
417 * least coff needs to be able to rearrange them from time to time, for
418 * which a doubly linked list is much more convenient. Loic did these
419 * as macros which seemed dangerous to me so they're now functions.
420 * xoxorich.
421 */
422
423/* Link symbol ADDME after symbol TARGET in the chain. */
6efd877d
KR
424void
425symbol_append (addme, target, rootPP, lastPP)
426 symbolS *addme;
427 symbolS *target;
428 symbolS **rootPP;
429 symbolS **lastPP;
fecd2382 430{
6efd877d
KR
431 if (target == NULL)
432 {
433 know (*rootPP == NULL);
434 know (*lastPP == NULL);
435 *rootPP = addme;
436 *lastPP = addme;
437 return;
438 } /* if the list is empty */
439
440 if (target->sy_next != NULL)
441 {
fecd2382 442#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 443 target->sy_next->sy_previous = addme;
fecd2382 444#endif /* SYMBOLS_NEED_BACKPOINTERS */
6efd877d
KR
445 }
446 else
447 {
448 know (*lastPP == target);
449 *lastPP = addme;
450 } /* if we have a next */
451
452 addme->sy_next = target->sy_next;
453 target->sy_next = addme;
454
fecd2382 455#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 456 addme->sy_previous = target;
fecd2382 457#endif /* SYMBOLS_NEED_BACKPOINTERS */
2b68b820 458}
fecd2382
RP
459
460#ifdef SYMBOLS_NEED_BACKPOINTERS
461/* Remove SYMBOLP from the list. */
6efd877d
KR
462void
463symbol_remove (symbolP, rootPP, lastPP)
464 symbolS *symbolP;
465 symbolS **rootPP;
466 symbolS **lastPP;
fecd2382 467{
6efd877d
KR
468 if (symbolP == *rootPP)
469 {
470 *rootPP = symbolP->sy_next;
471 } /* if it was the root */
472
473 if (symbolP == *lastPP)
474 {
475 *lastPP = symbolP->sy_previous;
476 } /* if it was the tail */
477
478 if (symbolP->sy_next != NULL)
479 {
480 symbolP->sy_next->sy_previous = symbolP->sy_previous;
481 } /* if not last */
482
483 if (symbolP->sy_previous != NULL)
484 {
485 symbolP->sy_previous->sy_next = symbolP->sy_next;
486 } /* if not first */
487
fecd2382 488#ifdef DEBUG
6efd877d 489 verify_symbol_chain (*rootPP, *lastPP);
fecd2382 490#endif /* DEBUG */
2b68b820 491}
fecd2382
RP
492
493/* Set the chain pointers of SYMBOL to null. */
6efd877d
KR
494void
495symbol_clear_list_pointers (symbolP)
496 symbolS *symbolP;
fecd2382 497{
6efd877d
KR
498 symbolP->sy_next = NULL;
499 symbolP->sy_previous = NULL;
2b68b820 500}
fecd2382
RP
501
502/* Link symbol ADDME before symbol TARGET in the chain. */
6efd877d
KR
503void
504symbol_insert (addme, target, rootPP, lastPP)
505 symbolS *addme;
506 symbolS *target;
507 symbolS **rootPP;
508 symbolS **lastPP;
fecd2382 509{
6efd877d
KR
510 if (target->sy_previous != NULL)
511 {
512 target->sy_previous->sy_next = addme;
513 }
514 else
515 {
516 know (*rootPP == target);
517 *rootPP = addme;
518 } /* if not first */
519
520 addme->sy_previous = target->sy_previous;
521 target->sy_previous = addme;
522 addme->sy_next = target;
523
fecd2382 524#ifdef DEBUG
6efd877d 525 verify_symbol_chain (*rootPP, *lastPP);
fecd2382 526#endif /* DEBUG */
2b68b820 527}
6efd877d 528
fecd2382
RP
529#endif /* SYMBOLS_NEED_BACKPOINTERS */
530
6efd877d
KR
531void
532verify_symbol_chain (rootP, lastP)
533 symbolS *rootP;
534 symbolS *lastP;
fecd2382 535{
6efd877d
KR
536 symbolS *symbolP = rootP;
537
538 if (symbolP == NULL)
2b68b820 539 return;
6efd877d
KR
540
541 for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
542 {
fecd2382 543#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 544 know (symbolP->sy_next->sy_previous == symbolP);
2b68b820
KR
545#else
546 /* Walk the list anyways, to make sure pointers are still good. */
547 *symbolP;
fecd2382 548#endif /* SYMBOLS_NEED_BACKPOINTERS */
2b68b820 549 }
6efd877d 550
2b68b820
KR
551 assert (lastP == symbolP);
552}
6efd877d 553
2b68b820
KR
554void
555verify_symbol_chain_2 (sym)
556 symbolS *sym;
557{
558 symbolS *p = sym, *n = sym;
559#ifdef SYMBOLS_NEED_BACKPOINTERS
560 while (symbol_previous (p))
561 p = symbol_previous (p);
562#endif
563 while (symbol_next (n))
564 n = symbol_next (n);
565 verify_symbol_chain (p, n);
566}
6efd877d 567
5868b1fe
ILT
568/* Resolve the value of a symbol. This is called during the final
569 pass over the symbol table to resolve any symbols with complex
570 values. */
571
572void
573resolve_symbol_value (symp)
574 symbolS *symp;
575{
576 if (symp->sy_resolved)
577 return;
578
579 if (symp->sy_resolving)
580 {
581 as_bad ("Symbol definition loop encountered at %s",
582 S_GET_NAME (symp));
583 S_SET_VALUE (symp, (valueT) 0);
584 }
585 else
586 {
587 symp->sy_resolving = 1;
588
589 if (symp->sy_value.X_seg == absolute_section)
590 S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
591 else if (symp->sy_value.X_seg == undefined_section)
592 {
593 resolve_symbol_value (symp->sy_value.X_add_symbol);
594
595#ifdef obj_frob_forward_symbol
596 /* Some object formats need to forward the segment. */
597 obj_frob_forward_symbol (symp);
598#endif
599
600 S_SET_VALUE (symp,
601 (symp->sy_value.X_add_number
602 + symp->sy_frag->fr_address
603 + S_GET_VALUE (symp->sy_value.X_add_symbol)));
604 }
605 else
606 {
607 /* More cases need to be added here. */
608 abort ();
609 }
610 }
611
612 symp->sy_resolved = 1;
613}
614
6efd877d
KR
615#ifdef LOCAL_LABELS_DOLLAR
616
617/* Dollar labels look like a number followed by a dollar sign. Eg, "42$".
618 They are *really* local. That is, they go out of scope whenever we see a
619 label that isn't local. Also, like fb labels, there can be multiple
620 instances of a dollar label. Therefor, we name encode each instance with
621 the instance number, keep a list of defined symbols separate from the real
622 symbol table, and we treat these buggers as a sparse array. */
623
2b68b820
KR
624static long *dollar_labels;
625static long *dollar_label_instances;
626static char *dollar_label_defines;
627static long dollar_label_count;
628static long dollar_label_max;
6efd877d
KR
629
630int
631dollar_label_defined (label)
632 long label;
633{
634 long *i;
635
636 know ((dollar_labels != NULL) || (dollar_label_count == 0));
637
638 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
639 if (*i == label)
640 return dollar_label_defines[i - dollar_labels];
6efd877d
KR
641
642 /* if we get here, label isn't defined */
2b68b820 643 return 0;
6efd877d
KR
644} /* dollar_label_defined() */
645
646static int
647dollar_label_instance (label)
648 long label;
649{
650 long *i;
651
652 know ((dollar_labels != NULL) || (dollar_label_count == 0));
653
654 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
655 if (*i == label)
656 return (dollar_label_instances[i - dollar_labels]);
6efd877d 657
2b68b820
KR
658 /* If we get here, we haven't seen the label before, therefore its instance
659 count is zero. */
660 return 0;
661}
6efd877d
KR
662
663void
664dollar_label_clear ()
665{
666 memset (dollar_label_defines, '\0', dollar_label_count);
2b68b820 667}
6efd877d
KR
668
669#define DOLLAR_LABEL_BUMP_BY 10
670
671void
672define_dollar_label (label)
673 long label;
674{
675 long *i;
676
677 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
678 if (*i == label)
679 {
680 ++dollar_label_instances[i - dollar_labels];
681 dollar_label_defines[i - dollar_labels] = 1;
682 return;
683 }
6efd877d
KR
684
685 /* if we get to here, we don't have label listed yet. */
686
687 if (dollar_labels == NULL)
688 {
689 dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
690 dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
691 dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
692 dollar_label_max = DOLLAR_LABEL_BUMP_BY;
693 dollar_label_count = 0;
6efd877d
KR
694 }
695 else if (dollar_label_count == dollar_label_max)
696 {
697 dollar_label_max += DOLLAR_LABEL_BUMP_BY;
698 dollar_labels = (long *) xrealloc ((char *) dollar_labels,
699 dollar_label_max * sizeof (long));
700 dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
701 dollar_label_max * sizeof (long));
702 dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
703 } /* if we needed to grow */
704
705 dollar_labels[dollar_label_count] = label;
706 dollar_label_instances[dollar_label_count] = 1;
707 dollar_label_defines[dollar_label_count] = 1;
708 ++dollar_label_count;
2b68b820 709}
6efd877d
KR
710
711/*
712 * dollar_label_name()
713 *
714 * Caller must copy returned name: we re-use the area for the next name.
715 *
2b68b820
KR
716 * The mth occurence of label n: is turned into the symbol "Ln^Am"
717 * where n is the label number and m is the instance number. "L" makes
718 * it a label discarded unless debugging and "^A"('\1') ensures no
719 * ordinary symbol SHOULD get the same name as a local label
720 * symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
6efd877d
KR
721 *
722 * fb labels get the same treatment, except that ^B is used in place of ^A.
723 */
724
725char * /* Return local label name. */
726dollar_label_name (n, augend)
727 register long n; /* we just saw "n$:" : n a number */
728 register int augend; /* 0 for current instance, 1 for new instance */
729{
730 long i;
731 /* Returned to caller, then copied. used for created names ("4f") */
732 static char symbol_name_build[24];
733 register char *p;
734 register char *q;
735 char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
736
737 know (n >= 0);
738 know (augend == 0 || augend == 1);
739 p = symbol_name_build;
740 *p++ = 'L';
741
742 /* Next code just does sprintf( {}, "%d", n); */
743 /* label number */
744 q = symbol_name_temporary;
745 for (*q++ = 0, i = n; i; ++q)
746 {
747 *q = i % 10 + '0';
748 i /= 10;
749 }
750 while ((*p = *--q) != '\0')
751 ++p;
752
753 *p++ = 1; /* ^A */
754
755 /* instance number */
756 q = symbol_name_temporary;
757 for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
758 {
759 *q = i % 10 + '0';
760 i /= 10;
761 }
762 while ((*p++ = *--q) != '\0');;
763
764 /* The label, as a '\0' ended string, starts at symbol_name_build. */
2b68b820
KR
765 return symbol_name_build;
766}
6efd877d
KR
767
768#endif /* LOCAL_LABELS_DOLLAR */
769
770#ifdef LOCAL_LABELS_FB
771
772/*
773 * Sombody else's idea of local labels. They are made by "n:" where n
774 * is any decimal digit. Refer to them with
775 * "nb" for previous (backward) n:
776 * or "nf" for next (forward) n:.
777 *
778 * We do a little better and let n be any number, not just a single digit, but
779 * since the other guy's assembler only does ten, we treat the first ten
780 * specially.
781 *
782 * Like someone else's assembler, we have one set of local label counters for
783 * entire assembly, not one set per (sub)segment like in most assemblers. This
784 * implies that one can refer to a label in another segment, and indeed some
785 * crufty compilers have done just that.
786 *
787 * Since there could be a LOT of these things, treat them as a sparse array.
788 */
789
790#define FB_LABEL_SPECIAL (10)
791
792static long fb_low_counter[FB_LABEL_SPECIAL];
793static long *fb_labels;
794static long *fb_label_instances;
795static long fb_label_count = 0;
796static long fb_label_max = 0;
797
798/* this must be more than FB_LABEL_SPECIAL */
799#define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
800
801static void
802fb_label_init ()
803{
804 memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
6efd877d
KR
805} /* fb_label_init() */
806
807/* add one to the instance number of this fb label */
808void
809fb_label_instance_inc (label)
810 long label;
811{
812 long *i;
813
814 if (label < FB_LABEL_SPECIAL)
815 {
816 ++fb_low_counter[label];
817 return;
818 }
819
e154ecf4 820 if (fb_labels != NULL)
6efd877d 821 {
e154ecf4
ILT
822 for (i = fb_labels + FB_LABEL_SPECIAL;
823 i < fb_labels + fb_label_count; ++i)
6efd877d 824 {
e154ecf4
ILT
825 if (*i == label)
826 {
827 ++fb_label_instances[i - fb_labels];
828 return;
829 } /* if we find it */
830 } /* for each existing label */
831 }
6efd877d
KR
832
833 /* if we get to here, we don't have label listed yet. */
834
835 if (fb_labels == NULL)
836 {
837 fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
838 fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
839 fb_label_max = FB_LABEL_BUMP_BY;
840 fb_label_count = FB_LABEL_SPECIAL;
841
842 }
843 else if (fb_label_count == fb_label_max)
844 {
845 fb_label_max += FB_LABEL_BUMP_BY;
846 fb_labels = (long *) xrealloc ((char *) fb_labels,
847 fb_label_max * sizeof (long));
848 fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
849 fb_label_max * sizeof (long));
850 } /* if we needed to grow */
851
852 fb_labels[fb_label_count] = label;
853 fb_label_instances[fb_label_count] = 1;
854 ++fb_label_count;
855 return;
856} /* fb_label_instance_inc() */
857
858static long
859fb_label_instance (label)
860 long label;
861{
862 long *i;
863
864 if (label < FB_LABEL_SPECIAL)
865 {
866 return (fb_low_counter[label]);
867 }
868
e154ecf4 869 if (fb_labels != NULL)
6efd877d 870 {
e154ecf4
ILT
871 for (i = fb_labels + FB_LABEL_SPECIAL;
872 i < fb_labels + fb_label_count; ++i)
6efd877d 873 {
e154ecf4
ILT
874 if (*i == label)
875 {
876 return (fb_label_instances[i - fb_labels]);
877 } /* if we find it */
878 } /* for each existing label */
879 }
6efd877d 880
e154ecf4
ILT
881 /* We didn't find the label, so this must be a reference to the
882 first instance. */
883 return 0;
2b68b820 884}
6efd877d
KR
885
886/*
887 * fb_label_name()
888 *
889 * Caller must copy returned name: we re-use the area for the next name.
890 *
2b68b820
KR
891 * The mth occurence of label n: is turned into the symbol "Ln^Bm"
892 * where n is the label number and m is the instance number. "L" makes
893 * it a label discarded unless debugging and "^B"('\2') ensures no
894 * ordinary symbol SHOULD get the same name as a local label
895 * symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
6efd877d 896 *
2b68b820 897 * dollar labels get the same treatment, except that ^A is used in place of ^B. */
6efd877d
KR
898
899char * /* Return local label name. */
900fb_label_name (n, augend)
901 long n; /* we just saw "n:", "nf" or "nb" : n a number */
902 long augend; /* 0 for nb, 1 for n:, nf */
903{
904 long i;
905 /* Returned to caller, then copied. used for created names ("4f") */
906 static char symbol_name_build[24];
907 register char *p;
908 register char *q;
909 char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
910
911 know (n >= 0);
912 know (augend == 0 || augend == 1);
913 p = symbol_name_build;
914 *p++ = 'L';
915
916 /* Next code just does sprintf( {}, "%d", n); */
917 /* label number */
918 q = symbol_name_temporary;
919 for (*q++ = 0, i = n; i; ++q)
920 {
921 *q = i % 10 + '0';
922 i /= 10;
923 }
924 while ((*p = *--q) != '\0')
925 ++p;
926
927 *p++ = 2; /* ^B */
928
929 /* instance number */
930 q = symbol_name_temporary;
931 for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
932 {
933 *q = i % 10 + '0';
934 i /= 10;
935 }
936 while ((*p++ = *--q) != '\0');;
937
938 /* The label, as a '\0' ended string, starts at symbol_name_build. */
939 return (symbol_name_build);
940} /* fb_label_name() */
941
942#endif /* LOCAL_LABELS_FB */
fecd2382
RP
943
944
a6c6eaf8 945/*
6efd877d
KR
946 * decode name that may have been generated by foo_label_name() above. If
947 * the name wasn't generated by foo_label_name(), then return it unaltered.
a6c6eaf8
RP
948 * This is used for error messages.
949 */
a39116f1 950
6efd877d
KR
951char *
952decode_local_label_name (s)
953 char *s;
a6c6eaf8 954{
6efd877d
KR
955 char *p;
956 char *symbol_decode;
957 int label_number;
958 int instance_number;
959 char *type;
960 const char *message_format = "\"%d\" (instance number %d of a %s label)";
961
962 if (s[0] != 'L')
963 return (s);
964
965 for (label_number = 0, p = s + 1; isdigit (*p); ++p)
966 {
967 label_number = (10 * label_number) + *p - '0';
968 }
969
970 if (*p == 1)
971 {
972 type = "dollar";
973 }
974 else if (*p == 2)
975 {
976 type = "fb";
977 }
978 else
979 {
980 return (s);
981 }
982
983 for (instance_number = 0, p = s + 1; isdigit (*p); ++p)
984 {
985 instance_number = (10 * instance_number) + *p - '0';
986 }
987
988 symbol_decode = obstack_alloc (&notes, strlen (message_format) + 30);
989 (void) sprintf (symbol_decode, message_format, label_number,
990 instance_number, type);
991
992 return (symbol_decode);
993} /* decode_local_label_name() */
a6c6eaf8 994
85051959
ILT
995/* Get the value of a symbol. */
996
997valueT
998S_GET_VALUE (s)
999 symbolS *s;
1000{
1001 if (s->sy_value.X_seg != absolute_section)
5868b1fe 1002 as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s));
85051959
ILT
1003 return (valueT) s->sy_value.X_add_number;
1004}
1005
1006/* Set the value of a symbol. */
1007
1008void
1009S_SET_VALUE (s, val)
1010 symbolS *s;
1011 valueT val;
1012{
1013 s->sy_value.X_seg = absolute_section;
1014 s->sy_value.X_add_number = (offsetT) val;
1015}
1016
2b68b820
KR
1017#ifdef BFD_ASSEMBLER
1018
1019int
1020S_IS_EXTERNAL (s)
1021 symbolS *s;
1022{
1023 flagword flags = s->bsym->flags;
1024
1025 /* sanity check */
1026 if (flags & BSF_LOCAL && flags & (BSF_EXPORT | BSF_GLOBAL))
1027 abort ();
1028
1029 return (flags & (BSF_EXPORT | BSF_GLOBAL)) != 0;
1030}
1031
1032int
1033S_IS_COMMON (s)
1034 symbolS *s;
1035{
1036 return s->bsym->section == &bfd_com_section;
1037}
1038
1039int
1040S_IS_DEFINED (s)
1041 symbolS *s;
1042{
1043 return s->bsym->section != undefined_section;
1044}
1045
1046int
1047S_IS_DEBUG (s)
1048 symbolS *s;
1049{
1050 if (s->bsym->flags & BSF_DEBUGGING)
1051 return 1;
1052 return 0;
1053}
1054
1055int
1056S_IS_LOCAL (s)
1057 symbolS *s;
1058{
1059 flagword flags = s->bsym->flags;
1060
1061 /* sanity check */
1062 if (flags & BSF_LOCAL && flags & (BSF_EXPORT | BSF_GLOBAL))
1063 abort ();
1064
1065 return (S_GET_NAME (s)
1066 && ! S_IS_DEBUG (s)
1067 && (strchr (S_GET_NAME (s), '\001')
1068 || strchr (S_GET_NAME (s), '\002')
1069 || (S_LOCAL_NAME (s)
1070 && !flagseen['L'])));
1071}
1072
1073int
1074S_IS_EXTERN (s)
1075 symbolS *s;
1076{
1077 return S_IS_EXTERNAL (s);
1078}
1079
1080int
1081S_IS_STABD (s)
1082 symbolS *s;
1083{
1084 return S_GET_NAME (s) == 0;
1085}
1086
2b68b820
KR
1087CONST char *
1088S_GET_NAME (s)
1089 symbolS *s;
1090{
1091 return s->bsym->name;
1092}
1093
1094segT
1095S_GET_SEGMENT (s)
1096 symbolS *s;
1097{
1098 return s->bsym->section;
1099}
1100
2b68b820
KR
1101void
1102S_SET_SEGMENT (s, seg)
1103 symbolS *s;
1104 segT seg;
1105{
1106 s->bsym->section = seg;
1107}
1108
1109void
1110S_SET_EXTERNAL (s)
1111 symbolS *s;
1112{
1113 s->bsym->flags |= BSF_EXPORT | BSF_GLOBAL;
1114 s->bsym->flags &= ~BSF_LOCAL;
1115}
1116
1117void
1118S_CLEAR_EXTERNAL (s)
1119 symbolS *s;
1120{
1121 s->bsym->flags |= BSF_LOCAL;
1122 s->bsym->flags &= ~(BSF_EXPORT | BSF_GLOBAL);
1123}
1124
1125void
1126S_SET_NAME (s, name)
1127 symbolS *s;
1128 char *name;
1129{
1130 s->bsym->name = name;
1131}
1132#endif /* BFD_ASSEMBLER */
1133
8b228fe9 1134/* end of symbols.c */
This page took 0.127226 seconds and 4 git commands to generate.