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