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