* hppa-tdep.c (frame_saved_pc): Don't try to dig a return pointer
[deliverable/binutils-gdb.git] / gas / symbols.c
CommitLineData
fecd2382 1/* symbols.c -symbol table-
dacf29ea
KR
2 Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994
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
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
58d4951d 21/* #define DEBUG_SYMS / * to debug symbol list maintenance */
2b68b820 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
dacf29ea
KR
42#ifdef DEBUG_SYMS
43#define debug_verify_symchain verify_symbol_chain
44#else
45#define debug_verify_symchain (void)
46#endif
47
6efd877d 48struct obstack notes;
fecd2382 49
85825401 50static void fb_label_init PARAMS ((void));
fecd2382 51
dacf29ea
KR
52/* symbol_new()
53
54 Return a pointer to a new symbol. Die if we can't make a new
55 symbol. Fill in the symbol's values. Add symbol to end of symbol
56 chain.
57
58 This function should be called in the general case of creating a
59 symbol. However, if the output file symbol table has already been
60 set, and you are certain that this symbol won't be wanted in the
61 output file, you can call symbol_create. */
fecd2382 62
6efd877d 63symbolS *
604633ae 64symbol_new (name, segment, valu, frag)
dacf29ea
KR
65 const char *name;
66 segT segment;
67 valueT valu;
68 fragS *frag;
69{
70 symbolS *symbolP = symbol_create (name, segment, valu, frag);
71
72 /*
73 * Link to end of symbol chain.
74 */
75#ifdef BFD_ASSEMBLER
76 {
77 extern int symbol_table_frozen;
78 if (symbol_table_frozen)
79 abort ();
80 }
81#endif
82 symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
83 debug_verify_symchain (symbol_rootP, symbol_lastP);
84
85 return symbolP;
86}
87
88symbolS *
89symbol_create (name, segment, valu, frag)
90 const char *name; /* It is copied, the caller can destroy/modify */
6efd877d 91 segT segment; /* Segment identifier (SEG_<something>) */
604633ae 92 valueT valu; /* Symbol value */
6efd877d 93 fragS *frag; /* Associated fragment */
fecd2382 94{
6efd877d
KR
95 unsigned int name_length;
96 char *preserved_copy_of_name;
97 symbolS *symbolP;
98
99 name_length = strlen (name) + 1; /* +1 for \0 */
100 obstack_grow (&notes, name, name_length);
101 preserved_copy_of_name = obstack_finish (&notes);
2b68b820
KR
102#ifdef STRIP_UNDERSCORE
103 if (preserved_copy_of_name[0] == '_')
104 preserved_copy_of_name++;
105#endif
dacf29ea
KR
106
107#ifdef tc_canonicalize_symbol_name
108 preserved_copy_of_name =
109 tc_canonicalize_symbol_name (preserved_copy_of_name);
110#endif
111
6efd877d
KR
112 symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
113
114 /* symbol must be born in some fixed state. This seems as good as any. */
115 memset (symbolP, 0, sizeof (symbolS));
116
2b68b820
KR
117#ifdef BFD_ASSEMBLER
118 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
119 assert (symbolP->bsym != 0);
87e48495 120 symbolP->bsym->udata.p = (PTR) symbolP;
2b68b820 121#endif
6efd877d 122 S_SET_NAME (symbolP, preserved_copy_of_name);
6efd877d
KR
123
124 S_SET_SEGMENT (symbolP, segment);
604633ae 125 S_SET_VALUE (symbolP, valu);
dacf29ea 126 symbol_clear_list_pointers (symbolP);
6efd877d
KR
127
128 symbolP->sy_frag = frag;
2b68b820 129#ifndef BFD_ASSEMBLER
6efd877d 130 symbolP->sy_number = ~0;
0cafaab1 131 symbolP->sy_name_offset = (unsigned int) ~0;
2b68b820 132#endif
6efd877d 133
6efd877d
KR
134 obj_symbol_new_hook (symbolP);
135
dacf29ea
KR
136#ifdef tc_symbol_new_hook
137 tc_symbol_new_hook (symbolP);
138#endif
fecd2382 139
2b68b820
KR
140 return symbolP;
141}
fecd2382 142\f
6efd877d 143
fecd2382
RP
144/*
145 * colon()
146 *
147 * We have just seen "<name>:".
148 * Creates a struct symbol unless it already exists.
149 *
150 * Gripes if we are redefining a symbol incompatibly (and ignores it).
151 *
152 */
6efd877d
KR
153void
154colon (sym_name) /* just seen "x:" - rattle symbols & frags */
155 register char *sym_name; /* symbol name, as a cannonical string */
156 /* We copy this string: OK to alter later. */
fecd2382 157{
6efd877d
KR
158 register symbolS *symbolP; /* symbol we are working with */
159
2b68b820
KR
160 /* Sun local labels go out of scope whenever a non-local symbol is
161 defined. */
56dc989a 162 if (LOCAL_LABELS_DOLLAR && *sym_name != 'L')
6efd877d 163 dollar_label_clear ();
6efd877d 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
87e48495 220 S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
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
58d4951d 285 as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%ld.",
6efd877d
KR
286 sym_name,
287 segment_name (S_GET_SEGMENT (symbolP)),
58d4951d 288 (long) 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
87e48495 297 && S_GET_VALUE (symbolP) == frag_now_fix ()
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 {
87e48495 305 symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (),
6efd877d 306 frag_now);
2b68b820 307#ifdef OBJ_VMS
6efd877d 308 S_SET_OTHER (symbolP, const_flag);
2b68b820 309#endif /* OBJ_VMS */
fecd2382 310
6efd877d
KR
311 symbol_table_insert (symbolP);
312 } /* if we have seen this symbol before */
1e9cf565
ILT
313
314#ifdef tc_frob_label
315 tc_frob_label (symbolP);
2b68b820 316#endif
1ecd6c4a 317}
fecd2382 318\f
6efd877d 319
fecd2382
RP
320/*
321 * symbol_table_insert()
322 *
323 * Die if we can't insert the symbol.
324 *
325 */
326
6efd877d
KR
327void
328symbol_table_insert (symbolP)
329 symbolS *symbolP;
fecd2382 330{
604633ae 331 register const char *error_string;
6efd877d
KR
332
333 know (symbolP);
334 know (S_GET_NAME (symbolP));
335
0cafaab1 336 if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
6efd877d
KR
337 {
338 as_fatal ("Inserting \"%s\" into symbol table failed: %s",
339 S_GET_NAME (symbolP), error_string);
340 } /* on error */
341} /* symbol_table_insert() */
fecd2382
RP
342\f
343/*
344 * symbol_find_or_make()
345 *
346 * If a symbol name does not exist, create it as undefined, and insert
347 * it into the symbol table. Return a pointer to it.
348 */
6efd877d
KR
349symbolS *
350symbol_find_or_make (name)
351 char *name;
fecd2382 352{
6efd877d
KR
353 register symbolS *symbolP;
354
355 symbolP = symbol_find (name);
356
357 if (symbolP == NULL)
358 {
359 symbolP = symbol_make (name);
360
361 symbol_table_insert (symbolP);
362 } /* if symbol wasn't found */
363
364 return (symbolP);
365} /* symbol_find_or_make() */
366
367symbolS *
368symbol_make (name)
2b68b820 369 CONST char *name;
fecd2382 370{
6efd877d
KR
371 symbolS *symbolP;
372
373 /* Let the machine description default it, e.g. for register names. */
2b68b820 374 symbolP = md_undefined_symbol ((char *) name);
6efd877d
KR
375
376 if (!symbolP)
2b68b820 377 symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
6efd877d
KR
378
379 return (symbolP);
380} /* symbol_make() */
fecd2382
RP
381
382/*
383 * symbol_find()
6efd877d 384 *
fecd2382
RP
385 * Implement symbol table lookup.
386 * In: A symbol's name as a string: '\0' can't be part of a symbol name.
387 * Out: NULL if the name was not in the symbol table, else the address
388 * of a struct symbol associated with that name.
389 */
390
6efd877d
KR
391symbolS *
392symbol_find (name)
2b68b820 393 CONST char *name;
fecd2382 394{
a6c6eaf8 395#ifdef STRIP_UNDERSCORE
6efd877d 396 return (symbol_find_base (name, 1));
a6c6eaf8 397#else /* STRIP_UNDERSCORE */
6efd877d 398 return (symbol_find_base (name, 0));
fecd2382 399#endif /* STRIP_UNDERSCORE */
6efd877d 400} /* symbol_find() */
fecd2382 401
6efd877d
KR
402symbolS *
403symbol_find_base (name, strip_underscore)
2b68b820 404 CONST char *name;
6efd877d 405 int strip_underscore;
fecd2382 406{
6efd877d
KR
407 if (strip_underscore && *name == '_')
408 name++;
dacf29ea
KR
409
410#ifdef tc_canonicalize_symbol_name
411 {
412 char *copy;
413
414 copy = (char *) alloca (strlen (name) + 1);
415 strcpy (copy, name);
416 name = tc_canonicalize_symbol_name (copy);
417 }
418#endif
419
6efd877d 420 return ((symbolS *) hash_find (sy_hash, name));
fecd2382
RP
421}
422
423/*
424 * Once upon a time, symbols were kept in a singly linked list. At
425 * least coff needs to be able to rearrange them from time to time, for
426 * which a doubly linked list is much more convenient. Loic did these
427 * as macros which seemed dangerous to me so they're now functions.
428 * xoxorich.
429 */
430
431/* Link symbol ADDME after symbol TARGET in the chain. */
6efd877d
KR
432void
433symbol_append (addme, target, rootPP, lastPP)
434 symbolS *addme;
435 symbolS *target;
436 symbolS **rootPP;
437 symbolS **lastPP;
fecd2382 438{
6efd877d
KR
439 if (target == NULL)
440 {
441 know (*rootPP == NULL);
442 know (*lastPP == NULL);
443 *rootPP = addme;
444 *lastPP = addme;
445 return;
446 } /* if the list is empty */
447
448 if (target->sy_next != NULL)
449 {
fecd2382 450#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 451 target->sy_next->sy_previous = addme;
fecd2382 452#endif /* SYMBOLS_NEED_BACKPOINTERS */
6efd877d
KR
453 }
454 else
455 {
456 know (*lastPP == target);
457 *lastPP = addme;
458 } /* if we have a next */
459
460 addme->sy_next = target->sy_next;
461 target->sy_next = addme;
462
fecd2382 463#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 464 addme->sy_previous = target;
fecd2382 465#endif /* SYMBOLS_NEED_BACKPOINTERS */
2b68b820 466}
fecd2382 467
dacf29ea
KR
468/* Set the chain pointers of SYMBOL to null. */
469void
470symbol_clear_list_pointers (symbolP)
471 symbolS *symbolP;
472{
473 symbolP->sy_next = NULL;
474#ifdef SYMBOLS_NEED_BACKPOINTERS
475 symbolP->sy_previous = NULL;
476#endif
477}
478
fecd2382
RP
479#ifdef SYMBOLS_NEED_BACKPOINTERS
480/* Remove SYMBOLP from the list. */
6efd877d
KR
481void
482symbol_remove (symbolP, rootPP, lastPP)
483 symbolS *symbolP;
484 symbolS **rootPP;
485 symbolS **lastPP;
fecd2382 486{
6efd877d
KR
487 if (symbolP == *rootPP)
488 {
489 *rootPP = symbolP->sy_next;
490 } /* if it was the root */
491
492 if (symbolP == *lastPP)
493 {
494 *lastPP = symbolP->sy_previous;
495 } /* if it was the tail */
496
497 if (symbolP->sy_next != NULL)
498 {
499 symbolP->sy_next->sy_previous = symbolP->sy_previous;
500 } /* if not last */
501
502 if (symbolP->sy_previous != NULL)
503 {
504 symbolP->sy_previous->sy_next = symbolP->sy_next;
505 } /* if not first */
506
dacf29ea 507 debug_verify_symchain (*rootPP, *lastPP);
2b68b820 508}
fecd2382
RP
509
510/* Link symbol ADDME before symbol TARGET in the chain. */
6efd877d
KR
511void
512symbol_insert (addme, target, rootPP, lastPP)
513 symbolS *addme;
514 symbolS *target;
515 symbolS **rootPP;
516 symbolS **lastPP;
fecd2382 517{
6efd877d
KR
518 if (target->sy_previous != NULL)
519 {
520 target->sy_previous->sy_next = addme;
521 }
522 else
523 {
524 know (*rootPP == target);
525 *rootPP = addme;
526 } /* if not first */
527
528 addme->sy_previous = target->sy_previous;
529 target->sy_previous = addme;
530 addme->sy_next = target;
531
dacf29ea 532 debug_verify_symchain (*rootPP, *lastPP);
2b68b820 533}
6efd877d 534
fecd2382
RP
535#endif /* SYMBOLS_NEED_BACKPOINTERS */
536
6efd877d
KR
537void
538verify_symbol_chain (rootP, lastP)
539 symbolS *rootP;
540 symbolS *lastP;
fecd2382 541{
6efd877d
KR
542 symbolS *symbolP = rootP;
543
544 if (symbolP == NULL)
2b68b820 545 return;
6efd877d
KR
546
547 for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
548 {
fecd2382 549#ifdef SYMBOLS_NEED_BACKPOINTERS
6efd877d 550 know (symbolP->sy_next->sy_previous == symbolP);
2b68b820
KR
551#else
552 /* Walk the list anyways, to make sure pointers are still good. */
604633ae 553 ;
fecd2382 554#endif /* SYMBOLS_NEED_BACKPOINTERS */
2b68b820 555 }
6efd877d 556
2b68b820
KR
557 assert (lastP == symbolP);
558}
6efd877d 559
2b68b820
KR
560void
561verify_symbol_chain_2 (sym)
562 symbolS *sym;
563{
564 symbolS *p = sym, *n = sym;
565#ifdef SYMBOLS_NEED_BACKPOINTERS
566 while (symbol_previous (p))
567 p = symbol_previous (p);
568#endif
569 while (symbol_next (n))
570 n = symbol_next (n);
571 verify_symbol_chain (p, n);
572}
6efd877d 573
5868b1fe
ILT
574/* Resolve the value of a symbol. This is called during the final
575 pass over the symbol table to resolve any symbols with complex
576 values. */
577
578void
579resolve_symbol_value (symp)
580 symbolS *symp;
581{
0cafaab1
ILT
582 int resolved;
583
5868b1fe
ILT
584 if (symp->sy_resolved)
585 return;
586
0cafaab1
ILT
587 resolved = 0;
588
5868b1fe
ILT
589 if (symp->sy_resolving)
590 {
591 as_bad ("Symbol definition loop encountered at %s",
592 S_GET_NAME (symp));
593 S_SET_VALUE (symp, (valueT) 0);
0cafaab1 594 resolved = 1;
5868b1fe
ILT
595 }
596 else
597 {
5ac34ac3
ILT
598 offsetT left, right, val;
599 segT seg_left, seg_right;
600
5868b1fe
ILT
601 symp->sy_resolving = 1;
602
e702f6e6 603 reduce:
5ac34ac3 604 switch (symp->sy_value.X_op)
5868b1fe 605 {
5ac34ac3
ILT
606 case O_absent:
607 S_SET_VALUE (symp, 0);
608 /* Fall through. */
609 case O_constant:
610 S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
611 if (S_GET_SEGMENT (symp) == expr_section)
612 S_SET_SEGMENT (symp, absolute_section);
0cafaab1 613 resolved = 1;
5ac34ac3
ILT
614 break;
615
616 case O_symbol:
5868b1fe
ILT
617 resolve_symbol_value (symp->sy_value.X_add_symbol);
618
87e48495
KR
619#if 0 /* I thought this was needed for some of the i386-svr4 PIC
620 support, but it appears I was wrong, and it breaks rs6000
621 support. */
e702f6e6
KR
622 if (S_GET_SEGMENT (symp->sy_value.X_add_symbol) != undefined_section
623 && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section)
87e48495 624#endif
e702f6e6
KR
625 {
626 if (symp->sy_value.X_add_number == 0)
627 copy_symbol_attributes (symp, symp->sy_value.X_add_symbol);
628
629 S_SET_VALUE (symp,
630 (symp->sy_value.X_add_number
631 + symp->sy_frag->fr_address
632 + S_GET_VALUE (symp->sy_value.X_add_symbol)));
633 if (S_GET_SEGMENT (symp) == expr_section
634 || S_GET_SEGMENT (symp) == undefined_section)
635 S_SET_SEGMENT (symp,
636 S_GET_SEGMENT (symp->sy_value.X_add_symbol));
637 }
0cafaab1 638 resolved = symp->sy_value.X_add_symbol->sy_resolved;
5ac34ac3
ILT
639 break;
640
641 case O_uminus:
642 case O_bit_not:
643 resolve_symbol_value (symp->sy_value.X_add_symbol);
644 if (symp->sy_value.X_op == O_uminus)
645 val = - S_GET_VALUE (symp->sy_value.X_add_symbol);
646 else
647 val = ~ S_GET_VALUE (symp->sy_value.X_add_symbol);
648 S_SET_VALUE (symp,
649 (val
650 + symp->sy_value.X_add_number
651 + symp->sy_frag->fr_address));
652 if (S_GET_SEGMENT (symp) == expr_section
653 || S_GET_SEGMENT (symp) == undefined_section)
654 S_SET_SEGMENT (symp, absolute_section);
0cafaab1 655 resolved = symp->sy_value.X_add_symbol->sy_resolved;
5ac34ac3
ILT
656 break;
657
e702f6e6 658 case O_add:
e702f6e6
KR
659 resolve_symbol_value (symp->sy_value.X_add_symbol);
660 resolve_symbol_value (symp->sy_value.X_op_symbol);
661 seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);
662 seg_right = S_GET_SEGMENT (symp->sy_value.X_op_symbol);
663 /* This case comes up with PIC support. */
664 {
665 symbolS *s_left = symp->sy_value.X_add_symbol;
666 symbolS *s_right = symp->sy_value.X_op_symbol;
667
668 if (seg_left == absolute_section)
669 {
670 symbolS *t;
671 segT ts;
672 t = s_left;
673 s_left = s_right;
674 s_right = t;
675 ts = seg_left;
676 seg_left = seg_right;
677 seg_right = ts;
678 }
679 if (seg_right == absolute_section
680 && s_right->sy_resolved)
681 {
682 symp->sy_value.X_add_number += S_GET_VALUE (s_right);
683 symp->sy_value.X_op_symbol = 0;
684 symp->sy_value.X_add_symbol = s_left;
685 symp->sy_value.X_op = O_symbol;
686 goto reduce;
687 }
688 }
e702f6e6
KR
689 /* fall through */
690
5ac34ac3
ILT
691 case O_multiply:
692 case O_divide:
693 case O_modulus:
694 case O_left_shift:
695 case O_right_shift:
696 case O_bit_inclusive_or:
697 case O_bit_or_not:
698 case O_bit_exclusive_or:
699 case O_bit_and:
5ac34ac3 700 case O_subtract:
c978e704 701 resolve_symbol_value (symp->sy_value.X_add_symbol);
5ac34ac3
ILT
702 resolve_symbol_value (symp->sy_value.X_op_symbol);
703 seg_left = S_GET_SEGMENT (symp->sy_value.X_add_symbol);
704 seg_right = S_GET_SEGMENT (symp->sy_value.X_op_symbol);
705 if (seg_left != seg_right
706 && seg_left != undefined_section
707 && seg_right != undefined_section)
708 as_bad ("%s is operation on symbols in different sections",
c978e704 709 S_GET_NAME (symp));
5ac34ac3
ILT
710 if ((S_GET_SEGMENT (symp->sy_value.X_add_symbol)
711 != absolute_section)
712 && symp->sy_value.X_op != O_subtract)
713 as_bad ("%s is illegal operation on non-absolute symbols",
714 S_GET_NAME (symp));
715 left = S_GET_VALUE (symp->sy_value.X_add_symbol);
716 right = S_GET_VALUE (symp->sy_value.X_op_symbol);
717 switch (symp->sy_value.X_op)
718 {
719 case O_multiply: val = left * right; break;
720 case O_divide: val = left / right; break;
721 case O_modulus: val = left % right; break;
722 case O_left_shift: val = left << right; break;
723 case O_right_shift: val = left >> right; break;
724 case O_bit_inclusive_or: val = left | right; break;
725 case O_bit_or_not: val = left |~ right; break;
726 case O_bit_exclusive_or: val = left ^ right; break;
727 case O_bit_and: val = left & right; break;
728 case O_add: val = left + right; break;
729 case O_subtract: val = left - right; break;
730 default: abort ();
731 }
c978e704
ILT
732 S_SET_VALUE (symp,
733 (symp->sy_value.X_add_number
734 + symp->sy_frag->fr_address
5ac34ac3
ILT
735 + val));
736 if (S_GET_SEGMENT (symp) == expr_section
737 || S_GET_SEGMENT (symp) == undefined_section)
738 S_SET_SEGMENT (symp, absolute_section);
0cafaab1
ILT
739 resolved = (symp->sy_value.X_add_symbol->sy_resolved
740 && symp->sy_value.X_op_symbol->sy_resolved);
5ac34ac3
ILT
741 break;
742
743 case O_register:
744 case O_big:
745 case O_illegal:
0cafaab1
ILT
746 /* Give an error (below) if not in expr_section. We don't
747 want to worry about expr_section symbols, because they
748 are fictional (they are created as part of expression
749 resolution), and any problems may not actually mean
750 anything. */
5ac34ac3 751 break;
5868b1fe
ILT
752 }
753 }
754
0cafaab1
ILT
755 /* Don't worry if we can't resolve an expr_section symbol. */
756 if (resolved)
757 symp->sy_resolved = 1;
758 else if (S_GET_SEGMENT (symp) != expr_section)
759 {
760 as_bad ("can't resolve value for symbol \"%s\"", S_GET_NAME (symp));
761 symp->sy_resolved = 1;
762 }
5868b1fe
ILT
763}
764
6efd877d
KR
765/* Dollar labels look like a number followed by a dollar sign. Eg, "42$".
766 They are *really* local. That is, they go out of scope whenever we see a
767 label that isn't local. Also, like fb labels, there can be multiple
768 instances of a dollar label. Therefor, we name encode each instance with
769 the instance number, keep a list of defined symbols separate from the real
770 symbol table, and we treat these buggers as a sparse array. */
771
2b68b820
KR
772static long *dollar_labels;
773static long *dollar_label_instances;
774static char *dollar_label_defines;
775static long dollar_label_count;
604633ae 776static unsigned long dollar_label_max;
6efd877d
KR
777
778int
779dollar_label_defined (label)
780 long label;
781{
782 long *i;
783
784 know ((dollar_labels != NULL) || (dollar_label_count == 0));
785
786 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
787 if (*i == label)
788 return dollar_label_defines[i - dollar_labels];
6efd877d
KR
789
790 /* if we get here, label isn't defined */
2b68b820 791 return 0;
6efd877d
KR
792} /* dollar_label_defined() */
793
794static int
795dollar_label_instance (label)
796 long label;
797{
798 long *i;
799
800 know ((dollar_labels != NULL) || (dollar_label_count == 0));
801
802 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
803 if (*i == label)
804 return (dollar_label_instances[i - dollar_labels]);
6efd877d 805
2b68b820
KR
806 /* If we get here, we haven't seen the label before, therefore its instance
807 count is zero. */
808 return 0;
809}
6efd877d
KR
810
811void
812dollar_label_clear ()
813{
604633ae 814 memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
2b68b820 815}
6efd877d
KR
816
817#define DOLLAR_LABEL_BUMP_BY 10
818
819void
820define_dollar_label (label)
821 long label;
822{
823 long *i;
824
825 for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
2b68b820
KR
826 if (*i == label)
827 {
828 ++dollar_label_instances[i - dollar_labels];
829 dollar_label_defines[i - dollar_labels] = 1;
830 return;
831 }
6efd877d
KR
832
833 /* if we get to here, we don't have label listed yet. */
834
835 if (dollar_labels == NULL)
836 {
837 dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
838 dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
839 dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
840 dollar_label_max = DOLLAR_LABEL_BUMP_BY;
841 dollar_label_count = 0;
6efd877d
KR
842 }
843 else if (dollar_label_count == dollar_label_max)
844 {
845 dollar_label_max += DOLLAR_LABEL_BUMP_BY;
846 dollar_labels = (long *) xrealloc ((char *) dollar_labels,
847 dollar_label_max * sizeof (long));
848 dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
849 dollar_label_max * sizeof (long));
850 dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
851 } /* if we needed to grow */
852
853 dollar_labels[dollar_label_count] = label;
854 dollar_label_instances[dollar_label_count] = 1;
855 dollar_label_defines[dollar_label_count] = 1;
856 ++dollar_label_count;
2b68b820 857}
6efd877d
KR
858
859/*
860 * dollar_label_name()
861 *
862 * Caller must copy returned name: we re-use the area for the next name.
863 *
2b68b820
KR
864 * The mth occurence of label n: is turned into the symbol "Ln^Am"
865 * where n is the label number and m is the instance number. "L" makes
866 * it a label discarded unless debugging and "^A"('\1') ensures no
867 * ordinary symbol SHOULD get the same name as a local label
868 * symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
6efd877d
KR
869 *
870 * fb labels get the same treatment, except that ^B is used in place of ^A.
871 */
872
873char * /* Return local label name. */
874dollar_label_name (n, augend)
875 register long n; /* we just saw "n$:" : n a number */
876 register int augend; /* 0 for current instance, 1 for new instance */
877{
878 long i;
879 /* Returned to caller, then copied. used for created names ("4f") */
880 static char symbol_name_build[24];
881 register char *p;
882 register char *q;
883 char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
884
885 know (n >= 0);
886 know (augend == 0 || augend == 1);
887 p = symbol_name_build;
888 *p++ = 'L';
889
890 /* Next code just does sprintf( {}, "%d", n); */
891 /* label number */
892 q = symbol_name_temporary;
893 for (*q++ = 0, i = n; i; ++q)
894 {
895 *q = i % 10 + '0';
896 i /= 10;
897 }
898 while ((*p = *--q) != '\0')
899 ++p;
900
901 *p++ = 1; /* ^A */
902
903 /* instance number */
904 q = symbol_name_temporary;
905 for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
906 {
907 *q = i % 10 + '0';
908 i /= 10;
909 }
910 while ((*p++ = *--q) != '\0');;
911
912 /* The label, as a '\0' ended string, starts at symbol_name_build. */
2b68b820
KR
913 return symbol_name_build;
914}
6efd877d 915
6efd877d
KR
916/*
917 * Sombody else's idea of local labels. They are made by "n:" where n
918 * is any decimal digit. Refer to them with
919 * "nb" for previous (backward) n:
920 * or "nf" for next (forward) n:.
921 *
922 * We do a little better and let n be any number, not just a single digit, but
923 * since the other guy's assembler only does ten, we treat the first ten
924 * specially.
925 *
926 * Like someone else's assembler, we have one set of local label counters for
927 * entire assembly, not one set per (sub)segment like in most assemblers. This
928 * implies that one can refer to a label in another segment, and indeed some
929 * crufty compilers have done just that.
930 *
931 * Since there could be a LOT of these things, treat them as a sparse array.
932 */
933
934#define FB_LABEL_SPECIAL (10)
935
936static long fb_low_counter[FB_LABEL_SPECIAL];
937static long *fb_labels;
938static long *fb_label_instances;
eec0de3f
KR
939static long fb_label_count;
940static long fb_label_max;
6efd877d
KR
941
942/* this must be more than FB_LABEL_SPECIAL */
943#define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
944
945static void
946fb_label_init ()
947{
948 memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
6efd877d
KR
949} /* fb_label_init() */
950
951/* add one to the instance number of this fb label */
952void
953fb_label_instance_inc (label)
954 long label;
955{
956 long *i;
957
958 if (label < FB_LABEL_SPECIAL)
959 {
960 ++fb_low_counter[label];
961 return;
962 }
963
e154ecf4 964 if (fb_labels != NULL)
6efd877d 965 {
e154ecf4
ILT
966 for (i = fb_labels + FB_LABEL_SPECIAL;
967 i < fb_labels + fb_label_count; ++i)
6efd877d 968 {
e154ecf4
ILT
969 if (*i == label)
970 {
971 ++fb_label_instances[i - fb_labels];
972 return;
973 } /* if we find it */
974 } /* for each existing label */
975 }
6efd877d
KR
976
977 /* if we get to here, we don't have label listed yet. */
978
979 if (fb_labels == NULL)
980 {
981 fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
982 fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
983 fb_label_max = FB_LABEL_BUMP_BY;
984 fb_label_count = FB_LABEL_SPECIAL;
985
986 }
987 else if (fb_label_count == fb_label_max)
988 {
989 fb_label_max += FB_LABEL_BUMP_BY;
990 fb_labels = (long *) xrealloc ((char *) fb_labels,
991 fb_label_max * sizeof (long));
992 fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
993 fb_label_max * sizeof (long));
994 } /* if we needed to grow */
995
996 fb_labels[fb_label_count] = label;
997 fb_label_instances[fb_label_count] = 1;
998 ++fb_label_count;
1ecd6c4a 999}
6efd877d
KR
1000
1001static long
1002fb_label_instance (label)
1003 long label;
1004{
1005 long *i;
1006
1007 if (label < FB_LABEL_SPECIAL)
1008 {
1009 return (fb_low_counter[label]);
1010 }
1011
e154ecf4 1012 if (fb_labels != NULL)
6efd877d 1013 {
e154ecf4
ILT
1014 for (i = fb_labels + FB_LABEL_SPECIAL;
1015 i < fb_labels + fb_label_count; ++i)
6efd877d 1016 {
e154ecf4
ILT
1017 if (*i == label)
1018 {
1019 return (fb_label_instances[i - fb_labels]);
1020 } /* if we find it */
1021 } /* for each existing label */
1022 }
6efd877d 1023
e154ecf4
ILT
1024 /* We didn't find the label, so this must be a reference to the
1025 first instance. */
1026 return 0;
2b68b820 1027}
6efd877d
KR
1028
1029/*
1030 * fb_label_name()
1031 *
1032 * Caller must copy returned name: we re-use the area for the next name.
1033 *
2b68b820
KR
1034 * The mth occurence of label n: is turned into the symbol "Ln^Bm"
1035 * where n is the label number and m is the instance number. "L" makes
1036 * it a label discarded unless debugging and "^B"('\2') ensures no
1037 * ordinary symbol SHOULD get the same name as a local label
1038 * symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
6efd877d 1039 *
2b68b820 1040 * dollar labels get the same treatment, except that ^A is used in place of ^B. */
6efd877d
KR
1041
1042char * /* Return local label name. */
1043fb_label_name (n, augend)
1044 long n; /* we just saw "n:", "nf" or "nb" : n a number */
1045 long augend; /* 0 for nb, 1 for n:, nf */
1046{
1047 long i;
1048 /* Returned to caller, then copied. used for created names ("4f") */
1049 static char symbol_name_build[24];
1050 register char *p;
1051 register char *q;
1052 char symbol_name_temporary[20]; /* build up a number, BACKWARDS */
1053
1054 know (n >= 0);
1055 know (augend == 0 || augend == 1);
1056 p = symbol_name_build;
1057 *p++ = 'L';
1058
1059 /* Next code just does sprintf( {}, "%d", n); */
1060 /* label number */
1061 q = symbol_name_temporary;
1062 for (*q++ = 0, i = n; i; ++q)
1063 {
1064 *q = i % 10 + '0';
1065 i /= 10;
1066 }
1067 while ((*p = *--q) != '\0')
1068 ++p;
1069
1070 *p++ = 2; /* ^B */
1071
1072 /* instance number */
1073 q = symbol_name_temporary;
1074 for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
1075 {
1076 *q = i % 10 + '0';
1077 i /= 10;
1078 }
1079 while ((*p++ = *--q) != '\0');;
1080
1081 /* The label, as a '\0' ended string, starts at symbol_name_build. */
1082 return (symbol_name_build);
1083} /* fb_label_name() */
1084
a6c6eaf8 1085/*
6efd877d
KR
1086 * decode name that may have been generated by foo_label_name() above. If
1087 * the name wasn't generated by foo_label_name(), then return it unaltered.
a6c6eaf8
RP
1088 * This is used for error messages.
1089 */
a39116f1 1090
6efd877d
KR
1091char *
1092decode_local_label_name (s)
1093 char *s;
a6c6eaf8 1094{
6efd877d
KR
1095 char *p;
1096 char *symbol_decode;
1097 int label_number;
1098 int instance_number;
1099 char *type;
1100 const char *message_format = "\"%d\" (instance number %d of a %s label)";
1101
1102 if (s[0] != 'L')
56dc989a 1103 return s;
6efd877d
KR
1104
1105 for (label_number = 0, p = s + 1; isdigit (*p); ++p)
56dc989a 1106 label_number = (10 * label_number) + *p - '0';
6efd877d
KR
1107
1108 if (*p == 1)
56dc989a 1109 type = "dollar";
6efd877d 1110 else if (*p == 2)
56dc989a 1111 type = "fb";
6efd877d 1112 else
56dc989a 1113 return s;
6efd877d 1114
56dc989a
ILT
1115 for (instance_number = 0, p++; isdigit (*p); ++p)
1116 instance_number = (10 * instance_number) + *p - '0';
6efd877d
KR
1117
1118 symbol_decode = obstack_alloc (&notes, strlen (message_format) + 30);
56dc989a 1119 sprintf (symbol_decode, message_format, label_number, instance_number, type);
6efd877d 1120
56dc989a
ILT
1121 return symbol_decode;
1122}
a6c6eaf8 1123
85051959
ILT
1124/* Get the value of a symbol. */
1125
1126valueT
1127S_GET_VALUE (s)
1128 symbolS *s;
1129{
e702f6e6
KR
1130 if (!s->sy_resolved && !s->sy_resolving && s->sy_value.X_op != O_constant)
1131 resolve_symbol_value (s);
5ac34ac3 1132 if (s->sy_value.X_op != O_constant)
5868b1fe 1133 as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s));
85051959
ILT
1134 return (valueT) s->sy_value.X_add_number;
1135}
1136
1137/* Set the value of a symbol. */
1138
1139void
1140S_SET_VALUE (s, val)
1141 symbolS *s;
1142 valueT val;
1143{
5ac34ac3 1144 s->sy_value.X_op = O_constant;
85051959 1145 s->sy_value.X_add_number = (offsetT) val;
0cafaab1 1146 s->sy_value.X_unsigned = 0;
85051959
ILT
1147}
1148
e702f6e6
KR
1149void
1150copy_symbol_attributes (dest, src)
1151 symbolS *dest, *src;
1152{
1153#ifdef BFD_ASSEMBLER
1154 /* In an expression, transfer the settings of these flags.
1155 The user can override later, of course. */
1156#define COPIED_SYMFLAGS (BSF_FUNCTION)
1157 dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
1158#endif
1159
1160#ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
1161 OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
1162#endif
1163}
1164
2b68b820
KR
1165#ifdef BFD_ASSEMBLER
1166
1167int
1168S_IS_EXTERNAL (s)
1169 symbolS *s;
1170{
1171 flagword flags = s->bsym->flags;
1172
1173 /* sanity check */
0cafaab1 1174 if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
2b68b820
KR
1175 abort ();
1176
0cafaab1 1177 return (flags & BSF_GLOBAL) != 0;
2b68b820
KR
1178}
1179
1180int
1181S_IS_COMMON (s)
1182 symbolS *s;
1183{
0cafaab1 1184 return bfd_is_com_section (s->bsym->section);
2b68b820
KR
1185}
1186
1187int
1188S_IS_DEFINED (s)
1189 symbolS *s;
1190{
1191 return s->bsym->section != undefined_section;
1192}
1193
1194int
1195S_IS_DEBUG (s)
1196 symbolS *s;
1197{
1198 if (s->bsym->flags & BSF_DEBUGGING)
1199 return 1;
1200 return 0;
1201}
1202
1203int
1204S_IS_LOCAL (s)
1205 symbolS *s;
1206{
1207 flagword flags = s->bsym->flags;
1208
1209 /* sanity check */
0cafaab1 1210 if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
2b68b820
KR
1211 abort ();
1212
1213 return (S_GET_NAME (s)
1214 && ! S_IS_DEBUG (s)
1215 && (strchr (S_GET_NAME (s), '\001')
1216 || strchr (S_GET_NAME (s), '\002')
1217 || (S_LOCAL_NAME (s)
dacf29ea 1218 && !flag_keep_locals)));
2b68b820
KR
1219}
1220
1221int
1222S_IS_EXTERN (s)
1223 symbolS *s;
1224{
1225 return S_IS_EXTERNAL (s);
1226}
1227
1228int
1229S_IS_STABD (s)
1230 symbolS *s;
1231{
1232 return S_GET_NAME (s) == 0;
1233}
1234
2b68b820
KR
1235CONST char *
1236S_GET_NAME (s)
1237 symbolS *s;
1238{
1239 return s->bsym->name;
1240}
1241
1242segT
1243S_GET_SEGMENT (s)
1244 symbolS *s;
1245{
1246 return s->bsym->section;
1247}
1248
2b68b820
KR
1249void
1250S_SET_SEGMENT (s, seg)
1251 symbolS *s;
1252 segT seg;
1253{
1254 s->bsym->section = seg;
1255}
1256
1257void
1258S_SET_EXTERNAL (s)
1259 symbolS *s;
1260{
56dc989a
ILT
1261 if ((s->bsym->flags & BSF_WEAK) != 0)
1262 as_warn ("%s already declared as weak", S_GET_NAME (s));
1ecd6c4a
KR
1263 s->bsym->flags |= BSF_GLOBAL;
1264 s->bsym->flags &= ~(BSF_LOCAL|BSF_WEAK);
2b68b820
KR
1265}
1266
1267void
1268S_CLEAR_EXTERNAL (s)
1269 symbolS *s;
1270{
56dc989a
ILT
1271 if ((s->bsym->flags & BSF_WEAK) != 0)
1272 as_warn ("%s already declared as weak", S_GET_NAME (s));
2b68b820 1273 s->bsym->flags |= BSF_LOCAL;
1ecd6c4a
KR
1274 s->bsym->flags &= ~(BSF_GLOBAL|BSF_WEAK);
1275}
1276
1277void
1278S_SET_WEAK (s)
1279 symbolS *s;
1280{
56dc989a
ILT
1281 if ((s->bsym->flags & BSF_GLOBAL) != 0)
1282 as_warn ("%s already declared as global", S_GET_NAME (s));
1ecd6c4a
KR
1283 s->bsym->flags |= BSF_WEAK;
1284 s->bsym->flags &= ~(BSF_GLOBAL|BSF_LOCAL);
2b68b820
KR
1285}
1286
1287void
1288S_SET_NAME (s, name)
1289 symbolS *s;
1290 char *name;
1291{
1292 s->bsym->name = name;
1293}
1294#endif /* BFD_ASSEMBLER */
1295
eec0de3f
KR
1296void
1297symbol_begin ()
1298{
1299 symbol_lastP = NULL;
1300 symbol_rootP = NULL; /* In case we have 0 symbols (!!) */
1301 sy_hash = hash_new ();
dacf29ea 1302
eec0de3f
KR
1303 memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
1304#ifdef BFD_ASSEMBLER
dacf29ea 1305#if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
eec0de3f 1306 abs_symbol.bsym = bfd_abs_section.symbol;
dacf29ea 1307#endif
eec0de3f
KR
1308#else
1309 /* Can't initialise a union. Sigh. */
1310 S_SET_SEGMENT (&abs_symbol, absolute_section);
1311#endif
dacf29ea
KR
1312 abs_symbol.sy_value.X_op = O_constant;
1313
56dc989a
ILT
1314 if (LOCAL_LABELS_FB)
1315 fb_label_init ();
eec0de3f
KR
1316}
1317
e702f6e6
KR
1318\f
1319int indent_level;
dacf29ea 1320
56dc989a
ILT
1321#if 0
1322
dacf29ea
KR
1323static void
1324indent ()
1325{
1326 printf ("%*s", indent_level * 4, "");
1327}
1328
56dc989a
ILT
1329#endif
1330
dacf29ea
KR
1331void print_expr_1 PARAMS ((FILE *, expressionS *));
1332void print_symbol_value_1 PARAMS ((FILE *, symbolS *));
1333
1334void
1335print_symbol_value_1 (file, sym)
1336 FILE *file;
1337 symbolS *sym;
1338{
1339 const char *name = S_GET_NAME (sym);
1340 if (!name || !name[0])
1341 name = "(unnamed)";
56dc989a 1342 fprintf (file, "sym %lx %s", (unsigned long) sym, name);
e702f6e6
KR
1343 if (sym->sy_frag != &zero_address_frag)
1344 fprintf (file, " frag %lx", (long) sym->sy_frag);
dacf29ea
KR
1345 if (sym->written)
1346 fprintf (file, " written");
1347 if (sym->sy_resolved)
1348 fprintf (file, " resolved");
e702f6e6 1349 else if (sym->sy_resolving)
dacf29ea
KR
1350 fprintf (file, " resolving");
1351 if (sym->sy_used_in_reloc)
1352 fprintf (file, " used-in-reloc");
1353 if (sym->sy_used)
1354 fprintf (file, " used");
87e48495
KR
1355 if (S_IS_LOCAL (sym))
1356 fprintf (file, " local");
1357 if (S_IS_EXTERN (sym))
1358 fprintf (file, " extern");
1359 if (S_IS_DEBUG (sym))
1360 fprintf (file, " debug");
1361 if (S_IS_DEFINED (sym))
1362 fprintf (file, " defined");
e702f6e6 1363 fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
dacf29ea
KR
1364 if (sym->sy_resolved)
1365 {
e702f6e6
KR
1366 segT s = S_GET_SEGMENT (sym);
1367
1368 if (s != undefined_section
1369 && s != expr_section)
1370 fprintf (file, " %lx", (long) S_GET_VALUE (sym));
dacf29ea 1371 }
e702f6e6 1372 else if (indent_level < 8 && S_GET_SEGMENT (sym) != undefined_section)
dacf29ea
KR
1373 {
1374 indent_level++;
1375 fprintf (file, "\n%*s<", indent_level * 4, "");
1376 print_expr_1 (file, &sym->sy_value);
1377 fprintf (file, ">");
1378 indent_level--;
1379 }
1380 fflush (file);
1381}
1382
1383void
1384print_symbol_value (sym)
1385 symbolS *sym;
1386{
1387 indent_level = 0;
1388 print_symbol_value_1 (stderr, sym);
1389 fprintf (stderr, "\n");
1390}
1391
1392void
1393print_expr_1 (file, exp)
1394 FILE *file;
1395 expressionS *exp;
1396{
1397 fprintf (file, "expr %lx ", (long) exp);
1398 switch (exp->X_op)
1399 {
1400 case O_illegal:
1401 fprintf (file, "illegal");
1402 break;
1403 case O_absent:
1404 fprintf (file, "absent");
1405 break;
1406 case O_constant:
1407 fprintf (file, "constant %lx", (long) exp->X_add_number);
1408 break;
1409 case O_symbol:
1410 indent_level++;
1411 fprintf (file, "symbol\n%*s<", indent_level * 4, "");
1412 print_symbol_value_1 (file, exp->X_add_symbol);
1413 fprintf (file, ">");
1414 maybe_print_addnum:
dacf29ea 1415 if (exp->X_add_number)
e702f6e6 1416 fprintf (file, "\n%*s%lx", indent_level * 4, "",
dacf29ea 1417 (long) exp->X_add_number);
e702f6e6 1418 indent_level--;
dacf29ea
KR
1419 break;
1420 case O_register:
1421 fprintf (file, "register #%d", (int) exp->X_add_number);
1422 break;
1423 case O_big:
1424 fprintf (file, "big");
1425 break;
1426 case O_uminus:
1427 fprintf (file, "uminus -<");
1428 indent_level++;
1429 print_symbol_value_1 (file, exp->X_add_symbol);
1430 fprintf (file, ">");
1431 goto maybe_print_addnum;
1432 case O_bit_not:
1433 fprintf (file, "bit_not");
1434 break;
1435 case O_multiply:
1436 fprintf (file, "multiply");
1437 break;
1438 case O_divide:
1439 fprintf (file, "divide");
1440 break;
1441 case O_modulus:
1442 fprintf (file, "modulus");
1443 break;
1444 case O_left_shift:
1445 fprintf (file, "lshift");
1446 break;
1447 case O_right_shift:
1448 fprintf (file, "rshift");
1449 break;
1450 case O_bit_inclusive_or:
1451 fprintf (file, "bit_ior");
1452 break;
1453 case O_bit_exclusive_or:
1454 fprintf (file, "bit_xor");
1455 break;
1456 case O_bit_and:
1457 fprintf (file, "bit_and");
1458 break;
1459 case O_add:
1460 indent_level++;
1461 fprintf (file, "add\n%*s<", indent_level * 4, "");
1462 print_symbol_value_1 (file, exp->X_add_symbol);
1463 fprintf (file, ">\n%*s<", indent_level * 4, "");
1464 print_symbol_value_1 (file, exp->X_op_symbol);
1465 fprintf (file, ">");
1466 goto maybe_print_addnum;
1467 case O_subtract:
1468 indent_level++;
1469 fprintf (file, "subtract\n%*s<", indent_level * 4, "");
1470 print_symbol_value_1 (file, exp->X_add_symbol);
1471 fprintf (file, ">\n%*s<", indent_level * 4, "");
1472 print_symbol_value_1 (file, exp->X_op_symbol);
1473 fprintf (file, ">");
1474 goto maybe_print_addnum;
1475 default:
1476 fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
1477 break;
1478 }
1479 fflush (stdout);
1480}
1481
1482void
1483print_expr (exp)
1484 expressionS *exp;
1485{
1486 print_expr_1 (stderr, exp);
1487 fprintf (stderr, "\n");
1488}
1489
8b228fe9 1490/* end of symbols.c */
This page took 0.207586 seconds and 4 git commands to generate.