Home | History | Annotate | Download | only in gas
      1 /* symbols.c -symbol table-
      2    Copyright (C) 1987-2014 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 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 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   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   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 #ifdef tc_canonicalize_symbol_name
    751   {
    752     char *copy;
    753     size_t len = strlen (name) + 1;
    754 
    755     copy = (char *) alloca (len);
    756     memcpy (copy, name, len);
    757     name = tc_canonicalize_symbol_name (copy);
    758   }
    759 #endif
    760 
    761   if (! symbols_case_sensitive)
    762     {
    763       char *copy;
    764       const char *orig;
    765       unsigned char c;
    766 
    767       orig = name;
    768       name = copy = (char *) alloca (strlen (name) + 1);
    769 
    770       while ((c = *orig++) != '\0')
    771 	{
    772 	  *copy++ = TOUPPER (c);
    773 	}
    774       *copy = '\0';
    775     }
    776 
    777   return symbol_find_exact_noref (name, noref);
    778 }
    779 
    780 /* Once upon a time, symbols were kept in a singly linked list.  At
    781    least coff needs to be able to rearrange them from time to time, for
    782    which a doubly linked list is much more convenient.  Loic did these
    783    as macros which seemed dangerous to me so they're now functions.
    784    xoxorich.  */
    785 
    786 /* Link symbol ADDME after symbol TARGET in the chain.  */
    787 
    788 void
    789 symbol_append (symbolS *addme, symbolS *target,
    790 	       symbolS **rootPP, symbolS **lastPP)
    791 {
    792   if (LOCAL_SYMBOL_CHECK (addme))
    793     abort ();
    794   if (target != NULL && LOCAL_SYMBOL_CHECK (target))
    795     abort ();
    796 
    797   if (target == NULL)
    798     {
    799       know (*rootPP == NULL);
    800       know (*lastPP == NULL);
    801       addme->sy_next = NULL;
    802       addme->sy_previous = NULL;
    803       *rootPP = addme;
    804       *lastPP = addme;
    805       return;
    806     }				/* if the list is empty  */
    807 
    808   if (target->sy_next != NULL)
    809     {
    810       target->sy_next->sy_previous = addme;
    811     }
    812   else
    813     {
    814       know (*lastPP == target);
    815       *lastPP = addme;
    816     }				/* if we have a next  */
    817 
    818   addme->sy_next = target->sy_next;
    819   target->sy_next = addme;
    820   addme->sy_previous = target;
    821 
    822   debug_verify_symchain (symbol_rootP, symbol_lastP);
    823 }
    824 
    825 /* Set the chain pointers of SYMBOL to null.  */
    826 
    827 void
    828 symbol_clear_list_pointers (symbolS *symbolP)
    829 {
    830   if (LOCAL_SYMBOL_CHECK (symbolP))
    831     abort ();
    832   symbolP->sy_next = NULL;
    833   symbolP->sy_previous = NULL;
    834 }
    835 
    836 /* Remove SYMBOLP from the list.  */
    837 
    838 void
    839 symbol_remove (symbolS *symbolP, symbolS **rootPP, symbolS **lastPP)
    840 {
    841   if (LOCAL_SYMBOL_CHECK (symbolP))
    842     abort ();
    843 
    844   if (symbolP == *rootPP)
    845     {
    846       *rootPP = symbolP->sy_next;
    847     }				/* if it was the root  */
    848 
    849   if (symbolP == *lastPP)
    850     {
    851       *lastPP = symbolP->sy_previous;
    852     }				/* if it was the tail  */
    853 
    854   if (symbolP->sy_next != NULL)
    855     {
    856       symbolP->sy_next->sy_previous = symbolP->sy_previous;
    857     }				/* if not last  */
    858 
    859   if (symbolP->sy_previous != NULL)
    860     {
    861       symbolP->sy_previous->sy_next = symbolP->sy_next;
    862     }				/* if not first  */
    863 
    864   debug_verify_symchain (*rootPP, *lastPP);
    865 }
    866 
    867 /* Link symbol ADDME before symbol TARGET in the chain.  */
    868 
    869 void
    870 symbol_insert (symbolS *addme, symbolS *target,
    871 	       symbolS **rootPP, symbolS **lastPP ATTRIBUTE_UNUSED)
    872 {
    873   if (LOCAL_SYMBOL_CHECK (addme))
    874     abort ();
    875   if (LOCAL_SYMBOL_CHECK (target))
    876     abort ();
    877 
    878   if (target->sy_previous != NULL)
    879     {
    880       target->sy_previous->sy_next = addme;
    881     }
    882   else
    883     {
    884       know (*rootPP == target);
    885       *rootPP = addme;
    886     }				/* if not first  */
    887 
    888   addme->sy_previous = target->sy_previous;
    889   target->sy_previous = addme;
    890   addme->sy_next = target;
    891 
    892   debug_verify_symchain (*rootPP, *lastPP);
    893 }
    894 
    895 void
    896 verify_symbol_chain (symbolS *rootP, symbolS *lastP)
    897 {
    898   symbolS *symbolP = rootP;
    899 
    900   if (symbolP == NULL)
    901     return;
    902 
    903   for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
    904     {
    905       gas_assert (symbolP->bsym != NULL);
    906       gas_assert (symbolP->sy_flags.sy_local_symbol == 0);
    907       gas_assert (symbolP->sy_next->sy_previous == symbolP);
    908     }
    909 
    910   gas_assert (lastP == symbolP);
    911 }
    912 
    913 #ifdef OBJ_COMPLEX_RELC
    914 
    915 static int
    916 use_complex_relocs_for (symbolS * symp)
    917 {
    918   switch (symp->sy_value.X_op)
    919     {
    920     case O_constant:
    921       return 0;
    922 
    923     case O_symbol:
    924     case O_symbol_rva:
    925     case O_uminus:
    926     case O_bit_not:
    927     case O_logical_not:
    928       if (  (S_IS_COMMON (symp->sy_value.X_add_symbol)
    929 	   || S_IS_LOCAL (symp->sy_value.X_add_symbol))
    930 	  &&
    931 	      (S_IS_DEFINED (symp->sy_value.X_add_symbol)
    932 	   && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section))
    933 	return 0;
    934       break;
    935 
    936     case O_multiply:
    937     case O_divide:
    938     case O_modulus:
    939     case O_left_shift:
    940     case O_right_shift:
    941     case O_bit_inclusive_or:
    942     case O_bit_or_not:
    943     case O_bit_exclusive_or:
    944     case O_bit_and:
    945     case O_add:
    946     case O_subtract:
    947     case O_eq:
    948     case O_ne:
    949     case O_lt:
    950     case O_le:
    951     case O_ge:
    952     case O_gt:
    953     case O_logical_and:
    954     case O_logical_or:
    955 
    956       if (  (S_IS_COMMON (symp->sy_value.X_add_symbol)
    957 	   || S_IS_LOCAL (symp->sy_value.X_add_symbol))
    958 	  &&
    959 	    (S_IS_COMMON (symp->sy_value.X_op_symbol)
    960 	   || S_IS_LOCAL (symp->sy_value.X_op_symbol))
    961 
    962 	  && S_IS_DEFINED (symp->sy_value.X_add_symbol)
    963 	  && S_IS_DEFINED (symp->sy_value.X_op_symbol)
    964 	  && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section
    965 	  && S_GET_SEGMENT (symp->sy_value.X_op_symbol) != expr_section)
    966 	return 0;
    967       break;
    968 
    969     default:
    970       break;
    971     }
    972   return 1;
    973 }
    974 #endif
    975 
    976 static void
    977 report_op_error (symbolS *symp, symbolS *left, operatorT op, symbolS *right)
    978 {
    979   char *file;
    980   unsigned int line;
    981   segT seg_left = left ? S_GET_SEGMENT (left) : 0;
    982   segT seg_right = S_GET_SEGMENT (right);
    983   const char *opname;
    984 
    985   switch (op)
    986     {
    987     default:
    988       abort ();
    989       return;
    990 
    991     case O_uminus:		opname = "-"; break;
    992     case O_bit_not:		opname = "~"; break;
    993     case O_logical_not:		opname = "!"; break;
    994     case O_multiply:		opname = "*"; break;
    995     case O_divide:		opname = "/"; break;
    996     case O_modulus:		opname = "%"; break;
    997     case O_left_shift:		opname = "<<"; break;
    998     case O_right_shift:		opname = ">>"; break;
    999     case O_bit_inclusive_or:	opname = "|"; break;
   1000     case O_bit_or_not:		opname = "|~"; break;
   1001     case O_bit_exclusive_or:	opname = "^"; break;
   1002     case O_bit_and:		opname = "&"; break;
   1003     case O_add:			opname = "+"; break;
   1004     case O_subtract:		opname = "-"; break;
   1005     case O_eq:			opname = "=="; break;
   1006     case O_ne:			opname = "!="; break;
   1007     case O_lt:			opname = "<"; break;
   1008     case O_le:			opname = "<="; break;
   1009     case O_ge:			opname = ">="; break;
   1010     case O_gt:			opname = ">"; break;
   1011     case O_logical_and:		opname = "&&"; break;
   1012     case O_logical_or:		opname = "||"; break;
   1013     }
   1014 
   1015   if (expr_symbol_where (symp, &file, &line))
   1016     {
   1017       if (left)
   1018 	as_bad_where (file, line,
   1019 		      _("invalid operands (%s and %s sections) for `%s'"),
   1020 		      seg_left->name, seg_right->name, opname);
   1021       else
   1022 	as_bad_where (file, line,
   1023 		      _("invalid operand (%s section) for `%s'"),
   1024 		      seg_right->name, opname);
   1025     }
   1026   else
   1027     {
   1028       const char *sname = S_GET_NAME (symp);
   1029 
   1030       if (left)
   1031 	as_bad (_("invalid operands (%s and %s sections) for `%s' when setting `%s'"),
   1032 		seg_left->name, seg_right->name, opname, sname);
   1033       else
   1034 	as_bad (_("invalid operand (%s section) for `%s' when setting `%s'"),
   1035 		seg_right->name, opname, sname);
   1036     }
   1037 }
   1038 
   1039 /* Resolve the value of a symbol.  This is called during the final
   1040    pass over the symbol table to resolve any symbols with complex
   1041    values.  */
   1042 
   1043 valueT
   1044 resolve_symbol_value (symbolS *symp)
   1045 {
   1046   int resolved;
   1047   valueT final_val = 0;
   1048   segT final_seg;
   1049 
   1050   if (LOCAL_SYMBOL_CHECK (symp))
   1051     {
   1052       struct local_symbol *locsym = (struct local_symbol *) symp;
   1053 
   1054       final_val = locsym->lsy_value;
   1055       if (local_symbol_resolved_p (locsym))
   1056 	return final_val;
   1057 
   1058       final_val += local_symbol_get_frag (locsym)->fr_address / OCTETS_PER_BYTE;
   1059 
   1060       if (finalize_syms)
   1061 	{
   1062 	  locsym->lsy_value = final_val;
   1063 	  local_symbol_mark_resolved (locsym);
   1064 	}
   1065 
   1066       return final_val;
   1067     }
   1068 
   1069   if (symp->sy_flags.sy_resolved)
   1070     {
   1071       if (symp->sy_value.X_op == O_constant)
   1072 	return (valueT) symp->sy_value.X_add_number;
   1073       else
   1074 	return 0;
   1075     }
   1076 
   1077   resolved = 0;
   1078   final_seg = S_GET_SEGMENT (symp);
   1079 
   1080   if (symp->sy_flags.sy_resolving)
   1081     {
   1082       if (finalize_syms)
   1083 	as_bad (_("symbol definition loop encountered at `%s'"),
   1084 		S_GET_NAME (symp));
   1085       final_val = 0;
   1086       resolved = 1;
   1087     }
   1088 #ifdef OBJ_COMPLEX_RELC
   1089   else if (final_seg == expr_section
   1090 	   && use_complex_relocs_for (symp))
   1091     {
   1092       symbolS * relc_symbol = NULL;
   1093       char * relc_symbol_name = NULL;
   1094 
   1095       relc_symbol_name = symbol_relc_make_expr (& symp->sy_value);
   1096 
   1097       /* For debugging, print out conversion input & output.  */
   1098 #ifdef DEBUG_SYMS
   1099       print_expr (& symp->sy_value);
   1100       if (relc_symbol_name)
   1101 	fprintf (stderr, "-> relc symbol: %s\n", relc_symbol_name);
   1102 #endif
   1103 
   1104       if (relc_symbol_name != NULL)
   1105 	relc_symbol = symbol_new (relc_symbol_name, undefined_section,
   1106 				  0, & zero_address_frag);
   1107 
   1108       if (relc_symbol == NULL)
   1109 	{
   1110 	  as_bad (_("cannot convert expression symbol %s to complex relocation"),
   1111 		  S_GET_NAME (symp));
   1112 	  resolved = 0;
   1113 	}
   1114       else
   1115 	{
   1116 	  symbol_table_insert (relc_symbol);
   1117 
   1118  	  /* S_CLEAR_EXTERNAL (relc_symbol); */
   1119 	  if (symp->bsym->flags & BSF_SRELC)
   1120 	    relc_symbol->bsym->flags |= BSF_SRELC;
   1121 	  else
   1122 	    relc_symbol->bsym->flags |= BSF_RELC;
   1123 	  /* symp->bsym->flags |= BSF_RELC; */
   1124 	  copy_symbol_attributes (symp, relc_symbol);
   1125 	  symp->sy_value.X_op = O_symbol;
   1126 	  symp->sy_value.X_add_symbol = relc_symbol;
   1127 	  symp->sy_value.X_add_number = 0;
   1128 	  resolved = 1;
   1129 	}
   1130 
   1131       final_seg = undefined_section;
   1132       goto exit_dont_set_value;
   1133     }
   1134 #endif
   1135   else
   1136     {
   1137       symbolS *add_symbol, *op_symbol;
   1138       offsetT left, right;
   1139       segT seg_left, seg_right;
   1140       operatorT op;
   1141       int move_seg_ok;
   1142 
   1143       symp->sy_flags.sy_resolving = 1;
   1144 
   1145       /* Help out with CSE.  */
   1146       add_symbol = symp->sy_value.X_add_symbol;
   1147       op_symbol = symp->sy_value.X_op_symbol;
   1148       final_val = symp->sy_value.X_add_number;
   1149       op = symp->sy_value.X_op;
   1150 
   1151       switch (op)
   1152 	{
   1153 	default:
   1154 	  BAD_CASE (op);
   1155 	  break;
   1156 
   1157 	case O_absent:
   1158 	  final_val = 0;
   1159 	  /* Fall through.  */
   1160 
   1161 	case O_constant:
   1162 	  final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE;
   1163 	  if (final_seg == expr_section)
   1164 	    final_seg = absolute_section;
   1165 	  /* Fall through.  */
   1166 
   1167 	case O_register:
   1168 	  resolved = 1;
   1169 	  break;
   1170 
   1171 	case O_symbol:
   1172 	case O_symbol_rva:
   1173 	  left = resolve_symbol_value (add_symbol);
   1174 	  seg_left = S_GET_SEGMENT (add_symbol);
   1175 	  if (finalize_syms)
   1176 	    symp->sy_value.X_op_symbol = NULL;
   1177 
   1178 	do_symbol:
   1179 	  if (S_IS_WEAKREFR (symp))
   1180 	    {
   1181 	      gas_assert (final_val == 0);
   1182 	      if (S_IS_WEAKREFR (add_symbol))
   1183 		{
   1184 		  gas_assert (add_symbol->sy_value.X_op == O_symbol
   1185 			  && add_symbol->sy_value.X_add_number == 0);
   1186 		  add_symbol = add_symbol->sy_value.X_add_symbol;
   1187 		  gas_assert (! S_IS_WEAKREFR (add_symbol));
   1188 		  symp->sy_value.X_add_symbol = add_symbol;
   1189 		}
   1190 	    }
   1191 
   1192 	  if (symp->sy_flags.sy_mri_common)
   1193 	    {
   1194 	      /* This is a symbol inside an MRI common section.  The
   1195 		 relocation routines are going to handle it specially.
   1196 		 Don't change the value.  */
   1197 	      resolved = symbol_resolved_p (add_symbol);
   1198 	      break;
   1199 	    }
   1200 
   1201 	  if (finalize_syms && final_val == 0)
   1202 	    {
   1203 	      if (LOCAL_SYMBOL_CHECK (add_symbol))
   1204 		add_symbol = local_symbol_convert ((struct local_symbol *)
   1205 						   add_symbol);
   1206 	      copy_symbol_attributes (symp, add_symbol);
   1207 	    }
   1208 
   1209 	  /* If we have equated this symbol to an undefined or common
   1210 	     symbol, keep X_op set to O_symbol, and don't change
   1211 	     X_add_number.  This permits the routine which writes out
   1212 	     relocation to detect this case, and convert the
   1213 	     relocation to be against the symbol to which this symbol
   1214 	     is equated.  */
   1215 	  if (! S_IS_DEFINED (add_symbol)
   1216 #if defined (OBJ_COFF) && defined (TE_PE)
   1217 	      || S_IS_WEAK (add_symbol)
   1218 #endif
   1219 	      || S_IS_COMMON (add_symbol))
   1220 	    {
   1221 	      if (finalize_syms)
   1222 		{
   1223 		  symp->sy_value.X_op = O_symbol;
   1224 		  symp->sy_value.X_add_symbol = add_symbol;
   1225 		  symp->sy_value.X_add_number = final_val;
   1226 		  /* Use X_op_symbol as a flag.  */
   1227 		  symp->sy_value.X_op_symbol = add_symbol;
   1228 		}
   1229 	      final_seg = seg_left;
   1230 	      final_val = 0;
   1231 	      resolved = symbol_resolved_p (add_symbol);
   1232 	      symp->sy_flags.sy_resolving = 0;
   1233 	      goto exit_dont_set_value;
   1234 	    }
   1235 	  else if (finalize_syms
   1236 		   && ((final_seg == expr_section && seg_left != expr_section)
   1237 		       || symbol_shadow_p (symp)))
   1238 	    {
   1239 	      /* If the symbol is an expression symbol, do similarly
   1240 		 as for undefined and common syms above.  Handles
   1241 		 "sym +/- expr" where "expr" cannot be evaluated
   1242 		 immediately, and we want relocations to be against
   1243 		 "sym", eg. because it is weak.  */
   1244 	      symp->sy_value.X_op = O_symbol;
   1245 	      symp->sy_value.X_add_symbol = add_symbol;
   1246 	      symp->sy_value.X_add_number = final_val;
   1247 	      symp->sy_value.X_op_symbol = add_symbol;
   1248 	      final_seg = seg_left;
   1249 	      final_val += symp->sy_frag->fr_address + left;
   1250 	      resolved = symbol_resolved_p (add_symbol);
   1251 	      symp->sy_flags.sy_resolving = 0;
   1252 	      goto exit_dont_set_value;
   1253 	    }
   1254 	  else
   1255 	    {
   1256 	      final_val += symp->sy_frag->fr_address + left;
   1257 	      if (final_seg == expr_section || final_seg == undefined_section)
   1258 		final_seg = seg_left;
   1259 	    }
   1260 
   1261 	  resolved = symbol_resolved_p (add_symbol);
   1262 	  if (S_IS_WEAKREFR (symp))
   1263 	    goto exit_dont_set_value;
   1264 	  break;
   1265 
   1266 	case O_uminus:
   1267 	case O_bit_not:
   1268 	case O_logical_not:
   1269 	  left = resolve_symbol_value (add_symbol);
   1270 	  seg_left = S_GET_SEGMENT (add_symbol);
   1271 
   1272 	  /* By reducing these to the relevant dyadic operator, we get
   1273 	     	!S -> S == 0 	permitted on anything,
   1274 		-S -> 0 - S 	only permitted on absolute
   1275 		~S -> S ^ ~0 	only permitted on absolute  */
   1276 	  if (op != O_logical_not && seg_left != absolute_section
   1277 	      && finalize_syms)
   1278 	    report_op_error (symp, NULL, op, add_symbol);
   1279 
   1280 	  if (final_seg == expr_section || final_seg == undefined_section)
   1281 	    final_seg = absolute_section;
   1282 
   1283 	  if (op == O_uminus)
   1284 	    left = -left;
   1285 	  else if (op == O_logical_not)
   1286 	    left = !left;
   1287 	  else
   1288 	    left = ~left;
   1289 
   1290 	  final_val += left + symp->sy_frag->fr_address;
   1291 
   1292 	  resolved = symbol_resolved_p (add_symbol);
   1293 	  break;
   1294 
   1295 	case O_multiply:
   1296 	case O_divide:
   1297 	case O_modulus:
   1298 	case O_left_shift:
   1299 	case O_right_shift:
   1300 	case O_bit_inclusive_or:
   1301 	case O_bit_or_not:
   1302 	case O_bit_exclusive_or:
   1303 	case O_bit_and:
   1304 	case O_add:
   1305 	case O_subtract:
   1306 	case O_eq:
   1307 	case O_ne:
   1308 	case O_lt:
   1309 	case O_le:
   1310 	case O_ge:
   1311 	case O_gt:
   1312 	case O_logical_and:
   1313 	case O_logical_or:
   1314 	  left = resolve_symbol_value (add_symbol);
   1315 	  right = resolve_symbol_value (op_symbol);
   1316 	  seg_left = S_GET_SEGMENT (add_symbol);
   1317 	  seg_right = S_GET_SEGMENT (op_symbol);
   1318 
   1319 	  /* Simplify addition or subtraction of a constant by folding the
   1320 	     constant into X_add_number.  */
   1321 	  if (op == O_add)
   1322 	    {
   1323 	      if (seg_right == absolute_section)
   1324 		{
   1325 		  final_val += right;
   1326 		  goto do_symbol;
   1327 		}
   1328 	      else if (seg_left == absolute_section)
   1329 		{
   1330 		  final_val += left;
   1331 		  add_symbol = op_symbol;
   1332 		  left = right;
   1333 		  seg_left = seg_right;
   1334 		  goto do_symbol;
   1335 		}
   1336 	    }
   1337 	  else if (op == O_subtract)
   1338 	    {
   1339 	      if (seg_right == absolute_section)
   1340 		{
   1341 		  final_val -= right;
   1342 		  goto do_symbol;
   1343 		}
   1344 	    }
   1345 
   1346 	  move_seg_ok = 1;
   1347 	  /* Equality and non-equality tests are permitted on anything.
   1348 	     Subtraction, and other comparison operators are permitted if
   1349 	     both operands are in the same section.  Otherwise, both
   1350 	     operands must be absolute.  We already handled the case of
   1351 	     addition or subtraction of a constant above.  This will
   1352 	     probably need to be changed for an object file format which
   1353 	     supports arbitrary expressions, such as IEEE-695.  */
   1354 	  if (!(seg_left == absolute_section
   1355 		&& seg_right == absolute_section)
   1356 	      && !(op == O_eq || op == O_ne)
   1357 	      && !((op == O_subtract
   1358 		    || op == O_lt || op == O_le || op == O_ge || op == O_gt)
   1359 		   && seg_left == seg_right
   1360 		   && (seg_left != undefined_section
   1361 		       || add_symbol == op_symbol)))
   1362 	    {
   1363 	      /* Don't emit messages unless we're finalizing the symbol value,
   1364 		 otherwise we may get the same message multiple times.  */
   1365 	      if (finalize_syms)
   1366 		report_op_error (symp, add_symbol, op, op_symbol);
   1367 	      /* However do not move the symbol into the absolute section
   1368 		 if it cannot currently be resolved - this would confuse
   1369 		 other parts of the assembler into believing that the
   1370 		 expression had been evaluated to zero.  */
   1371 	      else
   1372 		move_seg_ok = 0;
   1373 	    }
   1374 
   1375 	  if (move_seg_ok
   1376 	      && (final_seg == expr_section || final_seg == undefined_section))
   1377 	    final_seg = absolute_section;
   1378 
   1379 	  /* Check for division by zero.  */
   1380 	  if ((op == O_divide || op == O_modulus) && right == 0)
   1381 	    {
   1382 	      /* If seg_right is not absolute_section, then we've
   1383 		 already issued a warning about using a bad symbol.  */
   1384 	      if (seg_right == absolute_section && finalize_syms)
   1385 		{
   1386 		  char *file;
   1387 		  unsigned int line;
   1388 
   1389 		  if (expr_symbol_where (symp, &file, &line))
   1390 		    as_bad_where (file, line, _("division by zero"));
   1391 		  else
   1392 		    as_bad (_("division by zero when setting `%s'"),
   1393 			    S_GET_NAME (symp));
   1394 		}
   1395 
   1396 	      right = 1;
   1397 	    }
   1398 
   1399 	  switch (symp->sy_value.X_op)
   1400 	    {
   1401 	    case O_multiply:		left *= right; break;
   1402 	    case O_divide:		left /= right; break;
   1403 	    case O_modulus:		left %= right; break;
   1404 	    case O_left_shift:		left <<= right; break;
   1405 	    case O_right_shift:		left >>= right; break;
   1406 	    case O_bit_inclusive_or:	left |= right; break;
   1407 	    case O_bit_or_not:		left |= ~right; break;
   1408 	    case O_bit_exclusive_or:	left ^= right; break;
   1409 	    case O_bit_and:		left &= right; break;
   1410 	    case O_add:			left += right; break;
   1411 	    case O_subtract:		left -= right; break;
   1412 	    case O_eq:
   1413 	    case O_ne:
   1414 	      left = (left == right && seg_left == seg_right
   1415 		      && (seg_left != undefined_section
   1416 			  || add_symbol == op_symbol)
   1417 		      ? ~ (offsetT) 0 : 0);
   1418 	      if (symp->sy_value.X_op == O_ne)
   1419 		left = ~left;
   1420 	      break;
   1421 	    case O_lt:	left = left <  right ? ~ (offsetT) 0 : 0; break;
   1422 	    case O_le:	left = left <= right ? ~ (offsetT) 0 : 0; break;
   1423 	    case O_ge:	left = left >= right ? ~ (offsetT) 0 : 0; break;
   1424 	    case O_gt:	left = left >  right ? ~ (offsetT) 0 : 0; break;
   1425 	    case O_logical_and:	left = left && right; break;
   1426 	    case O_logical_or:	left = left || right; break;
   1427 	    default:		abort ();
   1428 	    }
   1429 
   1430 	  final_val += symp->sy_frag->fr_address + left;
   1431 	  if (final_seg == expr_section || final_seg == undefined_section)
   1432 	    {
   1433 	      if (seg_left == undefined_section
   1434 		  || seg_right == undefined_section)
   1435 		final_seg = undefined_section;
   1436 	      else if (seg_left == absolute_section)
   1437 		final_seg = seg_right;
   1438 	      else
   1439 		final_seg = seg_left;
   1440 	    }
   1441 	  resolved = (symbol_resolved_p (add_symbol)
   1442 		      && symbol_resolved_p (op_symbol));
   1443 	  break;
   1444 
   1445 	case O_big:
   1446 	case O_illegal:
   1447 	  /* Give an error (below) if not in expr_section.  We don't
   1448 	     want to worry about expr_section symbols, because they
   1449 	     are fictional (they are created as part of expression
   1450 	     resolution), and any problems may not actually mean
   1451 	     anything.  */
   1452 	  break;
   1453 	}
   1454 
   1455       symp->sy_flags.sy_resolving = 0;
   1456     }
   1457 
   1458   if (finalize_syms)
   1459     S_SET_VALUE (symp, final_val);
   1460 
   1461 exit_dont_set_value:
   1462   /* Always set the segment, even if not finalizing the value.
   1463      The segment is used to determine whether a symbol is defined.  */
   1464     S_SET_SEGMENT (symp, final_seg);
   1465 
   1466   /* Don't worry if we can't resolve an expr_section symbol.  */
   1467   if (finalize_syms)
   1468     {
   1469       if (resolved)
   1470 	symp->sy_flags.sy_resolved = 1;
   1471       else if (S_GET_SEGMENT (symp) != expr_section)
   1472 	{
   1473 	  as_bad (_("can't resolve value for symbol `%s'"),
   1474 		  S_GET_NAME (symp));
   1475 	  symp->sy_flags.sy_resolved = 1;
   1476 	}
   1477     }
   1478 
   1479   return final_val;
   1480 }
   1481 
   1482 static void resolve_local_symbol (const char *, void *);
   1483 
   1484 /* A static function passed to hash_traverse.  */
   1485 
   1486 static void
   1487 resolve_local_symbol (const char *key ATTRIBUTE_UNUSED, void *value)
   1488 {
   1489   if (value != NULL)
   1490     resolve_symbol_value ((symbolS *) value);
   1491 }
   1492 
   1493 /* Resolve all local symbols.  */
   1494 
   1495 void
   1496 resolve_local_symbol_values (void)
   1497 {
   1498   hash_traverse (local_hash, resolve_local_symbol);
   1499 }
   1500 
   1501 /* Obtain the current value of a symbol without changing any
   1502    sub-expressions used.  */
   1503 
   1504 int
   1505 snapshot_symbol (symbolS **symbolPP, valueT *valueP, segT *segP, fragS **fragPP)
   1506 {
   1507   symbolS *symbolP = *symbolPP;
   1508 
   1509   if (LOCAL_SYMBOL_CHECK (symbolP))
   1510     {
   1511       struct local_symbol *locsym = (struct local_symbol *) symbolP;
   1512 
   1513       *valueP = locsym->lsy_value;
   1514       *segP = locsym->lsy_section;
   1515       *fragPP = local_symbol_get_frag (locsym);
   1516     }
   1517   else
   1518     {
   1519       expressionS exp = symbolP->sy_value;
   1520 
   1521       if (!symbolP->sy_flags.sy_resolved && exp.X_op != O_illegal)
   1522 	{
   1523 	  int resolved;
   1524 
   1525 	  if (symbolP->sy_flags.sy_resolving)
   1526 	    return 0;
   1527 	  symbolP->sy_flags.sy_resolving = 1;
   1528 	  resolved = resolve_expression (&exp);
   1529 	  symbolP->sy_flags.sy_resolving = 0;
   1530 	  if (!resolved)
   1531 	    return 0;
   1532 
   1533 	  switch (exp.X_op)
   1534 	    {
   1535 	    case O_constant:
   1536 	    case O_register:
   1537 	      if (!symbol_equated_p (symbolP))
   1538 		break;
   1539 	      /* Fall thru.  */
   1540 	    case O_symbol:
   1541 	    case O_symbol_rva:
   1542 	      symbolP = exp.X_add_symbol;
   1543 	      break;
   1544 	    default:
   1545 	      return 0;
   1546 	    }
   1547 	}
   1548 
   1549       *symbolPP = symbolP;
   1550       *valueP = exp.X_add_number;
   1551       *segP = symbolP->bsym->section;
   1552       *fragPP = symbolP->sy_frag;
   1553 
   1554       if (*segP == expr_section)
   1555 	switch (exp.X_op)
   1556 	  {
   1557 	  case O_constant: *segP = absolute_section; break;
   1558 	  case O_register: *segP = reg_section; break;
   1559 	  default: break;
   1560 	  }
   1561     }
   1562 
   1563   return 1;
   1564 }
   1565 
   1566 /* Dollar labels look like a number followed by a dollar sign.  Eg, "42$".
   1567    They are *really* local.  That is, they go out of scope whenever we see a
   1568    label that isn't local.  Also, like fb labels, there can be multiple
   1569    instances of a dollar label.  Therefor, we name encode each instance with
   1570    the instance number, keep a list of defined symbols separate from the real
   1571    symbol table, and we treat these buggers as a sparse array.  */
   1572 
   1573 static long *dollar_labels;
   1574 static long *dollar_label_instances;
   1575 static char *dollar_label_defines;
   1576 static unsigned long dollar_label_count;
   1577 static unsigned long dollar_label_max;
   1578 
   1579 int
   1580 dollar_label_defined (long label)
   1581 {
   1582   long *i;
   1583 
   1584   know ((dollar_labels != NULL) || (dollar_label_count == 0));
   1585 
   1586   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
   1587     if (*i == label)
   1588       return dollar_label_defines[i - dollar_labels];
   1589 
   1590   /* If we get here, label isn't defined.  */
   1591   return 0;
   1592 }
   1593 
   1594 static long
   1595 dollar_label_instance (long label)
   1596 {
   1597   long *i;
   1598 
   1599   know ((dollar_labels != NULL) || (dollar_label_count == 0));
   1600 
   1601   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
   1602     if (*i == label)
   1603       return (dollar_label_instances[i - dollar_labels]);
   1604 
   1605   /* If we get here, we haven't seen the label before.
   1606      Therefore its instance count is zero.  */
   1607   return 0;
   1608 }
   1609 
   1610 void
   1611 dollar_label_clear (void)
   1612 {
   1613   memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
   1614 }
   1615 
   1616 #define DOLLAR_LABEL_BUMP_BY 10
   1617 
   1618 void
   1619 define_dollar_label (long label)
   1620 {
   1621   long *i;
   1622 
   1623   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
   1624     if (*i == label)
   1625       {
   1626 	++dollar_label_instances[i - dollar_labels];
   1627 	dollar_label_defines[i - dollar_labels] = 1;
   1628 	return;
   1629       }
   1630 
   1631   /* If we get to here, we don't have label listed yet.  */
   1632 
   1633   if (dollar_labels == NULL)
   1634     {
   1635       dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
   1636       dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
   1637       dollar_label_defines = (char *) xmalloc (DOLLAR_LABEL_BUMP_BY);
   1638       dollar_label_max = DOLLAR_LABEL_BUMP_BY;
   1639       dollar_label_count = 0;
   1640     }
   1641   else if (dollar_label_count == dollar_label_max)
   1642     {
   1643       dollar_label_max += DOLLAR_LABEL_BUMP_BY;
   1644       dollar_labels = (long *) xrealloc ((char *) dollar_labels,
   1645 					 dollar_label_max * sizeof (long));
   1646       dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
   1647 					  dollar_label_max * sizeof (long));
   1648       dollar_label_defines = (char *) xrealloc (dollar_label_defines, dollar_label_max);
   1649     }				/* if we needed to grow  */
   1650 
   1651   dollar_labels[dollar_label_count] = label;
   1652   dollar_label_instances[dollar_label_count] = 1;
   1653   dollar_label_defines[dollar_label_count] = 1;
   1654   ++dollar_label_count;
   1655 }
   1656 
   1657 /* Caller must copy returned name: we re-use the area for the next name.
   1658 
   1659    The mth occurence of label n: is turned into the symbol "Ln^Am"
   1660    where n is the label number and m is the instance number. "L" makes
   1661    it a label discarded unless debugging and "^A"('\1') ensures no
   1662    ordinary symbol SHOULD get the same name as a local label
   1663    symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
   1664 
   1665    fb labels get the same treatment, except that ^B is used in place
   1666    of ^A.  */
   1667 
   1668 char *				/* Return local label name.  */
   1669 dollar_label_name (long n,	/* we just saw "n$:" : n a number.  */
   1670 		   int augend	/* 0 for current instance, 1 for new instance.  */)
   1671 {
   1672   long i;
   1673   /* Returned to caller, then copied.  Used for created names ("4f").  */
   1674   static char symbol_name_build[24];
   1675   char *p;
   1676   char *q;
   1677   char symbol_name_temporary[20];	/* Build up a number, BACKWARDS.  */
   1678 
   1679   know (n >= 0);
   1680   know (augend == 0 || augend == 1);
   1681   p = symbol_name_build;
   1682 #ifdef LOCAL_LABEL_PREFIX
   1683   *p++ = LOCAL_LABEL_PREFIX;
   1684 #endif
   1685   *p++ = 'L';
   1686 
   1687   /* Next code just does sprintf( {}, "%d", n);  */
   1688   /* Label number.  */
   1689   q = symbol_name_temporary;
   1690   for (*q++ = 0, i = n; i; ++q)
   1691     {
   1692       *q = i % 10 + '0';
   1693       i /= 10;
   1694     }
   1695   while ((*p = *--q) != '\0')
   1696     ++p;
   1697 
   1698   *p++ = DOLLAR_LABEL_CHAR;		/* ^A  */
   1699 
   1700   /* Instance number.  */
   1701   q = symbol_name_temporary;
   1702   for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
   1703     {
   1704       *q = i % 10 + '0';
   1705       i /= 10;
   1706     }
   1707   while ((*p++ = *--q) != '\0');
   1708 
   1709   /* The label, as a '\0' ended string, starts at symbol_name_build.  */
   1710   return symbol_name_build;
   1711 }
   1712 
   1713 /* Somebody else's idea of local labels. They are made by "n:" where n
   1714    is any decimal digit. Refer to them with
   1715     "nb" for previous (backward) n:
   1716    or "nf" for next (forward) n:.
   1717 
   1718    We do a little better and let n be any number, not just a single digit, but
   1719    since the other guy's assembler only does ten, we treat the first ten
   1720    specially.
   1721 
   1722    Like someone else's assembler, we have one set of local label counters for
   1723    entire assembly, not one set per (sub)segment like in most assemblers. This
   1724    implies that one can refer to a label in another segment, and indeed some
   1725    crufty compilers have done just that.
   1726 
   1727    Since there could be a LOT of these things, treat them as a sparse
   1728    array.  */
   1729 
   1730 #define FB_LABEL_SPECIAL (10)
   1731 
   1732 static long fb_low_counter[FB_LABEL_SPECIAL];
   1733 static long *fb_labels;
   1734 static long *fb_label_instances;
   1735 static long fb_label_count;
   1736 static long fb_label_max;
   1737 
   1738 /* This must be more than FB_LABEL_SPECIAL.  */
   1739 #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
   1740 
   1741 static void
   1742 fb_label_init (void)
   1743 {
   1744   memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
   1745 }
   1746 
   1747 /* Add one to the instance number of this fb label.  */
   1748 
   1749 void
   1750 fb_label_instance_inc (long label)
   1751 {
   1752   long *i;
   1753 
   1754   if ((unsigned long) label < FB_LABEL_SPECIAL)
   1755     {
   1756       ++fb_low_counter[label];
   1757       return;
   1758     }
   1759 
   1760   if (fb_labels != NULL)
   1761     {
   1762       for (i = fb_labels + FB_LABEL_SPECIAL;
   1763 	   i < fb_labels + fb_label_count; ++i)
   1764 	{
   1765 	  if (*i == label)
   1766 	    {
   1767 	      ++fb_label_instances[i - fb_labels];
   1768 	      return;
   1769 	    }			/* if we find it  */
   1770 	}			/* for each existing label  */
   1771     }
   1772 
   1773   /* If we get to here, we don't have label listed yet.  */
   1774 
   1775   if (fb_labels == NULL)
   1776     {
   1777       fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
   1778       fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
   1779       fb_label_max = FB_LABEL_BUMP_BY;
   1780       fb_label_count = FB_LABEL_SPECIAL;
   1781 
   1782     }
   1783   else if (fb_label_count == fb_label_max)
   1784     {
   1785       fb_label_max += FB_LABEL_BUMP_BY;
   1786       fb_labels = (long *) xrealloc ((char *) fb_labels,
   1787 				     fb_label_max * sizeof (long));
   1788       fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
   1789 					      fb_label_max * sizeof (long));
   1790     }				/* if we needed to grow  */
   1791 
   1792   fb_labels[fb_label_count] = label;
   1793   fb_label_instances[fb_label_count] = 1;
   1794   ++fb_label_count;
   1795 }
   1796 
   1797 static long
   1798 fb_label_instance (long label)
   1799 {
   1800   long *i;
   1801 
   1802   if ((unsigned long) label < FB_LABEL_SPECIAL)
   1803     {
   1804       return (fb_low_counter[label]);
   1805     }
   1806 
   1807   if (fb_labels != NULL)
   1808     {
   1809       for (i = fb_labels + FB_LABEL_SPECIAL;
   1810 	   i < fb_labels + fb_label_count; ++i)
   1811 	{
   1812 	  if (*i == label)
   1813 	    {
   1814 	      return (fb_label_instances[i - fb_labels]);
   1815 	    }			/* if we find it  */
   1816 	}			/* for each existing label  */
   1817     }
   1818 
   1819   /* We didn't find the label, so this must be a reference to the
   1820      first instance.  */
   1821   return 0;
   1822 }
   1823 
   1824 /* Caller must copy returned name: we re-use the area for the next name.
   1825 
   1826    The mth occurence of label n: is turned into the symbol "Ln^Bm"
   1827    where n is the label number and m is the instance number. "L" makes
   1828    it a label discarded unless debugging and "^B"('\2') ensures no
   1829    ordinary symbol SHOULD get the same name as a local label
   1830    symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
   1831 
   1832    dollar labels get the same treatment, except that ^A is used in
   1833    place of ^B.  */
   1834 
   1835 char *				/* Return local label name.  */
   1836 fb_label_name (long n,	/* We just saw "n:", "nf" or "nb" : n a number.  */
   1837 	       long augend	/* 0 for nb, 1 for n:, nf.  */)
   1838 {
   1839   long i;
   1840   /* Returned to caller, then copied.  Used for created names ("4f").  */
   1841   static char symbol_name_build[24];
   1842   char *p;
   1843   char *q;
   1844   char symbol_name_temporary[20];	/* Build up a number, BACKWARDS.  */
   1845 
   1846   know (n >= 0);
   1847 #ifdef TC_MMIX
   1848   know ((unsigned long) augend <= 2 /* See mmix_fb_label.  */);
   1849 #else
   1850   know ((unsigned long) augend <= 1);
   1851 #endif
   1852   p = symbol_name_build;
   1853 #ifdef LOCAL_LABEL_PREFIX
   1854   *p++ = LOCAL_LABEL_PREFIX;
   1855 #endif
   1856   *p++ = 'L';
   1857 
   1858   /* Next code just does sprintf( {}, "%d", n);  */
   1859   /* Label number.  */
   1860   q = symbol_name_temporary;
   1861   for (*q++ = 0, i = n; i; ++q)
   1862     {
   1863       *q = i % 10 + '0';
   1864       i /= 10;
   1865     }
   1866   while ((*p = *--q) != '\0')
   1867     ++p;
   1868 
   1869   *p++ = LOCAL_LABEL_CHAR;		/* ^B  */
   1870 
   1871   /* Instance number.  */
   1872   q = symbol_name_temporary;
   1873   for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
   1874     {
   1875       *q = i % 10 + '0';
   1876       i /= 10;
   1877     }
   1878   while ((*p++ = *--q) != '\0');
   1879 
   1880   /* The label, as a '\0' ended string, starts at symbol_name_build.  */
   1881   return (symbol_name_build);
   1882 }
   1883 
   1884 /* Decode name that may have been generated by foo_label_name() above.
   1885    If the name wasn't generated by foo_label_name(), then return it
   1886    unaltered.  This is used for error messages.  */
   1887 
   1888 char *
   1889 decode_local_label_name (char *s)
   1890 {
   1891   char *p;
   1892   char *symbol_decode;
   1893   int label_number;
   1894   int instance_number;
   1895   char *type;
   1896   const char *message_format;
   1897   int lindex = 0;
   1898 
   1899 #ifdef LOCAL_LABEL_PREFIX
   1900   if (s[lindex] == LOCAL_LABEL_PREFIX)
   1901     ++lindex;
   1902 #endif
   1903 
   1904   if (s[lindex] != 'L')
   1905     return s;
   1906 
   1907   for (label_number = 0, p = s + lindex + 1; ISDIGIT (*p); ++p)
   1908     label_number = (10 * label_number) + *p - '0';
   1909 
   1910   if (*p == DOLLAR_LABEL_CHAR)
   1911     type = "dollar";
   1912   else if (*p == LOCAL_LABEL_CHAR)
   1913     type = "fb";
   1914   else
   1915     return s;
   1916 
   1917   for (instance_number = 0, p++; ISDIGIT (*p); ++p)
   1918     instance_number = (10 * instance_number) + *p - '0';
   1919 
   1920   message_format = _("\"%d\" (instance number %d of a %s label)");
   1921   symbol_decode = (char *) obstack_alloc (&notes, strlen (message_format) + 30);
   1922   sprintf (symbol_decode, message_format, label_number, instance_number, type);
   1923 
   1924   return symbol_decode;
   1925 }
   1926 
   1927 /* Get the value of a symbol.  */
   1928 
   1929 valueT
   1930 S_GET_VALUE (symbolS *s)
   1931 {
   1932   if (LOCAL_SYMBOL_CHECK (s))
   1933     return resolve_symbol_value (s);
   1934 
   1935   if (!s->sy_flags.sy_resolved)
   1936     {
   1937       valueT val = resolve_symbol_value (s);
   1938       if (!finalize_syms)
   1939 	return val;
   1940     }
   1941   if (S_IS_WEAKREFR (s))
   1942     return S_GET_VALUE (s->sy_value.X_add_symbol);
   1943 
   1944   if (s->sy_value.X_op != O_constant)
   1945     {
   1946       if (! s->sy_flags.sy_resolved
   1947 	  || s->sy_value.X_op != O_symbol
   1948 	  || (S_IS_DEFINED (s) && ! S_IS_COMMON (s)))
   1949 	as_bad (_("attempt to get value of unresolved symbol `%s'"),
   1950 		S_GET_NAME (s));
   1951     }
   1952   return (valueT) s->sy_value.X_add_number;
   1953 }
   1954 
   1955 /* Set the value of a symbol.  */
   1956 
   1957 void
   1958 S_SET_VALUE (symbolS *s, valueT val)
   1959 {
   1960   if (LOCAL_SYMBOL_CHECK (s))
   1961     {
   1962       ((struct local_symbol *) s)->lsy_value = val;
   1963       return;
   1964     }
   1965 
   1966   s->sy_value.X_op = O_constant;
   1967   s->sy_value.X_add_number = (offsetT) val;
   1968   s->sy_value.X_unsigned = 0;
   1969   S_CLEAR_WEAKREFR (s);
   1970 }
   1971 
   1972 void
   1973 copy_symbol_attributes (symbolS *dest, symbolS *src)
   1974 {
   1975   if (LOCAL_SYMBOL_CHECK (dest))
   1976     dest = local_symbol_convert ((struct local_symbol *) dest);
   1977   if (LOCAL_SYMBOL_CHECK (src))
   1978     src = local_symbol_convert ((struct local_symbol *) src);
   1979 
   1980   /* In an expression, transfer the settings of these flags.
   1981      The user can override later, of course.  */
   1982 #define COPIED_SYMFLAGS	(BSF_FUNCTION | BSF_OBJECT \
   1983 			 | BSF_GNU_INDIRECT_FUNCTION)
   1984   dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
   1985 
   1986 #ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
   1987   OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
   1988 #endif
   1989 
   1990 #ifdef TC_COPY_SYMBOL_ATTRIBUTES
   1991   TC_COPY_SYMBOL_ATTRIBUTES (dest, src);
   1992 #endif
   1993 }
   1994 
   1995 int
   1996 S_IS_FUNCTION (symbolS *s)
   1997 {
   1998   flagword flags;
   1999 
   2000   if (LOCAL_SYMBOL_CHECK (s))
   2001     return 0;
   2002 
   2003   flags = s->bsym->flags;
   2004 
   2005   return (flags & BSF_FUNCTION) != 0;
   2006 }
   2007 
   2008 int
   2009 S_IS_EXTERNAL (symbolS *s)
   2010 {
   2011   flagword flags;
   2012 
   2013   if (LOCAL_SYMBOL_CHECK (s))
   2014     return 0;
   2015 
   2016   flags = s->bsym->flags;
   2017 
   2018   /* Sanity check.  */
   2019   if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
   2020     abort ();
   2021 
   2022   return (flags & BSF_GLOBAL) != 0;
   2023 }
   2024 
   2025 int
   2026 S_IS_WEAK (symbolS *s)
   2027 {
   2028   if (LOCAL_SYMBOL_CHECK (s))
   2029     return 0;
   2030   /* Conceptually, a weakrefr is weak if the referenced symbol is.  We
   2031      could probably handle a WEAKREFR as always weak though.  E.g., if
   2032      the referenced symbol has lost its weak status, there's no reason
   2033      to keep handling the weakrefr as if it was weak.  */
   2034   if (S_IS_WEAKREFR (s))
   2035     return S_IS_WEAK (s->sy_value.X_add_symbol);
   2036   return (s->bsym->flags & BSF_WEAK) != 0;
   2037 }
   2038 
   2039 int
   2040 S_IS_WEAKREFR (symbolS *s)
   2041 {
   2042   if (LOCAL_SYMBOL_CHECK (s))
   2043     return 0;
   2044   return s->sy_flags.sy_weakrefr != 0;
   2045 }
   2046 
   2047 int
   2048 S_IS_WEAKREFD (symbolS *s)
   2049 {
   2050   if (LOCAL_SYMBOL_CHECK (s))
   2051     return 0;
   2052   return s->sy_flags.sy_weakrefd != 0;
   2053 }
   2054 
   2055 int
   2056 S_IS_COMMON (symbolS *s)
   2057 {
   2058   if (LOCAL_SYMBOL_CHECK (s))
   2059     return 0;
   2060   return bfd_is_com_section (s->bsym->section);
   2061 }
   2062 
   2063 int
   2064 S_IS_DEFINED (symbolS *s)
   2065 {
   2066   if (LOCAL_SYMBOL_CHECK (s))
   2067     return ((struct local_symbol *) s)->lsy_section != undefined_section;
   2068   return s->bsym->section != undefined_section;
   2069 }
   2070 
   2071 
   2072 #ifndef EXTERN_FORCE_RELOC
   2073 #define EXTERN_FORCE_RELOC IS_ELF
   2074 #endif
   2075 
   2076 /* Return true for symbols that should not be reduced to section
   2077    symbols or eliminated from expressions, because they may be
   2078    overridden by the linker.  */
   2079 int
   2080 S_FORCE_RELOC (symbolS *s, int strict)
   2081 {
   2082   if (LOCAL_SYMBOL_CHECK (s))
   2083     return ((struct local_symbol *) s)->lsy_section == undefined_section;
   2084 
   2085   return ((strict
   2086 	   && ((s->bsym->flags & BSF_WEAK) != 0
   2087 	       || (EXTERN_FORCE_RELOC
   2088 		   && (s->bsym->flags & BSF_GLOBAL) != 0)))
   2089 	  || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0
   2090 	  || s->bsym->section == undefined_section
   2091 	  || bfd_is_com_section (s->bsym->section));
   2092 }
   2093 
   2094 int
   2095 S_IS_DEBUG (symbolS *s)
   2096 {
   2097   if (LOCAL_SYMBOL_CHECK (s))
   2098     return 0;
   2099   if (s->bsym->flags & BSF_DEBUGGING)
   2100     return 1;
   2101   return 0;
   2102 }
   2103 
   2104 int
   2105 S_IS_LOCAL (symbolS *s)
   2106 {
   2107   flagword flags;
   2108   const char *name;
   2109 
   2110   if (LOCAL_SYMBOL_CHECK (s))
   2111     return 1;
   2112 
   2113   flags = s->bsym->flags;
   2114 
   2115   /* Sanity check.  */
   2116   if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
   2117     abort ();
   2118 
   2119   if (bfd_get_section (s->bsym) == reg_section)
   2120     return 1;
   2121 
   2122   if (flag_strip_local_absolute
   2123       /* Keep BSF_FILE symbols in order to allow debuggers to identify
   2124 	 the source file even when the object file is stripped.  */
   2125       && (flags & (BSF_GLOBAL | BSF_FILE)) == 0
   2126       && bfd_get_section (s->bsym) == absolute_section)
   2127     return 1;
   2128 
   2129   name = S_GET_NAME (s);
   2130   return (name != NULL
   2131 	  && ! S_IS_DEBUG (s)
   2132 	  && (strchr (name, DOLLAR_LABEL_CHAR)
   2133 	      || strchr (name, LOCAL_LABEL_CHAR)
   2134 	      || TC_LABEL_IS_LOCAL (name)
   2135 	      || (! flag_keep_locals
   2136 		  && (bfd_is_local_label (stdoutput, s->bsym)
   2137 		      || (flag_mri
   2138 			  && name[0] == '?'
   2139 			  && name[1] == '?')))));
   2140 }
   2141 
   2142 int
   2143 S_IS_STABD (symbolS *s)
   2144 {
   2145   return S_GET_NAME (s) == 0;
   2146 }
   2147 
   2148 int
   2149 S_CAN_BE_REDEFINED (const symbolS *s)
   2150 {
   2151   if (LOCAL_SYMBOL_CHECK (s))
   2152     return (local_symbol_get_frag ((struct local_symbol *) s)
   2153 	    == &predefined_address_frag);
   2154   /* Permit register names to be redefined.  */
   2155   return s->bsym->section == reg_section;
   2156 }
   2157 
   2158 int
   2159 S_IS_VOLATILE (const symbolS *s)
   2160 {
   2161   if (LOCAL_SYMBOL_CHECK (s))
   2162     return 0;
   2163   return s->sy_flags.sy_volatile;
   2164 }
   2165 
   2166 int
   2167 S_IS_FORWARD_REF (const symbolS *s)
   2168 {
   2169   if (LOCAL_SYMBOL_CHECK (s))
   2170     return 0;
   2171   return s->sy_flags.sy_forward_ref;
   2172 }
   2173 
   2174 const char *
   2175 S_GET_NAME (symbolS *s)
   2176 {
   2177   if (LOCAL_SYMBOL_CHECK (s))
   2178     return ((struct local_symbol *) s)->lsy_name;
   2179   return s->bsym->name;
   2180 }
   2181 
   2182 segT
   2183 S_GET_SEGMENT (symbolS *s)
   2184 {
   2185   if (LOCAL_SYMBOL_CHECK (s))
   2186     return ((struct local_symbol *) s)->lsy_section;
   2187   return s->bsym->section;
   2188 }
   2189 
   2190 void
   2191 S_SET_SEGMENT (symbolS *s, segT seg)
   2192 {
   2193   /* Don't reassign section symbols.  The direct reason is to prevent seg
   2194      faults assigning back to const global symbols such as *ABS*, but it
   2195      shouldn't happen anyway.  */
   2196 
   2197   if (LOCAL_SYMBOL_CHECK (s))
   2198     {
   2199       if (seg == reg_section)
   2200 	s = local_symbol_convert ((struct local_symbol *) s);
   2201       else
   2202 	{
   2203 	  ((struct local_symbol *) s)->lsy_section = seg;
   2204 	  return;
   2205 	}
   2206     }
   2207 
   2208   if (s->bsym->flags & BSF_SECTION_SYM)
   2209     {
   2210       if (s->bsym->section != seg)
   2211 	abort ();
   2212     }
   2213   else
   2214     s->bsym->section = seg;
   2215 }
   2216 
   2217 void
   2218 S_SET_EXTERNAL (symbolS *s)
   2219 {
   2220   if (LOCAL_SYMBOL_CHECK (s))
   2221     s = local_symbol_convert ((struct local_symbol *) s);
   2222   if ((s->bsym->flags & BSF_WEAK) != 0)
   2223     {
   2224       /* Let .weak override .global.  */
   2225       return;
   2226     }
   2227   if (s->bsym->flags & BSF_SECTION_SYM)
   2228     {
   2229       char * file;
   2230       unsigned int line;
   2231 
   2232       /* Do not reassign section symbols.  */
   2233       as_where (& file, & line);
   2234       as_warn_where (file, line,
   2235 		     _("section symbols are already global"));
   2236       return;
   2237     }
   2238 #ifndef TC_GLOBAL_REGISTER_SYMBOL_OK
   2239   if (S_GET_SEGMENT (s) == reg_section)
   2240     {
   2241       as_bad ("can't make register symbol `%s' global",
   2242 	      S_GET_NAME (s));
   2243       return;
   2244     }
   2245 #endif
   2246   s->bsym->flags |= BSF_GLOBAL;
   2247   s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK);
   2248 
   2249 #ifdef TE_PE
   2250   if (! an_external_name && S_GET_NAME(s)[0] != '.')
   2251     an_external_name = S_GET_NAME (s);
   2252 #endif
   2253 }
   2254 
   2255 void
   2256 S_CLEAR_EXTERNAL (symbolS *s)
   2257 {
   2258   if (LOCAL_SYMBOL_CHECK (s))
   2259     return;
   2260   if ((s->bsym->flags & BSF_WEAK) != 0)
   2261     {
   2262       /* Let .weak override.  */
   2263       return;
   2264     }
   2265   s->bsym->flags |= BSF_LOCAL;
   2266   s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
   2267 }
   2268 
   2269 void
   2270 S_SET_WEAK (symbolS *s)
   2271 {
   2272   if (LOCAL_SYMBOL_CHECK (s))
   2273     s = local_symbol_convert ((struct local_symbol *) s);
   2274 #ifdef obj_set_weak_hook
   2275   obj_set_weak_hook (s);
   2276 #endif
   2277   s->bsym->flags |= BSF_WEAK;
   2278   s->bsym->flags &= ~(BSF_GLOBAL | BSF_LOCAL);
   2279 }
   2280 
   2281 void
   2282 S_SET_WEAKREFR (symbolS *s)
   2283 {
   2284   if (LOCAL_SYMBOL_CHECK (s))
   2285     s = local_symbol_convert ((struct local_symbol *) s);
   2286   s->sy_flags.sy_weakrefr = 1;
   2287   /* If the alias was already used, make sure we mark the target as
   2288      used as well, otherwise it might be dropped from the symbol
   2289      table.  This may have unintended side effects if the alias is
   2290      later redirected to another symbol, such as keeping the unused
   2291      previous target in the symbol table.  Since it will be weak, it's
   2292      not a big deal.  */
   2293   if (s->sy_flags.sy_used)
   2294     symbol_mark_used (s->sy_value.X_add_symbol);
   2295 }
   2296 
   2297 void
   2298 S_CLEAR_WEAKREFR (symbolS *s)
   2299 {
   2300   if (LOCAL_SYMBOL_CHECK (s))
   2301     return;
   2302   s->sy_flags.sy_weakrefr = 0;
   2303 }
   2304 
   2305 void
   2306 S_SET_WEAKREFD (symbolS *s)
   2307 {
   2308   if (LOCAL_SYMBOL_CHECK (s))
   2309     s = local_symbol_convert ((struct local_symbol *) s);
   2310   s->sy_flags.sy_weakrefd = 1;
   2311   S_SET_WEAK (s);
   2312 }
   2313 
   2314 void
   2315 S_CLEAR_WEAKREFD (symbolS *s)
   2316 {
   2317   if (LOCAL_SYMBOL_CHECK (s))
   2318     return;
   2319   if (s->sy_flags.sy_weakrefd)
   2320     {
   2321       s->sy_flags.sy_weakrefd = 0;
   2322       /* If a weakref target symbol is weak, then it was never
   2323 	 referenced directly before, not even in a .global directive,
   2324 	 so decay it to local.  If it remains undefined, it will be
   2325 	 later turned into a global, like any other undefined
   2326 	 symbol.  */
   2327       if (s->bsym->flags & BSF_WEAK)
   2328 	{
   2329 #ifdef obj_clear_weak_hook
   2330 	  obj_clear_weak_hook (s);
   2331 #endif
   2332 	  s->bsym->flags &= ~BSF_WEAK;
   2333 	  s->bsym->flags |= BSF_LOCAL;
   2334 	}
   2335     }
   2336 }
   2337 
   2338 void
   2339 S_SET_THREAD_LOCAL (symbolS *s)
   2340 {
   2341   if (LOCAL_SYMBOL_CHECK (s))
   2342     s = local_symbol_convert ((struct local_symbol *) s);
   2343   if (bfd_is_com_section (s->bsym->section)
   2344       && (s->bsym->flags & BSF_THREAD_LOCAL) != 0)
   2345     return;
   2346   s->bsym->flags |= BSF_THREAD_LOCAL;
   2347   if ((s->bsym->flags & BSF_FUNCTION) != 0)
   2348     as_bad (_("Accessing function `%s' as thread-local object"),
   2349 	    S_GET_NAME (s));
   2350   else if (! bfd_is_und_section (s->bsym->section)
   2351 	   && (s->bsym->section->flags & SEC_THREAD_LOCAL) == 0)
   2352     as_bad (_("Accessing `%s' as thread-local object"),
   2353 	    S_GET_NAME (s));
   2354 }
   2355 
   2356 void
   2357 S_SET_NAME (symbolS *s, const char *name)
   2358 {
   2359   if (LOCAL_SYMBOL_CHECK (s))
   2360     {
   2361       ((struct local_symbol *) s)->lsy_name = name;
   2362       return;
   2363     }
   2364   s->bsym->name = name;
   2365 }
   2366 
   2367 void
   2368 S_SET_VOLATILE (symbolS *s)
   2369 {
   2370   if (LOCAL_SYMBOL_CHECK (s))
   2371     s = local_symbol_convert ((struct local_symbol *) s);
   2372   s->sy_flags.sy_volatile = 1;
   2373 }
   2374 
   2375 void
   2376 S_CLEAR_VOLATILE (symbolS *s)
   2377 {
   2378   if (!LOCAL_SYMBOL_CHECK (s))
   2379     s->sy_flags.sy_volatile = 0;
   2380 }
   2381 
   2382 void
   2383 S_SET_FORWARD_REF (symbolS *s)
   2384 {
   2385   if (LOCAL_SYMBOL_CHECK (s))
   2386     s = local_symbol_convert ((struct local_symbol *) s);
   2387   s->sy_flags.sy_forward_ref = 1;
   2388 }
   2389 
   2390 /* Return the previous symbol in a chain.  */
   2391 
   2392 symbolS *
   2393 symbol_previous (symbolS *s)
   2394 {
   2395   if (LOCAL_SYMBOL_CHECK (s))
   2396     abort ();
   2397   return s->sy_previous;
   2398 }
   2399 
   2400 /* Return the next symbol in a chain.  */
   2401 
   2402 symbolS *
   2403 symbol_next (symbolS *s)
   2404 {
   2405   if (LOCAL_SYMBOL_CHECK (s))
   2406     abort ();
   2407   return s->sy_next;
   2408 }
   2409 
   2410 /* Return a pointer to the value of a symbol as an expression.  */
   2411 
   2412 expressionS *
   2413 symbol_get_value_expression (symbolS *s)
   2414 {
   2415   if (LOCAL_SYMBOL_CHECK (s))
   2416     s = local_symbol_convert ((struct local_symbol *) s);
   2417   return &s->sy_value;
   2418 }
   2419 
   2420 /* Set the value of a symbol to an expression.  */
   2421 
   2422 void
   2423 symbol_set_value_expression (symbolS *s, const expressionS *exp)
   2424 {
   2425   if (LOCAL_SYMBOL_CHECK (s))
   2426     s = local_symbol_convert ((struct local_symbol *) s);
   2427   s->sy_value = *exp;
   2428   S_CLEAR_WEAKREFR (s);
   2429 }
   2430 
   2431 /* Return whether 2 symbols are the same.  */
   2432 
   2433 int
   2434 symbol_same_p (symbolS *s1, symbolS *s2)
   2435 {
   2436   if (s1->sy_flags.sy_local_symbol
   2437       && local_symbol_converted_p ((struct local_symbol *) s1))
   2438     s1 = local_symbol_get_real_symbol ((struct local_symbol *) s1);
   2439   if (s2->sy_flags.sy_local_symbol
   2440       && local_symbol_converted_p ((struct local_symbol *) s2))
   2441     s2 = local_symbol_get_real_symbol ((struct local_symbol *) s2);
   2442   return s1 == s2;
   2443 }
   2444 
   2445 /* Return a pointer to the X_add_number component of a symbol.  */
   2446 
   2447 offsetT *
   2448 symbol_X_add_number (symbolS *s)
   2449 {
   2450   if (LOCAL_SYMBOL_CHECK (s))
   2451     return (offsetT *) &((struct local_symbol *) s)->lsy_value;
   2452 
   2453   return &s->sy_value.X_add_number;
   2454 }
   2455 
   2456 /* Set the value of SYM to the current position in the current segment.  */
   2457 
   2458 void
   2459 symbol_set_value_now (symbolS *sym)
   2460 {
   2461   S_SET_SEGMENT (sym, now_seg);
   2462   S_SET_VALUE (sym, frag_now_fix ());
   2463   symbol_set_frag (sym, frag_now);
   2464 }
   2465 
   2466 /* Set the frag of a symbol.  */
   2467 
   2468 void
   2469 symbol_set_frag (symbolS *s, fragS *f)
   2470 {
   2471   if (LOCAL_SYMBOL_CHECK (s))
   2472     {
   2473       local_symbol_set_frag ((struct local_symbol *) s, f);
   2474       return;
   2475     }
   2476   s->sy_frag = f;
   2477   S_CLEAR_WEAKREFR (s);
   2478 }
   2479 
   2480 /* Return the frag of a symbol.  */
   2481 
   2482 fragS *
   2483 symbol_get_frag (symbolS *s)
   2484 {
   2485   if (LOCAL_SYMBOL_CHECK (s))
   2486     return local_symbol_get_frag ((struct local_symbol *) s);
   2487   return s->sy_frag;
   2488 }
   2489 
   2490 /* Mark a symbol as having been used.  */
   2491 
   2492 void
   2493 symbol_mark_used (symbolS *s)
   2494 {
   2495   if (LOCAL_SYMBOL_CHECK (s))
   2496     return;
   2497   s->sy_flags.sy_used = 1;
   2498   if (S_IS_WEAKREFR (s))
   2499     symbol_mark_used (s->sy_value.X_add_symbol);
   2500 }
   2501 
   2502 /* Clear the mark of whether a symbol has been used.  */
   2503 
   2504 void
   2505 symbol_clear_used (symbolS *s)
   2506 {
   2507   if (LOCAL_SYMBOL_CHECK (s))
   2508     s = local_symbol_convert ((struct local_symbol *) s);
   2509   s->sy_flags.sy_used = 0;
   2510 }
   2511 
   2512 /* Return whether a symbol has been used.  */
   2513 
   2514 int
   2515 symbol_used_p (symbolS *s)
   2516 {
   2517   if (LOCAL_SYMBOL_CHECK (s))
   2518     return 1;
   2519   return s->sy_flags.sy_used;
   2520 }
   2521 
   2522 /* Mark a symbol as having been used in a reloc.  */
   2523 
   2524 void
   2525 symbol_mark_used_in_reloc (symbolS *s)
   2526 {
   2527   if (LOCAL_SYMBOL_CHECK (s))
   2528     s = local_symbol_convert ((struct local_symbol *) s);
   2529   s->sy_flags.sy_used_in_reloc = 1;
   2530 }
   2531 
   2532 /* Clear the mark of whether a symbol has been used in a reloc.  */
   2533 
   2534 void
   2535 symbol_clear_used_in_reloc (symbolS *s)
   2536 {
   2537   if (LOCAL_SYMBOL_CHECK (s))
   2538     return;
   2539   s->sy_flags.sy_used_in_reloc = 0;
   2540 }
   2541 
   2542 /* Return whether a symbol has been used in a reloc.  */
   2543 
   2544 int
   2545 symbol_used_in_reloc_p (symbolS *s)
   2546 {
   2547   if (LOCAL_SYMBOL_CHECK (s))
   2548     return 0;
   2549   return s->sy_flags.sy_used_in_reloc;
   2550 }
   2551 
   2552 /* Mark a symbol as an MRI common symbol.  */
   2553 
   2554 void
   2555 symbol_mark_mri_common (symbolS *s)
   2556 {
   2557   if (LOCAL_SYMBOL_CHECK (s))
   2558     s = local_symbol_convert ((struct local_symbol *) s);
   2559   s->sy_flags.sy_mri_common = 1;
   2560 }
   2561 
   2562 /* Clear the mark of whether a symbol is an MRI common symbol.  */
   2563 
   2564 void
   2565 symbol_clear_mri_common (symbolS *s)
   2566 {
   2567   if (LOCAL_SYMBOL_CHECK (s))
   2568     return;
   2569   s->sy_flags.sy_mri_common = 0;
   2570 }
   2571 
   2572 /* Return whether a symbol is an MRI common symbol.  */
   2573 
   2574 int
   2575 symbol_mri_common_p (symbolS *s)
   2576 {
   2577   if (LOCAL_SYMBOL_CHECK (s))
   2578     return 0;
   2579   return s->sy_flags.sy_mri_common;
   2580 }
   2581 
   2582 /* Mark a symbol as having been written.  */
   2583 
   2584 void
   2585 symbol_mark_written (symbolS *s)
   2586 {
   2587   if (LOCAL_SYMBOL_CHECK (s))
   2588     return;
   2589   s->sy_flags.sy_written = 1;
   2590 }
   2591 
   2592 /* Clear the mark of whether a symbol has been written.  */
   2593 
   2594 void
   2595 symbol_clear_written (symbolS *s)
   2596 {
   2597   if (LOCAL_SYMBOL_CHECK (s))
   2598     return;
   2599   s->sy_flags.sy_written = 0;
   2600 }
   2601 
   2602 /* Return whether a symbol has been written.  */
   2603 
   2604 int
   2605 symbol_written_p (symbolS *s)
   2606 {
   2607   if (LOCAL_SYMBOL_CHECK (s))
   2608     return 0;
   2609   return s->sy_flags.sy_written;
   2610 }
   2611 
   2612 /* Mark a symbol has having been resolved.  */
   2613 
   2614 void
   2615 symbol_mark_resolved (symbolS *s)
   2616 {
   2617   if (LOCAL_SYMBOL_CHECK (s))
   2618     {
   2619       local_symbol_mark_resolved ((struct local_symbol *) s);
   2620       return;
   2621     }
   2622   s->sy_flags.sy_resolved = 1;
   2623 }
   2624 
   2625 /* Return whether a symbol has been resolved.  */
   2626 
   2627 int
   2628 symbol_resolved_p (symbolS *s)
   2629 {
   2630   if (LOCAL_SYMBOL_CHECK (s))
   2631     return local_symbol_resolved_p ((struct local_symbol *) s);
   2632   return s->sy_flags.sy_resolved;
   2633 }
   2634 
   2635 /* Return whether a symbol is a section symbol.  */
   2636 
   2637 int
   2638 symbol_section_p (symbolS *s ATTRIBUTE_UNUSED)
   2639 {
   2640   if (LOCAL_SYMBOL_CHECK (s))
   2641     return 0;
   2642   return (s->bsym->flags & BSF_SECTION_SYM) != 0;
   2643 }
   2644 
   2645 /* Return whether a symbol is equated to another symbol.  */
   2646 
   2647 int
   2648 symbol_equated_p (symbolS *s)
   2649 {
   2650   if (LOCAL_SYMBOL_CHECK (s))
   2651     return 0;
   2652   return s->sy_value.X_op == O_symbol;
   2653 }
   2654 
   2655 /* Return whether a symbol is equated to another symbol, and should be
   2656    treated specially when writing out relocs.  */
   2657 
   2658 int
   2659 symbol_equated_reloc_p (symbolS *s)
   2660 {
   2661   if (LOCAL_SYMBOL_CHECK (s))
   2662     return 0;
   2663   /* X_op_symbol, normally not used for O_symbol, is set by
   2664      resolve_symbol_value to flag expression syms that have been
   2665      equated.  */
   2666   return (s->sy_value.X_op == O_symbol
   2667 #if defined (OBJ_COFF) && defined (TE_PE)
   2668 	  && ! S_IS_WEAK (s)
   2669 #endif
   2670 	  && ((s->sy_flags.sy_resolved && s->sy_value.X_op_symbol != NULL)
   2671 	      || ! S_IS_DEFINED (s)
   2672 	      || S_IS_COMMON (s)));
   2673 }
   2674 
   2675 /* Return whether a symbol has a constant value.  */
   2676 
   2677 int
   2678 symbol_constant_p (symbolS *s)
   2679 {
   2680   if (LOCAL_SYMBOL_CHECK (s))
   2681     return 1;
   2682   return s->sy_value.X_op == O_constant;
   2683 }
   2684 
   2685 /* Return whether a symbol was cloned and thus removed from the global
   2686    symbol list.  */
   2687 
   2688 int
   2689 symbol_shadow_p (symbolS *s)
   2690 {
   2691   if (LOCAL_SYMBOL_CHECK (s))
   2692     return 0;
   2693   return s->sy_next == s;
   2694 }
   2695 
   2696 /* Return the BFD symbol for a symbol.  */
   2697 
   2698 asymbol *
   2699 symbol_get_bfdsym (symbolS *s)
   2700 {
   2701   if (LOCAL_SYMBOL_CHECK (s))
   2702     s = local_symbol_convert ((struct local_symbol *) s);
   2703   return s->bsym;
   2704 }
   2705 
   2706 /* Set the BFD symbol for a symbol.  */
   2707 
   2708 void
   2709 symbol_set_bfdsym (symbolS *s, asymbol *bsym)
   2710 {
   2711   if (LOCAL_SYMBOL_CHECK (s))
   2712     s = local_symbol_convert ((struct local_symbol *) s);
   2713   /* Usually, it is harmless to reset a symbol to a BFD section
   2714      symbol. For example, obj_elf_change_section sets the BFD symbol
   2715      of an old symbol with the newly created section symbol. But when
   2716      we have multiple sections with the same name, the newly created
   2717      section may have the same name as an old section. We check if the
   2718      old symbol has been already marked as a section symbol before
   2719      resetting it.  */
   2720   if ((s->bsym->flags & BSF_SECTION_SYM) == 0)
   2721     s->bsym = bsym;
   2722   /* else XXX - What do we do now ?  */
   2723 }
   2724 
   2725 #ifdef OBJ_SYMFIELD_TYPE
   2726 
   2727 /* Get a pointer to the object format information for a symbol.  */
   2728 
   2729 OBJ_SYMFIELD_TYPE *
   2730 symbol_get_obj (symbolS *s)
   2731 {
   2732   if (LOCAL_SYMBOL_CHECK (s))
   2733     s = local_symbol_convert ((struct local_symbol *) s);
   2734   return &s->sy_obj;
   2735 }
   2736 
   2737 /* Set the object format information for a symbol.  */
   2738 
   2739 void
   2740 symbol_set_obj (symbolS *s, OBJ_SYMFIELD_TYPE *o)
   2741 {
   2742   if (LOCAL_SYMBOL_CHECK (s))
   2743     s = local_symbol_convert ((struct local_symbol *) s);
   2744   s->sy_obj = *o;
   2745 }
   2746 
   2747 #endif /* OBJ_SYMFIELD_TYPE */
   2748 
   2749 #ifdef TC_SYMFIELD_TYPE
   2750 
   2751 /* Get a pointer to the processor information for a symbol.  */
   2752 
   2753 TC_SYMFIELD_TYPE *
   2754 symbol_get_tc (symbolS *s)
   2755 {
   2756   if (LOCAL_SYMBOL_CHECK (s))
   2757     s = local_symbol_convert ((struct local_symbol *) s);
   2758   return &s->sy_tc;
   2759 }
   2760 
   2761 /* Set the processor information for a symbol.  */
   2762 
   2763 void
   2764 symbol_set_tc (symbolS *s, TC_SYMFIELD_TYPE *o)
   2765 {
   2766   if (LOCAL_SYMBOL_CHECK (s))
   2767     s = local_symbol_convert ((struct local_symbol *) s);
   2768   s->sy_tc = *o;
   2769 }
   2770 
   2771 #endif /* TC_SYMFIELD_TYPE */
   2772 
   2773 void
   2774 symbol_begin (void)
   2775 {
   2776   symbol_lastP = NULL;
   2777   symbol_rootP = NULL;		/* In case we have 0 symbols (!!)  */
   2778   sy_hash = hash_new ();
   2779   local_hash = hash_new ();
   2780 
   2781   memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
   2782 #if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
   2783   abs_symbol.bsym = bfd_abs_section_ptr->symbol;
   2784 #endif
   2785   abs_symbol.sy_value.X_op = O_constant;
   2786   abs_symbol.sy_frag = &zero_address_frag;
   2787 
   2788   if (LOCAL_LABELS_FB)
   2789     fb_label_init ();
   2790 }
   2791 
   2792 void
   2793 dot_symbol_init (void)
   2794 {
   2795   dot_symbol.bsym = bfd_make_empty_symbol (stdoutput);
   2796   if (dot_symbol.bsym == NULL)
   2797     as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ()));
   2798   dot_symbol.bsym->name = ".";
   2799   dot_symbol.sy_flags.sy_forward_ref = 1;
   2800   dot_symbol.sy_value.X_op = O_constant;
   2801 }
   2802 
   2803 int indent_level;
   2805 
   2806 /* Maximum indent level.
   2807    Available for modification inside a gdb session.  */
   2808 static int max_indent_level = 8;
   2809 
   2810 void
   2811 print_symbol_value_1 (FILE *file, symbolS *sym)
   2812 {
   2813   const char *name = S_GET_NAME (sym);
   2814   if (!name || !name[0])
   2815     name = "(unnamed)";
   2816   fprintf (file, "sym ");
   2817   fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) sym));
   2818   fprintf (file, " %s", name);
   2819 
   2820   if (LOCAL_SYMBOL_CHECK (sym))
   2821     {
   2822       struct local_symbol *locsym = (struct local_symbol *) sym;
   2823 
   2824       if (local_symbol_get_frag (locsym) != & zero_address_frag
   2825 	  && local_symbol_get_frag (locsym) != NULL)
   2826 	{
   2827 	  fprintf (file, " frag ");
   2828 	  fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) local_symbol_get_frag (locsym)));
   2829         }
   2830       if (local_symbol_resolved_p (locsym))
   2831 	fprintf (file, " resolved");
   2832       fprintf (file, " local");
   2833     }
   2834   else
   2835     {
   2836       if (sym->sy_frag != &zero_address_frag)
   2837 	{
   2838 	  fprintf (file, " frag ");
   2839 	  fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) sym->sy_frag));
   2840 	}
   2841       if (sym->sy_flags.sy_written)
   2842 	fprintf (file, " written");
   2843       if (sym->sy_flags.sy_resolved)
   2844 	fprintf (file, " resolved");
   2845       else if (sym->sy_flags.sy_resolving)
   2846 	fprintf (file, " resolving");
   2847       if (sym->sy_flags.sy_used_in_reloc)
   2848 	fprintf (file, " used-in-reloc");
   2849       if (sym->sy_flags.sy_used)
   2850 	fprintf (file, " used");
   2851       if (S_IS_LOCAL (sym))
   2852 	fprintf (file, " local");
   2853       if (S_IS_EXTERNAL (sym))
   2854 	fprintf (file, " extern");
   2855       if (S_IS_WEAK (sym))
   2856 	fprintf (file, " weak");
   2857       if (S_IS_DEBUG (sym))
   2858 	fprintf (file, " debug");
   2859       if (S_IS_DEFINED (sym))
   2860 	fprintf (file, " defined");
   2861     }
   2862   if (S_IS_WEAKREFR (sym))
   2863     fprintf (file, " weakrefr");
   2864   if (S_IS_WEAKREFD (sym))
   2865     fprintf (file, " weakrefd");
   2866   fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
   2867   if (symbol_resolved_p (sym))
   2868     {
   2869       segT s = S_GET_SEGMENT (sym);
   2870 
   2871       if (s != undefined_section
   2872 	  && s != expr_section)
   2873 	fprintf (file, " %lx", (unsigned long) S_GET_VALUE (sym));
   2874     }
   2875   else if (indent_level < max_indent_level
   2876 	   && S_GET_SEGMENT (sym) != undefined_section)
   2877     {
   2878       indent_level++;
   2879       fprintf (file, "\n%*s<", indent_level * 4, "");
   2880       if (LOCAL_SYMBOL_CHECK (sym))
   2881 	fprintf (file, "constant %lx",
   2882 		 (unsigned long) ((struct local_symbol *) sym)->lsy_value);
   2883       else
   2884 	print_expr_1 (file, &sym->sy_value);
   2885       fprintf (file, ">");
   2886       indent_level--;
   2887     }
   2888   fflush (file);
   2889 }
   2890 
   2891 void
   2892 print_symbol_value (symbolS *sym)
   2893 {
   2894   indent_level = 0;
   2895   print_symbol_value_1 (stderr, sym);
   2896   fprintf (stderr, "\n");
   2897 }
   2898 
   2899 static void
   2900 print_binary (FILE *file, const char *name, expressionS *exp)
   2901 {
   2902   indent_level++;
   2903   fprintf (file, "%s\n%*s<", name, indent_level * 4, "");
   2904   print_symbol_value_1 (file, exp->X_add_symbol);
   2905   fprintf (file, ">\n%*s<", indent_level * 4, "");
   2906   print_symbol_value_1 (file, exp->X_op_symbol);
   2907   fprintf (file, ">");
   2908   indent_level--;
   2909 }
   2910 
   2911 void
   2912 print_expr_1 (FILE *file, expressionS *exp)
   2913 {
   2914   fprintf (file, "expr ");
   2915   fprintf_vma (file, (bfd_vma) ((bfd_hostptr_t) exp));
   2916   fprintf (file, " ");
   2917   switch (exp->X_op)
   2918     {
   2919     case O_illegal:
   2920       fprintf (file, "illegal");
   2921       break;
   2922     case O_absent:
   2923       fprintf (file, "absent");
   2924       break;
   2925     case O_constant:
   2926       fprintf (file, "constant %lx", (unsigned long) exp->X_add_number);
   2927       break;
   2928     case O_symbol:
   2929       indent_level++;
   2930       fprintf (file, "symbol\n%*s<", indent_level * 4, "");
   2931       print_symbol_value_1 (file, exp->X_add_symbol);
   2932       fprintf (file, ">");
   2933     maybe_print_addnum:
   2934       if (exp->X_add_number)
   2935 	fprintf (file, "\n%*s%lx", indent_level * 4, "",
   2936 		 (unsigned long) exp->X_add_number);
   2937       indent_level--;
   2938       break;
   2939     case O_register:
   2940       fprintf (file, "register #%d", (int) exp->X_add_number);
   2941       break;
   2942     case O_big:
   2943       fprintf (file, "big");
   2944       break;
   2945     case O_uminus:
   2946       fprintf (file, "uminus -<");
   2947       indent_level++;
   2948       print_symbol_value_1 (file, exp->X_add_symbol);
   2949       fprintf (file, ">");
   2950       goto maybe_print_addnum;
   2951     case O_bit_not:
   2952       fprintf (file, "bit_not");
   2953       break;
   2954     case O_multiply:
   2955       print_binary (file, "multiply", exp);
   2956       break;
   2957     case O_divide:
   2958       print_binary (file, "divide", exp);
   2959       break;
   2960     case O_modulus:
   2961       print_binary (file, "modulus", exp);
   2962       break;
   2963     case O_left_shift:
   2964       print_binary (file, "lshift", exp);
   2965       break;
   2966     case O_right_shift:
   2967       print_binary (file, "rshift", exp);
   2968       break;
   2969     case O_bit_inclusive_or:
   2970       print_binary (file, "bit_ior", exp);
   2971       break;
   2972     case O_bit_exclusive_or:
   2973       print_binary (file, "bit_xor", exp);
   2974       break;
   2975     case O_bit_and:
   2976       print_binary (file, "bit_and", exp);
   2977       break;
   2978     case O_eq:
   2979       print_binary (file, "eq", exp);
   2980       break;
   2981     case O_ne:
   2982       print_binary (file, "ne", exp);
   2983       break;
   2984     case O_lt:
   2985       print_binary (file, "lt", exp);
   2986       break;
   2987     case O_le:
   2988       print_binary (file, "le", exp);
   2989       break;
   2990     case O_ge:
   2991       print_binary (file, "ge", exp);
   2992       break;
   2993     case O_gt:
   2994       print_binary (file, "gt", exp);
   2995       break;
   2996     case O_logical_and:
   2997       print_binary (file, "logical_and", exp);
   2998       break;
   2999     case O_logical_or:
   3000       print_binary (file, "logical_or", exp);
   3001       break;
   3002     case O_add:
   3003       indent_level++;
   3004       fprintf (file, "add\n%*s<", indent_level * 4, "");
   3005       print_symbol_value_1 (file, exp->X_add_symbol);
   3006       fprintf (file, ">\n%*s<", indent_level * 4, "");
   3007       print_symbol_value_1 (file, exp->X_op_symbol);
   3008       fprintf (file, ">");
   3009       goto maybe_print_addnum;
   3010     case O_subtract:
   3011       indent_level++;
   3012       fprintf (file, "subtract\n%*s<", indent_level * 4, "");
   3013       print_symbol_value_1 (file, exp->X_add_symbol);
   3014       fprintf (file, ">\n%*s<", indent_level * 4, "");
   3015       print_symbol_value_1 (file, exp->X_op_symbol);
   3016       fprintf (file, ">");
   3017       goto maybe_print_addnum;
   3018     default:
   3019       fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
   3020       break;
   3021     }
   3022   fflush (stdout);
   3023 }
   3024 
   3025 void
   3026 print_expr (expressionS *exp)
   3027 {
   3028   print_expr_1 (stderr, exp);
   3029   fprintf (stderr, "\n");
   3030 }
   3031 
   3032 void
   3033 symbol_print_statistics (FILE *file)
   3034 {
   3035   hash_print_statistics (file, "symbol table", sy_hash);
   3036   hash_print_statistics (file, "mini local symbol table", local_hash);
   3037   fprintf (file, "%lu mini local symbols created, %lu converted\n",
   3038 	   local_symbol_count, local_symbol_conversion_count);
   3039 }
   3040 
   3041 #ifdef OBJ_COMPLEX_RELC
   3042 
   3043 /* Convert given symbol to a new complex-relocation symbol name.  This
   3044    may be a recursive function, since it might be called for non-leaf
   3045    nodes (plain symbols) in the expression tree.  The caller owns the
   3046    returning string, so should free it eventually.  Errors are
   3047    indicated via as_bad and a NULL return value.  The given symbol
   3048    is marked with sy_used_in_reloc.  */
   3049 
   3050 char *
   3051 symbol_relc_make_sym (symbolS * sym)
   3052 {
   3053   char * terminal = NULL;
   3054   const char * sname;
   3055   char typetag;
   3056   int sname_len;
   3057 
   3058   gas_assert (sym != NULL);
   3059 
   3060   /* Recurse to symbol_relc_make_expr if this symbol
   3061      is defined as an expression or a plain value.  */
   3062   if (   S_GET_SEGMENT (sym) == expr_section
   3063       || S_GET_SEGMENT (sym) == absolute_section)
   3064     return symbol_relc_make_expr (& sym->sy_value);
   3065 
   3066   /* This may be a "fake symbol" L0\001, referring to ".".
   3067      Write out a special null symbol to refer to this position.  */
   3068   if (! strcmp (S_GET_NAME (sym), FAKE_LABEL_NAME))
   3069     return xstrdup (".");
   3070 
   3071   /* We hope this is a plain leaf symbol.  Construct the encoding
   3072      as {S,s}II...:CCCCCCC....
   3073      where 'S'/'s' means section symbol / plain symbol
   3074      III is decimal for the symbol name length
   3075      CCC is the symbol name itself.  */
   3076   symbol_mark_used_in_reloc (sym);
   3077 
   3078   sname = S_GET_NAME (sym);
   3079   sname_len = strlen (sname);
   3080   typetag = symbol_section_p (sym) ? 'S' : 's';
   3081 
   3082   terminal = xmalloc (1 /* S or s */
   3083 		      + 8 /* sname_len in decimal */
   3084 		      + 1 /* _ spacer */
   3085 		      + sname_len /* name itself */
   3086 		      + 1 /* \0 */ );
   3087 
   3088   sprintf (terminal, "%c%d:%s", typetag, sname_len, sname);
   3089   return terminal;
   3090 }
   3091 
   3092 /* Convert given value to a new complex-relocation symbol name.  This
   3093    is a non-recursive function, since it is be called for leaf nodes
   3094    (plain values) in the expression tree.  The caller owns the
   3095    returning string, so should free() it eventually.  No errors.  */
   3096 
   3097 char *
   3098 symbol_relc_make_value (offsetT val)
   3099 {
   3100   char * terminal = xmalloc (28);  /* Enough for long long.  */
   3101 
   3102   terminal[0] = '#';
   3103   bfd_sprintf_vma (stdoutput, terminal + 1, val);
   3104   return terminal;
   3105 }
   3106 
   3107 /* Convert given expression to a new complex-relocation symbol name.
   3108    This is a recursive function, since it traverses the entire given
   3109    expression tree.  The caller owns the returning string, so should
   3110    free() it eventually.  Errors are indicated via as_bad() and a NULL
   3111    return value.  */
   3112 
   3113 char *
   3114 symbol_relc_make_expr (expressionS * exp)
   3115 {
   3116   char * opstr = NULL; /* Operator prefix string.  */
   3117   int    arity = 0;    /* Arity of this operator.  */
   3118   char * operands[3];  /* Up to three operands.  */
   3119   char * concat_string = NULL;
   3120 
   3121   operands[0] = operands[1] = operands[2] = NULL;
   3122 
   3123   gas_assert (exp != NULL);
   3124 
   3125   /* Match known operators -> fill in opstr, arity, operands[] and fall
   3126      through to construct subexpression fragments; may instead return
   3127      string directly for leaf nodes.  */
   3128 
   3129   /* See expr.h for the meaning of all these enums.  Many operators
   3130      have an unnatural arity (X_add_number implicitly added).  The
   3131      conversion logic expands them to explicit "+" subexpressions.   */
   3132 
   3133   switch (exp->X_op)
   3134     {
   3135     default:
   3136       as_bad ("Unknown expression operator (enum %d)", exp->X_op);
   3137       break;
   3138 
   3139       /* Leaf nodes.  */
   3140     case O_constant:
   3141       return symbol_relc_make_value (exp->X_add_number);
   3142 
   3143     case O_symbol:
   3144       if (exp->X_add_number)
   3145 	{
   3146 	  arity = 2;
   3147 	  opstr = "+";
   3148 	  operands[0] = symbol_relc_make_sym (exp->X_add_symbol);
   3149 	  operands[1] = symbol_relc_make_value (exp->X_add_number);
   3150 	  break;
   3151 	}
   3152       else
   3153 	return symbol_relc_make_sym (exp->X_add_symbol);
   3154 
   3155       /* Helper macros for nesting nodes.  */
   3156 
   3157 #define HANDLE_XADD_OPT1(str_) 						\
   3158       if (exp->X_add_number)						\
   3159         {								\
   3160           arity = 2;							\
   3161           opstr = "+:" str_;						\
   3162           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);	\
   3163           operands[1] = symbol_relc_make_value (exp->X_add_number);	\
   3164           break;							\
   3165         }								\
   3166       else								\
   3167         {								\
   3168           arity = 1;							\
   3169           opstr = str_;							\
   3170           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);	\
   3171         }								\
   3172       break
   3173 
   3174 #define HANDLE_XADD_OPT2(str_) 						\
   3175       if (exp->X_add_number)						\
   3176         {								\
   3177           arity = 3;							\
   3178           opstr = "+:" str_;						\
   3179           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);	\
   3180           operands[1] = symbol_relc_make_sym (exp->X_op_symbol);	\
   3181           operands[2] = symbol_relc_make_value (exp->X_add_number);	\
   3182         }								\
   3183       else								\
   3184         {								\
   3185           arity = 2;							\
   3186           opstr = str_;							\
   3187           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);	\
   3188           operands[1] = symbol_relc_make_sym (exp->X_op_symbol);	\
   3189         } 								\
   3190       break
   3191 
   3192       /* Nesting nodes.  */
   3193 
   3194     case O_uminus:       	HANDLE_XADD_OPT1 ("0-");
   3195     case O_bit_not:      	HANDLE_XADD_OPT1 ("~");
   3196     case O_logical_not:  	HANDLE_XADD_OPT1 ("!");
   3197     case O_multiply:     	HANDLE_XADD_OPT2 ("*");
   3198     case O_divide:       	HANDLE_XADD_OPT2 ("/");
   3199     case O_modulus:      	HANDLE_XADD_OPT2 ("%");
   3200     case O_left_shift:   	HANDLE_XADD_OPT2 ("<<");
   3201     case O_right_shift:  	HANDLE_XADD_OPT2 (">>");
   3202     case O_bit_inclusive_or:	HANDLE_XADD_OPT2 ("|");
   3203     case O_bit_exclusive_or:	HANDLE_XADD_OPT2 ("^");
   3204     case O_bit_and:      	HANDLE_XADD_OPT2 ("&");
   3205     case O_add:          	HANDLE_XADD_OPT2 ("+");
   3206     case O_subtract:     	HANDLE_XADD_OPT2 ("-");
   3207     case O_eq:           	HANDLE_XADD_OPT2 ("==");
   3208     case O_ne:           	HANDLE_XADD_OPT2 ("!=");
   3209     case O_lt:           	HANDLE_XADD_OPT2 ("<");
   3210     case O_le:           	HANDLE_XADD_OPT2 ("<=");
   3211     case O_ge:           	HANDLE_XADD_OPT2 (">=");
   3212     case O_gt:           	HANDLE_XADD_OPT2 (">");
   3213     case O_logical_and:  	HANDLE_XADD_OPT2 ("&&");
   3214     case O_logical_or:   	HANDLE_XADD_OPT2 ("||");
   3215     }
   3216 
   3217   /* Validate & reject early.  */
   3218   if (arity >= 1 && ((operands[0] == NULL) || (strlen (operands[0]) == 0)))
   3219     opstr = NULL;
   3220   if (arity >= 2 && ((operands[1] == NULL) || (strlen (operands[1]) == 0)))
   3221     opstr = NULL;
   3222   if (arity >= 3 && ((operands[2] == NULL) || (strlen (operands[2]) == 0)))
   3223     opstr = NULL;
   3224 
   3225   if (opstr == NULL)
   3226     concat_string = NULL;
   3227   else
   3228     {
   3229       /* Allocate new string; include inter-operand padding gaps etc.  */
   3230       concat_string = xmalloc (strlen (opstr)
   3231 			       + 1
   3232 			       + (arity >= 1 ? (strlen (operands[0]) + 1 ) : 0)
   3233 			       + (arity >= 2 ? (strlen (operands[1]) + 1 ) : 0)
   3234 			       + (arity >= 3 ? (strlen (operands[2]) + 0 ) : 0)
   3235 			       + 1);
   3236       gas_assert (concat_string != NULL);
   3237 
   3238       /* Format the thing.  */
   3239       sprintf (concat_string,
   3240 	       (arity == 0 ? "%s" :
   3241 		arity == 1 ? "%s:%s" :
   3242 		arity == 2 ? "%s:%s:%s" :
   3243 		/* arity == 3 */ "%s:%s:%s:%s"),
   3244 	       opstr, operands[0], operands[1], operands[2]);
   3245     }
   3246 
   3247   /* Free operand strings (not opstr).  */
   3248   if (arity >= 1) xfree (operands[0]);
   3249   if (arity >= 2) xfree (operands[1]);
   3250   if (arity >= 3) xfree (operands[2]);
   3251 
   3252   return concat_string;
   3253 }
   3254 
   3255 #endif
   3256