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