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