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