Fix v850 sanitization.
[deliverable/binutils-gdb.git] / gas / symbols.c
CommitLineData
fecd2382 1/* symbols.c -symbol table-
e95ef7c1 2 Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 1997
dacf29ea 3 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 17 You should have received a copy of the GNU General Public License
e95ef7c1
ILT
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
fecd2382 21
58d4951d 22/* #define DEBUG_SYMS / * to debug symbol list maintenance */
2b68b820 23
6efd877d
KR
24#include <ctype.h>
25
fecd2382
RP
26#include "as.h"
27
28#include "obstack.h" /* For "symbols.h" */
29#include "subsegs.h"
30
1356d77d
ILT
31/* This is non-zero if symbols are case sensitive, which is the
32 default. */
33int symbols_case_sensitive = 1;
34
fecd2382
RP
35#ifndef WORKING_DOT_WORD
36extern int new_broken_words;
37#endif
fecd2382 38
2b68b820
KR
39/* symbol-name => struct symbol pointer */
40static struct hash_control *sy_hash;
fecd2382 41
a39116f1 42/* Below are commented in "symbols.h". */
6efd877d
KR
43symbolS *symbol_rootP;
44symbolS *symbol_lastP;
45symbolS abs_symbol;
fecd2382 46
dacf29ea
KR
47#ifdef DEBUG_SYMS
48#define debug_verify_symchain verify_symbol_chain
49#else
8095b665 50#define debug_verify_symchain(root, last) ((void) 0)
dacf29ea
KR
51#endif
52
6efd877d 53struct obstack notes;
fecd2382 54
85825401 55static void fb_label_init PARAMS ((void));
f59fb6ca
ILT
56static long dollar_label_instance PARAMS ((long));
57static long fb_label_instance PARAMS ((long));
fecd2382 58
dacf29ea
KR
59/* symbol_new()
60
61 Return a pointer to a new symbol. Die if we can't make a new
62 symbol. Fill in the symbol's values. Add symbol to end of symbol
63 chain.
64
65 This function should be called in the general case of creating a
66 symbol. However, if the output file symbol table has already been
67 set, and you are certain that this symbol won't be wanted in the
68 output file, you can call symbol_create. */
fecd2382 69
6efd877d 70symbolS *
604633ae 71symbol_new (name, segment, valu, frag)
dacf29ea
KR
72 const char *name;
73 segT segment;
74 valueT valu;
75 fragS *frag;
76{
77 symbolS *symbolP = symbol_create (name, segment, valu, frag);
78
79 /*
80 * Link to end of symbol chain.
81 */
82#ifdef BFD_ASSEMBLER
83 {
84 extern int symbol_table_frozen;
85 if (symbol_table_frozen)
86 abort ();
87 }
88#endif
89 symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
dacf29ea
KR
90
91 return symbolP;
92}
93
94symbolS *
95symbol_create (name, segment, valu, frag)
96 const char *name; /* It is copied, the caller can destroy/modify */
6efd877d 97 segT segment; /* Segment identifier (SEG_<something>) */
604633ae 98 valueT valu; /* Symbol value */
6efd877d 99 fragS *frag; /* Associated fragment */
fecd2382 100{
6efd877d
KR
101 unsigned int name_length;
102 char *preserved_copy_of_name;
103 symbolS *symbolP;
104
105 name_length = strlen (name) + 1; /* +1 for \0 */
106 obstack_grow (&notes, name, name_length);
107 preserved_copy_of_name = obstack_finish (&notes);
2b68b820
KR
108#ifdef STRIP_UNDERSCORE
109 if (preserved_copy_of_name[0] == '_')
110 preserved_copy_of_name++;
111#endif
dacf29ea
KR
112
113#ifdef tc_canonicalize_symbol_name
114 preserved_copy_of_name =
115 tc_canonicalize_symbol_name (preserved_copy_of_name);
116#endif
117
1356d77d
ILT
118 if (! symbols_case_sensitive)
119 {
120 unsigned char *s;
121
122 for (s = (unsigned char *) preserved_copy_of_name; *s != '\0'; s++)
123 if (islower (*s))
124 *s = toupper (*s);
125 }
126
6efd877d
KR
127 symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
128
129 /* symbol must be born in some fixed state. This seems as good as any. */
130 memset (symbolP, 0, sizeof (symbolS));
131
2b68b820
KR
132#ifdef BFD_ASSEMBLER
133 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
943bdfdc
ILT
134 if (symbolP->bsym == NULL)
135 as_perror ("%s", "bfd_make_empty_symbol");
87e48495 136 symbolP->bsym->udata.p = (PTR) symbolP;
2b68b820 137#endif
6efd877d 138 S_SET_NAME (symbolP, preserved_copy_of_name);
6efd877d
KR
139
140 S_SET_SEGMENT (symbolP, segment);
604633ae 141 S_SET_VALUE (symbolP, valu);
dacf29ea 142 symbol_clear_list_pointers (symbolP);
6efd877d
KR
143
144 symbolP->sy_frag = frag;
2b68b820 145#ifndef BFD_ASSEMBLER
6efd877d 146 symbolP->sy_number = ~0;
0cafaab1 147 symbolP->sy_name_offset = (unsigned int) ~0;
2b68b820 148#endif
6efd877d 149
6efd877d
KR
150 obj_symbol_new_hook (symbolP);
151
dacf29ea
KR
152#ifdef tc_symbol_new_hook
153 tc_symbol_new_hook (symbolP);
154#endif
fecd2382 155
2b68b820
KR
156 return symbolP;
157}
fecd2382 158\f
6efd877d 159
fecd2382
RP
160/*
161 * colon()
162 *
163 * We have just seen "<name>:".
164 * Creates a struct symbol unless it already exists.
165 *
166 * Gripes if we are redefining a symbol incompatibly (and ignores it).
167 *
168 */
1356d77d 169symbolS *
6efd877d 170colon (sym_name) /* just seen "x:" - rattle symbols & frags */
2a0f64a5 171 const char *sym_name; /* symbol name, as a cannonical string */
6efd877d 172 /* We copy this string: OK to alter later. */
fecd2382 173{
6efd877d
KR
174 register symbolS *symbolP; /* symbol we are working with */
175
2b68b820
KR
176 /* Sun local labels go out of scope whenever a non-local symbol is
177 defined. */
e95ef7c1
ILT
178 if (LOCAL_LABELS_DOLLAR)
179 {
180 int local;
181
182#ifdef BFD_ASSEMBLER
183 local = bfd_is_local_label_name (stdoutput, sym_name);
184#else
185 local = LOCAL_LABEL (sym_name);
186#endif
187
188 if (! local)
189 dollar_label_clear ();
190 }
6efd877d 191
fecd2382 192#ifndef WORKING_DOT_WORD
6efd877d
KR
193 if (new_broken_words)
194 {
195 struct broken_word *a;
196 int possible_bytes;
197 fragS *frag_tmp;
198 char *frag_opcode;
199
2b68b820
KR
200 extern const int md_short_jump_size;
201 extern const int md_long_jump_size;
202 possible_bytes = (md_short_jump_size
203 + new_broken_words * md_long_jump_size);
6efd877d
KR
204
205 frag_tmp = frag_now;
206 frag_opcode = frag_var (rs_broken_word,
207 possible_bytes,
208 possible_bytes,
209 (relax_substateT) 0,
210 (symbolS *) broken_words,
f59fb6ca 211 (offsetT) 0,
6efd877d
KR
212 NULL);
213
214 /* We want to store the pointer to where to insert the jump table in the
2b68b820
KR
215 fr_opcode of the rs_broken_word frag. This requires a little
216 hackery. */
217 while (frag_tmp
218 && (frag_tmp->fr_type != rs_broken_word
219 || frag_tmp->fr_opcode))
6efd877d
KR
220 frag_tmp = frag_tmp->fr_next;
221 know (frag_tmp);
222 frag_tmp->fr_opcode = frag_opcode;
223 new_broken_words = 0;
224
225 for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
226 a->dispfrag = frag_tmp;
227 }
228#endif /* WORKING_DOT_WORD */
229
230 if ((symbolP = symbol_find (sym_name)) != 0)
231 {
2b68b820
KR
232#ifdef RESOLVE_SYMBOL_REDEFINITION
233 if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
1356d77d 234 return symbolP;
2b68b820 235#endif
6efd877d 236 /*
2b68b820
KR
237 * Now check for undefined symbols
238 */
2051ec0e 239 if (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
6efd877d
KR
240 {
241 if (S_GET_VALUE (symbolP) == 0)
242 {
243 symbolP->sy_frag = frag_now;
2b68b820 244#ifdef OBJ_VMS
214f540d 245 S_SET_OTHER(symbolP, const_flag);
fecd2382 246#endif
87e48495 247 S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
6efd877d 248 S_SET_SEGMENT (symbolP, now_seg);
fecd2382 249#ifdef N_UNDF
6efd877d 250 know (N_UNDF == 0);
fecd2382 251#endif /* if we have one, it better be zero. */
6efd877d
KR
252
253 }
254 else
255 {
256 /*
2b68b820
KR
257 * There are still several cases to check:
258 * A .comm/.lcomm symbol being redefined as
259 * initialized data is OK
260 * A .comm/.lcomm symbol being redefined with
261 * a larger size is also OK
262 *
263 * This only used to be allowed on VMS gas, but Sun cc
264 * on the sparc also depends on it.
265 */
266
267 if (((!S_IS_DEBUG (symbolP)
2051ec0e 268 && (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
2b68b820
KR
269 && S_IS_EXTERNAL (symbolP))
270 || S_GET_SEGMENT (symbolP) == bss_section)
271 && (now_seg == data_section
272 || now_seg == S_GET_SEGMENT (symbolP)))
6efd877d
KR
273 {
274 /*
2b68b820
KR
275 * Select which of the 2 cases this is
276 */
277 if (now_seg != data_section)
6efd877d
KR
278 {
279 /*
2b68b820
KR
280 * New .comm for prev .comm symbol.
281 * If the new size is larger we just
282 * change its value. If the new size
283 * is smaller, we ignore this symbol
284 */
6efd877d 285 if (S_GET_VALUE (symbolP)
2b68b820 286 < ((unsigned) frag_now_fix ()))
6efd877d 287 {
2b68b820 288 S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
6efd877d
KR
289 }
290 }
291 else
292 {
85825401
ILT
293 /* It is a .comm/.lcomm being converted to initialized
294 data. */
6efd877d 295 symbolP->sy_frag = frag_now;
2b68b820 296#ifdef OBJ_VMS
214f540d
KR
297 S_SET_OTHER(symbolP, const_flag);
298#endif
2b68b820 299 S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
6efd877d
KR
300 S_SET_SEGMENT (symbolP, now_seg); /* keep N_EXT bit */
301 }
302 }
303 else
304 {
2b68b820
KR
305#if defined (S_GET_OTHER) && defined (S_GET_DESC)
306 as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
6efd877d
KR
307 sym_name,
308 segment_name (S_GET_SEGMENT (symbolP)),
2b68b820
KR
309 S_GET_OTHER (symbolP), S_GET_DESC (symbolP),
310 (long) S_GET_VALUE (symbolP));
311#else
58d4951d 312 as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%ld.",
6efd877d
KR
313 sym_name,
314 segment_name (S_GET_SEGMENT (symbolP)),
58d4951d 315 (long) S_GET_VALUE (symbolP));
2b68b820 316#endif
6efd877d
KR
317 }
318 } /* if the undefined symbol has no value */
319 }
320 else
321 {
322 /* Don't blow up if the definition is the same */
323 if (!(frag_now == symbolP->sy_frag
87e48495 324 && S_GET_VALUE (symbolP) == frag_now_fix ()
6efd877d
KR
325 && S_GET_SEGMENT (symbolP) == now_seg))
326 as_fatal ("Symbol %s already defined.", sym_name);
327 } /* if this symbol is not yet defined */
328
329 }
330 else
331 {
87e48495 332 symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (),
6efd877d 333 frag_now);
2b68b820 334#ifdef OBJ_VMS
6efd877d 335 S_SET_OTHER (symbolP, const_flag);
2b68b820 336#endif /* OBJ_VMS */
fecd2382 337
6efd877d
KR
338 symbol_table_insert (symbolP);
339 } /* if we have seen this symbol before */
1e9cf565 340
1356d77d
ILT
341 if (mri_common_symbol != NULL)
342 {
343 /* This symbol is actually being defined within an MRI common
344 section. This requires special handling. */
345 symbolP->sy_value.X_op = O_symbol;
346 symbolP->sy_value.X_add_symbol = mri_common_symbol;
347 symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol);
348 symbolP->sy_frag = &zero_address_frag;
349 S_SET_SEGMENT (symbolP, expr_section);
350 symbolP->sy_mri_common = 1;
351 }
352
1e9cf565
ILT
353#ifdef tc_frob_label
354 tc_frob_label (symbolP);
2b68b820 355#endif
2051ec0e
ILT
356#ifdef obj_frob_label
357 obj_frob_label (symbolP);
358#endif
1356d77d
ILT
359
360 return symbolP;
1ecd6c4a 361}
fecd2382 362\f
6efd877d 363
fecd2382
RP
364/*
365 * symbol_table_insert()
366 *
367 * Die if we can't insert the symbol.
368 *
369 */
370
6efd877d
KR
371void
372symbol_table_insert (symbolP)
373 symbolS *symbolP;
fecd2382 374{
604633ae 375 register const char *error_string;
6efd877d
KR
376
377 know (symbolP);
378 know (S_GET_NAME (symbolP));
379
0cafaab1 380 if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
6efd877d
KR
381 {
382 as_fatal ("Inserting \"%s\" into symbol table failed: %s",
383 S_GET_NAME (symbolP), error_string);
384 } /* on error */
385} /* symbol_table_insert() */
fecd2382
RP
386\f
387/*
388 * symbol_find_or_make()
389 *
390 * If a symbol name does not exist, create it as undefined, and insert
391 * it into the symbol table. Return a pointer to it.
392 */
6efd877d
KR
393symbolS *
394symbol_find_or_make (name)
73255941 395 const char *name;
fecd2382 396{
6efd877d
KR
397 register symbolS *symbolP;
398
399 symbolP = symbol_find (name);
400
401 if (symbolP == NULL)
402 {
403 symbolP = symbol_make (name);
404
405 symbol_table_insert (symbolP);
406 } /* if symbol wasn't found */
407
408 return (symbolP);
409} /* symbol_find_or_make() */
410
411symbolS *
412symbol_make (name)
2b68b820 413 CONST char *name;
fecd2382 414{
6efd877d
KR
415 symbolS *symbolP;
416
417 /* Let the machine description default it, e.g. for register names. */
2b68b820 418 symbolP = md_undefined_symbol ((char *) name);
6efd877d
KR
419
420 if (!symbolP)
2b68b820 421 symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
6efd877d
KR
422
423 return (symbolP);
424} /* symbol_make() */
fecd2382
RP
425
426/*
427 * symbol_find()
6efd877d 428 *
fecd2382
RP
429 * Implement symbol table lookup.
430 * In: A symbol's name as a string: '\0' can't be part of a symbol name.
431 * Out: NULL if the name was not in the symbol table, else the address
432 * of a struct symbol associated with that name.
433 */
434
6efd877d
KR
435symbolS *
436symbol_find (name)
2b68b820 437 CONST char *name;
fecd2382 438{
a6c6eaf8 439#ifdef STRIP_UNDERSCORE
6efd877d 440 return (symbol_find_base (name, 1));
a6c6eaf8 441#else /* STRIP_UNDERSCORE */
6efd877d 442 return (symbol_find_base (name, 0));
fecd2382 443#endif /* STRIP_UNDERSCORE */
6efd877d 444} /* symbol_find() */
fecd2382 445
6efd877d
KR
446symbolS *
447symbol_find_base (name, strip_underscore)
2b68b820 448 CONST char *name;
6efd877d 449 int strip_underscore;
fecd2382 450{
6efd877d
KR
451 if (strip_underscore && *name == '_')
452 name++;
dacf29ea
KR
453
454#ifdef tc_canonicalize_symbol_name
455 {
456 char *copy;
457
458 copy = (char *) alloca (strlen (name) + 1);
459 strcpy (copy, name);
460 name = tc_canonicalize_symbol_name (copy);
461 }
462#endif
463
1356d77d
ILT
464 if (! symbols_case_sensitive)
465 {
466 unsigned char *copy;
467
468 copy = (unsigned char *) alloca (strlen (name) + 1);
469 name = (const char *) copy;
470 for (; *copy != '\0'; copy++)
471 if (islower (*copy))
472 *copy = toupper (*copy);
473 }
474
6efd877d 475 return ((symbolS *) hash_find (sy_hash, name));
fecd2382
RP
476}
477
478/*
479 * Once upon a time, symbols were kept in a singly linked list. At
480 * least coff needs to be able to rearrange them from time to time, for
481 * which a doubly linked list is much more convenient. Loic did these
482 * as macros which seemed dangerous to me so they're now functions.
483 * xoxorich.
484 */
485
486/* Link symbol ADDME after symbol TARGET in the chain. */
6efd877d
KR
487void
488symbol_append (addme, target, rootPP, lastPP)
489 symbolS *addme;
490 symbolS *target;
491 symbolS **rootPP;
492 symbolS **lastPP;
fecd2382 493{
6efd877d
KR
494 if (target == NULL)
495 {
496 know (*rootPP == NULL);
497 know (*lastPP == NULL);
e95ef7c1
ILT
498 addme->sy_next = NULL;
499#ifdef SYMBOLS_NEED_BACKPOINTERS
500 addme->sy_previous = NULL;
501#endif
6efd877d
KR
502 *rootPP = addme;
503 *lastPP = addme;
504 return;
505 } /* if the list is empty */
506
507 if (target->sy_next != NULL)
508 {
fecd2382 509#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 510 target->sy_next->sy_previous = addme;
fecd2382 511#endif /* SYMBOLS_NEED_BACKPOINTERS */
6efd877d
KR
512 }
513 else
514 {
515 know (*lastPP == target);
516 *lastPP = addme;
517 } /* if we have a next */
518
519 addme->sy_next = target->sy_next;
520 target->sy_next = addme;
521
fecd2382 522#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 523 addme->sy_previous = target;
fecd2382 524#endif /* SYMBOLS_NEED_BACKPOINTERS */
e95ef7c1
ILT
525
526 debug_verify_symchain (symbol_rootP, symbol_lastP);
2b68b820 527}
fecd2382 528
dacf29ea
KR
529/* Set the chain pointers of SYMBOL to null. */
530void
531symbol_clear_list_pointers (symbolP)
532 symbolS *symbolP;
533{
534 symbolP->sy_next = NULL;
535#ifdef SYMBOLS_NEED_BACKPOINTERS
536 symbolP->sy_previous = NULL;
537#endif
538}
539
fecd2382
RP
540#ifdef SYMBOLS_NEED_BACKPOINTERS
541/* Remove SYMBOLP from the list. */
6efd877d
KR
542void
543symbol_remove (symbolP, rootPP, lastPP)
544 symbolS *symbolP;
545 symbolS **rootPP;
546 symbolS **lastPP;
fecd2382 547{
6efd877d
KR
548 if (symbolP == *rootPP)
549 {
550 *rootPP = symbolP->sy_next;
551 } /* if it was the root */
552
553 if (symbolP == *lastPP)
554 {
555 *lastPP = symbolP->sy_previous;
556 } /* if it was the tail */
557
558 if (symbolP->sy_next != NULL)
559 {
560 symbolP->sy_next->sy_previous = symbolP->sy_previous;
561 } /* if not last */
562
563 if (symbolP->sy_previous != NULL)
564 {
565 symbolP->sy_previous->sy_next = symbolP->sy_next;
566 } /* if not first */
567
dacf29ea 568 debug_verify_symchain (*rootPP, *lastPP);
2b68b820 569}
fecd2382
RP
570
571/* Link symbol ADDME before symbol TARGET in the chain. */
6efd877d
KR
572void
573symbol_insert (addme, target, rootPP, lastPP)
574 symbolS *addme;
575 symbolS *target;
576 symbolS **rootPP;
577 symbolS **lastPP;
fecd2382 578{
6efd877d
KR
579 if (target->sy_previous != NULL)
580 {
581 target->sy_previous->sy_next = addme;
582 }
583 else
584 {
585 know (*rootPP == target);
586 *rootPP = addme;
587 } /* if not first */
588
589 addme->sy_previous = target->sy_previous;
590 target->sy_previous = addme;
591 addme->sy_next = target;
592
dacf29ea 593 debug_verify_symchain (*rootPP, *lastPP);
2b68b820 594}
6efd877d 595
fecd2382
RP
596#endif /* SYMBOLS_NEED_BACKPOINTERS */
597
6efd877d
KR
598void
599verify_symbol_chain (rootP, lastP)
600 symbolS *rootP;
601 symbolS *lastP;
fecd2382 602{
6efd877d
KR
603 symbolS *symbolP = rootP;
604
605 if (symbolP == NULL)
2b68b820 606 return;
6efd877d
KR
607
608 for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
609 {
fecd2382 610#ifdef SYMBOLS_NEED_BACKPOINTERS
e95ef7c1 611 assert (symbolP->sy_next->sy_previous == symbolP);
2b68b820
KR
612#else
613 /* Walk the list anyways, to make sure pointers are still good. */
604633ae 614 ;
fecd2382 615#endif /* SYMBOLS_NEED_BACKPOINTERS */
2b68b820 616 }
6efd877d 617
2b68b820
KR
618 assert (lastP == symbolP);
619}
6efd877d 620
2b68b820
KR
621void
622verify_symbol_chain_2 (sym)
623 symbolS *sym;
624{
625 symbolS *p = sym, *n = sym;
626#ifdef SYMBOLS_NEED_BACKPOINTERS
627 while (symbol_previous (p))
628 p = symbol_previous (p);
629#endif
630 while (symbol_next (n))
631 n = symbol_next (n);
632 verify_symbol_chain (p, n);
633}
6efd877d 634
5868b1fe
ILT
635/* Resolve the value of a symbol. This is called during the final
636 pass over the symbol table to resolve any symbols with complex
637 values. */
638
2051ec0e
ILT
639valueT
640resolve_symbol_value (symp, finalize)
5868b1fe 641 symbolS *symp;
2051ec0e 642 int finalize;
5868b1fe 643{
0cafaab1 644 int resolved;
2051ec0e
ILT
645 valueT final_val;
646 segT final_seg;
0cafaab1 647
5868b1fe 648 if (symp->sy_resolved)
2051ec0e
ILT
649 {
650 if (symp->sy_value.X_op == O_constant)
651 return (valueT) symp->sy_value.X_add_number;
652 else
653 return 0;
654 }
5868b1fe 655
0cafaab1 656 resolved = 0;
2051ec0e 657 final_seg = S_GET_SEGMENT (symp);
0cafaab1 658
5868b1fe
ILT
659 if (symp->sy_resolving)
660 {
2051ec0e
ILT
661 if (finalize)
662 as_bad ("Symbol definition loop encountered at %s", S_GET_NAME (symp));
663 final_val = 0;
0cafaab1 664 resolved = 1;
5868b1fe
ILT
665 }
666 else
667 {
2051ec0e
ILT
668 symbolS *add_symbol, *op_symbol;
669 offsetT left, right;
5ac34ac3 670 segT seg_left, seg_right;
2051ec0e 671 operatorT op;
5ac34ac3 672
5868b1fe
ILT
673 symp->sy_resolving = 1;
674
2051ec0e
ILT
675 /* Help out with CSE. */
676 add_symbol = symp->sy_value.X_add_symbol;
677 op_symbol = symp->sy_value.X_op_symbol;
678 final_val = symp->sy_value.X_add_number;
679 op = symp->sy_value.X_op;
3569064f 680
2051ec0e 681 switch (op)
5868b1fe 682 {
2051ec0e
ILT
683 default:
684 BAD_CASE (op);
685 break;
686
5ac34ac3 687 case O_absent:
2051ec0e 688 final_val = 0;
5ac34ac3 689 /* Fall through. */
2051ec0e 690
5ac34ac3 691 case O_constant:
2051ec0e
ILT
692 final_val += symp->sy_frag->fr_address;
693 if (final_seg == expr_section)
694 final_seg = absolute_section;
0cafaab1 695 resolved = 1;
5ac34ac3
ILT
696 break;
697
698 case O_symbol:
2051ec0e
ILT
699 case O_symbol_rva:
700 left = resolve_symbol_value (add_symbol, finalize);
701 do_symbol:
5868b1fe 702
1356d77d
ILT
703 if (symp->sy_mri_common)
704 {
705 /* This is a symbol inside an MRI common section. The
706 relocation routines are going to handle it specially.
707 Don't change the value. */
2051ec0e 708 resolved = add_symbol->sy_resolved;
1356d77d
ILT
709 break;
710 }
711
2051ec0e
ILT
712 if (finalize && final_val == 0)
713 copy_symbol_attributes (symp, add_symbol);
943bdfdc 714
943bdfdc 715 /* If we have equated this symbol to an undefined symbol, we
3569064f
ILT
716 keep X_op set to O_symbol, and we don't change
717 X_add_number. This permits the routine which writes out
718 relocation to detect this case, and convert the
719 relocation to be against the symbol to which this symbol
720 is equated. */
2051ec0e 721 if (! S_IS_DEFINED (add_symbol) || S_IS_COMMON (add_symbol))
e95ef7c1 722 {
2051ec0e
ILT
723 if (finalize)
724 {
725 symp->sy_value.X_op = O_symbol;
726 S_SET_SEGMENT (symp, S_GET_SEGMENT (add_symbol));
727 }
728 symp->sy_value.X_add_number = final_val;
729 final_val = 0;
730 resolved = add_symbol->sy_resolved;
731 goto exit_dont_set_value;
e95ef7c1 732 }
3569064f
ILT
733 else
734 {
2051ec0e
ILT
735 final_val += symp->sy_frag->fr_address + left;
736 if (final_seg == expr_section || final_seg == undefined_section)
737 final_seg = S_GET_SEGMENT (add_symbol);
3569064f 738 }
943bdfdc 739
2051ec0e 740 resolved = add_symbol->sy_resolved;
5ac34ac3
ILT
741 break;
742
743 case O_uminus:
744 case O_bit_not:
943bdfdc 745 case O_logical_not:
2051ec0e
ILT
746 left = resolve_symbol_value (add_symbol, finalize);
747
748 if (op == O_uminus)
749 left = -left;
750 else if (op == O_logical_not)
751 left = !left;
5ac34ac3 752 else
2051ec0e
ILT
753 left = ~left;
754
755 final_val += left + symp->sy_frag->fr_address;
756 if (final_seg == expr_section || final_seg == undefined_section)
757 final_seg = absolute_section;
758
759 resolved = add_symbol->sy_resolved;
5ac34ac3
ILT
760 break;
761
762 case O_multiply:
763 case O_divide:
764 case O_modulus:
765 case O_left_shift:
766 case O_right_shift:
767 case O_bit_inclusive_or:
768 case O_bit_or_not:
769 case O_bit_exclusive_or:
770 case O_bit_and:
3569064f 771 case O_add:
5ac34ac3 772 case O_subtract:
1356d77d
ILT
773 case O_eq:
774 case O_ne:
775 case O_lt:
776 case O_le:
777 case O_ge:
778 case O_gt:
73255941
ILT
779 case O_logical_and:
780 case O_logical_or:
2051ec0e
ILT
781 left = resolve_symbol_value (add_symbol, finalize);
782 right = resolve_symbol_value (op_symbol, finalize);
783 seg_left = S_GET_SEGMENT (add_symbol);
784 seg_right = S_GET_SEGMENT (op_symbol);
785
786 /* Simplify addition or subtraction of a constant by folding the
787 constant into X_add_number. */
788 if (op == O_add || op == O_subtract)
789 {
790 if (seg_right == absolute_section)
791 {
792 if (op == O_add)
793 final_val += right;
794 else
795 final_val -= right;
796 op = O_symbol;
797 op_symbol = NULL;
798 goto do_symbol;
799 }
800 else if (seg_left == absolute_section && op == O_add)
801 {
802 op = O_symbol;
803 final_val += left;
804 add_symbol = op_symbol;
805 left = right;
806 op_symbol = NULL;
807 goto do_symbol;
808 }
809 }
c0b34702 810
3569064f
ILT
811 /* Subtraction is permitted if both operands are in the same
812 section. Otherwise, both operands must be absolute. We
813 already handled the case of addition or subtraction of a
814 constant above. This will probably need to be changed
815 for an object file format which supports arbitrary
816 expressions, such as IEEE-695. */
2051ec0e
ILT
817 /* Don't emit messages unless we're finalizing the symbol value,
818 otherwise we may get the same message multiple times. */
819 if ((seg_left != absolute_section || seg_right != absolute_section)
820 && (op != O_subtract || seg_left != seg_right)
821 && finalize)
c0b34702
ILT
822 {
823 char *file;
824 unsigned int line;
825
826 if (expr_symbol_where (symp, &file, &line))
3569064f 827 {
e95ef7c1 828 if (seg_left == undefined_section)
3569064f
ILT
829 as_bad_where (file, line,
830 "undefined symbol %s in operation",
e95ef7c1
ILT
831 S_GET_NAME (symp->sy_value.X_add_symbol));
832 if (seg_right == undefined_section)
833 as_bad_where (file, line,
834 "undefined symbol %s in operation",
835 S_GET_NAME (symp->sy_value.X_op_symbol));
836 if (seg_left != undefined_section
837 && seg_right != undefined_section)
3569064f
ILT
838 as_bad_where (file, line, "invalid section for operation");
839 }
c0b34702 840 else
3569064f 841 {
e95ef7c1 842 if (seg_left == undefined_section)
3569064f 843 as_bad ("undefined symbol %s in operation setting %s",
e95ef7c1 844 S_GET_NAME (symp->sy_value.X_add_symbol),
3569064f 845 S_GET_NAME (symp));
e95ef7c1
ILT
846 if (seg_right == undefined_section)
847 as_bad ("undefined symbol %s in operation setting %s",
848 S_GET_NAME (symp->sy_value.X_op_symbol),
849 S_GET_NAME (symp));
850 if (seg_left != undefined_section
851 && seg_right != undefined_section)
3569064f
ILT
852 as_bad ("invalid section for operation setting %s",
853 S_GET_NAME (symp));
854 }
c0b34702 855 }
3569064f 856
2051ec0e
ILT
857 /* Check for division by zero. */
858 if ((op == O_divide || op == O_modulus) && right == 0)
859 {
860 /* If seg_right is not absolute_section, then we've
861 already issued a warning about using a bad symbol. */
862 if (seg_right == absolute_section && finalize)
863 {
864 char *file;
865 unsigned int line;
866
867 if (expr_symbol_where (symp, &file, &line))
868 as_bad_where (file, line, "division by zero");
869 else
870 as_bad ("division by zero when setting %s",
871 S_GET_NAME (symp));
872 }
873
874 right = 1;
875 }
876
5ac34ac3
ILT
877 switch (symp->sy_value.X_op)
878 {
2051ec0e
ILT
879 case O_multiply: left *= right; break;
880 case O_divide: left /= right; break;
881 case O_modulus: left %= right; break;
882 case O_left_shift: left <<= right; break;
883 case O_right_shift: left >>= right; break;
884 case O_bit_inclusive_or: left |= right; break;
885 case O_bit_or_not: left |= ~right; break;
886 case O_bit_exclusive_or: left ^= right; break;
887 case O_bit_and: left &= right; break;
888 case O_add: left += right; break;
889 case O_subtract: left -= right; break;
890 case O_eq: left = left == right ? ~ (offsetT) 0 : 0;
891 case O_ne: left = left != right ? ~ (offsetT) 0 : 0;
892 case O_lt: left = left < right ? ~ (offsetT) 0 : 0;
893 case O_le: left = left <= right ? ~ (offsetT) 0 : 0;
894 case O_ge: left = left >= right ? ~ (offsetT) 0 : 0;
895 case O_gt: left = left > right ? ~ (offsetT) 0 : 0;
896 case O_logical_and: left = left && right; break;
897 case O_logical_or: left = left || right; break;
898 default: abort ();
5ac34ac3 899 }
2051ec0e
ILT
900
901 final_val += symp->sy_frag->fr_address + left;
902 if (final_seg == expr_section || final_seg == undefined_section)
903 final_seg = absolute_section;
904 resolved = (add_symbol->sy_resolved && op_symbol->sy_resolved);
5ac34ac3
ILT
905 break;
906
907 case O_register:
908 case O_big:
909 case O_illegal:
0cafaab1
ILT
910 /* Give an error (below) if not in expr_section. We don't
911 want to worry about expr_section symbols, because they
912 are fictional (they are created as part of expression
913 resolution), and any problems may not actually mean
914 anything. */
5ac34ac3 915 break;
5868b1fe 916 }
2051ec0e
ILT
917
918 symp->sy_resolving = 0;
5868b1fe
ILT
919 }
920
2051ec0e
ILT
921 if (finalize)
922 {
923 S_SET_VALUE (symp, final_val);
924 S_SET_SEGMENT (symp, final_seg);
925 }
926
927exit_dont_set_value:
0cafaab1 928 /* Don't worry if we can't resolve an expr_section symbol. */
2051ec0e 929 if (finalize)
0cafaab1 930 {
2051ec0e
ILT
931 if (resolved)
932 symp->sy_resolved = 1;
933 else if (S_GET_SEGMENT (symp) != expr_section)
934 {
935 as_bad ("can't resolve value for symbol \"%s\"", S_GET_NAME (symp));
936 symp->sy_resolved = 1;
937 }
0cafaab1 938 }
2051ec0e
ILT
939
940 return final_val;
5868b1fe
ILT
941}
942
6efd877d
KR
943/* Dollar labels look like a number followed by a dollar sign. Eg, "42$".
944 They are *really* local. That is, they go out of scope whenever we see a
945 label that isn't local. Also, like fb labels, there can be multiple
946 instances of a dollar label. Therefor, we name encode each instance with
947 the instance number, keep a list of defined symbols separate from the real
948 symbol table, and we treat these buggers as a sparse array. */
949
2b68b820
KR
950static long *dollar_labels;
951static long *dollar_label_instances;
952static char *dollar_label_defines;
953static long dollar_label_count;
604633ae 954static unsigned long dollar_label_max;
6efd877d
KR
955
956int
957dollar_label_defined (label)
958 long label;
959{
960 long *i;
961
962 know ((dollar_labels != NULL) || (dollar_label_count == 0));
963
964 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
965 if (*i == label)
966 return dollar_label_defines[i - dollar_labels];
6efd877d
KR
967
968 /* if we get here, label isn't defined */
2b68b820 969 return 0;
6efd877d
KR
970} /* dollar_label_defined() */
971
f59fb6ca 972static long
6efd877d
KR
973dollar_label_instance (label)
974 long label;
975{
976 long *i;
977
978 know ((dollar_labels != NULL) || (dollar_label_count == 0));
979
980 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
981 if (*i == label)
982 return (dollar_label_instances[i - dollar_labels]);
6efd877d 983
2b68b820
KR
984 /* If we get here, we haven't seen the label before, therefore its instance
985 count is zero. */
986 return 0;
987}
6efd877d
KR
988
989void
990dollar_label_clear ()
991{
604633ae 992 memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
2b68b820 993}
6efd877d
KR
994
995#define DOLLAR_LABEL_BUMP_BY 10
996
997void
998define_dollar_label (label)
999 long label;
1000{
1001 long *i;
1002
1003 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
1004 if (*i == label)
1005 {
1006 ++dollar_label_instances[i - dollar_labels];
1007 dollar_label_defines[i - dollar_labels] = 1;
1008 return;
1009 }
6efd877d
KR
1010
1011 /* if we get to here, we don't have label listed yet. */
1012
1013 if (dollar_labels == NULL)
1014 {
1015 dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
1016 dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
1017 dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
1018 dollar_label_max = DOLLAR_LABEL_BUMP_BY;
1019 dollar_label_count = 0;
6efd877d
KR
1020 }
1021 else if (dollar_label_count == dollar_label_max)
1022 {
1023 dollar_label_max += DOLLAR_LABEL_BUMP_BY;
1024 dollar_labels = (long *) xrealloc ((char *) dollar_labels,
1025 dollar_label_max * sizeof (long));
1026 dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
1027 dollar_label_max * sizeof (long));
1028 dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
1029 } /* if we needed to grow */
1030
1031 dollar_labels[dollar_label_count] = label;
1032 dollar_label_instances[dollar_label_count] = 1;
1033 dollar_label_defines[dollar_label_count] = 1;
1034 ++dollar_label_count;
2b68b820 1035}
6efd877d
KR
1036
1037/*
1038 * dollar_label_name()
1039 *
1040 * Caller must copy returned name: we re-use the area for the next name.
1041 *
2b68b820
KR
1042 * The mth occurence of label n: is turned into the symbol "Ln^Am"
1043 * where n is the label number and m is the instance number. "L" makes
1044 * it a label discarded unless debugging and "^A"('\1') ensures no
1045 * ordinary symbol SHOULD get the same name as a local label
1046 * symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
6efd877d
KR
1047 *
1048 * fb labels get the same treatment, except that ^B is used in place of ^A.
1049 */
1050
1051char * /* Return local label name. */
1052dollar_label_name (n, augend)
1053 register long n; /* we just saw "n$:" : n a number */
1054 register int augend; /* 0 for current instance, 1 for new instance */
1055{
1056 long i;
1057 /* Returned to caller, then copied. used for created names ("4f") */
1058 static char symbol_name_build[24];
1059 register char *p;
1060 register char *q;
1061 char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
1062
1063 know (n >= 0);
1064 know (augend == 0 || augend == 1);
1065 p = symbol_name_build;
1066 *p++ = 'L';
1067
1068 /* Next code just does sprintf( {}, "%d", n); */
1069 /* label number */
1070 q = symbol_name_temporary;
1071 for (*q++ = 0, i = n; i; ++q)
1072 {
1073 *q = i % 10 + '0';
1074 i /= 10;
1075 }
1076 while ((*p = *--q) != '\0')
1077 ++p;
1078
1079 *p++ = 1; /* ^A */
1080
1081 /* instance number */
1082 q = symbol_name_temporary;
1083 for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
1084 {
1085 *q = i % 10 + '0';
1086 i /= 10;
1087 }
1088 while ((*p++ = *--q) != '\0');;
1089
1090 /* The label, as a '\0' ended string, starts at symbol_name_build. */
2b68b820
KR
1091 return symbol_name_build;
1092}
6efd877d 1093
6efd877d
KR
1094/*
1095 * Sombody else's idea of local labels. They are made by "n:" where n
1096 * is any decimal digit. Refer to them with
1097 * "nb" for previous (backward) n:
1098 * or "nf" for next (forward) n:.
1099 *
1100 * We do a little better and let n be any number, not just a single digit, but
1101 * since the other guy's assembler only does ten, we treat the first ten
1102 * specially.
1103 *
1104 * Like someone else's assembler, we have one set of local label counters for
1105 * entire assembly, not one set per (sub)segment like in most assemblers. This
1106 * implies that one can refer to a label in another segment, and indeed some
1107 * crufty compilers have done just that.
1108 *
1109 * Since there could be a LOT of these things, treat them as a sparse array.
1110 */
1111
1112#define FB_LABEL_SPECIAL (10)
1113
1114static long fb_low_counter[FB_LABEL_SPECIAL];
1115static long *fb_labels;
1116static long *fb_label_instances;
eec0de3f
KR
1117static long fb_label_count;
1118static long fb_label_max;
6efd877d
KR
1119
1120/* this must be more than FB_LABEL_SPECIAL */
1121#define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
1122
1123static void
1124fb_label_init ()
1125{
1126 memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
6efd877d
KR
1127} /* fb_label_init() */
1128
1129/* add one to the instance number of this fb label */
1130void
1131fb_label_instance_inc (label)
1132 long label;
1133{
1134 long *i;
1135
1136 if (label < FB_LABEL_SPECIAL)
1137 {
1138 ++fb_low_counter[label];
1139 return;
1140 }
1141
e154ecf4 1142 if (fb_labels != NULL)
6efd877d 1143 {
e154ecf4
ILT
1144 for (i = fb_labels + FB_LABEL_SPECIAL;
1145 i < fb_labels + fb_label_count; ++i)
6efd877d 1146 {
e154ecf4
ILT
1147 if (*i == label)
1148 {
1149 ++fb_label_instances[i - fb_labels];
1150 return;
1151 } /* if we find it */
1152 } /* for each existing label */
1153 }
6efd877d
KR
1154
1155 /* if we get to here, we don't have label listed yet. */
1156
1157 if (fb_labels == NULL)
1158 {
1159 fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
1160 fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
1161 fb_label_max = FB_LABEL_BUMP_BY;
1162 fb_label_count = FB_LABEL_SPECIAL;
1163
1164 }
1165 else if (fb_label_count == fb_label_max)
1166 {
1167 fb_label_max += FB_LABEL_BUMP_BY;
1168 fb_labels = (long *) xrealloc ((char *) fb_labels,
1169 fb_label_max * sizeof (long));
1170 fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
1171 fb_label_max * sizeof (long));
1172 } /* if we needed to grow */
1173
1174 fb_labels[fb_label_count] = label;
1175 fb_label_instances[fb_label_count] = 1;
1176 ++fb_label_count;
1ecd6c4a 1177}
6efd877d
KR
1178
1179static long
1180fb_label_instance (label)
1181 long label;
1182{
1183 long *i;
1184
1185 if (label < FB_LABEL_SPECIAL)
1186 {
1187 return (fb_low_counter[label]);
1188 }
1189
e154ecf4 1190 if (fb_labels != NULL)
6efd877d 1191 {
e154ecf4
ILT
1192 for (i = fb_labels + FB_LABEL_SPECIAL;
1193 i < fb_labels + fb_label_count; ++i)
6efd877d 1194 {
e154ecf4
ILT
1195 if (*i == label)
1196 {
1197 return (fb_label_instances[i - fb_labels]);
1198 } /* if we find it */
1199 } /* for each existing label */
1200 }
6efd877d 1201
e154ecf4
ILT
1202 /* We didn't find the label, so this must be a reference to the
1203 first instance. */
1204 return 0;
2b68b820 1205}
6efd877d
KR
1206
1207/*
1208 * fb_label_name()
1209 *
1210 * Caller must copy returned name: we re-use the area for the next name.
1211 *
2b68b820
KR
1212 * The mth occurence of label n: is turned into the symbol "Ln^Bm"
1213 * where n is the label number and m is the instance number. "L" makes
1214 * it a label discarded unless debugging and "^B"('\2') ensures no
1215 * ordinary symbol SHOULD get the same name as a local label
1216 * symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
6efd877d 1217 *
2b68b820 1218 * dollar labels get the same treatment, except that ^A is used in place of ^B. */
6efd877d
KR
1219
1220char * /* Return local label name. */
1221fb_label_name (n, augend)
1222 long n; /* we just saw "n:", "nf" or "nb" : n a number */
1223 long augend; /* 0 for nb, 1 for n:, nf */
1224{
1225 long i;
1226 /* Returned to caller, then copied. used for created names ("4f") */
1227 static char symbol_name_build[24];
1228 register char *p;
1229 register char *q;
1230 char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
1231
1232 know (n >= 0);
1233 know (augend == 0 || augend == 1);
1234 p = symbol_name_build;
1235 *p++ = 'L';
1236
1237 /* Next code just does sprintf( {}, "%d", n); */
1238 /* label number */
1239 q = symbol_name_temporary;
1240 for (*q++ = 0, i = n; i; ++q)
1241 {
1242 *q = i % 10 + '0';
1243 i /= 10;
1244 }
1245 while ((*p = *--q) != '\0')
1246 ++p;
1247
1248 *p++ = 2; /* ^B */
1249
1250 /* instance number */
1251 q = symbol_name_temporary;
1252 for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
1253 {
1254 *q = i % 10 + '0';
1255 i /= 10;
1256 }
1257 while ((*p++ = *--q) != '\0');;
1258
1259 /* The label, as a '\0' ended string, starts at symbol_name_build. */
1260 return (symbol_name_build);
1261} /* fb_label_name() */
1262
a6c6eaf8 1263/*
6efd877d
KR
1264 * decode name that may have been generated by foo_label_name() above. If
1265 * the name wasn't generated by foo_label_name(), then return it unaltered.
a6c6eaf8
RP
1266 * This is used for error messages.
1267 */
a39116f1 1268
6efd877d
KR
1269char *
1270decode_local_label_name (s)
1271 char *s;
a6c6eaf8 1272{
6efd877d
KR
1273 char *p;
1274 char *symbol_decode;
1275 int label_number;
1276 int instance_number;
1277 char *type;
1278 const char *message_format = "\"%d\" (instance number %d of a %s label)";
1279
1280 if (s[0] != 'L')
56dc989a 1281 return s;
6efd877d
KR
1282
1283 for (label_number = 0, p = s + 1; isdigit (*p); ++p)
56dc989a 1284 label_number = (10 * label_number) + *p - '0';
6efd877d
KR
1285
1286 if (*p == 1)
56dc989a 1287 type = "dollar";
6efd877d 1288 else if (*p == 2)
56dc989a 1289 type = "fb";
6efd877d 1290 else
56dc989a 1291 return s;
6efd877d 1292
56dc989a
ILT
1293 for (instance_number = 0, p++; isdigit (*p); ++p)
1294 instance_number = (10 * instance_number) + *p - '0';
6efd877d
KR
1295
1296 symbol_decode = obstack_alloc (&notes, strlen (message_format) + 30);
56dc989a 1297 sprintf (symbol_decode, message_format, label_number, instance_number, type);
6efd877d 1298
56dc989a
ILT
1299 return symbol_decode;
1300}
a6c6eaf8 1301
85051959
ILT
1302/* Get the value of a symbol. */
1303
1304valueT
1305S_GET_VALUE (s)
1306 symbolS *s;
1307{
2051ec0e
ILT
1308 if (!s->sy_resolved && s->sy_value.X_op != O_constant)
1309 resolve_symbol_value (s, 1);
5ac34ac3 1310 if (s->sy_value.X_op != O_constant)
943bdfdc
ILT
1311 {
1312 static symbolS *recur;
1313
1314 /* FIXME: In non BFD assemblers, S_IS_DEFINED and S_IS_COMMON
1315 may call S_GET_VALUE. We use a static symbol to avoid the
1316 immediate recursion. */
1317 if (recur == s)
1318 return (valueT) s->sy_value.X_add_number;
1319 recur = s;
1320 if (! s->sy_resolved
1321 || s->sy_value.X_op != O_symbol
1322 || (S_IS_DEFINED (s) && ! S_IS_COMMON (s)))
1323 as_bad ("Attempt to get value of unresolved symbol %s",
1324 S_GET_NAME (s));
1325 recur = NULL;
1326 }
85051959
ILT
1327 return (valueT) s->sy_value.X_add_number;
1328}
1329
1330/* Set the value of a symbol. */
1331
1332void
1333S_SET_VALUE (s, val)
1334 symbolS *s;
1335 valueT val;
1336{
5ac34ac3 1337 s->sy_value.X_op = O_constant;
85051959 1338 s->sy_value.X_add_number = (offsetT) val;
0cafaab1 1339 s->sy_value.X_unsigned = 0;
85051959
ILT
1340}
1341
e702f6e6
KR
1342void
1343copy_symbol_attributes (dest, src)
1344 symbolS *dest, *src;
1345{
1346#ifdef BFD_ASSEMBLER
1347 /* In an expression, transfer the settings of these flags.
1348 The user can override later, of course. */
2051ec0e 1349#define COPIED_SYMFLAGS (BSF_FUNCTION | BSF_OBJECT)
e702f6e6
KR
1350 dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
1351#endif
1352
1353#ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
1354 OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
1355#endif
1356}
1357
2b68b820
KR
1358#ifdef BFD_ASSEMBLER
1359
1360int
1361S_IS_EXTERNAL (s)
1362 symbolS *s;
1363{
1364 flagword flags = s->bsym->flags;
1365
1366 /* sanity check */
0cafaab1 1367 if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
2b68b820
KR
1368 abort ();
1369
0cafaab1 1370 return (flags & BSF_GLOBAL) != 0;
2b68b820
KR
1371}
1372
943bdfdc
ILT
1373int
1374S_IS_WEAK (s)
1375 symbolS *s;
1376{
1377 return (s->bsym->flags & BSF_WEAK) != 0;
1378}
1379
2b68b820
KR
1380int
1381S_IS_COMMON (s)
1382 symbolS *s;
1383{
0cafaab1 1384 return bfd_is_com_section (s->bsym->section);
2b68b820
KR
1385}
1386
1387int
1388S_IS_DEFINED (s)
1389 symbolS *s;
1390{
1391 return s->bsym->section != undefined_section;
1392}
1393
1394int
1395S_IS_DEBUG (s)
1396 symbolS *s;
1397{
1398 if (s->bsym->flags & BSF_DEBUGGING)
1399 return 1;
1400 return 0;
1401}
1402
1403int
1404S_IS_LOCAL (s)
1405 symbolS *s;
1406{
1407 flagword flags = s->bsym->flags;
1356d77d 1408 const char *name;
2b68b820
KR
1409
1410 /* sanity check */
0cafaab1 1411 if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
2b68b820
KR
1412 abort ();
1413
2a0f64a5
ILT
1414 if (bfd_get_section (s->bsym) == reg_section)
1415 return 1;
1416
1356d77d
ILT
1417 name = S_GET_NAME (s);
1418 return (name != NULL
2b68b820 1419 && ! S_IS_DEBUG (s)
1356d77d
ILT
1420 && (strchr (name, '\001')
1421 || strchr (name, '\002')
1422 || (! flag_keep_locals
e95ef7c1 1423 && (bfd_is_local_label (stdoutput, s->bsym)
1356d77d
ILT
1424 || (flag_mri
1425 && name[0] == '?'
1426 && name[1] == '?')))));
2b68b820
KR
1427}
1428
1429int
1430S_IS_EXTERN (s)
1431 symbolS *s;
1432{
1433 return S_IS_EXTERNAL (s);
1434}
1435
1436int
1437S_IS_STABD (s)
1438 symbolS *s;
1439{
1440 return S_GET_NAME (s) == 0;
1441}
1442
2b68b820
KR
1443CONST char *
1444S_GET_NAME (s)
1445 symbolS *s;
1446{
1447 return s->bsym->name;
1448}
1449
1450segT
1451S_GET_SEGMENT (s)
1452 symbolS *s;
1453{
1454 return s->bsym->section;
1455}
1456
2b68b820
KR
1457void
1458S_SET_SEGMENT (s, seg)
1459 symbolS *s;
1460 segT seg;
1461{
1462 s->bsym->section = seg;
1463}
1464
1465void
1466S_SET_EXTERNAL (s)
1467 symbolS *s;
1468{
56dc989a 1469 if ((s->bsym->flags & BSF_WEAK) != 0)
c0b34702 1470 {
5ca547dc 1471 /* Let .weak override .global. */
c0b34702
ILT
1472 return;
1473 }
1ecd6c4a
KR
1474 s->bsym->flags |= BSF_GLOBAL;
1475 s->bsym->flags &= ~(BSF_LOCAL|BSF_WEAK);
2b68b820
KR
1476}
1477
1478void
1479S_CLEAR_EXTERNAL (s)
1480 symbolS *s;
1481{
56dc989a 1482 if ((s->bsym->flags & BSF_WEAK) != 0)
c0b34702 1483 {
5ca547dc 1484 /* Let .weak override. */
c0b34702
ILT
1485 return;
1486 }
2b68b820 1487 s->bsym->flags |= BSF_LOCAL;
1ecd6c4a
KR
1488 s->bsym->flags &= ~(BSF_GLOBAL|BSF_WEAK);
1489}
1490
1491void
1492S_SET_WEAK (s)
1493 symbolS *s;
1494{
1495 s->bsym->flags |= BSF_WEAK;
1496 s->bsym->flags &= ~(BSF_GLOBAL|BSF_LOCAL);
2b68b820
KR
1497}
1498
1499void
1500S_SET_NAME (s, name)
1501 symbolS *s;
1502 char *name;
1503{
1504 s->bsym->name = name;
1505}
1506#endif /* BFD_ASSEMBLER */
1507
eec0de3f
KR
1508void
1509symbol_begin ()
1510{
1511 symbol_lastP = NULL;
1512 symbol_rootP = NULL; /* In case we have 0 symbols (!!) */
1513 sy_hash = hash_new ();
dacf29ea 1514
eec0de3f
KR
1515 memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
1516#ifdef BFD_ASSEMBLER
dacf29ea 1517#if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
eec0de3f 1518 abs_symbol.bsym = bfd_abs_section.symbol;
dacf29ea 1519#endif
eec0de3f
KR
1520#else
1521 /* Can't initialise a union. Sigh. */
1522 S_SET_SEGMENT (&abs_symbol, absolute_section);
1523#endif
dacf29ea 1524 abs_symbol.sy_value.X_op = O_constant;
db317fe7 1525 abs_symbol.sy_frag = &zero_address_frag;
dacf29ea 1526
56dc989a
ILT
1527 if (LOCAL_LABELS_FB)
1528 fb_label_init ();
eec0de3f
KR
1529}
1530
e702f6e6
KR
1531\f
1532int indent_level;
dacf29ea 1533
56dc989a
ILT
1534#if 0
1535
dacf29ea
KR
1536static void
1537indent ()
1538{
1539 printf ("%*s", indent_level * 4, "");
1540}
1541
56dc989a
ILT
1542#endif
1543
dacf29ea
KR
1544void
1545print_symbol_value_1 (file, sym)
1546 FILE *file;
1547 symbolS *sym;
1548{
1549 const char *name = S_GET_NAME (sym);
1550 if (!name || !name[0])
1551 name = "(unnamed)";
56dc989a 1552 fprintf (file, "sym %lx %s", (unsigned long) sym, name);
e702f6e6
KR
1553 if (sym->sy_frag != &zero_address_frag)
1554 fprintf (file, " frag %lx", (long) sym->sy_frag);
dacf29ea
KR
1555 if (sym->written)
1556 fprintf (file, " written");
1557 if (sym->sy_resolved)
1558 fprintf (file, " resolved");
e702f6e6 1559 else if (sym->sy_resolving)
dacf29ea
KR
1560 fprintf (file, " resolving");
1561 if (sym->sy_used_in_reloc)
1562 fprintf (file, " used-in-reloc");
1563 if (sym->sy_used)
1564 fprintf (file, " used");
87e48495
KR
1565 if (S_IS_LOCAL (sym))
1566 fprintf (file, " local");
1567 if (S_IS_EXTERN (sym))
1568 fprintf (file, " extern");
1569 if (S_IS_DEBUG (sym))
1570 fprintf (file, " debug");
1571 if (S_IS_DEFINED (sym))
1572 fprintf (file, " defined");
e702f6e6 1573 fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
dacf29ea
KR
1574 if (sym->sy_resolved)
1575 {
e702f6e6
KR
1576 segT s = S_GET_SEGMENT (sym);
1577
1578 if (s != undefined_section
1579 && s != expr_section)
1580 fprintf (file, " %lx", (long) S_GET_VALUE (sym));
dacf29ea 1581 }
e702f6e6 1582 else if (indent_level < 8 && S_GET_SEGMENT (sym) != undefined_section)
dacf29ea
KR
1583 {
1584 indent_level++;
1585 fprintf (file, "\n%*s<", indent_level * 4, "");
1586 print_expr_1 (file, &sym->sy_value);
1587 fprintf (file, ">");
1588 indent_level--;
1589 }
1590 fflush (file);
1591}
1592
1593void
1594print_symbol_value (sym)
1595 symbolS *sym;
1596{
1597 indent_level = 0;
1598 print_symbol_value_1 (stderr, sym);
1599 fprintf (stderr, "\n");
1600}
1601
1602void
1603print_expr_1 (file, exp)
1604 FILE *file;
1605 expressionS *exp;
1606{
1607 fprintf (file, "expr %lx ", (long) exp);
1608 switch (exp->X_op)
1609 {
1610 case O_illegal:
1611 fprintf (file, "illegal");
1612 break;
1613 case O_absent:
1614 fprintf (file, "absent");
1615 break;
1616 case O_constant:
1617 fprintf (file, "constant %lx", (long) exp->X_add_number);
1618 break;
1619 case O_symbol:
1620 indent_level++;
1621 fprintf (file, "symbol\n%*s<", indent_level * 4, "");
1622 print_symbol_value_1 (file, exp->X_add_symbol);
1623 fprintf (file, ">");
1624 maybe_print_addnum:
dacf29ea 1625 if (exp->X_add_number)
e702f6e6 1626 fprintf (file, "\n%*s%lx", indent_level * 4, "",
dacf29ea 1627 (long) exp->X_add_number);
e702f6e6 1628 indent_level--;
dacf29ea
KR
1629 break;
1630 case O_register:
1631 fprintf (file, "register #%d", (int) exp->X_add_number);
1632 break;
1633 case O_big:
1634 fprintf (file, "big");
1635 break;
1636 case O_uminus:
1637 fprintf (file, "uminus -<");
1638 indent_level++;
1639 print_symbol_value_1 (file, exp->X_add_symbol);
1640 fprintf (file, ">");
1641 goto maybe_print_addnum;
1642 case O_bit_not:
1643 fprintf (file, "bit_not");
1644 break;
1645 case O_multiply:
1646 fprintf (file, "multiply");
1647 break;
1648 case O_divide:
1649 fprintf (file, "divide");
1650 break;
1651 case O_modulus:
1652 fprintf (file, "modulus");
1653 break;
1654 case O_left_shift:
1655 fprintf (file, "lshift");
1656 break;
1657 case O_right_shift:
1658 fprintf (file, "rshift");
1659 break;
1660 case O_bit_inclusive_or:
1661 fprintf (file, "bit_ior");
1662 break;
1663 case O_bit_exclusive_or:
1664 fprintf (file, "bit_xor");
1665 break;
1666 case O_bit_and:
1667 fprintf (file, "bit_and");
1668 break;
1356d77d
ILT
1669 case O_eq:
1670 fprintf (file, "eq");
1671 break;
1672 case O_ne:
1673 fprintf (file, "ne");
1674 break;
1675 case O_lt:
1676 fprintf (file, "lt");
1677 break;
1678 case O_le:
1679 fprintf (file, "le");
1680 break;
1681 case O_ge:
1682 fprintf (file, "ge");
1683 break;
1684 case O_gt:
1685 fprintf (file, "gt");
1686 break;
73255941
ILT
1687 case O_logical_and:
1688 fprintf (file, "logical_and");
1689 break;
1690 case O_logical_or:
1691 fprintf (file, "logical_or");
1692 break;
dacf29ea
KR
1693 case O_add:
1694 indent_level++;
1695 fprintf (file, "add\n%*s<", indent_level * 4, "");
1696 print_symbol_value_1 (file, exp->X_add_symbol);
1697 fprintf (file, ">\n%*s<", indent_level * 4, "");
1698 print_symbol_value_1 (file, exp->X_op_symbol);
1699 fprintf (file, ">");
1700 goto maybe_print_addnum;
1701 case O_subtract:
1702 indent_level++;
1703 fprintf (file, "subtract\n%*s<", indent_level * 4, "");
1704 print_symbol_value_1 (file, exp->X_add_symbol);
1705 fprintf (file, ">\n%*s<", indent_level * 4, "");
1706 print_symbol_value_1 (file, exp->X_op_symbol);
1707 fprintf (file, ">");
1708 goto maybe_print_addnum;
1709 default:
1710 fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
1711 break;
1712 }
1713 fflush (stdout);
1714}
1715
1716void
1717print_expr (exp)
1718 expressionS *exp;
1719{
1720 print_expr_1 (stderr, exp);
1721 fprintf (stderr, "\n");
1722}
1723
943bdfdc
ILT
1724void
1725symbol_print_statistics (file)
1726 FILE *file;
1727{
1728 hash_print_statistics (file, "symbol table", sy_hash);
1729}
1730
8b228fe9 1731/* end of symbols.c */
This page took 0.30795 seconds and 4 git commands to generate.