* frags.c (frag_init): Call obstack_begin on `frags'.
[external/binutils.git] / gas / symbols.c
1 /* symbols.c -symbol table-
2    Copyright (C) 1987, 1990, 1991, 1992, 1993, 1994
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, 675 Mass Ave, Cambridge, MA 02139, 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 #ifndef WORKING_DOT_WORD
31 extern int new_broken_words;
32 #endif
33
34 /* symbol-name => struct symbol pointer */
35 static struct hash_control *sy_hash;
36
37 /* Below are commented in "symbols.h". */
38 symbolS *symbol_rootP;
39 symbolS *symbol_lastP;
40 symbolS abs_symbol;
41
42 #ifdef DEBUG_SYMS
43 #define debug_verify_symchain verify_symbol_chain
44 #else
45 #define debug_verify_symchain (void)
46 #endif
47
48 struct obstack notes;
49
50 static void fb_label_init PARAMS ((void));
51
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.  */
62
63 symbolS *
64 symbol_new (name, segment, valu, frag)
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
88 symbolS *
89 symbol_create (name, segment, valu, frag)
90      const char *name;          /* It is copied, the caller can destroy/modify */
91      segT segment;              /* Segment identifier (SEG_<something>) */
92      valueT valu;               /* Symbol value */
93      fragS *frag;               /* Associated fragment */
94 {
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);
102 #ifdef STRIP_UNDERSCORE
103   if (preserved_copy_of_name[0] == '_')
104     preserved_copy_of_name++;
105 #endif
106
107 #ifdef tc_canonicalize_symbol_name
108   preserved_copy_of_name =
109     tc_canonicalize_symbol_name (preserved_copy_of_name);
110 #endif
111
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
117 #ifdef BFD_ASSEMBLER
118   symbolP->bsym = bfd_make_empty_symbol (stdoutput);
119   assert (symbolP->bsym != 0);
120   symbolP->bsym->udata.p = (PTR) symbolP;
121 #endif
122   S_SET_NAME (symbolP, preserved_copy_of_name);
123
124   S_SET_SEGMENT (symbolP, segment);
125   S_SET_VALUE (symbolP, valu);
126   symbol_clear_list_pointers (symbolP);
127
128   symbolP->sy_frag = frag;
129 #ifndef BFD_ASSEMBLER
130   symbolP->sy_number = ~0;
131   symbolP->sy_name_offset = (unsigned int) ~0;
132 #endif
133
134   obj_symbol_new_hook (symbolP);
135
136 #ifdef tc_symbol_new_hook
137   tc_symbol_new_hook (symbolP);
138 #endif
139
140   return symbolP;
141 }
142 \f
143
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  */
153 void 
154 colon (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. */
157 {
158   register symbolS *symbolP;    /* symbol we are working with */
159
160 #ifdef LOCAL_LABELS_DOLLAR
161   /* Sun local labels go out of scope whenever a non-local symbol is
162      defined.  */
163
164   if (*sym_name != 'L')
165     dollar_label_clear ();
166 #endif /* LOCAL_LABELS_DOLLAR */
167
168 #ifndef WORKING_DOT_WORD
169   if (new_broken_words)
170     {
171       struct broken_word *a;
172       int possible_bytes;
173       fragS *frag_tmp;
174       char *frag_opcode;
175
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);
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
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))
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     {
208 #ifdef RESOLVE_SYMBOL_REDEFINITION
209       if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
210         return;
211 #endif
212       /*
213        *        Now check for undefined symbols
214        */
215       if (!S_IS_DEFINED (symbolP))
216         {
217           if (S_GET_VALUE (symbolP) == 0)
218             {
219               symbolP->sy_frag = frag_now;
220 #ifdef OBJ_VMS
221               S_GET_OTHER(symbolP) = const_flag;
222 #endif
223               S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
224               S_SET_SEGMENT (symbolP, now_seg);
225 #ifdef N_UNDF
226               know (N_UNDF == 0);
227 #endif /* if we have one, it better be zero. */
228
229             }
230           else
231             {
232               /*
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)))
249                 {
250                   /*
251                    *    Select which of the 2 cases this is
252                    */
253                   if (now_seg != data_section)
254                     {
255                       /*
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                        */
261                       if (S_GET_VALUE (symbolP)
262                           < ((unsigned) frag_now_fix ()))
263                         {
264                           S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
265                         }
266                     }
267                   else
268                     {
269                       /* It is a .comm/.lcomm being converted to initialized
270                          data.  */
271                       symbolP->sy_frag = frag_now;
272 #ifdef OBJ_VMS
273                       S_GET_OTHER(symbolP) = const_flag;
274 #endif /* OBJ_VMS */
275                       S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
276                       S_SET_SEGMENT (symbolP, now_seg); /* keep N_EXT bit */
277                     }
278                 }
279               else
280                 {
281 #if defined (S_GET_OTHER) && defined (S_GET_DESC)
282                   as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
283                             sym_name,
284                             segment_name (S_GET_SEGMENT (symbolP)),
285                             S_GET_OTHER (symbolP), S_GET_DESC (symbolP),
286                             (long) S_GET_VALUE (symbolP));
287 #else
288                   as_fatal ("Symbol \"%s\" is already defined as \"%s\"/%ld.",
289                             sym_name,
290                             segment_name (S_GET_SEGMENT (symbolP)),
291                             (long) S_GET_VALUE (symbolP));
292 #endif
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
300                 && S_GET_VALUE (symbolP) == frag_now_fix ()
301                 && S_GET_SEGMENT (symbolP) == now_seg))
302             as_fatal ("Symbol %s already defined.", sym_name);
303         }                       /* if this symbol is not yet defined */
304
305     }
306   else
307     {
308       symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (),
309                             frag_now);
310 #ifdef OBJ_VMS
311       S_SET_OTHER (symbolP, const_flag);
312 #endif /* OBJ_VMS */
313
314       symbol_table_insert (symbolP);
315     }                           /* if we have seen this symbol before */
316
317 #ifdef tc_frob_label
318   tc_frob_label (symbolP);
319 #endif
320 }
321 \f
322
323 /*
324  *                      symbol_table_insert()
325  *
326  * Die if we can't insert the symbol.
327  *
328  */
329
330 void 
331 symbol_table_insert (symbolP)
332      symbolS *symbolP;
333 {
334   register const char *error_string;
335
336   know (symbolP);
337   know (S_GET_NAME (symbolP));
338
339   if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
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() */
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  */
352 symbolS *
353 symbol_find_or_make (name)
354      char *name;
355 {
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
370 symbolS *
371 symbol_make (name)
372      CONST char *name;
373 {
374   symbolS *symbolP;
375
376   /* Let the machine description default it, e.g. for register names. */
377   symbolP = md_undefined_symbol ((char *) name);
378
379   if (!symbolP)
380     symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
381
382   return (symbolP);
383 }                               /* symbol_make() */
384
385 /*
386  *                      symbol_find()
387  *
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
394 symbolS *
395 symbol_find (name)
396      CONST char *name;
397 {
398 #ifdef STRIP_UNDERSCORE
399   return (symbol_find_base (name, 1));
400 #else /* STRIP_UNDERSCORE */
401   return (symbol_find_base (name, 0));
402 #endif /* STRIP_UNDERSCORE */
403 }                               /* symbol_find() */
404
405 symbolS *
406 symbol_find_base (name, strip_underscore)
407      CONST char *name;
408      int strip_underscore;
409 {
410   if (strip_underscore && *name == '_')
411     name++;
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
423   return ((symbolS *) hash_find (sy_hash, name));
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. */
435 void 
436 symbol_append (addme, target, rootPP, lastPP)
437      symbolS *addme;
438      symbolS *target;
439      symbolS **rootPP;
440      symbolS **lastPP;
441 {
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     {
453 #ifdef SYMBOLS_NEED_BACKPOINTERS
454       target->sy_next->sy_previous = addme;
455 #endif /* SYMBOLS_NEED_BACKPOINTERS */
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
466 #ifdef SYMBOLS_NEED_BACKPOINTERS
467   addme->sy_previous = target;
468 #endif /* SYMBOLS_NEED_BACKPOINTERS */
469 }
470
471 /* Set the chain pointers of SYMBOL to null. */
472 void 
473 symbol_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
482 #ifdef SYMBOLS_NEED_BACKPOINTERS
483 /* Remove SYMBOLP from the list. */
484 void 
485 symbol_remove (symbolP, rootPP, lastPP)
486      symbolS *symbolP;
487      symbolS **rootPP;
488      symbolS **lastPP;
489 {
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
510   debug_verify_symchain (*rootPP, *lastPP);
511 }
512
513 /* Link symbol ADDME before symbol TARGET in the chain. */
514 void 
515 symbol_insert (addme, target, rootPP, lastPP)
516      symbolS *addme;
517      symbolS *target;
518      symbolS **rootPP;
519      symbolS **lastPP;
520 {
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
535   debug_verify_symchain (*rootPP, *lastPP);
536 }
537
538 #endif /* SYMBOLS_NEED_BACKPOINTERS */
539
540 void 
541 verify_symbol_chain (rootP, lastP)
542      symbolS *rootP;
543      symbolS *lastP;
544 {
545   symbolS *symbolP = rootP;
546
547   if (symbolP == NULL)
548     return;
549
550   for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
551     {
552 #ifdef SYMBOLS_NEED_BACKPOINTERS
553       know (symbolP->sy_next->sy_previous == symbolP);
554 #else
555       /* Walk the list anyways, to make sure pointers are still good.  */
556       ;
557 #endif /* SYMBOLS_NEED_BACKPOINTERS */
558     }
559
560   assert (lastP == symbolP);
561 }
562
563 void
564 verify_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 }
576
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
581 void
582 resolve_symbol_value (symp)
583      symbolS *symp;
584 {
585   int resolved;
586
587   if (symp->sy_resolved)
588     return;
589
590   resolved = 0;
591
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);
597       resolved = 1;
598     }
599   else
600     {
601       offsetT left, right, val;
602       segT seg_left, seg_right;
603
604       symp->sy_resolving = 1;
605
606     reduce:
607       switch (symp->sy_value.X_op)
608         {
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);
616           resolved = 1;
617           break;
618
619         case O_symbol:
620           resolve_symbol_value (symp->sy_value.X_add_symbol);
621
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.  */
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)
627 #endif
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             }
641           resolved = symp->sy_value.X_add_symbol->sy_resolved;
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);
658           resolved = symp->sy_value.X_add_symbol->sy_resolved;
659           break;
660
661         case O_add:
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           }
692           /* fall through */
693
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:
703         case O_subtract:
704           resolve_symbol_value (symp->sy_value.X_add_symbol);
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",
712                     S_GET_NAME (symp));
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             }
735           S_SET_VALUE (symp,
736                        (symp->sy_value.X_add_number
737                         + symp->sy_frag->fr_address
738                         + val));
739           if (S_GET_SEGMENT (symp) == expr_section
740               || S_GET_SEGMENT (symp) == undefined_section)
741             S_SET_SEGMENT (symp, absolute_section);
742           resolved = (symp->sy_value.X_add_symbol->sy_resolved
743                       && symp->sy_value.X_op_symbol->sy_resolved);
744           break;
745
746         case O_register:
747         case O_big:
748         case O_illegal:
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.  */
754           break;
755         }
756     }
757
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     }
766 }
767
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
777 static long *dollar_labels;
778 static long *dollar_label_instances;
779 static char *dollar_label_defines;
780 static long dollar_label_count;
781 static unsigned long dollar_label_max;
782
783 int 
784 dollar_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)
792     if (*i == label)
793       return dollar_label_defines[i - dollar_labels];
794
795   /* if we get here, label isn't defined */
796   return 0;
797 }                               /* dollar_label_defined() */
798
799 static int 
800 dollar_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)
808     if (*i == label)
809       return (dollar_label_instances[i - dollar_labels]);
810
811   /* If we get here, we haven't seen the label before, therefore its instance
812      count is zero.  */
813   return 0;
814 }
815
816 void 
817 dollar_label_clear ()
818 {
819   memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
820 }
821
822 #define DOLLAR_LABEL_BUMP_BY 10
823
824 void 
825 define_dollar_label (label)
826      long label;
827 {
828   long *i;
829
830   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
831     if (*i == label)
832       {
833         ++dollar_label_instances[i - dollar_labels];
834         dollar_label_defines[i - dollar_labels] = 1;
835         return;
836       }
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;
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;
862 }
863
864 /*
865  *                      dollar_label_name()
866  *
867  * Caller must copy returned name: we re-use the area for the next name.
868  *
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.
874  *
875  * fb labels get the same treatment, except that ^B is used in place of ^A.
876  */
877
878 char *                          /* Return local label name. */
879 dollar_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. */
918   return symbol_name_build;
919 }
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
945 static long fb_low_counter[FB_LABEL_SPECIAL];
946 static long *fb_labels;
947 static long *fb_label_instances;
948 static long fb_label_count;
949 static long fb_label_max;
950
951 /* this must be more than FB_LABEL_SPECIAL */
952 #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
953
954 static void 
955 fb_label_init ()
956 {
957   memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
958 }                               /* fb_label_init() */
959
960 /* add one to the instance number of this fb label */
961 void 
962 fb_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
973   if (fb_labels != NULL)
974     {
975       for (i = fb_labels + FB_LABEL_SPECIAL;
976            i < fb_labels + fb_label_count; ++i)
977         {
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     }
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;
1008 }
1009
1010 static long 
1011 fb_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
1021   if (fb_labels != NULL)
1022     {
1023       for (i = fb_labels + FB_LABEL_SPECIAL;
1024            i < fb_labels + fb_label_count; ++i)
1025         {
1026           if (*i == label)
1027             {
1028               return (fb_label_instances[i - fb_labels]);
1029             }                   /* if we find it */
1030         }                       /* for each existing label */
1031     }
1032
1033   /* We didn't find the label, so this must be a reference to the
1034      first instance.  */
1035   return 0;
1036 }
1037
1038 /*
1039  *                      fb_label_name()
1040  *
1041  * Caller must copy returned name: we re-use the area for the next name.
1042  *
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.
1048  *
1049  * dollar labels get the same treatment, except that ^A is used in place of ^B. */
1050
1051 char *                          /* Return local label name. */
1052 fb_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 */
1095
1096
1097 /*
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.
1100  * This is used for error messages.
1101  */
1102
1103 char *
1104 decode_local_label_name (s)
1105      char *s;
1106 {
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() */
1146
1147 /* Get the value of a symbol.  */
1148
1149 valueT
1150 S_GET_VALUE (s)
1151      symbolS *s;
1152 {
1153   if (!s->sy_resolved && !s->sy_resolving && s->sy_value.X_op != O_constant)
1154     resolve_symbol_value (s);
1155   if (s->sy_value.X_op != O_constant)
1156     as_bad ("Attempt to get value of unresolved symbol %s", S_GET_NAME (s));
1157   return (valueT) s->sy_value.X_add_number;
1158 }
1159
1160 /* Set the value of a symbol.  */
1161
1162 void
1163 S_SET_VALUE (s, val)
1164      symbolS *s;
1165      valueT val;
1166 {
1167   s->sy_value.X_op = O_constant;
1168   s->sy_value.X_add_number = (offsetT) val;
1169   s->sy_value.X_unsigned = 0;
1170 }
1171
1172 void
1173 copy_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
1188 #ifdef BFD_ASSEMBLER
1189
1190 int
1191 S_IS_EXTERNAL (s)
1192      symbolS *s;
1193 {
1194   flagword flags = s->bsym->flags;
1195
1196   /* sanity check */
1197   if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
1198     abort ();
1199
1200   return (flags & BSF_GLOBAL) != 0;
1201 }
1202
1203 int
1204 S_IS_COMMON (s)
1205      symbolS *s;
1206 {
1207   return bfd_is_com_section (s->bsym->section);
1208 }
1209
1210 int
1211 S_IS_DEFINED (s)
1212      symbolS *s;
1213 {
1214   return s->bsym->section != undefined_section;
1215 }
1216
1217 int
1218 S_IS_DEBUG (s)
1219      symbolS *s;
1220 {
1221   if (s->bsym->flags & BSF_DEBUGGING)
1222     return 1;
1223   return 0;
1224 }
1225
1226 int
1227 S_IS_LOCAL (s)
1228      symbolS *s;
1229 {
1230   flagword flags = s->bsym->flags;
1231
1232   /* sanity check */
1233   if (flags & BSF_LOCAL && flags & BSF_GLOBAL)
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)
1241                   && !flag_keep_locals)));
1242 }
1243
1244 int
1245 S_IS_EXTERN (s)
1246      symbolS *s;
1247 {
1248   return S_IS_EXTERNAL (s);
1249 }
1250
1251 int
1252 S_IS_STABD (s)
1253      symbolS *s;
1254 {
1255   return S_GET_NAME (s) == 0;
1256 }
1257
1258 CONST char *
1259 S_GET_NAME (s)
1260      symbolS *s;
1261 {
1262   return s->bsym->name;
1263 }
1264
1265 segT
1266 S_GET_SEGMENT (s)
1267      symbolS *s;
1268 {
1269   return s->bsym->section;
1270 }
1271
1272 void
1273 S_SET_SEGMENT (s, seg)
1274      symbolS *s;
1275      segT seg;
1276 {
1277   s->bsym->section = seg;
1278 }
1279
1280 void
1281 S_SET_EXTERNAL (s)
1282      symbolS *s;
1283 {
1284   s->bsym->flags |= BSF_GLOBAL;
1285   s->bsym->flags &= ~(BSF_LOCAL|BSF_WEAK);
1286 }
1287
1288 void
1289 S_CLEAR_EXTERNAL (s)
1290      symbolS *s;
1291 {
1292   s->bsym->flags |= BSF_LOCAL;
1293   s->bsym->flags &= ~(BSF_GLOBAL|BSF_WEAK);
1294 }
1295
1296 void
1297 S_SET_WEAK (s)
1298      symbolS *s;
1299 {
1300   s->bsym->flags |= BSF_WEAK;
1301   s->bsym->flags &= ~(BSF_GLOBAL|BSF_LOCAL);
1302 }
1303
1304 void
1305 S_SET_NAME (s, name)
1306      symbolS *s;
1307      char *name;
1308 {
1309   s->bsym->name = name;
1310 }
1311 #endif /* BFD_ASSEMBLER */
1312
1313 void
1314 symbol_begin ()
1315 {
1316   symbol_lastP = NULL;
1317   symbol_rootP = NULL;          /* In case we have 0 symbols (!!) */
1318   sy_hash = hash_new ();
1319
1320   memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
1321 #ifdef BFD_ASSEMBLER
1322 #if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
1323   abs_symbol.bsym = bfd_abs_section.symbol;
1324 #endif
1325 #else
1326   /* Can't initialise a union. Sigh. */
1327   S_SET_SEGMENT (&abs_symbol, absolute_section);
1328 #endif
1329   abs_symbol.sy_value.X_op = O_constant;
1330
1331 #ifdef LOCAL_LABELS_FB
1332   fb_label_init ();
1333 #endif /* LOCAL_LABELS_FB */
1334 }
1335
1336 \f
1337 int indent_level;
1338
1339 static void
1340 indent ()
1341 {
1342   printf ("%*s", indent_level * 4, "");
1343 }
1344
1345 void print_expr_1 PARAMS ((FILE *, expressionS *));
1346 void print_symbol_value_1 PARAMS ((FILE *, symbolS *));
1347
1348 void
1349 print_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)";
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);
1359   if (sym->written)
1360     fprintf (file, " written");
1361   if (sym->sy_resolved)
1362     fprintf (file, " resolved");
1363   else if (sym->sy_resolving)
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");
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");
1377   fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
1378   if (sym->sy_resolved)
1379     {
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));
1385     }
1386   else if (indent_level < 8 && S_GET_SEGMENT (sym) != undefined_section)
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
1397 void
1398 print_symbol_value (sym)
1399      symbolS *sym;
1400 {
1401   indent_level = 0;
1402   print_symbol_value_1 (stderr, sym);
1403   fprintf (stderr, "\n");
1404 }
1405
1406 void
1407 print_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:
1429       if (exp->X_add_number)
1430         fprintf (file, "\n%*s%lx", indent_level * 4, "",
1431                  (long) exp->X_add_number);
1432       indent_level--;
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
1496 void
1497 print_expr (exp)
1498      expressionS *exp;
1499 {
1500   print_expr_1 (stderr, exp);
1501   fprintf (stderr, "\n");
1502 }
1503
1504 /* end of symbols.c */