1 /* symbols.c -symbol table-
2    Copyright (C) 1987-2020 Free Software Foundation, Inc.
3 
4    This file is part of GAS, the GNU Assembler.
5 
6    GAS is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GAS is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GAS; see the file COPYING.  If not, write to the Free
18    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19    02110-1301, USA.  */
20 
21 /* #define DEBUG_SYMS / * to debug symbol list maintenance.  */
22 
23 #include "as.h"
24 #include "safe-ctype.h"
25 #include "obstack.h"		/* For "symbols.h" */
26 #include "subsegs.h"
27 #include "write.h"
28 
29 struct symbol_flags
30 {
31   /* Whether the symbol is a local_symbol.  */
32   unsigned int sy_local_symbol : 1;
33 
34   /* Weather symbol has been written.  */
35   unsigned int sy_written : 1;
36 
37   /* Whether symbol value has been completely resolved (used during
38      final pass over symbol table).  */
39   unsigned int sy_resolved : 1;
40 
41   /* Whether the symbol value is currently being resolved (used to
42      detect loops in symbol dependencies).  */
43   unsigned int sy_resolving : 1;
44 
45   /* Whether the symbol value is used in a reloc.  This is used to
46      ensure that symbols used in relocs are written out, even if they
47      are local and would otherwise not be.  */
48   unsigned int sy_used_in_reloc : 1;
49 
50   /* Whether the symbol is used as an operand or in an expression.
51      NOTE:  Not all the backends keep this information accurate;
52      backends which use this bit are responsible for setting it when
53      a symbol is used in backend routines.  */
54   unsigned int sy_used : 1;
55 
56   /* Whether the symbol can be re-defined.  */
57   unsigned int sy_volatile : 1;
58 
59   /* Whether the symbol is a forward reference.  */
60   unsigned int sy_forward_ref : 1;
61 
62   /* This is set if the symbol is defined in an MRI common section.
63      We handle such sections as single common symbols, so symbols
64      defined within them must be treated specially by the relocation
65      routines.  */
66   unsigned int sy_mri_common : 1;
67 
68   /* This is set if the symbol is set with a .weakref directive.  */
69   unsigned int sy_weakrefr : 1;
70 
71   /* This is set when the symbol is referenced as part of a .weakref
72      directive, but only if the symbol was not in the symbol table
73      before.  It is cleared as soon as any direct reference to the
74      symbol is present.  */
75   unsigned int sy_weakrefd : 1;
76 };
77 
78 /* The information we keep for a symbol.  Note that the symbol table
79    holds pointers both to this and to local_symbol structures.  See
80    below.  */
81 
82 struct symbol
83 {
84   /* Symbol flags.  */
85   struct symbol_flags sy_flags;
86 
87   /* BFD symbol */
88   asymbol *bsym;
89 
90   /* The value of the symbol.  */
91   expressionS sy_value;
92 
93   /* Forwards and (optionally) backwards chain pointers.  */
94   struct symbol *sy_next;
95   struct symbol *sy_previous;
96 
97   /* Pointer to the frag this symbol is attached to, if any.
98      Otherwise, NULL.  */
99   struct frag *sy_frag;
100 
101 #ifdef OBJ_SYMFIELD_TYPE
102   OBJ_SYMFIELD_TYPE sy_obj;
103 #endif
104 
105 #ifdef TC_SYMFIELD_TYPE
106   TC_SYMFIELD_TYPE sy_tc;
107 #endif
108 
109 #ifdef TARGET_SYMBOL_FIELDS
110   TARGET_SYMBOL_FIELDS
111 #endif
112 };
113 
114 /* A pointer in the symbol may point to either a complete symbol
115    (struct symbol above) or to a local symbol (struct local_symbol
116    defined here).  The symbol code can detect the case by examining
117    the first field.  It is always NULL for a local symbol.
118 
119    We do this because we ordinarily only need a small amount of
120    information for a local symbol.  The symbol table takes up a lot of
121    space, and storing less information for a local symbol can make a
122    big difference in assembler memory usage when assembling a large
123    file.  */
124 
125 struct local_symbol
126 {
127   /* Symbol flags.  Only sy_local_symbol and sy_resolved are relevant.  */
128   struct symbol_flags lsy_flags;
129 
130   /* The symbol section.  This also serves as a flag.  If this is
131      reg_section, then this symbol has been converted into a regular
132      symbol, and lsy_sym points to it.  */
133   segT lsy_section;
134 
135   /* The symbol name.  */
136   const char *lsy_name;
137 
138   /* The symbol frag or the real symbol, depending upon the value in
139      lsy_section.  */
140   union
141   {
142     fragS *lsy_frag;
143     symbolS *lsy_sym;
144   } u;
145 
146   /* The value of the symbol.  */
147   valueT lsy_value;
148 
149 #ifdef TC_LOCAL_SYMFIELD_TYPE
150   TC_LOCAL_SYMFIELD_TYPE lsy_tc;
151 #endif
152 };
153 
154 #define local_symbol_converted_p(l) ((l)->lsy_section == reg_section)
155 #define local_symbol_mark_converted(l) ((l)->lsy_section = reg_section)
156 #define local_symbol_resolved_p(l) ((l)->lsy_flags.sy_resolved)
157 #define local_symbol_mark_resolved(l) ((l)->lsy_flags.sy_resolved = 1)
158 #define local_symbol_get_frag(l) ((l)->u.lsy_frag)
159 #define local_symbol_set_frag(l, f) ((l)->u.lsy_frag = (f))
160 #define local_symbol_get_real_symbol(l) ((l)->u.lsy_sym)
161 #define local_symbol_set_real_symbol(l, s) ((l)->u.lsy_sym = (s))
162 
163 /* This is non-zero if symbols are case sensitive, which is the
164    default.  */
165 int symbols_case_sensitive = 1;
166 
167 #ifndef WORKING_DOT_WORD
168 extern int new_broken_words;
169 #endif
170 
171 /* symbol-name => struct symbol pointer */
172 static struct hash_control *sy_hash;
173 
174 /* Table of local symbols.  */
175 static struct hash_control *local_hash;
176 
177 /* Below are commented in "symbols.h".  */
178 symbolS *symbol_rootP;
179 symbolS *symbol_lastP;
180 symbolS abs_symbol;
181 symbolS dot_symbol;
182 
183 #ifdef DEBUG_SYMS
184 #define debug_verify_symchain verify_symbol_chain
185 #else
186 #define debug_verify_symchain(root, last) ((void) 0)
187 #endif
188 
189 #define DOLLAR_LABEL_CHAR	'\001'
190 #define LOCAL_LABEL_CHAR	'\002'
191 
192 #ifndef TC_LABEL_IS_LOCAL
193 #define TC_LABEL_IS_LOCAL(name)	0
194 #endif
195 
196 struct obstack notes;
197 #ifdef TE_PE
198 /* The name of an external symbol which is
199    used to make weak PE symbol names unique.  */
200 const char * an_external_name;
201 #endif
202 
203 static const char *save_symbol_name (const char *);
204 static void fb_label_init (void);
205 static long dollar_label_instance (long);
206 static long fb_label_instance (long);
207 
208 static void print_binary (FILE *, const char *, expressionS *);
209 
210 /* Return a pointer to a new symbol.  Die if we can't make a new
211    symbol.  Fill in the symbol's values.  Add symbol to end of symbol
212    chain.
213 
214    This function should be called in the general case of creating a
215    symbol.  However, if the output file symbol table has already been
216    set, and you are certain that this symbol won't be wanted in the
217    output file, you can call symbol_create.  */
218 
219 symbolS *
220 symbol_new (const char *name, segT segment, valueT valu, fragS *frag)
221 {
222   symbolS *symbolP = symbol_create (name, segment, valu, frag);
223 
224   /* Link to end of symbol chain.  */
225   {
226     extern int symbol_table_frozen;
227     if (symbol_table_frozen)
228       abort ();
229   }
230   symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
231 
232   return symbolP;
233 }
234 
235 /* Save a symbol name on a permanent obstack, and convert it according
236    to the object file format.  */
237 
238 static const char *
239 save_symbol_name (const char *name)
240 {
241   size_t name_length;
242   char *ret;
243 
244   gas_assert (name != NULL);
245   name_length = strlen (name) + 1;	/* +1 for \0.  */
246   obstack_grow (&notes, name, name_length);
247   ret = (char *) obstack_finish (&notes);
248 
249 #ifdef tc_canonicalize_symbol_name
250   ret = tc_canonicalize_symbol_name (ret);
251 #endif
252 
253   if (! symbols_case_sensitive)
254     {
255       char *s;
256 
257       for (s = ret; *s != '\0'; s++)
258 	*s = TOUPPER (*s);
259     }
260 
261   return ret;
262 }
263 
264 symbolS *
265 symbol_create (const char *name, /* It is copied, the caller can destroy/modify.  */
266 	       segT segment,	/* Segment identifier (SEG_<something>).  */
267 	       valueT valu,	/* Symbol value.  */
268 	       fragS *frag	/* Associated fragment.  */)
269 {
270   const char *preserved_copy_of_name;
271   symbolS *symbolP;
272 
273   preserved_copy_of_name = save_symbol_name (name);
274 
275   symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
276 
277   /* symbol must be born in some fixed state.  This seems as good as any.  */
278   memset (symbolP, 0, sizeof (symbolS));
279 
280   symbolP->bsym = bfd_make_empty_symbol (stdoutput);
281   if (symbolP->bsym == NULL)
282     as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ()));
283   S_SET_NAME (symbolP, preserved_copy_of_name);
284 
285   S_SET_SEGMENT (symbolP, segment);
286   S_SET_VALUE (symbolP, valu);
287   symbol_clear_list_pointers (symbolP);
288 
289   symbolP->sy_frag = frag;
290 
291   obj_symbol_new_hook (symbolP);
292 
293 #ifdef tc_symbol_new_hook
294   tc_symbol_new_hook (symbolP);
295 #endif
296 
297   return symbolP;
298 }
299 
300 
301 /* Local symbol support.  If we can get away with it, we keep only a
302    small amount of information for local symbols.  */
303 
304 static symbolS *local_symbol_convert (struct local_symbol *);
305 
306 /* Used for statistics.  */
307 
308 static unsigned long local_symbol_count;
309 static unsigned long local_symbol_conversion_count;
310 
311 /* This macro is called with a symbol argument passed by reference.
312    It returns whether this is a local symbol.  If necessary, it
313    changes its argument to the real symbol.  */
314 
315 #define LOCAL_SYMBOL_CHECK(s)						\
316   (s->sy_flags.sy_local_symbol 						\
317    ? (local_symbol_converted_p ((struct local_symbol *) s)		\
318       ? (s = local_symbol_get_real_symbol ((struct local_symbol *) s),	\
319 	 0)								\
320       : 1)								\
321    : 0)
322 
323 /* Create a local symbol and insert it into the local hash table.  */
324 
325 struct local_symbol *
326 local_symbol_make (const char *name, segT section, valueT val, fragS *frag)
327 {
328   const char *name_copy;
329   struct local_symbol *ret;
330 
331   ++local_symbol_count;
332 
333   name_copy = save_symbol_name (name);
334 
335   ret = (struct local_symbol *) obstack_alloc (&notes, sizeof *ret);
336   ret->lsy_flags.sy_local_symbol = 1;
337   ret->lsy_flags.sy_resolved = 0;
338   ret->lsy_name = name_copy;
339   ret->lsy_section = section;
340   local_symbol_set_frag (ret, frag);
341   ret->lsy_value = val;
342 
343   hash_jam (local_hash, name_copy, (void *) ret);
344 
345   return ret;
346 }
347 
348 /* Convert a local symbol into a real symbol.  Note that we do not
349    reclaim the space used by the local symbol.  */
350 
351 static symbolS *
352 local_symbol_convert (struct local_symbol *locsym)
353 {
354   symbolS *ret;
355 
356   gas_assert (locsym->lsy_flags.sy_local_symbol);
357   if (local_symbol_converted_p (locsym))
358     return local_symbol_get_real_symbol (locsym);
359 
360   ++local_symbol_conversion_count;
361 
362   ret = symbol_new (locsym->lsy_name, locsym->lsy_section, locsym->lsy_value,
363 		    local_symbol_get_frag (locsym));
364 
365   if (local_symbol_resolved_p (locsym))
366     ret->sy_flags.sy_resolved = 1;
367 
368   /* Local symbols are always either defined or used.  */
369   ret->sy_flags.sy_used = 1;
370 
371 #ifdef TC_LOCAL_SYMFIELD_CONVERT
372   TC_LOCAL_SYMFIELD_CONVERT (locsym, ret);
373 #endif
374 
375   symbol_table_insert (ret);
376 
377   local_symbol_mark_converted (locsym);
378   local_symbol_set_real_symbol (locsym, ret);
379 
380   hash_jam (local_hash, locsym->lsy_name, NULL);
381 
382   return ret;
383 }
384 
385 static void
386 define_sym_at_dot (symbolS *symbolP)
387 {
388   symbolP->sy_frag = frag_now;
389   S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
390   S_SET_SEGMENT (symbolP, now_seg);
391 }
392 
393 /* We have just seen "<name>:".
394    Creates a struct symbol unless it already exists.
395 
396    Gripes if we are redefining a symbol incompatibly (and ignores it).  */
397 
398 symbolS *
399 colon (/* Just seen "x:" - rattle symbols & frags.  */
400        const char *sym_name	/* Symbol name, as a canonical string.  */
401        /* We copy this string: OK to alter later.  */)
402 {
403   symbolS *symbolP;	/* Symbol we are working with.  */
404 
405   /* Sun local labels go out of scope whenever a non-local symbol is
406      defined.  */
407   if (LOCAL_LABELS_DOLLAR
408       && !bfd_is_local_label_name (stdoutput, sym_name))
409     dollar_label_clear ();
410 
411 #ifndef WORKING_DOT_WORD
412   if (new_broken_words)
413     {
414       struct broken_word *a;
415       int possible_bytes;
416       fragS *frag_tmp;
417       char *frag_opcode;
418 
419       if (now_seg == absolute_section)
420 	{
421 	  as_bad (_("cannot define symbol `%s' in absolute section"), sym_name);
422 	  return NULL;
423 	}
424 
425       possible_bytes = (md_short_jump_size
426 			+ new_broken_words * md_long_jump_size);
427 
428       frag_tmp = frag_now;
429       frag_opcode = frag_var (rs_broken_word,
430 			      possible_bytes,
431 			      possible_bytes,
432 			      (relax_substateT) 0,
433 			      (symbolS *) broken_words,
434 			      (offsetT) 0,
435 			      NULL);
436 
437       /* We want to store the pointer to where to insert the jump
438 	 table in the fr_opcode of the rs_broken_word frag.  This
439 	 requires a little hackery.  */
440       while (frag_tmp
441 	     && (frag_tmp->fr_type != rs_broken_word
442 		 || frag_tmp->fr_opcode))
443 	frag_tmp = frag_tmp->fr_next;
444       know (frag_tmp);
445       frag_tmp->fr_opcode = frag_opcode;
446       new_broken_words = 0;
447 
448       for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
449 	a->dispfrag = frag_tmp;
450     }
451 #endif /* WORKING_DOT_WORD */
452 
453 #ifdef obj_frob_colon
454   obj_frob_colon (sym_name);
455 #endif
456 
457   if ((symbolP = symbol_find (sym_name)) != 0)
458     {
459       S_CLEAR_WEAKREFR (symbolP);
460 #ifdef RESOLVE_SYMBOL_REDEFINITION
461       if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
462 	return symbolP;
463 #endif
464       /* Now check for undefined symbols.  */
465       if (LOCAL_SYMBOL_CHECK (symbolP))
466 	{
467 	  struct local_symbol *locsym = (struct local_symbol *) symbolP;
468 
469 	  if (locsym->lsy_section != undefined_section
470 	      && (local_symbol_get_frag (locsym) != frag_now
471 		  || locsym->lsy_section != now_seg
472 		  || locsym->lsy_value != frag_now_fix ()))
473 	    {
474 	      as_bad (_("symbol `%s' is already defined"), sym_name);
475 	      return symbolP;
476 	    }
477 
478 	  locsym->lsy_section = now_seg;
479 	  local_symbol_set_frag (locsym, frag_now);
480 	  locsym->lsy_value = frag_now_fix ();
481 	}
482       else if (!(S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
483 	       || S_IS_COMMON (symbolP)
484 	       || S_IS_VOLATILE (symbolP))
485 	{
486 	  if (S_IS_VOLATILE (symbolP))
487 	    {
488 	      symbolP = symbol_clone (symbolP, 1);
489 	      S_SET_VALUE (symbolP, 0);
490 	      S_CLEAR_VOLATILE (symbolP);
491 	    }
492 	  if (S_GET_VALUE (symbolP) == 0)
493 	    {
494 	      define_sym_at_dot (symbolP);
495 #ifdef N_UNDF
496 	      know (N_UNDF == 0);
497 #endif /* if we have one, it better be zero.  */
498 
499 	    }
500 	  else
501 	    {
502 	      /* There are still several cases to check:
503 
504 		 A .comm/.lcomm symbol being redefined as initialized
505 		 data is OK
506 
507 		 A .comm/.lcomm symbol being redefined with a larger
508 		 size is also OK
509 
510 		 This only used to be allowed on VMS gas, but Sun cc
511 		 on the sparc also depends on it.  */
512 
513 	      if (((!S_IS_DEBUG (symbolP)
514 		    && (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
515 		    && S_IS_EXTERNAL (symbolP))
516 		   || S_GET_SEGMENT (symbolP) == bss_section)
517 		  && (now_seg == data_section
518 		      || now_seg == bss_section
519 		      || now_seg == S_GET_SEGMENT (symbolP)))
520 		{
521 		  /* Select which of the 2 cases this is.  */
522 		  if (now_seg != data_section)
523 		    {
524 		      /* New .comm for prev .comm symbol.
525 
526 			 If the new size is larger we just change its
527 			 value.  If the new size is smaller, we ignore
528 			 this symbol.  */
529 		      if (S_GET_VALUE (symbolP)
530 			  < ((unsigned) frag_now_fix ()))
531 			{
532 			  S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
533 			}
534 		    }
535 		  else
536 		    {
537 		      /* It is a .comm/.lcomm being converted to initialized
538 			 data.  */
539 		      define_sym_at_dot (symbolP);
540 		    }
541 		}
542 	      else
543 		{
544 #if (!defined (OBJ_AOUT) && !defined (OBJ_MAYBE_AOUT))
545 		  static const char *od_buf = "";
546 #else
547 		  char od_buf[100];
548 		  od_buf[0] = '\0';
549 		  if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
550 		    sprintf (od_buf, "%d.%d.",
551 			     S_GET_OTHER (symbolP),
552 			     S_GET_DESC (symbolP));
553 #endif
554 		  as_bad (_("symbol `%s' is already defined as \"%s\"/%s%ld"),
555 			    sym_name,
556 			    segment_name (S_GET_SEGMENT (symbolP)),
557 			    od_buf,
558 			    (long) S_GET_VALUE (symbolP));
559 		}
560 	    }			/* if the undefined symbol has no value  */
561 	}
562       else
563 	{
564 	  /* Don't blow up if the definition is the same.  */
565 	  if (!(frag_now == symbolP->sy_frag
566 		&& S_GET_VALUE (symbolP) == frag_now_fix ()
567 		&& S_GET_SEGMENT (symbolP) == now_seg))
568 	    {
569 	      as_bad (_("symbol `%s' is already defined"), sym_name);
570 	      symbolP = symbol_clone (symbolP, 0);
571 	      define_sym_at_dot (symbolP);
572 	    }
573 	}
574 
575     }
576   else if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, sym_name))
577     {
578       symbolP = (symbolS *) local_symbol_make (sym_name, now_seg,
579 					       (valueT) frag_now_fix (),
580 					       frag_now);
581     }
582   else
583     {
584       symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (),
585 			    frag_now);
586 
587       symbol_table_insert (symbolP);
588     }
589 
590   if (mri_common_symbol != NULL)
591     {
592       /* This symbol is actually being defined within an MRI common
593 	 section.  This requires special handling.  */
594       if (LOCAL_SYMBOL_CHECK (symbolP))
595 	symbolP = local_symbol_convert ((struct local_symbol *) symbolP);
596       symbolP->sy_value.X_op = O_symbol;
597       symbolP->sy_value.X_add_symbol = mri_common_symbol;
598       symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol);
599       symbolP->sy_frag = &zero_address_frag;
600       S_SET_SEGMENT (symbolP, expr_section);
601       symbolP->sy_flags.sy_mri_common = 1;
602     }
603 
604 #ifdef tc_frob_label
605   tc_frob_label (symbolP);
606 #endif
607 #ifdef obj_frob_label
608   obj_frob_label (symbolP);
609 #endif
610 
611   return symbolP;
612 }
613 
614 /* Die if we can't insert the symbol.  */
615 
616 void
617 symbol_table_insert (symbolS *symbolP)
618 {
619   const char *error_string;
620 
621   know (symbolP);
622   know (S_GET_NAME (symbolP));
623 
624   if (LOCAL_SYMBOL_CHECK (symbolP))
625     {
626       error_string = hash_jam (local_hash, S_GET_NAME (symbolP),
627 			       (void *) symbolP);
628       if (error_string != NULL)
629 	as_fatal (_("inserting \"%s\" into symbol table failed: %s"),
630 		  S_GET_NAME (symbolP), error_string);
631       return;
632     }
633 
634   if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (void *) symbolP)))
635     {
636       as_fatal (_("inserting \"%s\" into symbol table failed: %s"),
637 		S_GET_NAME (symbolP), error_string);
638     }				/* on error  */
639 }
640 
641 /* If a symbol name does not exist, create it as undefined, and insert
642    it into the symbol table.  Return a pointer to it.  */
643 
644 symbolS *
645 symbol_find_or_make (const char *name)
646 {
647   symbolS *symbolP;
648 
649   symbolP = symbol_find (name);
650 
651   if (symbolP == NULL)
652     {
653       if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, name))
654 	{
655 	  symbolP = md_undefined_symbol ((char *) name);
656 	  if (symbolP != NULL)
657 	    return symbolP;
658 
659 	  symbolP = (symbolS *) local_symbol_make (name, undefined_section,
660 						   (valueT) 0,
661 						   &zero_address_frag);
662 	  return symbolP;
663 	}
664 
665       symbolP = symbol_make (name);
666 
667       symbol_table_insert (symbolP);
668     }				/* if symbol wasn't found */
669 
670   return (symbolP);
671 }
672 
673 symbolS *
674 symbol_make (const char *name)
675 {
676   symbolS *symbolP;
677 
678   /* Let the machine description default it, e.g. for register names.  */
679   symbolP = md_undefined_symbol ((char *) name);
680 
681   if (!symbolP)
682     symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
683 
684   return (symbolP);
685 }
686 
687 symbolS *
688 symbol_clone (symbolS *orgsymP, int replace)
689 {
690   symbolS *newsymP;
691   asymbol *bsymorg, *bsymnew;
692 
693   /* Make sure we never clone the dot special symbol.  */
694   gas_assert (orgsymP != &dot_symbol);
695 
696   /* Running local_symbol_convert on a clone that's not the one currently
697      in local_hash would incorrectly replace the hash entry.  Thus the
698      symbol must be converted here.  Note that the rest of the function
699      depends on not encountering an unconverted symbol.  */
700   if (LOCAL_SYMBOL_CHECK (orgsymP))
701     orgsymP = local_symbol_convert ((struct local_symbol *) orgsymP);
702   bsymorg = orgsymP->bsym;
703 
704   newsymP = (symbolS *) obstack_alloc (&notes, sizeof (*newsymP));
705   *newsymP = *orgsymP;
706   bsymnew = bfd_make_empty_symbol (bfd_asymbol_bfd (bsymorg));
707   if (bsymnew == NULL)
708     as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ()));
709   newsymP->bsym = bsymnew;
710   bsymnew->name = bsymorg->name;
711   bsymnew->flags = bsymorg->flags & ~BSF_SECTION_SYM;
712   bsymnew->section = bsymorg->section;
713   bfd_copy_private_symbol_data (bfd_asymbol_bfd (bsymorg), bsymorg,
714 				bfd_asymbol_bfd (bsymnew), bsymnew);
715 
716 #ifdef obj_symbol_clone_hook
717   obj_symbol_clone_hook (newsymP, orgsymP);
718 #endif
719 
720 #ifdef tc_symbol_clone_hook
721   tc_symbol_clone_hook (newsymP, orgsymP);
722 #endif
723 
724   if (replace)
725     {
726       if (symbol_rootP == orgsymP)
727 	symbol_rootP = newsymP;
728       else if (orgsymP->sy_previous)
729 	{
730 	  orgsymP->sy_previous->sy_next = newsymP;
731 	  orgsymP->sy_previous = NULL;
732 	}
733       if (symbol_lastP == orgsymP)
734 	symbol_lastP = newsymP;
735       else if (orgsymP->sy_next)
736 	orgsymP->sy_next->sy_previous = newsymP;
737 
738       /* Symbols that won't be output can't be external.  */
739       S_CLEAR_EXTERNAL (orgsymP);
740       orgsymP->sy_previous = orgsymP->sy_next = orgsymP;
741       debug_verify_symchain (symbol_rootP, symbol_lastP);
742 
743       symbol_table_insert (newsymP);
744     }
745   else
746     {
747       /* Symbols that won't be output can't be external.  */
748       S_CLEAR_EXTERNAL (newsymP);
749       newsymP->sy_previous = newsymP->sy_next = newsymP;
750     }
751 
752   return newsymP;
753 }
754 
755 /* If S is a local symbol that has been converted, return the
756    converted symbol.  Otherwise return S.  */
757 
758 static inline symbolS *
759 get_real_sym (symbolS *s)
760 {
761   if (s != NULL
762       && s->sy_flags.sy_local_symbol
763       && local_symbol_converted_p ((struct local_symbol *) s))
764     s = local_symbol_get_real_symbol ((struct local_symbol *) s);
765   return s;
766 }
767 
768 /* Referenced symbols, if they are forward references, need to be cloned
769    (without replacing the original) so that the value of the referenced
770    symbols at the point of use is saved by the clone.  */
771 
772 #undef symbol_clone_if_forward_ref
773 symbolS *
774 symbol_clone_if_forward_ref (symbolS *symbolP, int is_forward)
775 {
776   if (symbolP && !LOCAL_SYMBOL_CHECK (symbolP))
777     {
778       symbolS *orig_add_symbol = get_real_sym (symbolP->sy_value.X_add_symbol);
779       symbolS *orig_op_symbol = get_real_sym (symbolP->sy_value.X_op_symbol);
780       symbolS *add_symbol = orig_add_symbol;
781       symbolS *op_symbol = orig_op_symbol;
782 
783       if (symbolP->sy_flags.sy_forward_ref)
784 	is_forward = 1;
785 
786       if (is_forward)
787 	{
788 	  /* assign_symbol() clones volatile symbols; pre-existing expressions
789 	     hold references to the original instance, but want the current
790 	     value.  Just repeat the lookup.  */
791 	  if (add_symbol && S_IS_VOLATILE (add_symbol))
792 	    add_symbol = symbol_find_exact (S_GET_NAME (add_symbol));
793 	  if (op_symbol && S_IS_VOLATILE (op_symbol))
794 	    op_symbol = symbol_find_exact (S_GET_NAME (op_symbol));
795 	}
796 
797       /* Re-using sy_resolving here, as this routine cannot get called from
798 	 symbol resolution code.  */
799       if ((symbolP->bsym->section == expr_section
800            || symbolP->sy_flags.sy_forward_ref)
801 	  && !symbolP->sy_flags.sy_resolving)
802 	{
803 	  symbolP->sy_flags.sy_resolving = 1;
804 	  add_symbol = symbol_clone_if_forward_ref (add_symbol, is_forward);
805 	  op_symbol = symbol_clone_if_forward_ref (op_symbol, is_forward);
806 	  symbolP->sy_flags.sy_resolving = 0;
807 	}
808 
809       if (symbolP->sy_flags.sy_forward_ref
810 	  || add_symbol != orig_add_symbol
811 	  || op_symbol != orig_op_symbol)
812 	{
813 	  if (symbolP != &dot_symbol)
814 	    {
815 	      symbolP = symbol_clone (symbolP, 0);
816 	      symbolP->sy_flags.sy_resolving = 0;
817 	    }
818 	  else
819 	    {
820 	      symbolP = symbol_temp_new_now ();
821 #ifdef tc_new_dot_label
822 	      tc_new_dot_label (symbolP);
823 #endif
824 	    }
825 	}
826 
827       symbolP->sy_value.X_add_symbol = add_symbol;
828       symbolP->sy_value.X_op_symbol = op_symbol;
829     }
830 
831   return symbolP;
832 }
833 
834 symbolS *
835 symbol_temp_new (segT seg, valueT ofs, fragS *frag)
836 {
837   return symbol_new (FAKE_LABEL_NAME, seg, ofs, frag);
838 }
839 
840 symbolS *
841 symbol_temp_new_now (void)
842 {
843   return symbol_temp_new (now_seg, frag_now_fix (), frag_now);
844 }
845 
846 symbolS *
847 symbol_temp_new_now_octets (void)
848 {
849   return symbol_temp_new (now_seg, frag_now_fix_octets (), frag_now);
850 }
851 
852 symbolS *
853 symbol_temp_make (void)
854 {
855   return symbol_make (FAKE_LABEL_NAME);
856 }
857 
858 /* Implement symbol table lookup.
859    In:	A symbol's name as a string: '\0' can't be part of a symbol name.
860    Out:	NULL if the name was not in the symbol table, else the address
861    of a struct symbol associated with that name.  */
862 
863 symbolS *
864 symbol_find_exact (const char *name)
865 {
866   return symbol_find_exact_noref (name, 0);
867 }
868 
869 symbolS *
870 symbol_find_exact_noref (const char *name, int noref)
871 {
872   struct local_symbol *locsym;
873   symbolS* sym;
874 
875   locsym = (struct local_symbol *) hash_find (local_hash, name);
876   if (locsym != NULL)
877     return (symbolS *) locsym;
878 
879   sym = ((symbolS *) hash_find (sy_hash, name));
880 
881   /* Any references to the symbol, except for the reference in
882      .weakref, must clear this flag, such that the symbol does not
883      turn into a weak symbol.  Note that we don't have to handle the
884      local_symbol case, since a weakrefd is always promoted out of the
885      local_symbol table when it is turned into a weak symbol.  */
886   if (sym && ! noref)
887     S_CLEAR_WEAKREFD (sym);
888 
889   return sym;
890 }
891 
892 symbolS *
893 symbol_find (const char *name)
894 {
895   return symbol_find_noref (name, 0);
896 }
897 
898 symbolS *
899 symbol_find_noref (const char *name, int noref)
900 {
901   symbolS * result;
902   char * copy = NULL;
903 
904 #ifdef tc_canonicalize_symbol_name
905   {
906     copy = xstrdup (name);
907     name = tc_canonicalize_symbol_name (copy);
908   }
909 #endif
910 
911   if (! symbols_case_sensitive)
912     {
913       const char *orig;
914       char *copy2 = NULL;
915       unsigned char c;
916 
917       orig = name;
918       if (copy != NULL)
919 	copy2 = copy;
920       name = copy = XNEWVEC (char, strlen (name) + 1);
921 
922       while ((c = *orig++) != '\0')
923 	*copy++ = TOUPPER (c);
924       *copy = '\0';
925 
926       if (copy2 != NULL)
927 	free (copy2);
928       copy = (char *) name;
929     }
930 
931   result = symbol_find_exact_noref (name, noref);
932   if (copy != NULL)
933     free (copy);
934   return result;
935 }
936 
937 /* Once upon a time, symbols were kept in a singly linked list.  At
938    least coff needs to be able to rearrange them from time to time, for
939    which a doubly linked list is much more convenient.  Loic did these
940    as macros which seemed dangerous to me so they're now functions.
941    xoxorich.  */
942 
943 /* Link symbol ADDME after symbol TARGET in the chain.  */
944 
945 void
946 symbol_append (symbolS *addme, symbolS *target,
947 	       symbolS **rootPP, symbolS **lastPP)
948 {
949   if (LOCAL_SYMBOL_CHECK (addme))
950     abort ();
951   if (target != NULL && LOCAL_SYMBOL_CHECK (target))
952     abort ();
953 
954   if (target == NULL)
955     {
956       know (*rootPP == NULL);
957       know (*lastPP == NULL);
958       addme->sy_next = NULL;
959       addme->sy_previous = NULL;
960       *rootPP = addme;
961       *lastPP = addme;
962       return;
963     }				/* if the list is empty  */
964 
965   if (target->sy_next != NULL)
966     {
967       target->sy_next->sy_previous = addme;
968     }
969   else
970     {
971       know (*lastPP == target);
972       *lastPP = addme;
973     }				/* if we have a next  */
974 
975   addme->sy_next = target->sy_next;
976   target->sy_next = addme;
977   addme->sy_previous = target;
978 
979   debug_verify_symchain (symbol_rootP, symbol_lastP);
980 }
981 
982 /* Set the chain pointers of SYMBOL to null.  */
983 
984 void
985 symbol_clear_list_pointers (symbolS *symbolP)
986 {
987   if (LOCAL_SYMBOL_CHECK (symbolP))
988     abort ();
989   symbolP->sy_next = NULL;
990   symbolP->sy_previous = NULL;
991 }
992 
993 /* Remove SYMBOLP from the list.  */
994 
995 void
996 symbol_remove (symbolS *symbolP, symbolS **rootPP, symbolS **lastPP)
997 {
998   if (LOCAL_SYMBOL_CHECK (symbolP))
999     abort ();
1000 
1001   if (symbolP == *rootPP)
1002     {
1003       *rootPP = symbolP->sy_next;
1004     }				/* if it was the root  */
1005 
1006   if (symbolP == *lastPP)
1007     {
1008       *lastPP = symbolP->sy_previous;
1009     }				/* if it was the tail  */
1010 
1011   if (symbolP->sy_next != NULL)
1012     {
1013       symbolP->sy_next->sy_previous = symbolP->sy_previous;
1014     }				/* if not last  */
1015 
1016   if (symbolP->sy_previous != NULL)
1017     {
1018       symbolP->sy_previous->sy_next = symbolP->sy_next;
1019     }				/* if not first  */
1020 
1021   debug_verify_symchain (*rootPP, *lastPP);
1022 }
1023 
1024 /* Link symbol ADDME before symbol TARGET in the chain.  */
1025 
1026 void
1027 symbol_insert (symbolS *addme, symbolS *target,
1028 	       symbolS **rootPP, symbolS **lastPP ATTRIBUTE_UNUSED)
1029 {
1030   if (LOCAL_SYMBOL_CHECK (addme))
1031     abort ();
1032   if (LOCAL_SYMBOL_CHECK (target))
1033     abort ();
1034 
1035   if (target->sy_previous != NULL)
1036     {
1037       target->sy_previous->sy_next = addme;
1038     }
1039   else
1040     {
1041       know (*rootPP == target);
1042       *rootPP = addme;
1043     }				/* if not first  */
1044 
1045   addme->sy_previous = target->sy_previous;
1046   target->sy_previous = addme;
1047   addme->sy_next = target;
1048 
1049   debug_verify_symchain (*rootPP, *lastPP);
1050 }
1051 
1052 void
1053 verify_symbol_chain (symbolS *rootP, symbolS *lastP)
1054 {
1055   symbolS *symbolP = rootP;
1056 
1057   if (symbolP == NULL)
1058     return;
1059 
1060   for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
1061     {
1062       gas_assert (symbolP->bsym != NULL);
1063       gas_assert (symbolP->sy_flags.sy_local_symbol == 0);
1064       gas_assert (symbolP->sy_next->sy_previous == symbolP);
1065     }
1066 
1067   gas_assert (lastP == symbolP);
1068 }
1069 
1070 int
1071 symbol_on_chain (symbolS *s, symbolS *rootPP, symbolS *lastPP)
1072 {
1073   return (!LOCAL_SYMBOL_CHECK (s)
1074 	  && ((s->sy_next != s
1075 	       && s->sy_next != NULL
1076 	       && s->sy_next->sy_previous == s)
1077 	      || s == lastPP)
1078 	  && ((s->sy_previous != s
1079 	       && s->sy_previous != NULL
1080 	       && s->sy_previous->sy_next == s)
1081 	      || s == rootPP));
1082 }
1083 
1084 #ifdef OBJ_COMPLEX_RELC
1085 
1086 static int
1087 use_complex_relocs_for (symbolS * symp)
1088 {
1089   switch (symp->sy_value.X_op)
1090     {
1091     case O_constant:
1092       return 0;
1093 
1094     case O_multiply:
1095     case O_divide:
1096     case O_modulus:
1097     case O_left_shift:
1098     case O_right_shift:
1099     case O_bit_inclusive_or:
1100     case O_bit_or_not:
1101     case O_bit_exclusive_or:
1102     case O_bit_and:
1103     case O_add:
1104     case O_subtract:
1105     case O_eq:
1106     case O_ne:
1107     case O_lt:
1108     case O_le:
1109     case O_ge:
1110     case O_gt:
1111     case O_logical_and:
1112     case O_logical_or:
1113       if ((S_IS_COMMON (symp->sy_value.X_op_symbol)
1114 	   || S_IS_LOCAL (symp->sy_value.X_op_symbol))
1115 	  && S_IS_DEFINED (symp->sy_value.X_op_symbol)
1116 	  && S_GET_SEGMENT (symp->sy_value.X_op_symbol) != expr_section)
1117 	{
1118 	case O_symbol:
1119 	case O_symbol_rva:
1120 	case O_uminus:
1121 	case O_bit_not:
1122 	case O_logical_not:
1123 	  if ((S_IS_COMMON (symp->sy_value.X_add_symbol)
1124 	       || S_IS_LOCAL (symp->sy_value.X_add_symbol))
1125 	      && S_IS_DEFINED (symp->sy_value.X_add_symbol)
1126 	      && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section)
1127 	    return 0;
1128 	}
1129       break;
1130 
1131     default:
1132       break;
1133     }
1134   return 1;
1135 }
1136 #endif
1137 
1138 static void
1139 report_op_error (symbolS *symp, symbolS *left, operatorT op, symbolS *right)
1140 {
1141   const char *file;
1142   unsigned int line;
1143   segT seg_left = left ? S_GET_SEGMENT (left) : 0;
1144   segT seg_right = S_GET_SEGMENT (right);
1145   const char *opname;
1146 
1147   switch (op)
1148     {
1149     default:
1150       abort ();
1151       return;
1152 
1153     case O_uminus:		opname = "-"; break;
1154     case O_bit_not:		opname = "~"; break;
1155     case O_logical_not:		opname = "!"; break;
1156     case O_multiply:		opname = "*"; break;
1157     case O_divide:		opname = "/"; break;
1158     case O_modulus:		opname = "%"; break;
1159     case O_left_shift:		opname = "<<"; break;
1160     case O_right_shift:		opname = ">>"; break;
1161     case O_bit_inclusive_or:	opname = "|"; break;
1162     case O_bit_or_not:		opname = "|~"; break;
1163     case O_bit_exclusive_or:	opname = "^"; break;
1164     case O_bit_and:		opname = "&"; break;
1165     case O_add:			opname = "+"; break;
1166     case O_subtract:		opname = "-"; break;
1167     case O_eq:			opname = "=="; break;
1168     case O_ne:			opname = "!="; break;
1169     case O_lt:			opname = "<"; break;
1170     case O_le:			opname = "<="; break;
1171     case O_ge:			opname = ">="; break;
1172     case O_gt:			opname = ">"; break;
1173     case O_logical_and:		opname = "&&"; break;
1174     case O_logical_or:		opname = "||"; break;
1175     }
1176 
1177   if (expr_symbol_where (symp, &file, &line))
1178     {
1179       if (left)
1180 	as_bad_where (file, line,
1181 		      _("invalid operands (%s and %s sections) for `%s'"),
1182 		      seg_left->name, seg_right->name, opname);
1183       else
1184 	as_bad_where (file, line,
1185 		      _("invalid operand (%s section) for `%s'"),
1186 		      seg_right->name, opname);
1187     }
1188   else
1189     {
1190       const char *sname = S_GET_NAME (symp);
1191 
1192       if (left)
1193 	as_bad (_("invalid operands (%s and %s sections) for `%s' when setting `%s'"),
1194 		seg_left->name, seg_right->name, opname, sname);
1195       else
1196 	as_bad (_("invalid operand (%s section) for `%s' when setting `%s'"),
1197 		seg_right->name, opname, sname);
1198     }
1199 }
1200 
1201 /* Resolve the value of a symbol.  This is called during the final
1202    pass over the symbol table to resolve any symbols with complex
1203    values.  */
1204 
1205 valueT
1206 resolve_symbol_value (symbolS *symp)
1207 {
1208   int resolved;
1209   valueT final_val;
1210   segT final_seg;
1211 
1212   if (LOCAL_SYMBOL_CHECK (symp))
1213     {
1214       struct local_symbol *locsym = (struct local_symbol *) symp;
1215 
1216       final_val = locsym->lsy_value;
1217       if (local_symbol_resolved_p (locsym))
1218 	return final_val;
1219 
1220       /* Symbols whose section has SEC_ELF_OCTETS set,
1221 	 resolve to octets instead of target bytes. */
1222       if (locsym->lsy_section->flags & SEC_OCTETS)
1223 	final_val += local_symbol_get_frag (locsym)->fr_address;
1224       else
1225 	final_val += (local_symbol_get_frag (locsym)->fr_address
1226 		      / OCTETS_PER_BYTE);
1227 
1228       if (finalize_syms)
1229 	{
1230 	  locsym->lsy_value = final_val;
1231 	  local_symbol_mark_resolved (locsym);
1232 	}
1233 
1234       return final_val;
1235     }
1236 
1237   if (symp->sy_flags.sy_resolved)
1238     {
1239       final_val = 0;
1240       while (symp->sy_value.X_op == O_symbol
1241 	     && symp->sy_value.X_add_symbol->sy_flags.sy_resolved)
1242 	{
1243 	  final_val += symp->sy_value.X_add_number;
1244 	  symp = symp->sy_value.X_add_symbol;
1245 	}
1246       if (symp->sy_value.X_op == O_constant)
1247 	final_val += symp->sy_value.X_add_number;
1248       else
1249 	final_val = 0;
1250       return final_val;
1251     }
1252 
1253   resolved = 0;
1254   final_seg = S_GET_SEGMENT (symp);
1255 
1256   if (symp->sy_flags.sy_resolving)
1257     {
1258       if (finalize_syms)
1259 	as_bad (_("symbol definition loop encountered at `%s'"),
1260 		S_GET_NAME (symp));
1261       final_val = 0;
1262       resolved = 1;
1263     }
1264 #ifdef OBJ_COMPLEX_RELC
1265   else if (final_seg == expr_section
1266 	   && use_complex_relocs_for (symp))
1267     {
1268       symbolS * relc_symbol = NULL;
1269       char * relc_symbol_name = NULL;
1270 
1271       relc_symbol_name = symbol_relc_make_expr (& symp->sy_value);
1272 
1273       /* For debugging, print out conversion input & output.  */
1274 #ifdef DEBUG_SYMS
1275       print_expr (& symp->sy_value);
1276       if (relc_symbol_name)
1277 	fprintf (stderr, "-> relc symbol: %s\n", relc_symbol_name);
1278 #endif
1279 
1280       if (relc_symbol_name != NULL)
1281 	relc_symbol = symbol_new (relc_symbol_name, undefined_section,
1282 				  0, & zero_address_frag);
1283 
1284       if (relc_symbol == NULL)
1285 	{
1286 	  as_bad (_("cannot convert expression symbol %s to complex relocation"),
1287 		  S_GET_NAME (symp));
1288 	  resolved = 0;
1289 	}
1290       else
1291 	{
1292 	  symbol_table_insert (relc_symbol);
1293 
1294  	  /* S_CLEAR_EXTERNAL (relc_symbol); */
1295 	  if (symp->bsym->flags & BSF_SRELC)
1296 	    relc_symbol->bsym->flags |= BSF_SRELC;
1297 	  else
1298 	    relc_symbol->bsym->flags |= BSF_RELC;
1299 	  /* symp->bsym->flags |= BSF_RELC; */
1300 	  copy_symbol_attributes (symp, relc_symbol);
1301 	  symp->sy_value.X_op = O_symbol;
1302 	  symp->sy_value.X_add_symbol = relc_symbol;
1303 	  symp->sy_value.X_add_number = 0;
1304 	  resolved = 1;
1305 	}
1306 
1307       final_val = 0;
1308       final_seg = undefined_section;
1309       goto exit_dont_set_value;
1310     }
1311 #endif
1312   else
1313     {
1314       symbolS *add_symbol, *op_symbol;
1315       offsetT left, right;
1316       segT seg_left, seg_right;
1317       operatorT op;
1318       int move_seg_ok;
1319 
1320       symp->sy_flags.sy_resolving = 1;
1321 
1322       /* Help out with CSE.  */
1323       add_symbol = symp->sy_value.X_add_symbol;
1324       op_symbol = symp->sy_value.X_op_symbol;
1325       final_val = symp->sy_value.X_add_number;
1326       op = symp->sy_value.X_op;
1327 
1328       switch (op)
1329 	{
1330 	default:
1331 	  BAD_CASE (op);
1332 	  break;
1333 
1334 	case O_absent:
1335 	  final_val = 0;
1336 	  /* Fall through.  */
1337 
1338 	case O_constant:
1339 	  /* Symbols whose section has SEC_ELF_OCTETS set,
1340 	     resolve to octets instead of target bytes. */
1341 	  if (symp->bsym->section->flags & SEC_OCTETS)
1342 	    final_val += symp->sy_frag->fr_address;
1343 	  else
1344 	    final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE;
1345 	  if (final_seg == expr_section)
1346 	    final_seg = absolute_section;
1347 	  /* Fall through.  */
1348 
1349 	case O_register:
1350 	  resolved = 1;
1351 	  break;
1352 
1353 	case O_symbol:
1354 	case O_symbol_rva:
1355 	  left = resolve_symbol_value (add_symbol);
1356 	  seg_left = S_GET_SEGMENT (add_symbol);
1357 	  if (finalize_syms)
1358 	    symp->sy_value.X_op_symbol = NULL;
1359 
1360 	do_symbol:
1361 	  if (S_IS_WEAKREFR (symp))
1362 	    {
1363 	      gas_assert (final_val == 0);
1364 	      if (S_IS_WEAKREFR (add_symbol))
1365 		{
1366 		  gas_assert (add_symbol->sy_value.X_op == O_symbol
1367 			  && add_symbol->sy_value.X_add_number == 0);
1368 		  add_symbol = add_symbol->sy_value.X_add_symbol;
1369 		  gas_assert (! S_IS_WEAKREFR (add_symbol));
1370 		  symp->sy_value.X_add_symbol = add_symbol;
1371 		}
1372 	    }
1373 
1374 	  if (symp->sy_flags.sy_mri_common)
1375 	    {
1376 	      /* This is a symbol inside an MRI common section.  The
1377 		 relocation routines are going to handle it specially.
1378 		 Don't change the value.  */
1379 	      resolved = symbol_resolved_p (add_symbol);
1380 	      break;
1381 	    }
1382 
1383 	  if (finalize_syms && final_val == 0)
1384 	    {
1385 	      if (LOCAL_SYMBOL_CHECK (add_symbol))
1386 		add_symbol = local_symbol_convert ((struct local_symbol *)
1387 						   add_symbol);
1388 	      copy_symbol_attributes (symp, add_symbol);
1389 	    }
1390 
1391 	  /* If we have equated this symbol to an undefined or common
1392 	     symbol, keep X_op set to O_symbol, and don't change
1393 	     X_add_number.  This permits the routine which writes out
1394 	     relocation to detect this case, and convert the
1395 	     relocation to be against the symbol to which this symbol
1396 	     is equated.  */
1397 	  if (seg_left == undefined_section
1398 	      || bfd_is_com_section (seg_left)
1399 #if defined (OBJ_COFF) && defined (TE_PE)
1400 	      || S_IS_WEAK (add_symbol)
1401 #endif
1402 	      || (finalize_syms
1403 		  && ((final_seg == expr_section
1404 		       && seg_left != expr_section
1405 		       && seg_left != absolute_section)
1406 		      || symbol_shadow_p (symp))))
1407 	    {
1408 	      if (finalize_syms)
1409 		{
1410 		  symp->sy_value.X_op = O_symbol;
1411 		  symp->sy_value.X_add_symbol = add_symbol;
1412 		  symp->sy_value.X_add_number = final_val;
1413 		  /* Use X_op_symbol as a flag.  */
1414 		  symp->sy_value.X_op_symbol = add_symbol;
1415 		}
1416 	      final_seg = seg_left;
1417 	      final_val += symp->sy_frag->fr_address + left;
1418 	      resolved = symbol_resolved_p (add_symbol);
1419 	      symp->sy_flags.sy_resolving = 0;
1420 	      goto exit_dont_set_value;
1421 	    }
1422 	  else
1423 	    {
1424 	      final_val += symp->sy_frag->fr_address + left;
1425 	      if (final_seg == expr_section || final_seg == undefined_section)
1426 		final_seg = seg_left;
1427 	    }
1428 
1429 	  resolved = symbol_resolved_p (add_symbol);
1430 	  if (S_IS_WEAKREFR (symp))
1431 	    {
1432 	      symp->sy_flags.sy_resolving = 0;
1433 	      goto exit_dont_set_value;
1434 	    }
1435 	  break;
1436 
1437 	case O_uminus:
1438 	case O_bit_not:
1439 	case O_logical_not:
1440 	  left = resolve_symbol_value (add_symbol);
1441 	  seg_left = S_GET_SEGMENT (add_symbol);
1442 
1443 	  /* By reducing these to the relevant dyadic operator, we get
1444 	     	!S -> S == 0 	permitted on anything,
1445 		-S -> 0 - S 	only permitted on absolute
1446 		~S -> S ^ ~0 	only permitted on absolute  */
1447 	  if (op != O_logical_not && seg_left != absolute_section
1448 	      && finalize_syms)
1449 	    report_op_error (symp, NULL, op, add_symbol);
1450 
1451 	  if (final_seg == expr_section || final_seg == undefined_section)
1452 	    final_seg = absolute_section;
1453 
1454 	  if (op == O_uminus)
1455 	    left = -left;
1456 	  else if (op == O_logical_not)
1457 	    left = !left;
1458 	  else
1459 	    left = ~left;
1460 
1461 	  final_val += left + symp->sy_frag->fr_address;
1462 
1463 	  resolved = symbol_resolved_p (add_symbol);
1464 	  break;
1465 
1466 	case O_multiply:
1467 	case O_divide:
1468 	case O_modulus:
1469 	case O_left_shift:
1470 	case O_right_shift:
1471 	case O_bit_inclusive_or:
1472 	case O_bit_or_not:
1473 	case O_bit_exclusive_or:
1474 	case O_bit_and:
1475 	case O_add:
1476 	case O_subtract:
1477 	case O_eq:
1478 	case O_ne:
1479 	case O_lt:
1480 	case O_le:
1481 	case O_ge:
1482 	case O_gt:
1483 	case O_logical_and:
1484 	case O_logical_or:
1485 	  left = resolve_symbol_value (add_symbol);
1486 	  right = resolve_symbol_value (op_symbol);
1487 	  seg_left = S_GET_SEGMENT (add_symbol);
1488 	  seg_right = S_GET_SEGMENT (op_symbol);
1489 
1490 	  /* Simplify addition or subtraction of a constant by folding the
1491 	     constant into X_add_number.  */
1492 	  if (op == O_add)
1493 	    {
1494 	      if (seg_right == absolute_section)
1495 		{
1496 		  final_val += right;
1497 		  goto do_symbol;
1498 		}
1499 	      else if (seg_left == absolute_section)
1500 		{
1501 		  final_val += left;
1502 		  add_symbol = op_symbol;
1503 		  left = right;
1504 		  seg_left = seg_right;
1505 		  goto do_symbol;
1506 		}
1507 	    }
1508 	  else if (op == O_subtract)
1509 	    {
1510 	      if (seg_right == absolute_section)
1511 		{
1512 		  final_val -= right;
1513 		  goto do_symbol;
1514 		}
1515 	    }
1516 
1517 	  move_seg_ok = 1;
1518 	  /* Equality and non-equality tests are permitted on anything.
1519 	     Subtraction, and other comparison operators are permitted if
1520 	     both operands are in the same section.  Otherwise, both
1521 	     operands must be absolute.  We already handled the case of
1522 	     addition or subtraction of a constant above.  This will
1523 	     probably need to be changed for an object file format which
1524 	     supports arbitrary expressions.  */
1525 	  if (!(seg_left == absolute_section
1526 		&& seg_right == absolute_section)
1527 	      && !(op == O_eq || op == O_ne)
1528 	      && !((op == O_subtract
1529 		    || op == O_lt || op == O_le || op == O_ge || op == O_gt)
1530 		   && seg_left == seg_right
1531 		   && (seg_left != undefined_section
1532 		       || add_symbol == op_symbol)))
1533 	    {
1534 	      /* Don't emit messages unless we're finalizing the symbol value,
1535 		 otherwise we may get the same message multiple times.  */
1536 	      if (finalize_syms)
1537 		report_op_error (symp, add_symbol, op, op_symbol);
1538 	      /* However do not move the symbol into the absolute section
1539 		 if it cannot currently be resolved - this would confuse
1540 		 other parts of the assembler into believing that the
1541 		 expression had been evaluated to zero.  */
1542 	      else
1543 		move_seg_ok = 0;
1544 	    }
1545 
1546 	  if (move_seg_ok
1547 	      && (final_seg == expr_section || final_seg == undefined_section))
1548 	    final_seg = absolute_section;
1549 
1550 	  /* Check for division by zero.  */
1551 	  if ((op == O_divide || op == O_modulus) && right == 0)
1552 	    {
1553 	      /* If seg_right is not absolute_section, then we've
1554 		 already issued a warning about using a bad symbol.  */
1555 	      if (seg_right == absolute_section && finalize_syms)
1556 		{
1557 		  const char *file;
1558 		  unsigned int line;
1559 
1560 		  if (expr_symbol_where (symp, &file, &line))
1561 		    as_bad_where (file, line, _("division by zero"));
1562 		  else
1563 		    as_bad (_("division by zero when setting `%s'"),
1564 			    S_GET_NAME (symp));
1565 		}
1566 
1567 	      right = 1;
1568 	    }
1569 
1570 	  switch (symp->sy_value.X_op)
1571 	    {
1572 	    case O_multiply:		left *= right; break;
1573 	    case O_divide:		left /= right; break;
1574 	    case O_modulus:		left %= right; break;
1575 	    case O_left_shift:		left <<= right; break;
1576 	    case O_right_shift:		left >>= right; break;
1577 	    case O_bit_inclusive_or:	left |= right; break;
1578 	    case O_bit_or_not:		left |= ~right; break;
1579 	    case O_bit_exclusive_or:	left ^= right; break;
1580 	    case O_bit_and:		left &= right; break;
1581 	    case O_add:			left += right; break;
1582 	    case O_subtract:		left -= right; break;
1583 	    case O_eq:
1584 	    case O_ne:
1585 	      left = (left == right && seg_left == seg_right
1586 		      && (seg_left != undefined_section
1587 			  || add_symbol == op_symbol)
1588 		      ? ~ (offsetT) 0 : 0);
1589 	      if (symp->sy_value.X_op == O_ne)
1590 		left = ~left;
1591 	      break;
1592 	    case O_lt:	left = left <  right ? ~ (offsetT) 0 : 0; break;
1593 	    case O_le:	left = left <= right ? ~ (offsetT) 0 : 0; break;
1594 	    case O_ge:	left = left >= right ? ~ (offsetT) 0 : 0; break;
1595 	    case O_gt:	left = left >  right ? ~ (offsetT) 0 : 0; break;
1596 	    case O_logical_and:	left = left && right; break;
1597 	    case O_logical_or:	left = left || right; break;
1598 
1599 	    case O_illegal:
1600 	    case O_absent:
1601 	    case O_constant:
1602 	      /* See PR 20895 for a reproducer.  */
1603 	      as_bad (_("Invalid operation on symbol"));
1604 	      goto exit_dont_set_value;
1605 
1606 	    default:
1607 	      abort ();
1608 	    }
1609 
1610 	  final_val += symp->sy_frag->fr_address + left;
1611 	  if (final_seg == expr_section || final_seg == undefined_section)
1612 	    {
1613 	      if (seg_left == undefined_section
1614 		  || seg_right == undefined_section)
1615 		final_seg = undefined_section;
1616 	      else if (seg_left == absolute_section)
1617 		final_seg = seg_right;
1618 	      else
1619 		final_seg = seg_left;
1620 	    }
1621 	  resolved = (symbol_resolved_p (add_symbol)
1622 		      && symbol_resolved_p (op_symbol));
1623 	  break;
1624 
1625 	case O_big:
1626 	case O_illegal:
1627 	  /* Give an error (below) if not in expr_section.  We don't
1628 	     want to worry about expr_section symbols, because they
1629 	     are fictional (they are created as part of expression
1630 	     resolution), and any problems may not actually mean
1631 	     anything.  */
1632 	  break;
1633 	}
1634 
1635       symp->sy_flags.sy_resolving = 0;
1636     }
1637 
1638   if (finalize_syms)
1639     S_SET_VALUE (symp, final_val);
1640 
1641 exit_dont_set_value:
1642   /* Always set the segment, even if not finalizing the value.
1643      The segment is used to determine whether a symbol is defined.  */
1644     S_SET_SEGMENT (symp, final_seg);
1645 
1646   /* Don't worry if we can't resolve an expr_section symbol.  */
1647   if (finalize_syms)
1648     {
1649       if (resolved)
1650 	symp->sy_flags.sy_resolved = 1;
1651       else if (S_GET_SEGMENT (symp) != expr_section)
1652 	{
1653 	  as_bad (_("can't resolve value for symbol `%s'"),
1654 		  S_GET_NAME (symp));
1655 	  symp->sy_flags.sy_resolved = 1;
1656 	}
1657     }
1658 
1659   return final_val;
1660 }
1661 
1662 static void resolve_local_symbol (const char *, void *);
1663 
1664 /* A static function passed to hash_traverse.  */
1665 
1666 static void
1667 resolve_local_symbol (const char *key ATTRIBUTE_UNUSED, void *value)
1668 {
1669   if (value != NULL)
1670     resolve_symbol_value ((symbolS *) value);
1671 }
1672 
1673 /* Resolve all local symbols.  */
1674 
1675 void
1676 resolve_local_symbol_values (void)
1677 {
1678   hash_traverse (local_hash, resolve_local_symbol);
1679 }
1680 
1681 /* Obtain the current value of a symbol without changing any
1682    sub-expressions used.  */
1683 
1684 int
1685 snapshot_symbol (symbolS **symbolPP, valueT *valueP, segT *segP, fragS **fragPP)
1686 {
1687   symbolS *symbolP = *symbolPP;
1688 
1689   if (LOCAL_SYMBOL_CHECK (symbolP))
1690     {
1691       struct local_symbol *locsym = (struct local_symbol *) symbolP;
1692 
1693       *valueP = locsym->lsy_value;
1694       *segP = locsym->lsy_section;
1695       *fragPP = local_symbol_get_frag (locsym);
1696     }
1697   else
1698     {
1699       expressionS exp = symbolP->sy_value;
1700 
1701       if (!symbolP->sy_flags.sy_resolved && exp.X_op != O_illegal)
1702 	{
1703 	  int resolved;
1704 
1705 	  if (symbolP->sy_flags.sy_resolving)
1706 	    return 0;
1707 	  symbolP->sy_flags.sy_resolving = 1;
1708 	  resolved = resolve_expression (&exp);
1709 	  symbolP->sy_flags.sy_resolving = 0;
1710 	  if (!resolved)
1711 	    return 0;
1712 
1713 	  switch (exp.X_op)
1714 	    {
1715 	    case O_constant:
1716 	    case O_register:
1717 	      if (!symbol_equated_p (symbolP))
1718 		break;
1719 	      /* Fallthru.  */
1720 	    case O_symbol:
1721 	    case O_symbol_rva:
1722 	      symbolP = exp.X_add_symbol;
1723 	      break;
1724 	    default:
1725 	      return 0;
1726 	    }
1727 	}
1728 
1729       *symbolPP = symbolP;
1730 
1731       /* A bogus input file can result in resolve_expression()
1732 	 generating a local symbol, so we have to check again.  */
1733       if (LOCAL_SYMBOL_CHECK (symbolP))
1734 	{
1735 	  struct local_symbol *locsym = (struct local_symbol *) symbolP;
1736 
1737 	  *valueP = locsym->lsy_value;
1738 	  *segP = locsym->lsy_section;
1739 	  *fragPP = local_symbol_get_frag (locsym);
1740 	}
1741       else
1742 	{
1743 	  *valueP = exp.X_add_number;
1744 	  *segP = symbolP->bsym->section;
1745 	  *fragPP = symbolP->sy_frag;
1746 	}
1747 
1748       if (*segP == expr_section)
1749 	switch (exp.X_op)
1750 	  {
1751 	  case O_constant: *segP = absolute_section; break;
1752 	  case O_register: *segP = reg_section; break;
1753 	  default: break;
1754 	  }
1755     }
1756 
1757   return 1;
1758 }
1759 
1760 /* Dollar labels look like a number followed by a dollar sign.  Eg, "42$".
1761    They are *really* local.  That is, they go out of scope whenever we see a
1762    label that isn't local.  Also, like fb labels, there can be multiple
1763    instances of a dollar label.  Therefor, we name encode each instance with
1764    the instance number, keep a list of defined symbols separate from the real
1765    symbol table, and we treat these buggers as a sparse array.  */
1766 
1767 static long *dollar_labels;
1768 static long *dollar_label_instances;
1769 static char *dollar_label_defines;
1770 static unsigned long dollar_label_count;
1771 static unsigned long dollar_label_max;
1772 
1773 int
1774 dollar_label_defined (long label)
1775 {
1776   long *i;
1777 
1778   know ((dollar_labels != NULL) || (dollar_label_count == 0));
1779 
1780   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
1781     if (*i == label)
1782       return dollar_label_defines[i - dollar_labels];
1783 
1784   /* If we get here, label isn't defined.  */
1785   return 0;
1786 }
1787 
1788 static long
1789 dollar_label_instance (long label)
1790 {
1791   long *i;
1792 
1793   know ((dollar_labels != NULL) || (dollar_label_count == 0));
1794 
1795   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
1796     if (*i == label)
1797       return (dollar_label_instances[i - dollar_labels]);
1798 
1799   /* If we get here, we haven't seen the label before.
1800      Therefore its instance count is zero.  */
1801   return 0;
1802 }
1803 
1804 void
1805 dollar_label_clear (void)
1806 {
1807   memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
1808 }
1809 
1810 #define DOLLAR_LABEL_BUMP_BY 10
1811 
1812 void
1813 define_dollar_label (long label)
1814 {
1815   long *i;
1816 
1817   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
1818     if (*i == label)
1819       {
1820 	++dollar_label_instances[i - dollar_labels];
1821 	dollar_label_defines[i - dollar_labels] = 1;
1822 	return;
1823       }
1824 
1825   /* If we get to here, we don't have label listed yet.  */
1826 
1827   if (dollar_labels == NULL)
1828     {
1829       dollar_labels = XNEWVEC (long, DOLLAR_LABEL_BUMP_BY);
1830       dollar_label_instances = XNEWVEC (long, DOLLAR_LABEL_BUMP_BY);
1831       dollar_label_defines = XNEWVEC (char, DOLLAR_LABEL_BUMP_BY);
1832       dollar_label_max = DOLLAR_LABEL_BUMP_BY;
1833       dollar_label_count = 0;
1834     }
1835   else if (dollar_label_count == dollar_label_max)
1836     {
1837       dollar_label_max += DOLLAR_LABEL_BUMP_BY;
1838       dollar_labels = XRESIZEVEC (long, dollar_labels, dollar_label_max);
1839       dollar_label_instances = XRESIZEVEC (long, dollar_label_instances,
1840 					  dollar_label_max);
1841       dollar_label_defines = XRESIZEVEC (char, dollar_label_defines,
1842 					 dollar_label_max);
1843     }				/* if we needed to grow  */
1844 
1845   dollar_labels[dollar_label_count] = label;
1846   dollar_label_instances[dollar_label_count] = 1;
1847   dollar_label_defines[dollar_label_count] = 1;
1848   ++dollar_label_count;
1849 }
1850 
1851 /* Caller must copy returned name: we re-use the area for the next name.
1852 
1853    The mth occurrence of label n: is turned into the symbol "Ln^Am"
1854    where n is the label number and m is the instance number. "L" makes
1855    it a label discarded unless debugging and "^A"('\1') ensures no
1856    ordinary symbol SHOULD get the same name as a local label
1857    symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
1858 
1859    fb labels get the same treatment, except that ^B is used in place
1860    of ^A.  */
1861 
1862 char *				/* Return local label name.  */
1863 dollar_label_name (long n,	/* we just saw "n$:" : n a number.  */
1864 		   int augend	/* 0 for current instance, 1 for new instance.  */)
1865 {
1866   long i;
1867   /* Returned to caller, then copied.  Used for created names ("4f").  */
1868   static char symbol_name_build[24];
1869   char *p;
1870   char *q;
1871   char symbol_name_temporary[20];	/* Build up a number, BACKWARDS.  */
1872 
1873   know (n >= 0);
1874   know (augend == 0 || augend == 1);
1875   p = symbol_name_build;
1876 #ifdef LOCAL_LABEL_PREFIX
1877   *p++ = LOCAL_LABEL_PREFIX;
1878 #endif
1879   *p++ = 'L';
1880 
1881   /* Next code just does sprintf( {}, "%d", n);  */
1882   /* Label number.  */
1883   q = symbol_name_temporary;
1884   for (*q++ = 0, i = n; i; ++q)
1885     {
1886       *q = i % 10 + '0';
1887       i /= 10;
1888     }
1889   while ((*p = *--q) != '\0')
1890     ++p;
1891 
1892   *p++ = DOLLAR_LABEL_CHAR;		/* ^A  */
1893 
1894   /* Instance number.  */
1895   q = symbol_name_temporary;
1896   for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
1897     {
1898       *q = i % 10 + '0';
1899       i /= 10;
1900     }
1901   while ((*p++ = *--q) != '\0');
1902 
1903   /* The label, as a '\0' ended string, starts at symbol_name_build.  */
1904   return symbol_name_build;
1905 }
1906 
1907 /* Somebody else's idea of local labels. They are made by "n:" where n
1908    is any decimal digit. Refer to them with
1909     "nb" for previous (backward) n:
1910    or "nf" for next (forward) n:.
1911 
1912    We do a little better and let n be any number, not just a single digit, but
1913    since the other guy's assembler only does ten, we treat the first ten
1914    specially.
1915 
1916    Like someone else's assembler, we have one set of local label counters for
1917    entire assembly, not one set per (sub)segment like in most assemblers. This
1918    implies that one can refer to a label in another segment, and indeed some
1919    crufty compilers have done just that.
1920 
1921    Since there could be a LOT of these things, treat them as a sparse
1922    array.  */
1923 
1924 #define FB_LABEL_SPECIAL (10)
1925 
1926 static long fb_low_counter[FB_LABEL_SPECIAL];
1927 static long *fb_labels;
1928 static long *fb_label_instances;
1929 static long fb_label_count;
1930 static long fb_label_max;
1931 
1932 /* This must be more than FB_LABEL_SPECIAL.  */
1933 #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
1934 
1935 static void
1936 fb_label_init (void)
1937 {
1938   memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
1939 }
1940 
1941 /* Add one to the instance number of this fb label.  */
1942 
1943 void
1944 fb_label_instance_inc (long label)
1945 {
1946   long *i;
1947 
1948   if ((unsigned long) label < FB_LABEL_SPECIAL)
1949     {
1950       ++fb_low_counter[label];
1951       return;
1952     }
1953 
1954   if (fb_labels != NULL)
1955     {
1956       for (i = fb_labels + FB_LABEL_SPECIAL;
1957 	   i < fb_labels + fb_label_count; ++i)
1958 	{
1959 	  if (*i == label)
1960 	    {
1961 	      ++fb_label_instances[i - fb_labels];
1962 	      return;
1963 	    }			/* if we find it  */
1964 	}			/* for each existing label  */
1965     }
1966 
1967   /* If we get to here, we don't have label listed yet.  */
1968 
1969   if (fb_labels == NULL)
1970     {
1971       fb_labels = XNEWVEC (long, FB_LABEL_BUMP_BY);
1972       fb_label_instances = XNEWVEC (long, FB_LABEL_BUMP_BY);
1973       fb_label_max = FB_LABEL_BUMP_BY;
1974       fb_label_count = FB_LABEL_SPECIAL;
1975 
1976     }
1977   else if (fb_label_count == fb_label_max)
1978     {
1979       fb_label_max += FB_LABEL_BUMP_BY;
1980       fb_labels = XRESIZEVEC (long, fb_labels, fb_label_max);
1981       fb_label_instances = XRESIZEVEC (long, fb_label_instances, fb_label_max);
1982     }				/* if we needed to grow  */
1983 
1984   fb_labels[fb_label_count] = label;
1985   fb_label_instances[fb_label_count] = 1;
1986   ++fb_label_count;
1987 }
1988 
1989 static long
1990 fb_label_instance (long label)
1991 {
1992   long *i;
1993 
1994   if ((unsigned long) label < FB_LABEL_SPECIAL)
1995     {
1996       return (fb_low_counter[label]);
1997     }
1998 
1999   if (fb_labels != NULL)
2000     {
2001       for (i = fb_labels + FB_LABEL_SPECIAL;
2002 	   i < fb_labels + fb_label_count; ++i)
2003 	{
2004 	  if (*i == label)
2005 	    {
2006 	      return (fb_label_instances[i - fb_labels]);
2007 	    }			/* if we find it  */
2008 	}			/* for each existing label  */
2009     }
2010 
2011   /* We didn't find the label, so this must be a reference to the
2012      first instance.  */
2013   return 0;
2014 }
2015 
2016 /* Caller must copy returned name: we re-use the area for the next name.
2017 
2018    The mth occurrence of label n: is turned into the symbol "Ln^Bm"
2019    where n is the label number and m is the instance number. "L" makes
2020    it a label discarded unless debugging and "^B"('\2') ensures no
2021    ordinary symbol SHOULD get the same name as a local label
2022    symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
2023 
2024    dollar labels get the same treatment, except that ^A is used in
2025    place of ^B.  */
2026 
2027 char *				/* Return local label name.  */
2028 fb_label_name (long n,	/* We just saw "n:", "nf" or "nb" : n a number.  */
2029 	       long augend	/* 0 for nb, 1 for n:, nf.  */)
2030 {
2031   long i;
2032   /* Returned to caller, then copied.  Used for created names ("4f").  */
2033   static char symbol_name_build[24];
2034   char *p;
2035   char *q;
2036   char symbol_name_temporary[20];	/* Build up a number, BACKWARDS.  */
2037 
2038   know (n >= 0);
2039 #ifdef TC_MMIX
2040   know ((unsigned long) augend <= 2 /* See mmix_fb_label.  */);
2041 #else
2042   know ((unsigned long) augend <= 1);
2043 #endif
2044   p = symbol_name_build;
2045 #ifdef LOCAL_LABEL_PREFIX
2046   *p++ = LOCAL_LABEL_PREFIX;
2047 #endif
2048   *p++ = 'L';
2049 
2050   /* Next code just does sprintf( {}, "%d", n);  */
2051   /* Label number.  */
2052   q = symbol_name_temporary;
2053   for (*q++ = 0, i = n; i; ++q)
2054     {
2055       *q = i % 10 + '0';
2056       i /= 10;
2057     }
2058   while ((*p = *--q) != '\0')
2059     ++p;
2060 
2061   *p++ = LOCAL_LABEL_CHAR;		/* ^B  */
2062 
2063   /* Instance number.  */
2064   q = symbol_name_temporary;
2065   for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
2066     {
2067       *q = i % 10 + '0';
2068       i /= 10;
2069     }
2070   while ((*p++ = *--q) != '\0');
2071 
2072   /* The label, as a '\0' ended string, starts at symbol_name_build.  */
2073   return (symbol_name_build);
2074 }
2075 
2076 /* Decode name that may have been generated by foo_label_name() above.
2077    If the name wasn't generated by foo_label_name(), then return it
2078    unaltered.  This is used for error messages.  */
2079 
2080 char *
2081 decode_local_label_name (char *s)
2082 {
2083   char *p;
2084   char *symbol_decode;
2085   int label_number;
2086   int instance_number;
2087   const char *type;
2088   const char *message_format;
2089   int lindex = 0;
2090 
2091 #ifdef LOCAL_LABEL_PREFIX
2092   if (s[lindex] == LOCAL_LABEL_PREFIX)
2093     ++lindex;
2094 #endif
2095 
2096   if (s[lindex] != 'L')
2097     return s;
2098 
2099   for (label_number = 0, p = s + lindex + 1; ISDIGIT (*p); ++p)
2100     label_number = (10 * label_number) + *p - '0';
2101 
2102   if (*p == DOLLAR_LABEL_CHAR)
2103     type = "dollar";
2104   else if (*p == LOCAL_LABEL_CHAR)
2105     type = "fb";
2106   else
2107     return s;
2108 
2109   for (instance_number = 0, p++; ISDIGIT (*p); ++p)
2110     instance_number = (10 * instance_number) + *p - '0';
2111 
2112   message_format = _("\"%d\" (instance number %d of a %s label)");
2113   symbol_decode = (char *) obstack_alloc (&notes, strlen (message_format) + 30);
2114   sprintf (symbol_decode, message_format, label_number, instance_number, type);
2115 
2116   return symbol_decode;
2117 }
2118 
2119 /* Get the value of a symbol.  */
2120 
2121 valueT
2122 S_GET_VALUE (symbolS *s)
2123 {
2124   if (LOCAL_SYMBOL_CHECK (s))
2125     return resolve_symbol_value (s);
2126 
2127   if (!s->sy_flags.sy_resolved)
2128     {
2129       valueT val = resolve_symbol_value (s);
2130       if (!finalize_syms)
2131 	return val;
2132     }
2133   if (S_IS_WEAKREFR (s))
2134     return S_GET_VALUE (s->sy_value.X_add_symbol);
2135 
2136   if (s->sy_value.X_op != O_constant)
2137     {
2138       if (! s->sy_flags.sy_resolved
2139 	  || s->sy_value.X_op != O_symbol
2140 	  || (S_IS_DEFINED (s) && ! S_IS_COMMON (s)))
2141 	as_bad (_("attempt to get value of unresolved symbol `%s'"),
2142 		S_GET_NAME (s));
2143     }
2144   return (valueT) s->sy_value.X_add_number;
2145 }
2146 
2147 /* Set the value of a symbol.  */
2148 
2149 void
2150 S_SET_VALUE (symbolS *s, valueT val)
2151 {
2152   if (LOCAL_SYMBOL_CHECK (s))
2153     {
2154       ((struct local_symbol *) s)->lsy_value = val;
2155       return;
2156     }
2157 
2158   s->sy_value.X_op = O_constant;
2159   s->sy_value.X_add_number = (offsetT) val;
2160   s->sy_value.X_unsigned = 0;
2161   S_CLEAR_WEAKREFR (s);
2162 }
2163 
2164 void
2165 copy_symbol_attributes (symbolS *dest, symbolS *src)
2166 {
2167   if (LOCAL_SYMBOL_CHECK (dest))
2168     dest = local_symbol_convert ((struct local_symbol *) dest);
2169   if (LOCAL_SYMBOL_CHECK (src))
2170     src = local_symbol_convert ((struct local_symbol *) src);
2171 
2172   /* In an expression, transfer the settings of these flags.
2173      The user can override later, of course.  */
2174 #define COPIED_SYMFLAGS	(BSF_FUNCTION | BSF_OBJECT \
2175 			 | BSF_GNU_INDIRECT_FUNCTION)
2176   dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
2177 
2178 #ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
2179   OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
2180 #endif
2181 
2182 #ifdef TC_COPY_SYMBOL_ATTRIBUTES
2183   TC_COPY_SYMBOL_ATTRIBUTES (dest, src);
2184 #endif
2185 }
2186 
2187 int
2188 S_IS_FUNCTION (symbolS *s)
2189 {
2190   flagword flags;
2191 
2192   if (LOCAL_SYMBOL_CHECK (s))
2193     return 0;
2194 
2195   flags = s->bsym->flags;
2196 
2197   return (flags & BSF_FUNCTION) != 0;
2198 }
2199 
2200 int
2201 S_IS_EXTERNAL (symbolS *s)
2202 {
2203   flagword flags;
2204 
2205   if (LOCAL_SYMBOL_CHECK (s))
2206     return 0;
2207 
2208   flags = s->bsym->flags;
2209 
2210   /* Sanity check.  */
2211   if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
2212     abort ();
2213 
2214   return (flags & BSF_GLOBAL) != 0;
2215 }
2216 
2217 int
2218 S_IS_WEAK (symbolS *s)
2219 {
2220   if (LOCAL_SYMBOL_CHECK (s))
2221     return 0;
2222   /* Conceptually, a weakrefr is weak if the referenced symbol is.  We
2223      could probably handle a WEAKREFR as always weak though.  E.g., if
2224      the referenced symbol has lost its weak status, there's no reason
2225      to keep handling the weakrefr as if it was weak.  */
2226   if (S_IS_WEAKREFR (s))
2227     return S_IS_WEAK (s->sy_value.X_add_symbol);
2228   return (s->bsym->flags & BSF_WEAK) != 0;
2229 }
2230 
2231 int
2232 S_IS_WEAKREFR (symbolS *s)
2233 {
2234   if (LOCAL_SYMBOL_CHECK (s))
2235     return 0;
2236   return s->sy_flags.sy_weakrefr != 0;
2237 }
2238 
2239 int
2240 S_IS_WEAKREFD (symbolS *s)
2241 {
2242   if (LOCAL_SYMBOL_CHECK (s))
2243     return 0;
2244   return s->sy_flags.sy_weakrefd != 0;
2245 }
2246 
2247 int
2248 S_IS_COMMON (symbolS *s)
2249 {
2250   if (LOCAL_SYMBOL_CHECK (s))
2251     return 0;
2252   return bfd_is_com_section (s->bsym->section);
2253 }
2254 
2255 int
2256 S_IS_DEFINED (symbolS *s)
2257 {
2258   if (LOCAL_SYMBOL_CHECK (s))
2259     return ((struct local_symbol *) s)->lsy_section != undefined_section;
2260   return s->bsym->section != undefined_section;
2261 }
2262 
2263 
2264 #ifndef EXTERN_FORCE_RELOC
2265 #define EXTERN_FORCE_RELOC IS_ELF
2266 #endif
2267 
2268 /* Return true for symbols that should not be reduced to section
2269    symbols or eliminated from expressions, because they may be
2270    overridden by the linker.  */
2271 int
2272 S_FORCE_RELOC (symbolS *s, int strict)
2273 {
2274   segT sec;
2275   if (LOCAL_SYMBOL_CHECK (s))
2276     sec = ((struct local_symbol *) s)->lsy_section;
2277   else
2278     {
2279       if ((strict
2280 	   && ((s->bsym->flags & BSF_WEAK) != 0
2281 	       || (EXTERN_FORCE_RELOC
2282 		   && (s->bsym->flags & BSF_GLOBAL) != 0)))
2283 	  || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0)
2284 	return TRUE;
2285       sec = s->bsym->section;
2286     }
2287   return bfd_is_und_section (sec) || bfd_is_com_section (sec);
2288 }
2289 
2290 int
2291 S_IS_DEBUG (symbolS *s)
2292 {
2293   if (LOCAL_SYMBOL_CHECK (s))
2294     return 0;
2295   if (s->bsym->flags & BSF_DEBUGGING)
2296     return 1;
2297   return 0;
2298 }
2299 
2300 int
2301 S_IS_LOCAL (symbolS *s)
2302 {
2303   flagword flags;
2304   const char *name;
2305 
2306   if (LOCAL_SYMBOL_CHECK (s))
2307     return 1;
2308 
2309   flags = s->bsym->flags;
2310 
2311   /* Sanity check.  */
2312   if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
2313     abort ();
2314 
2315   if (bfd_asymbol_section (s->bsym) == reg_section)
2316     return 1;
2317 
2318   if (flag_strip_local_absolute
2319       /* Keep BSF_FILE symbols in order to allow debuggers to identify
2320 	 the source file even when the object file is stripped.  */
2321       && (flags & (BSF_GLOBAL | BSF_FILE)) == 0
2322       && bfd_asymbol_section (s->bsym) == absolute_section)
2323     return 1;
2324 
2325   name = S_GET_NAME (s);
2326   return (name != NULL
2327 	  && ! S_IS_DEBUG (s)
2328 	  && (strchr (name, DOLLAR_LABEL_CHAR)
2329 	      || strchr (name, LOCAL_LABEL_CHAR)
2330 #if FAKE_LABEL_CHAR != DOLLAR_LABEL_CHAR
2331 	      || strchr (name, FAKE_LABEL_CHAR)
2332 #endif
2333 	      || TC_LABEL_IS_LOCAL (name)
2334 	      || (! flag_keep_locals
2335 		  && (bfd_is_local_label (stdoutput, s->bsym)
2336 		      || (flag_mri
2337 			  && name[0] == '?'
2338 			  && name[1] == '?')))));
2339 }
2340 
2341 int
2342 S_IS_STABD (symbolS *s)
2343 {
2344   return S_GET_NAME (s) == 0;
2345 }
2346 
2347 int
2348 S_CAN_BE_REDEFINED (const symbolS *s)
2349 {
2350   if (LOCAL_SYMBOL_CHECK (s))
2351     return (local_symbol_get_frag ((struct local_symbol *) s)
2352 	    == &predefined_address_frag);
2353   /* Permit register names to be redefined.  */
2354   return s->bsym->section == reg_section;
2355 }
2356 
2357 int
2358 S_IS_VOLATILE (const symbolS *s)
2359 {
2360   if (LOCAL_SYMBOL_CHECK (s))
2361     return 0;
2362   return s->sy_flags.sy_volatile;
2363 }
2364 
2365 int
2366 S_IS_FORWARD_REF (const symbolS *s)
2367 {
2368   if (LOCAL_SYMBOL_CHECK (s))
2369     return 0;
2370   return s->sy_flags.sy_forward_ref;
2371 }
2372 
2373 const char *
2374 S_GET_NAME (symbolS *s)
2375 {
2376   if (LOCAL_SYMBOL_CHECK (s))
2377     return ((struct local_symbol *) s)->lsy_name;
2378   return s->bsym->name;
2379 }
2380 
2381 segT
2382 S_GET_SEGMENT (symbolS *s)
2383 {
2384   if (LOCAL_SYMBOL_CHECK (s))
2385     return ((struct local_symbol *) s)->lsy_section;
2386   return s->bsym->section;
2387 }
2388 
2389 void
2390 S_SET_SEGMENT (symbolS *s, segT seg)
2391 {
2392   /* Don't reassign section symbols.  The direct reason is to prevent seg
2393      faults assigning back to const global symbols such as *ABS*, but it
2394      shouldn't happen anyway.  */
2395 
2396   if (LOCAL_SYMBOL_CHECK (s))
2397     {
2398       if (seg == reg_section)
2399 	s = local_symbol_convert ((struct local_symbol *) s);
2400       else
2401 	{
2402 	  ((struct local_symbol *) s)->lsy_section = seg;
2403 	  return;
2404 	}
2405     }
2406 
2407   if (s->bsym->flags & BSF_SECTION_SYM)
2408     {
2409       if (s->bsym->section != seg)
2410 	abort ();
2411     }
2412   else
2413     s->bsym->section = seg;
2414 }
2415 
2416 void
2417 S_SET_EXTERNAL (symbolS *s)
2418 {
2419   if (LOCAL_SYMBOL_CHECK (s))
2420     s = local_symbol_convert ((struct local_symbol *) s);
2421   if ((s->bsym->flags & BSF_WEAK) != 0)
2422     {
2423       /* Let .weak override .global.  */
2424       return;
2425     }
2426   if (s->bsym->flags & BSF_SECTION_SYM)
2427     {
2428       /* Do not reassign section symbols.  */
2429       as_warn (_("section symbols are already global"));
2430       return;
2431     }
2432 #ifndef TC_GLOBAL_REGISTER_SYMBOL_OK
2433   if (S_GET_SEGMENT (s) == reg_section)
2434     {
2435       as_bad ("can't make register symbol `%s' global",
2436 	      S_GET_NAME (s));
2437       return;
2438     }
2439 #endif
2440   s->bsym->flags |= BSF_GLOBAL;
2441   s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK);
2442 
2443 #ifdef TE_PE
2444   if (! an_external_name && S_GET_NAME(s)[0] != '.')
2445     an_external_name = S_GET_NAME (s);
2446 #endif
2447 }
2448 
2449 void
2450 S_CLEAR_EXTERNAL (symbolS *s)
2451 {
2452   if (LOCAL_SYMBOL_CHECK (s))
2453     return;
2454   if ((s->bsym->flags & BSF_WEAK) != 0)
2455     {
2456       /* Let .weak override.  */
2457       return;
2458     }
2459   s->bsym->flags |= BSF_LOCAL;
2460   s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
2461 }
2462 
2463 void
2464 S_SET_WEAK (symbolS *s)
2465 {
2466   if (LOCAL_SYMBOL_CHECK (s))
2467     s = local_symbol_convert ((struct local_symbol *) s);
2468 #ifdef obj_set_weak_hook
2469   obj_set_weak_hook (s);
2470 #endif
2471   s->bsym->flags |= BSF_WEAK;
2472   s->bsym->flags &= ~(BSF_GLOBAL | BSF_LOCAL);
2473 }
2474 
2475 void
2476 S_SET_WEAKREFR (symbolS *s)
2477 {
2478   if (LOCAL_SYMBOL_CHECK (s))
2479     s = local_symbol_convert ((struct local_symbol *) s);
2480   s->sy_flags.sy_weakrefr = 1;
2481   /* If the alias was already used, make sure we mark the target as
2482      used as well, otherwise it might be dropped from the symbol
2483      table.  This may have unintended side effects if the alias is
2484      later redirected to another symbol, such as keeping the unused
2485      previous target in the symbol table.  Since it will be weak, it's
2486      not a big deal.  */
2487   if (s->sy_flags.sy_used)
2488     symbol_mark_used (s->sy_value.X_add_symbol);
2489 }
2490 
2491 void
2492 S_CLEAR_WEAKREFR (symbolS *s)
2493 {
2494   if (LOCAL_SYMBOL_CHECK (s))
2495     return;
2496   s->sy_flags.sy_weakrefr = 0;
2497 }
2498 
2499 void
2500 S_SET_WEAKREFD (symbolS *s)
2501 {
2502   if (LOCAL_SYMBOL_CHECK (s))
2503     s = local_symbol_convert ((struct local_symbol *) s);
2504   s->sy_flags.sy_weakrefd = 1;
2505   S_SET_WEAK (s);
2506 }
2507 
2508 void
2509 S_CLEAR_WEAKREFD (symbolS *s)
2510 {
2511   if (LOCAL_SYMBOL_CHECK (s))
2512     return;
2513   if (s->sy_flags.sy_weakrefd)
2514     {
2515       s->sy_flags.sy_weakrefd = 0;
2516       /* If a weakref target symbol is weak, then it was never
2517 	 referenced directly before, not even in a .global directive,
2518 	 so decay it to local.  If it remains undefined, it will be
2519 	 later turned into a global, like any other undefined
2520 	 symbol.  */
2521       if (s->bsym->flags & BSF_WEAK)
2522 	{
2523 #ifdef obj_clear_weak_hook
2524 	  obj_clear_weak_hook (s);
2525 #endif
2526 	  s->bsym->flags &= ~BSF_WEAK;
2527 	  s->bsym->flags |= BSF_LOCAL;
2528 	}
2529     }
2530 }
2531 
2532 void
2533 S_SET_THREAD_LOCAL (symbolS *s)
2534 {
2535   if (LOCAL_SYMBOL_CHECK (s))
2536     s = local_symbol_convert ((struct local_symbol *) s);
2537   if (bfd_is_com_section (s->bsym->section)
2538       && (s->bsym->flags & BSF_THREAD_LOCAL) != 0)
2539     return;
2540   s->bsym->flags |= BSF_THREAD_LOCAL;
2541   if ((s->bsym->flags & BSF_FUNCTION) != 0)
2542     as_bad (_("Accessing function `%s' as thread-local object"),
2543 	    S_GET_NAME (s));
2544   else if (! bfd_is_und_section (s->bsym->section)
2545 	   && (s->bsym->section->flags & SEC_THREAD_LOCAL) == 0)
2546     as_bad (_("Accessing `%s' as thread-local object"),
2547 	    S_GET_NAME (s));
2548 }
2549 
2550 void
2551 S_SET_NAME (symbolS *s, const char *name)
2552 {
2553   if (LOCAL_SYMBOL_CHECK (s))
2554     {
2555       ((struct local_symbol *) s)->lsy_name = name;
2556       return;
2557     }
2558   s->bsym->name = name;
2559 }
2560 
2561 void
2562 S_SET_VOLATILE (symbolS *s)
2563 {
2564   if (LOCAL_SYMBOL_CHECK (s))
2565     s = local_symbol_convert ((struct local_symbol *) s);
2566   s->sy_flags.sy_volatile = 1;
2567 }
2568 
2569 void
2570 S_CLEAR_VOLATILE (symbolS *s)
2571 {
2572   if (!LOCAL_SYMBOL_CHECK (s))
2573     s->sy_flags.sy_volatile = 0;
2574 }
2575 
2576 void
2577 S_SET_FORWARD_REF (symbolS *s)
2578 {
2579   if (LOCAL_SYMBOL_CHECK (s))
2580     s = local_symbol_convert ((struct local_symbol *) s);
2581   s->sy_flags.sy_forward_ref = 1;
2582 }
2583 
2584 /* Return the previous symbol in a chain.  */
2585 
2586 symbolS *
2587 symbol_previous (symbolS *s)
2588 {
2589   if (LOCAL_SYMBOL_CHECK (s))
2590     abort ();
2591   return s->sy_previous;
2592 }
2593 
2594 /* Return the next symbol in a chain.  */
2595 
2596 symbolS *
2597 symbol_next (symbolS *s)
2598 {
2599   if (LOCAL_SYMBOL_CHECK (s))
2600     abort ();
2601   return s->sy_next;
2602 }
2603 
2604 /* Return a pointer to the value of a symbol as an expression.  */
2605 
2606 expressionS *
2607 symbol_get_value_expression (symbolS *s)
2608 {
2609   if (LOCAL_SYMBOL_CHECK (s))
2610     s = local_symbol_convert ((struct local_symbol *) s);
2611   return &s->sy_value;
2612 }
2613 
2614 /* Set the value of a symbol to an expression.  */
2615 
2616 void
2617 symbol_set_value_expression (symbolS *s, const expressionS *exp)
2618 {
2619   if (LOCAL_SYMBOL_CHECK (s))
2620     s = local_symbol_convert ((struct local_symbol *) s);
2621   s->sy_value = *exp;
2622   S_CLEAR_WEAKREFR (s);
2623 }
2624 
2625 /* Return whether 2 symbols are the same.  */
2626 
2627 int
2628 symbol_same_p (symbolS *s1, symbolS *s2)
2629 {
2630   s1 = get_real_sym (s1);
2631   s2 = get_real_sym (s2);
2632   return s1 == s2;
2633 }
2634 
2635 /* Return a pointer to the X_add_number component of a symbol.  */
2636 
2637 offsetT *
2638 symbol_X_add_number (symbolS *s)
2639 {
2640   if (LOCAL_SYMBOL_CHECK (s))
2641     return (offsetT *) &((struct local_symbol *) s)->lsy_value;
2642 
2643   return &s->sy_value.X_add_number;
2644 }
2645 
2646 /* Set the value of SYM to the current position in the current segment.  */
2647 
2648 void
2649 symbol_set_value_now (symbolS *sym)
2650 {
2651   S_SET_SEGMENT (sym, now_seg);
2652   S_SET_VALUE (sym, frag_now_fix ());
2653   symbol_set_frag (sym, frag_now);
2654 }
2655 
2656 /* Set the frag of a symbol.  */
2657 
2658 void
2659 symbol_set_frag (symbolS *s, fragS *f)
2660 {
2661   if (LOCAL_SYMBOL_CHECK (s))
2662     {
2663       local_symbol_set_frag ((struct local_symbol *) s, f);
2664       return;
2665     }
2666   s->sy_frag = f;
2667   S_CLEAR_WEAKREFR (s);
2668 }
2669 
2670 /* Return the frag of a symbol.  */
2671 
2672 fragS *
2673 symbol_get_frag (symbolS *s)
2674 {
2675   if (LOCAL_SYMBOL_CHECK (s))
2676     return local_symbol_get_frag ((struct local_symbol *) s);
2677   return s->sy_frag;
2678 }
2679 
2680 /* Mark a symbol as having been used.  */
2681 
2682 void
2683 symbol_mark_used (symbolS *s)
2684 {
2685   if (LOCAL_SYMBOL_CHECK (s))
2686     return;
2687   s->sy_flags.sy_used = 1;
2688   if (S_IS_WEAKREFR (s))
2689     symbol_mark_used (s->sy_value.X_add_symbol);
2690 }
2691 
2692 /* Clear the mark of whether a symbol has been used.  */
2693 
2694 void
2695 symbol_clear_used (symbolS *s)
2696 {
2697   if (LOCAL_SYMBOL_CHECK (s))
2698     s = local_symbol_convert ((struct local_symbol *) s);
2699   s->sy_flags.sy_used = 0;
2700 }
2701 
2702 /* Return whether a symbol has been used.  */
2703 
2704 int
2705 symbol_used_p (symbolS *s)
2706 {
2707   if (LOCAL_SYMBOL_CHECK (s))
2708     return 1;
2709   return s->sy_flags.sy_used;
2710 }
2711 
2712 /* Mark a symbol as having been used in a reloc.  */
2713 
2714 void
2715 symbol_mark_used_in_reloc (symbolS *s)
2716 {
2717   if (LOCAL_SYMBOL_CHECK (s))
2718     s = local_symbol_convert ((struct local_symbol *) s);
2719   s->sy_flags.sy_used_in_reloc = 1;
2720 }
2721 
2722 /* Clear the mark of whether a symbol has been used in a reloc.  */
2723 
2724 void
2725 symbol_clear_used_in_reloc (symbolS *s)
2726 {
2727   if (LOCAL_SYMBOL_CHECK (s))
2728     return;
2729   s->sy_flags.sy_used_in_reloc = 0;
2730 }
2731 
2732 /* Return whether a symbol has been used in a reloc.  */
2733 
2734 int
2735 symbol_used_in_reloc_p (symbolS *s)
2736 {
2737   if (LOCAL_SYMBOL_CHECK (s))
2738     return 0;
2739   return s->sy_flags.sy_used_in_reloc;
2740 }
2741 
2742 /* Mark a symbol as an MRI common symbol.  */
2743 
2744 void
2745 symbol_mark_mri_common (symbolS *s)
2746 {
2747   if (LOCAL_SYMBOL_CHECK (s))
2748     s = local_symbol_convert ((struct local_symbol *) s);
2749   s->sy_flags.sy_mri_common = 1;
2750 }
2751 
2752 /* Clear the mark of whether a symbol is an MRI common symbol.  */
2753 
2754 void
2755 symbol_clear_mri_common (symbolS *s)
2756 {
2757   if (LOCAL_SYMBOL_CHECK (s))
2758     return;
2759   s->sy_flags.sy_mri_common = 0;
2760 }
2761 
2762 /* Return whether a symbol is an MRI common symbol.  */
2763 
2764 int
2765 symbol_mri_common_p (symbolS *s)
2766 {
2767   if (LOCAL_SYMBOL_CHECK (s))
2768     return 0;
2769   return s->sy_flags.sy_mri_common;
2770 }
2771 
2772 /* Mark a symbol as having been written.  */
2773 
2774 void
2775 symbol_mark_written (symbolS *s)
2776 {
2777   if (LOCAL_SYMBOL_CHECK (s))
2778     return;
2779   s->sy_flags.sy_written = 1;
2780 }
2781 
2782 /* Clear the mark of whether a symbol has been written.  */
2783 
2784 void
2785 symbol_clear_written (symbolS *s)
2786 {
2787   if (LOCAL_SYMBOL_CHECK (s))
2788     return;
2789   s->sy_flags.sy_written = 0;
2790 }
2791 
2792 /* Return whether a symbol has been written.  */
2793 
2794 int
2795 symbol_written_p (symbolS *s)
2796 {
2797   if (LOCAL_SYMBOL_CHECK (s))
2798     return 0;
2799   return s->sy_flags.sy_written;
2800 }
2801 
2802 /* Mark a symbol has having been resolved.  */
2803 
2804 void
2805 symbol_mark_resolved (symbolS *s)
2806 {
2807   if (LOCAL_SYMBOL_CHECK (s))
2808     {
2809       local_symbol_mark_resolved ((struct local_symbol *) s);
2810       return;
2811     }
2812   s->sy_flags.sy_resolved = 1;
2813 }
2814 
2815 /* Return whether a symbol has been resolved.  */
2816 
2817 int
2818 symbol_resolved_p (symbolS *s)
2819 {
2820   if (LOCAL_SYMBOL_CHECK (s))
2821     return local_symbol_resolved_p ((struct local_symbol *) s);
2822   return s->sy_flags.sy_resolved;
2823 }
2824 
2825 /* Return whether a symbol is a section symbol.  */
2826 
2827 int
2828 symbol_section_p (symbolS *s ATTRIBUTE_UNUSED)
2829 {
2830   if (LOCAL_SYMBOL_CHECK (s))
2831     return 0;
2832   return (s->bsym->flags & BSF_SECTION_SYM) != 0;
2833 }
2834 
2835 /* Return whether a symbol is equated to another symbol.  */
2836 
2837 int
2838 symbol_equated_p (symbolS *s)
2839 {
2840   if (LOCAL_SYMBOL_CHECK (s))
2841     return 0;
2842   return s->sy_value.X_op == O_symbol;
2843 }
2844 
2845 /* Return whether a symbol is equated to another symbol, and should be
2846    treated specially when writing out relocs.  */
2847 
2848 int
2849 symbol_equated_reloc_p (symbolS *s)
2850 {
2851   if (LOCAL_SYMBOL_CHECK (s))
2852     return 0;
2853   /* X_op_symbol, normally not used for O_symbol, is set by
2854      resolve_symbol_value to flag expression syms that have been
2855      equated.  */
2856   return (s->sy_value.X_op == O_symbol
2857 #if defined (OBJ_COFF) && defined (TE_PE)
2858 	  && ! S_IS_WEAK (s)
2859 #endif
2860 	  && ((s->sy_flags.sy_resolved && s->sy_value.X_op_symbol != NULL)
2861 	      || ! S_IS_DEFINED (s)
2862 	      || S_IS_COMMON (s)));
2863 }
2864 
2865 /* Return whether a symbol has a constant value.  */
2866 
2867 int
2868 symbol_constant_p (symbolS *s)
2869 {
2870   if (LOCAL_SYMBOL_CHECK (s))
2871     return 1;
2872   return s->sy_value.X_op == O_constant;
2873 }
2874 
2875 /* Return whether a symbol was cloned and thus removed from the global
2876    symbol list.  */
2877 
2878 int
2879 symbol_shadow_p (symbolS *s)
2880 {
2881   if (LOCAL_SYMBOL_CHECK (s))
2882     return 0;
2883   return s->sy_next == s;
2884 }
2885 
2886 /* If S was created as a struct symbol, return S, otherwise if S is a
2887    converted local_symbol return the converted symbol, otherwise
2888    return NULL.  */
2889 
2890 symbolS *
2891 symbol_symbolS (symbolS *s)
2892 {
2893   if (LOCAL_SYMBOL_CHECK (s))
2894     return NULL;
2895   return s;
2896 }
2897 
2898 /* Return the BFD symbol for a symbol.  */
2899 
2900 asymbol *
2901 symbol_get_bfdsym (symbolS *s)
2902 {
2903   if (LOCAL_SYMBOL_CHECK (s))
2904     s = local_symbol_convert ((struct local_symbol *) s);
2905   return s->bsym;
2906 }
2907 
2908 /* Set the BFD symbol for a symbol.  */
2909 
2910 void
2911 symbol_set_bfdsym (symbolS *s, asymbol *bsym)
2912 {
2913   if (LOCAL_SYMBOL_CHECK (s))
2914     s = local_symbol_convert ((struct local_symbol *) s);
2915   /* Usually, it is harmless to reset a symbol to a BFD section
2916      symbol. For example, obj_elf_change_section sets the BFD symbol
2917      of an old symbol with the newly created section symbol. But when
2918      we have multiple sections with the same name, the newly created
2919      section may have the same name as an old section. We check if the
2920      old symbol has been already marked as a section symbol before
2921      resetting it.  */
2922   if ((s->bsym->flags & BSF_SECTION_SYM) == 0)
2923     s->bsym = bsym;
2924   /* else XXX - What do we do now ?  */
2925 }
2926 
2927 #ifdef OBJ_SYMFIELD_TYPE
2928 
2929 /* Get a pointer to the object format information for a symbol.  */
2930 
2931 OBJ_SYMFIELD_TYPE *
2932 symbol_get_obj (symbolS *s)
2933 {
2934   if (LOCAL_SYMBOL_CHECK (s))
2935     s = local_symbol_convert ((struct local_symbol *) s);
2936   return &s->sy_obj;
2937 }
2938 
2939 /* Set the object format information for a symbol.  */
2940 
2941 void
2942 symbol_set_obj (symbolS *s, OBJ_SYMFIELD_TYPE *o)
2943 {
2944   if (LOCAL_SYMBOL_CHECK (s))
2945     s = local_symbol_convert ((struct local_symbol *) s);
2946   s->sy_obj = *o;
2947 }
2948 
2949 #endif /* OBJ_SYMFIELD_TYPE */
2950 
2951 #ifdef TC_SYMFIELD_TYPE
2952 
2953 /* Get a pointer to the processor information for a symbol.  */
2954 
2955 TC_SYMFIELD_TYPE *
2956 symbol_get_tc (symbolS *s)
2957 {
2958   if (LOCAL_SYMBOL_CHECK (s))
2959     s = local_symbol_convert ((struct local_symbol *) s);
2960   return &s->sy_tc;
2961 }
2962 
2963 /* Set the processor information for a symbol.  */
2964 
2965 void
2966 symbol_set_tc (symbolS *s, TC_SYMFIELD_TYPE *o)
2967 {
2968   if (LOCAL_SYMBOL_CHECK (s))
2969     s = local_symbol_convert ((struct local_symbol *) s);
2970   s->sy_tc = *o;
2971 }
2972 
2973 #endif /* TC_SYMFIELD_TYPE */
2974 
2975 void
2976 symbol_begin (void)
2977 {
2978   symbol_lastP = NULL;
2979   symbol_rootP = NULL;		/* In case we have 0 symbols (!!)  */
2980   sy_hash = hash_new ();
2981   local_hash = hash_new ();
2982 
2983   memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
2984 #if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
2985   abs_symbol.bsym = bfd_abs_section_ptr->symbol;
2986 #endif
2987   abs_symbol.sy_value.X_op = O_constant;
2988   abs_symbol.sy_frag = &zero_address_frag;
2989 
2990   if (LOCAL_LABELS_FB)
2991     fb_label_init ();
2992 }
2993 
2994 void
2995 dot_symbol_init (void)
2996 {
2997   dot_symbol.bsym = bfd_make_empty_symbol (stdoutput);
2998   if (dot_symbol.bsym == NULL)
2999     as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ()));
3000   dot_symbol.bsym->name = ".";
3001   dot_symbol.sy_flags.sy_forward_ref = 1;
3002   dot_symbol.sy_value.X_op = O_constant;
3003 }
3004 
3005 int indent_level;
3006 
3007 /* Maximum indent level.
3008    Available for modification inside a gdb session.  */
3009 static int max_indent_level = 8;
3010 
3011 void
3012 print_symbol_value_1 (FILE *file, symbolS *sym)
3013 {
3014   const char *name = S_GET_NAME (sym);
3015   if (!name || !name[0])
3016     name = "(unnamed)";
3017   fprintf (file, "sym ");
3018   fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) sym));
3019   fprintf (file, " %s", name);
3020 
3021   if (LOCAL_SYMBOL_CHECK (sym))
3022     {
3023       struct local_symbol *locsym = (struct local_symbol *) sym;
3024 
3025       if (local_symbol_get_frag (locsym) != & zero_address_frag
3026 	  && local_symbol_get_frag (locsym) != NULL)
3027 	{
3028 	  fprintf (file, " frag ");
3029 	  fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) local_symbol_get_frag (locsym)));
3030         }
3031       if (local_symbol_resolved_p (locsym))
3032 	fprintf (file, " resolved");
3033       fprintf (file, " local");
3034     }
3035   else
3036     {
3037       if (sym->sy_frag != &zero_address_frag)
3038 	{
3039 	  fprintf (file, " frag ");
3040 	  fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) sym->sy_frag));
3041 	}
3042       if (sym->sy_flags.sy_written)
3043 	fprintf (file, " written");
3044       if (sym->sy_flags.sy_resolved)
3045 	fprintf (file, " resolved");
3046       else if (sym->sy_flags.sy_resolving)
3047 	fprintf (file, " resolving");
3048       if (sym->sy_flags.sy_used_in_reloc)
3049 	fprintf (file, " used-in-reloc");
3050       if (sym->sy_flags.sy_used)
3051 	fprintf (file, " used");
3052       if (S_IS_LOCAL (sym))
3053 	fprintf (file, " local");
3054       if (S_IS_EXTERNAL (sym))
3055 	fprintf (file, " extern");
3056       if (S_IS_WEAK (sym))
3057 	fprintf (file, " weak");
3058       if (S_IS_DEBUG (sym))
3059 	fprintf (file, " debug");
3060       if (S_IS_DEFINED (sym))
3061 	fprintf (file, " defined");
3062     }
3063   if (S_IS_WEAKREFR (sym))
3064     fprintf (file, " weakrefr");
3065   if (S_IS_WEAKREFD (sym))
3066     fprintf (file, " weakrefd");
3067   fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
3068   if (symbol_resolved_p (sym))
3069     {
3070       segT s = S_GET_SEGMENT (sym);
3071 
3072       if (s != undefined_section
3073 	  && s != expr_section)
3074 	fprintf (file, " %lx", (unsigned long) S_GET_VALUE (sym));
3075     }
3076   else if (indent_level < max_indent_level
3077 	   && S_GET_SEGMENT (sym) != undefined_section)
3078     {
3079       indent_level++;
3080       fprintf (file, "\n%*s<", indent_level * 4, "");
3081       if (LOCAL_SYMBOL_CHECK (sym))
3082 	fprintf (file, "constant %lx",
3083 		 (unsigned long) ((struct local_symbol *) sym)->lsy_value);
3084       else
3085 	print_expr_1 (file, &sym->sy_value);
3086       fprintf (file, ">");
3087       indent_level--;
3088     }
3089   fflush (file);
3090 }
3091 
3092 void
3093 print_symbol_value (symbolS *sym)
3094 {
3095   indent_level = 0;
3096   print_symbol_value_1 (stderr, sym);
3097   fprintf (stderr, "\n");
3098 }
3099 
3100 static void
3101 print_binary (FILE *file, const char *name, expressionS *exp)
3102 {
3103   indent_level++;
3104   fprintf (file, "%s\n%*s<", name, indent_level * 4, "");
3105   print_symbol_value_1 (file, exp->X_add_symbol);
3106   fprintf (file, ">\n%*s<", indent_level * 4, "");
3107   print_symbol_value_1 (file, exp->X_op_symbol);
3108   fprintf (file, ">");
3109   indent_level--;
3110 }
3111 
3112 void
3113 print_expr_1 (FILE *file, expressionS *exp)
3114 {
3115   fprintf (file, "expr ");
3116   fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) exp));
3117   fprintf (file, " ");
3118   switch (exp->X_op)
3119     {
3120     case O_illegal:
3121       fprintf (file, "illegal");
3122       break;
3123     case O_absent:
3124       fprintf (file, "absent");
3125       break;
3126     case O_constant:
3127       fprintf (file, "constant %lx", (unsigned long) exp->X_add_number);
3128       break;
3129     case O_symbol:
3130       indent_level++;
3131       fprintf (file, "symbol\n%*s<", indent_level * 4, "");
3132       print_symbol_value_1 (file, exp->X_add_symbol);
3133       fprintf (file, ">");
3134     maybe_print_addnum:
3135       if (exp->X_add_number)
3136 	fprintf (file, "\n%*s%lx", indent_level * 4, "",
3137 		 (unsigned long) exp->X_add_number);
3138       indent_level--;
3139       break;
3140     case O_register:
3141       fprintf (file, "register #%d", (int) exp->X_add_number);
3142       break;
3143     case O_big:
3144       fprintf (file, "big");
3145       break;
3146     case O_uminus:
3147       fprintf (file, "uminus -<");
3148       indent_level++;
3149       print_symbol_value_1 (file, exp->X_add_symbol);
3150       fprintf (file, ">");
3151       goto maybe_print_addnum;
3152     case O_bit_not:
3153       fprintf (file, "bit_not");
3154       break;
3155     case O_multiply:
3156       print_binary (file, "multiply", exp);
3157       break;
3158     case O_divide:
3159       print_binary (file, "divide", exp);
3160       break;
3161     case O_modulus:
3162       print_binary (file, "modulus", exp);
3163       break;
3164     case O_left_shift:
3165       print_binary (file, "lshift", exp);
3166       break;
3167     case O_right_shift:
3168       print_binary (file, "rshift", exp);
3169       break;
3170     case O_bit_inclusive_or:
3171       print_binary (file, "bit_ior", exp);
3172       break;
3173     case O_bit_exclusive_or:
3174       print_binary (file, "bit_xor", exp);
3175       break;
3176     case O_bit_and:
3177       print_binary (file, "bit_and", exp);
3178       break;
3179     case O_eq:
3180       print_binary (file, "eq", exp);
3181       break;
3182     case O_ne:
3183       print_binary (file, "ne", exp);
3184       break;
3185     case O_lt:
3186       print_binary (file, "lt", exp);
3187       break;
3188     case O_le:
3189       print_binary (file, "le", exp);
3190       break;
3191     case O_ge:
3192       print_binary (file, "ge", exp);
3193       break;
3194     case O_gt:
3195       print_binary (file, "gt", exp);
3196       break;
3197     case O_logical_and:
3198       print_binary (file, "logical_and", exp);
3199       break;
3200     case O_logical_or:
3201       print_binary (file, "logical_or", exp);
3202       break;
3203     case O_add:
3204       indent_level++;
3205       fprintf (file, "add\n%*s<", indent_level * 4, "");
3206       print_symbol_value_1 (file, exp->X_add_symbol);
3207       fprintf (file, ">\n%*s<", indent_level * 4, "");
3208       print_symbol_value_1 (file, exp->X_op_symbol);
3209       fprintf (file, ">");
3210       goto maybe_print_addnum;
3211     case O_subtract:
3212       indent_level++;
3213       fprintf (file, "subtract\n%*s<", indent_level * 4, "");
3214       print_symbol_value_1 (file, exp->X_add_symbol);
3215       fprintf (file, ">\n%*s<", indent_level * 4, "");
3216       print_symbol_value_1 (file, exp->X_op_symbol);
3217       fprintf (file, ">");
3218       goto maybe_print_addnum;
3219     default:
3220       fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
3221       break;
3222     }
3223   fflush (stdout);
3224 }
3225 
3226 void
3227 print_expr (expressionS *exp)
3228 {
3229   print_expr_1 (stderr, exp);
3230   fprintf (stderr, "\n");
3231 }
3232 
3233 void
3234 symbol_print_statistics (FILE *file)
3235 {
3236   hash_print_statistics (file, "symbol table", sy_hash);
3237   hash_print_statistics (file, "mini local symbol table", local_hash);
3238   fprintf (file, "%lu mini local symbols created, %lu converted\n",
3239 	   local_symbol_count, local_symbol_conversion_count);
3240 }
3241 
3242 #ifdef OBJ_COMPLEX_RELC
3243 
3244 /* Convert given symbol to a new complex-relocation symbol name.  This
3245    may be a recursive function, since it might be called for non-leaf
3246    nodes (plain symbols) in the expression tree.  The caller owns the
3247    returning string, so should free it eventually.  Errors are
3248    indicated via as_bad and a NULL return value.  The given symbol
3249    is marked with sy_used_in_reloc.  */
3250 
3251 char *
3252 symbol_relc_make_sym (symbolS * sym)
3253 {
3254   char * terminal = NULL;
3255   const char * sname;
3256   char typetag;
3257   int sname_len;
3258 
3259   gas_assert (sym != NULL);
3260 
3261   /* Recurse to symbol_relc_make_expr if this symbol
3262      is defined as an expression or a plain value.  */
3263   if (   S_GET_SEGMENT (sym) == expr_section
3264       || S_GET_SEGMENT (sym) == absolute_section)
3265     return symbol_relc_make_expr (symbol_get_value_expression (sym));
3266 
3267   /* This may be a "fake symbol", referring to ".".
3268      Write out a special null symbol to refer to this position.  */
3269   if (! strcmp (S_GET_NAME (sym), FAKE_LABEL_NAME))
3270     return xstrdup (".");
3271 
3272   /* We hope this is a plain leaf symbol.  Construct the encoding
3273      as {S,s}II...:CCCCCCC....
3274      where 'S'/'s' means section symbol / plain symbol
3275      III is decimal for the symbol name length
3276      CCC is the symbol name itself.  */
3277   symbol_mark_used_in_reloc (sym);
3278 
3279   sname = S_GET_NAME (sym);
3280   sname_len = strlen (sname);
3281   typetag = symbol_section_p (sym) ? 'S' : 's';
3282 
3283   terminal = XNEWVEC (char, (1 /* S or s */
3284 			     + 8 /* sname_len in decimal */
3285 			     + 1 /* _ spacer */
3286 			     + sname_len /* name itself */
3287 			     + 1 /* \0 */ ));
3288 
3289   sprintf (terminal, "%c%d:%s", typetag, sname_len, sname);
3290   return terminal;
3291 }
3292 
3293 /* Convert given value to a new complex-relocation symbol name.  This
3294    is a non-recursive function, since it is be called for leaf nodes
3295    (plain values) in the expression tree.  The caller owns the
3296    returning string, so should free() it eventually.  No errors.  */
3297 
3298 char *
3299 symbol_relc_make_value (offsetT val)
3300 {
3301   char * terminal = XNEWVEC (char, 28);  /* Enough for long long.  */
3302 
3303   terminal[0] = '#';
3304   bfd_sprintf_vma (stdoutput, terminal + 1, val);
3305   return terminal;
3306 }
3307 
3308 /* Convert given expression to a new complex-relocation symbol name.
3309    This is a recursive function, since it traverses the entire given
3310    expression tree.  The caller owns the returning string, so should
3311    free() it eventually.  Errors are indicated via as_bad() and a NULL
3312    return value.  */
3313 
3314 char *
3315 symbol_relc_make_expr (expressionS * exp)
3316 {
3317   const char * opstr = NULL; /* Operator prefix string.  */
3318   int    arity = 0;    /* Arity of this operator.  */
3319   char * operands[3];  /* Up to three operands.  */
3320   char * concat_string = NULL;
3321 
3322   operands[0] = operands[1] = operands[2] = NULL;
3323 
3324   gas_assert (exp != NULL);
3325 
3326   /* Match known operators -> fill in opstr, arity, operands[] and fall
3327      through to construct subexpression fragments; may instead return
3328      string directly for leaf nodes.  */
3329 
3330   /* See expr.h for the meaning of all these enums.  Many operators
3331      have an unnatural arity (X_add_number implicitly added).  The
3332      conversion logic expands them to explicit "+" subexpressions.   */
3333 
3334   switch (exp->X_op)
3335     {
3336     default:
3337       as_bad ("Unknown expression operator (enum %d)", exp->X_op);
3338       break;
3339 
3340       /* Leaf nodes.  */
3341     case O_constant:
3342       return symbol_relc_make_value (exp->X_add_number);
3343 
3344     case O_symbol:
3345       if (exp->X_add_number)
3346 	{
3347 	  arity = 2;
3348 	  opstr = "+";
3349 	  operands[0] = symbol_relc_make_sym (exp->X_add_symbol);
3350 	  operands[1] = symbol_relc_make_value (exp->X_add_number);
3351 	  break;
3352 	}
3353       else
3354 	return symbol_relc_make_sym (exp->X_add_symbol);
3355 
3356       /* Helper macros for nesting nodes.  */
3357 
3358 #define HANDLE_XADD_OPT1(str_) 						\
3359       if (exp->X_add_number)						\
3360         {								\
3361           arity = 2;							\
3362           opstr = "+:" str_;						\
3363           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);	\
3364           operands[1] = symbol_relc_make_value (exp->X_add_number);	\
3365           break;							\
3366         }								\
3367       else								\
3368         {								\
3369           arity = 1;							\
3370           opstr = str_;							\
3371           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);	\
3372         }								\
3373       break
3374 
3375 #define HANDLE_XADD_OPT2(str_) 						\
3376       if (exp->X_add_number)						\
3377         {								\
3378           arity = 3;							\
3379           opstr = "+:" str_;						\
3380           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);	\
3381           operands[1] = symbol_relc_make_sym (exp->X_op_symbol);	\
3382           operands[2] = symbol_relc_make_value (exp->X_add_number);	\
3383         }								\
3384       else								\
3385         {								\
3386           arity = 2;							\
3387           opstr = str_;							\
3388           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);	\
3389           operands[1] = symbol_relc_make_sym (exp->X_op_symbol);	\
3390         } 								\
3391       break
3392 
3393       /* Nesting nodes.  */
3394 
3395     case O_uminus:       	HANDLE_XADD_OPT1 ("0-");
3396     case O_bit_not:      	HANDLE_XADD_OPT1 ("~");
3397     case O_logical_not:  	HANDLE_XADD_OPT1 ("!");
3398     case O_multiply:     	HANDLE_XADD_OPT2 ("*");
3399     case O_divide:       	HANDLE_XADD_OPT2 ("/");
3400     case O_modulus:      	HANDLE_XADD_OPT2 ("%");
3401     case O_left_shift:   	HANDLE_XADD_OPT2 ("<<");
3402     case O_right_shift:  	HANDLE_XADD_OPT2 (">>");
3403     case O_bit_inclusive_or:	HANDLE_XADD_OPT2 ("|");
3404     case O_bit_exclusive_or:	HANDLE_XADD_OPT2 ("^");
3405     case O_bit_and:      	HANDLE_XADD_OPT2 ("&");
3406     case O_add:          	HANDLE_XADD_OPT2 ("+");
3407     case O_subtract:     	HANDLE_XADD_OPT2 ("-");
3408     case O_eq:           	HANDLE_XADD_OPT2 ("==");
3409     case O_ne:           	HANDLE_XADD_OPT2 ("!=");
3410     case O_lt:           	HANDLE_XADD_OPT2 ("<");
3411     case O_le:           	HANDLE_XADD_OPT2 ("<=");
3412     case O_ge:           	HANDLE_XADD_OPT2 (">=");
3413     case O_gt:           	HANDLE_XADD_OPT2 (">");
3414     case O_logical_and:  	HANDLE_XADD_OPT2 ("&&");
3415     case O_logical_or:   	HANDLE_XADD_OPT2 ("||");
3416     }
3417 
3418   /* Validate & reject early.  */
3419   if (arity >= 1 && ((operands[0] == NULL) || (strlen (operands[0]) == 0)))
3420     opstr = NULL;
3421   if (arity >= 2 && ((operands[1] == NULL) || (strlen (operands[1]) == 0)))
3422     opstr = NULL;
3423   if (arity >= 3 && ((operands[2] == NULL) || (strlen (operands[2]) == 0)))
3424     opstr = NULL;
3425 
3426   if (opstr == NULL)
3427     concat_string = NULL;
3428   else if (arity == 0)
3429     concat_string = xstrdup (opstr);
3430   else if (arity == 1)
3431     concat_string = concat (opstr, ":", operands[0], (char *) NULL);
3432   else if (arity == 2)
3433     concat_string = concat (opstr, ":", operands[0], ":", operands[1],
3434 			    (char *) NULL);
3435   else
3436     concat_string = concat (opstr, ":", operands[0], ":", operands[1], ":",
3437 			    operands[2], (char *) NULL);
3438 
3439   /* Free operand strings (not opstr).  */
3440   if (arity >= 1) xfree (operands[0]);
3441   if (arity >= 2) xfree (operands[1]);
3442   if (arity >= 3) xfree (operands[2]);
3443 
3444   return concat_string;
3445 }
3446 
3447 #endif
3448