Back to index

cell-binutils  2.17cvs20070401
symbols.c
Go to the documentation of this file.
00001 /* symbols.c -symbol table-
00002    Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
00003    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
00004    Free Software Foundation, Inc.
00005 
00006    This file is part of GAS, the GNU Assembler.
00007 
00008    GAS is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    GAS is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with GAS; see the file COPYING.  If not, write to the Free
00020    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00021    02110-1301, USA.  */
00022 
00023 /* #define DEBUG_SYMS / * to debug symbol list maintenance.  */
00024 
00025 #include "as.h"
00026 
00027 #include "safe-ctype.h"
00028 #include "obstack.h"        /* For "symbols.h" */
00029 #include "subsegs.h"
00030 
00031 #include "struc-symbol.h"
00032 
00033 /* This is non-zero if symbols are case sensitive, which is the
00034    default.  */
00035 int symbols_case_sensitive = 1;
00036 
00037 #ifndef WORKING_DOT_WORD
00038 extern int new_broken_words;
00039 #endif
00040 
00041 /* symbol-name => struct symbol pointer */
00042 static struct hash_control *sy_hash;
00043 
00044 /* Table of local symbols.  */
00045 static struct hash_control *local_hash;
00046 
00047 /* Below are commented in "symbols.h".  */
00048 symbolS *symbol_rootP;
00049 symbolS *symbol_lastP;
00050 symbolS abs_symbol;
00051 
00052 #ifdef DEBUG_SYMS
00053 #define debug_verify_symchain verify_symbol_chain
00054 #else
00055 #define debug_verify_symchain(root, last) ((void) 0)
00056 #endif
00057 
00058 #define DOLLAR_LABEL_CHAR   '\001'
00059 #define LOCAL_LABEL_CHAR    '\002'
00060 
00061 struct obstack notes;
00062 #ifdef USE_UNIQUE
00063 /* The name of an external symbol which is
00064    used to make weak PE symbol names unique.  */
00065 const char * an_external_name;
00066 #endif
00067 
00068 static char *save_symbol_name (const char *);
00069 static void fb_label_init (void);
00070 static long dollar_label_instance (long);
00071 static long fb_label_instance (long);
00072 
00073 static void print_binary (FILE *, const char *, expressionS *);
00074 static void report_op_error (symbolS *, symbolS *, symbolS *);
00075 
00076 /* Return a pointer to a new symbol.  Die if we can't make a new
00077    symbol.  Fill in the symbol's values.  Add symbol to end of symbol
00078    chain.
00079 
00080    This function should be called in the general case of creating a
00081    symbol.  However, if the output file symbol table has already been
00082    set, and you are certain that this symbol won't be wanted in the
00083    output file, you can call symbol_create.  */
00084 
00085 symbolS *
00086 symbol_new (const char *name, segT segment, valueT valu, fragS *frag)
00087 {
00088   symbolS *symbolP = symbol_create (name, segment, valu, frag);
00089 
00090   /* Link to end of symbol chain.  */
00091   {
00092     extern int symbol_table_frozen;
00093     if (symbol_table_frozen)
00094       abort ();
00095   }
00096   symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
00097 
00098   return symbolP;
00099 }
00100 
00101 /* Save a symbol name on a permanent obstack, and convert it according
00102    to the object file format.  */
00103 
00104 static char *
00105 save_symbol_name (const char *name)
00106 {
00107   unsigned int name_length;
00108   char *ret;
00109 
00110   name_length = strlen (name) + 1; /* +1 for \0.  */
00111   obstack_grow (&notes, name, name_length);
00112   ret = obstack_finish (&notes);
00113 
00114 #ifdef tc_canonicalize_symbol_name
00115   ret = tc_canonicalize_symbol_name (ret);
00116 #endif
00117 
00118   if (! symbols_case_sensitive)
00119     {
00120       char *s;
00121 
00122       for (s = ret; *s != '\0'; s++)
00123        *s = TOUPPER (*s);
00124     }
00125 
00126   return ret;
00127 }
00128 
00129 symbolS *
00130 symbol_create (const char *name, /* It is copied, the caller can destroy/modify.  */
00131               segT segment, /* Segment identifier (SEG_<something>).  */
00132               valueT valu,  /* Symbol value.  */
00133               fragS *frag   /* Associated fragment.  */)
00134 {
00135   char *preserved_copy_of_name;
00136   symbolS *symbolP;
00137 
00138   preserved_copy_of_name = save_symbol_name (name);
00139 
00140   symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
00141 
00142   /* symbol must be born in some fixed state.  This seems as good as any.  */
00143   memset (symbolP, 0, sizeof (symbolS));
00144 
00145   symbolP->bsym = bfd_make_empty_symbol (stdoutput);
00146   if (symbolP->bsym == NULL)
00147     as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ()));
00148   S_SET_NAME (symbolP, preserved_copy_of_name);
00149 
00150   S_SET_SEGMENT (symbolP, segment);
00151   S_SET_VALUE (symbolP, valu);
00152   symbol_clear_list_pointers (symbolP);
00153 
00154   symbolP->sy_frag = frag;
00155 
00156   obj_symbol_new_hook (symbolP);
00157 
00158 #ifdef tc_symbol_new_hook
00159   tc_symbol_new_hook (symbolP);
00160 #endif
00161 
00162   return symbolP;
00163 }
00164 
00165 
00166 /* Local symbol support.  If we can get away with it, we keep only a
00167    small amount of information for local symbols.  */
00168 
00169 static symbolS *local_symbol_convert (struct local_symbol *);
00170 
00171 /* Used for statistics.  */
00172 
00173 static unsigned long local_symbol_count;
00174 static unsigned long local_symbol_conversion_count;
00175 
00176 /* This macro is called with a symbol argument passed by reference.
00177    It returns whether this is a local symbol.  If necessary, it
00178    changes its argument to the real symbol.  */
00179 
00180 #define LOCAL_SYMBOL_CHECK(s)                                         \
00181   (s->bsym == NULL                                             \
00182    ? (local_symbol_converted_p ((struct local_symbol *) s)            \
00183       ? (s = local_symbol_get_real_symbol ((struct local_symbol *) s),       \
00184         0)                                                     \
00185       : 1)                                                     \
00186    : 0)
00187 
00188 /* Create a local symbol and insert it into the local hash table.  */
00189 
00190 static struct local_symbol *
00191 local_symbol_make (const char *name, segT section, valueT value, fragS *frag)
00192 {
00193   char *name_copy;
00194   struct local_symbol *ret;
00195 
00196   ++local_symbol_count;
00197 
00198   name_copy = save_symbol_name (name);
00199 
00200   ret = (struct local_symbol *) obstack_alloc (&notes, sizeof *ret);
00201   ret->lsy_marker = NULL;
00202   ret->lsy_name = name_copy;
00203   ret->lsy_section = section;
00204   local_symbol_set_frag (ret, frag);
00205   ret->lsy_value = value;
00206 
00207   hash_jam (local_hash, name_copy, (PTR) ret);
00208 
00209   return ret;
00210 }
00211 
00212 /* Convert a local symbol into a real symbol.  Note that we do not
00213    reclaim the space used by the local symbol.  */
00214 
00215 static symbolS *
00216 local_symbol_convert (struct local_symbol *locsym)
00217 {
00218   symbolS *ret;
00219 
00220   assert (locsym->lsy_marker == NULL);
00221   if (local_symbol_converted_p (locsym))
00222     return local_symbol_get_real_symbol (locsym);
00223 
00224   ++local_symbol_conversion_count;
00225 
00226   ret = symbol_new (locsym->lsy_name, locsym->lsy_section, locsym->lsy_value,
00227                   local_symbol_get_frag (locsym));
00228 
00229   if (local_symbol_resolved_p (locsym))
00230     ret->sy_resolved = 1;
00231 
00232   /* Local symbols are always either defined or used.  */
00233   ret->sy_used = 1;
00234 
00235 #ifdef TC_LOCAL_SYMFIELD_CONVERT
00236   TC_LOCAL_SYMFIELD_CONVERT (locsym, ret);
00237 #endif
00238 
00239   symbol_table_insert (ret);
00240 
00241   local_symbol_mark_converted (locsym);
00242   local_symbol_set_real_symbol (locsym, ret);
00243 
00244   hash_jam (local_hash, locsym->lsy_name, NULL);
00245 
00246   return ret;
00247 }
00248 
00249 /* We have just seen "<name>:".
00250    Creates a struct symbol unless it already exists.
00251 
00252    Gripes if we are redefining a symbol incompatibly (and ignores it).  */
00253 
00254 symbolS *
00255 colon (/* Just seen "x:" - rattle symbols & frags.  */
00256        const char *sym_name /* Symbol name, as a cannonical string.  */
00257        /* We copy this string: OK to alter later.  */)
00258 {
00259   register symbolS *symbolP;       /* Symbol we are working with.  */
00260 
00261   /* Sun local labels go out of scope whenever a non-local symbol is
00262      defined.  */
00263   if (LOCAL_LABELS_DOLLAR
00264       && !bfd_is_local_label_name (stdoutput, sym_name))
00265     dollar_label_clear ();
00266 
00267 #ifndef WORKING_DOT_WORD
00268   if (new_broken_words)
00269     {
00270       struct broken_word *a;
00271       int possible_bytes;
00272       fragS *frag_tmp;
00273       char *frag_opcode;
00274 
00275       if (now_seg == absolute_section)
00276        {
00277          as_bad (_("cannot define symbol `%s' in absolute section"), sym_name);
00278          return NULL;
00279        }
00280 
00281       possible_bytes = (md_short_jump_size
00282                      + new_broken_words * md_long_jump_size);
00283 
00284       frag_tmp = frag_now;
00285       frag_opcode = frag_var (rs_broken_word,
00286                            possible_bytes,
00287                            possible_bytes,
00288                            (relax_substateT) 0,
00289                            (symbolS *) broken_words,
00290                            (offsetT) 0,
00291                            NULL);
00292 
00293       /* We want to store the pointer to where to insert the jump
00294         table in the fr_opcode of the rs_broken_word frag.  This
00295         requires a little hackery.  */
00296       while (frag_tmp
00297             && (frag_tmp->fr_type != rs_broken_word
00298                || frag_tmp->fr_opcode))
00299        frag_tmp = frag_tmp->fr_next;
00300       know (frag_tmp);
00301       frag_tmp->fr_opcode = frag_opcode;
00302       new_broken_words = 0;
00303 
00304       for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
00305        a->dispfrag = frag_tmp;
00306     }
00307 #endif /* WORKING_DOT_WORD */
00308 
00309   if ((symbolP = symbol_find (sym_name)) != 0)
00310     {
00311       S_CLEAR_WEAKREFR (symbolP);
00312 #ifdef RESOLVE_SYMBOL_REDEFINITION
00313       if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
00314        return symbolP;
00315 #endif
00316       /* Now check for undefined symbols.  */
00317       if (LOCAL_SYMBOL_CHECK (symbolP))
00318        {
00319          struct local_symbol *locsym = (struct local_symbol *) symbolP;
00320 
00321          if (locsym->lsy_section != undefined_section
00322              && (local_symbol_get_frag (locsym) != frag_now
00323                 || locsym->lsy_section != now_seg
00324                 || locsym->lsy_value != frag_now_fix ()))
00325            {
00326              as_bad (_("symbol `%s' is already defined"), sym_name);
00327              return symbolP;
00328            }
00329 
00330          locsym->lsy_section = now_seg;
00331          local_symbol_set_frag (locsym, frag_now);
00332          locsym->lsy_value = frag_now_fix ();
00333        }
00334       else if (!(S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
00335               || S_IS_COMMON (symbolP)
00336               || S_IS_VOLATILE (symbolP))
00337        {
00338          if (S_IS_VOLATILE (symbolP))
00339            {
00340              symbolP = symbol_clone (symbolP, 1);
00341              S_SET_VALUE (symbolP, 0);
00342              S_CLEAR_VOLATILE (symbolP);
00343            }
00344          if (S_GET_VALUE (symbolP) == 0)
00345            {
00346              symbolP->sy_frag = frag_now;
00347 #ifdef OBJ_VMS
00348              S_SET_OTHER (symbolP, const_flag);
00349 #endif
00350              S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
00351              S_SET_SEGMENT (symbolP, now_seg);
00352 #ifdef N_UNDF
00353              know (N_UNDF == 0);
00354 #endif /* if we have one, it better be zero.  */
00355 
00356            }
00357          else
00358            {
00359              /* There are still several cases to check:
00360 
00361                A .comm/.lcomm symbol being redefined as initialized
00362                data is OK
00363 
00364                A .comm/.lcomm symbol being redefined with a larger
00365                size is also OK
00366 
00367                This only used to be allowed on VMS gas, but Sun cc
00368                on the sparc also depends on it.  */
00369 
00370              if (((!S_IS_DEBUG (symbolP)
00371                   && (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
00372                   && S_IS_EXTERNAL (symbolP))
00373                  || S_GET_SEGMENT (symbolP) == bss_section)
00374                 && (now_seg == data_section
00375                     || now_seg == bss_section
00376                     || now_seg == S_GET_SEGMENT (symbolP)))
00377               {
00378                 /* Select which of the 2 cases this is.  */
00379                 if (now_seg != data_section)
00380                   {
00381                     /* New .comm for prev .comm symbol.
00382 
00383                       If the new size is larger we just change its
00384                       value.  If the new size is smaller, we ignore
00385                       this symbol.  */
00386                     if (S_GET_VALUE (symbolP)
00387                        < ((unsigned) frag_now_fix ()))
00388                      {
00389                        S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
00390                      }
00391                   }
00392                 else
00393                   {
00394                     /* It is a .comm/.lcomm being converted to initialized
00395                       data.  */
00396                     symbolP->sy_frag = frag_now;
00397 #ifdef OBJ_VMS
00398                     S_SET_OTHER (symbolP, const_flag);
00399 #endif
00400                     S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
00401                     S_SET_SEGMENT (symbolP, now_seg);   /* Keep N_EXT bit.  */
00402                   }
00403               }
00404              else
00405               {
00406 #if (!defined (OBJ_AOUT) && !defined (OBJ_MAYBE_AOUT) \
00407      && !defined (OBJ_BOUT) && !defined (OBJ_MAYBE_BOUT))
00408                 static const char *od_buf = "";
00409 #else
00410                 char od_buf[100];
00411                 od_buf[0] = '\0';
00412                 if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
00413                   sprintf (od_buf, "%d.%d.",
00414                           S_GET_OTHER (symbolP),
00415                           S_GET_DESC (symbolP));
00416 #endif
00417                 as_bad (_("symbol `%s' is already defined as \"%s\"/%s%ld"),
00418                          sym_name,
00419                          segment_name (S_GET_SEGMENT (symbolP)),
00420                          od_buf,
00421                          (long) S_GET_VALUE (symbolP));
00422               }
00423            }                /* if the undefined symbol has no value  */
00424        }
00425       else
00426        {
00427          /* Don't blow up if the definition is the same.  */
00428          if (!(frag_now == symbolP->sy_frag
00429               && S_GET_VALUE (symbolP) == frag_now_fix ()
00430               && S_GET_SEGMENT (symbolP) == now_seg))
00431            {
00432              as_bad (_("symbol `%s' is already defined"), sym_name);
00433              symbolP = symbol_clone (symbolP, 0);
00434            }
00435        }
00436 
00437     }
00438   else if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, sym_name))
00439     {
00440       symbolP = (symbolS *) local_symbol_make (sym_name, now_seg,
00441                                           (valueT) frag_now_fix (),
00442                                           frag_now);
00443     }
00444   else
00445     {
00446       symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (),
00447                          frag_now);
00448 #ifdef OBJ_VMS
00449       S_SET_OTHER (symbolP, const_flag);
00450 #endif /* OBJ_VMS */
00451 
00452       symbol_table_insert (symbolP);
00453     }
00454 
00455   if (mri_common_symbol != NULL)
00456     {
00457       /* This symbol is actually being defined within an MRI common
00458         section.  This requires special handling.  */
00459       if (LOCAL_SYMBOL_CHECK (symbolP))
00460        symbolP = local_symbol_convert ((struct local_symbol *) symbolP);
00461       symbolP->sy_value.X_op = O_symbol;
00462       symbolP->sy_value.X_add_symbol = mri_common_symbol;
00463       symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol);
00464       symbolP->sy_frag = &zero_address_frag;
00465       S_SET_SEGMENT (symbolP, expr_section);
00466       symbolP->sy_mri_common = 1;
00467     }
00468 
00469 #ifdef tc_frob_label
00470   tc_frob_label (symbolP);
00471 #endif
00472 #ifdef obj_frob_label
00473   obj_frob_label (symbolP);
00474 #endif
00475 
00476   return symbolP;
00477 }
00478 
00479 /* Die if we can't insert the symbol.  */
00480 
00481 void
00482 symbol_table_insert (symbolS *symbolP)
00483 {
00484   register const char *error_string;
00485 
00486   know (symbolP);
00487   know (S_GET_NAME (symbolP));
00488 
00489   if (LOCAL_SYMBOL_CHECK (symbolP))
00490     {
00491       error_string = hash_jam (local_hash, S_GET_NAME (symbolP),
00492                             (PTR) symbolP);
00493       if (error_string != NULL)
00494        as_fatal (_("inserting \"%s\" into symbol table failed: %s"),
00495                 S_GET_NAME (symbolP), error_string);
00496       return;
00497     }
00498 
00499   if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
00500     {
00501       as_fatal (_("inserting \"%s\" into symbol table failed: %s"),
00502               S_GET_NAME (symbolP), error_string);
00503     }                       /* on error  */
00504 }
00505 
00506 /* If a symbol name does not exist, create it as undefined, and insert
00507    it into the symbol table.  Return a pointer to it.  */
00508 
00509 symbolS *
00510 symbol_find_or_make (const char *name)
00511 {
00512   register symbolS *symbolP;
00513 
00514   symbolP = symbol_find (name);
00515 
00516   if (symbolP == NULL)
00517     {
00518       if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, name))
00519        {
00520          symbolP = md_undefined_symbol ((char *) name);
00521          if (symbolP != NULL)
00522            return symbolP;
00523 
00524          symbolP = (symbolS *) local_symbol_make (name, undefined_section,
00525                                              (valueT) 0,
00526                                              &zero_address_frag);
00527          return symbolP;
00528        }
00529 
00530       symbolP = symbol_make (name);
00531 
00532       symbol_table_insert (symbolP);
00533     }                       /* if symbol wasn't found */
00534 
00535   return (symbolP);
00536 }
00537 
00538 symbolS *
00539 symbol_make (const char *name)
00540 {
00541   symbolS *symbolP;
00542 
00543   /* Let the machine description default it, e.g. for register names.  */
00544   symbolP = md_undefined_symbol ((char *) name);
00545 
00546   if (!symbolP)
00547     symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
00548 
00549   return (symbolP);
00550 }
00551 
00552 symbolS *
00553 symbol_clone (symbolS *orgsymP, int replace)
00554 {
00555   symbolS *newsymP;
00556   asymbol *bsymorg, *bsymnew;
00557 
00558   /* Running local_symbol_convert on a clone that's not the one currently
00559      in local_hash would incorrectly replace the hash entry.  Thus the
00560      symbol must be converted here.  Note that the rest of the function
00561      depends on not encountering an unconverted symbol.  */
00562   if (LOCAL_SYMBOL_CHECK (orgsymP))
00563     orgsymP = local_symbol_convert ((struct local_symbol *) orgsymP);
00564   bsymorg = orgsymP->bsym;
00565 
00566   know (S_IS_DEFINED (orgsymP));
00567 
00568   newsymP = obstack_alloc (&notes, sizeof (*newsymP));
00569   *newsymP = *orgsymP;
00570   bsymnew = bfd_make_empty_symbol (bfd_asymbol_bfd (bsymorg));
00571   if (bsymnew == NULL)
00572     as_fatal ("bfd_make_empty_symbol: %s", bfd_errmsg (bfd_get_error ()));
00573   newsymP->bsym = bsymnew;
00574   bsymnew->name = bsymorg->name;
00575   bsymnew->flags =  bsymorg->flags;
00576   bsymnew->section =  bsymorg->section;
00577   bfd_copy_private_symbol_data (bfd_asymbol_bfd (bsymorg), bsymorg,
00578                             bfd_asymbol_bfd (bsymnew), bsymnew);
00579 
00580 #ifdef obj_symbol_clone_hook
00581   obj_symbol_clone_hook (newsymP, orgsymP);
00582 #endif
00583 
00584 #ifdef tc_symbol_clone_hook
00585   tc_symbol_clone_hook (newsymP, orgsymP);
00586 #endif
00587 
00588   if (replace)
00589     {
00590       if (symbol_rootP == orgsymP)
00591        symbol_rootP = newsymP;
00592       else if (orgsymP->sy_previous)
00593        {
00594          orgsymP->sy_previous->sy_next = newsymP;
00595          orgsymP->sy_previous = NULL;
00596        }
00597       if (symbol_lastP == orgsymP)
00598        symbol_lastP = newsymP;
00599       else if (orgsymP->sy_next)
00600        orgsymP->sy_next->sy_previous = newsymP;
00601       orgsymP->sy_previous = orgsymP->sy_next = orgsymP;
00602       debug_verify_symchain (symbol_rootP, symbol_lastP);
00603 
00604       symbol_table_insert (newsymP);
00605     }
00606   else
00607     newsymP->sy_previous = newsymP->sy_next = newsymP;
00608 
00609   return newsymP;
00610 }
00611 
00612 /* Referenced symbols, if they are forward references, need to be cloned
00613    (without replacing the original) so that the value of the referenced
00614    symbols at the point of use .  */
00615 
00616 #undef symbol_clone_if_forward_ref
00617 symbolS *
00618 symbol_clone_if_forward_ref (symbolS *symbolP, int is_forward)
00619 {
00620   if (symbolP && !LOCAL_SYMBOL_CHECK (symbolP))
00621     {
00622       symbolS *add_symbol = symbolP->sy_value.X_add_symbol;
00623       symbolS *op_symbol = symbolP->sy_value.X_op_symbol;
00624 
00625       if (symbolP->sy_forward_ref)
00626        is_forward = 1;
00627 
00628       if (is_forward)
00629        {
00630          /* assign_symbol() clones volatile symbols; pre-existing expressions
00631             hold references to the original instance, but want the current
00632             value.  Just repeat the lookup.  */
00633          if (add_symbol && S_IS_VOLATILE (add_symbol))
00634            add_symbol = symbol_find_exact (S_GET_NAME (add_symbol));
00635          if (op_symbol && S_IS_VOLATILE (op_symbol))
00636            op_symbol = symbol_find_exact (S_GET_NAME (op_symbol));
00637        }
00638 
00639       /* Re-using sy_resolving here, as this routine cannot get called from
00640         symbol resolution code.  */
00641       if (symbolP->bsym->section == expr_section && !symbolP->sy_resolving)
00642        {
00643          symbolP->sy_resolving = 1;
00644          add_symbol = symbol_clone_if_forward_ref (add_symbol, is_forward);
00645          op_symbol = symbol_clone_if_forward_ref (op_symbol, is_forward);
00646          symbolP->sy_resolving = 0;
00647        }
00648 
00649       if (symbolP->sy_forward_ref
00650          || add_symbol != symbolP->sy_value.X_add_symbol
00651          || op_symbol != symbolP->sy_value.X_op_symbol)
00652        symbolP = symbol_clone (symbolP, 0);
00653 
00654       symbolP->sy_value.X_add_symbol = add_symbol;
00655       symbolP->sy_value.X_op_symbol = op_symbol;
00656     }
00657 
00658   return symbolP;
00659 }
00660 
00661 symbolS *
00662 symbol_temp_new (segT seg, valueT ofs, fragS *frag)
00663 {
00664   return symbol_new (FAKE_LABEL_NAME, seg, ofs, frag);
00665 }
00666 
00667 symbolS *
00668 symbol_temp_new_now (void)
00669 {
00670   return symbol_temp_new (now_seg, frag_now_fix (), frag_now);
00671 }
00672 
00673 symbolS *
00674 symbol_temp_make (void)
00675 {
00676   return symbol_make (FAKE_LABEL_NAME);
00677 }
00678 
00679 /* Implement symbol table lookup.
00680    In: A symbol's name as a string: '\0' can't be part of a symbol name.
00681    Out:       NULL if the name was not in the symbol table, else the address
00682    of a struct symbol associated with that name.  */
00683 
00684 symbolS *
00685 symbol_find_exact (const char *name)
00686 {
00687   return symbol_find_exact_noref (name, 0);
00688 }
00689 
00690 symbolS *
00691 symbol_find_exact_noref (const char *name, int noref)
00692 {
00693   struct local_symbol *locsym;
00694   symbolS* sym;
00695 
00696   locsym = (struct local_symbol *) hash_find (local_hash, name);
00697   if (locsym != NULL)
00698     return (symbolS *) locsym;
00699 
00700   sym = ((symbolS *) hash_find (sy_hash, name));
00701 
00702   /* Any references to the symbol, except for the reference in
00703      .weakref, must clear this flag, such that the symbol does not
00704      turn into a weak symbol.  Note that we don't have to handle the
00705      local_symbol case, since a weakrefd is always promoted out of the
00706      local_symbol table when it is turned into a weak symbol.  */
00707   if (sym && ! noref)
00708     S_CLEAR_WEAKREFD (sym);
00709 
00710   return sym;
00711 }
00712 
00713 symbolS *
00714 symbol_find (const char *name)
00715 {
00716   return symbol_find_noref (name, 0);
00717 }
00718 
00719 symbolS *
00720 symbol_find_noref (const char *name, int noref)
00721 {
00722 #ifdef tc_canonicalize_symbol_name
00723   {
00724     char *copy;
00725     size_t len = strlen (name) + 1;
00726 
00727     copy = (char *) alloca (len);
00728     memcpy (copy, name, len);
00729     name = tc_canonicalize_symbol_name (copy);
00730   }
00731 #endif
00732 
00733   if (! symbols_case_sensitive)
00734     {
00735       char *copy;
00736       const char *orig;
00737       unsigned char c;
00738 
00739       orig = name;
00740       name = copy = (char *) alloca (strlen (name) + 1);
00741 
00742       while ((c = *orig++) != '\0')
00743        {
00744          *copy++ = TOUPPER (c);
00745        }
00746       *copy = '\0';
00747     }
00748 
00749   return symbol_find_exact_noref (name, noref);
00750 }
00751 
00752 /* Once upon a time, symbols were kept in a singly linked list.  At
00753    least coff needs to be able to rearrange them from time to time, for
00754    which a doubly linked list is much more convenient.  Loic did these
00755    as macros which seemed dangerous to me so they're now functions.
00756    xoxorich.  */
00757 
00758 /* Link symbol ADDME after symbol TARGET in the chain.  */
00759 
00760 void
00761 symbol_append (symbolS *addme, symbolS *target,
00762               symbolS **rootPP, symbolS **lastPP)
00763 {
00764   if (LOCAL_SYMBOL_CHECK (addme))
00765     abort ();
00766   if (target != NULL && LOCAL_SYMBOL_CHECK (target))
00767     abort ();
00768 
00769   if (target == NULL)
00770     {
00771       know (*rootPP == NULL);
00772       know (*lastPP == NULL);
00773       addme->sy_next = NULL;
00774       addme->sy_previous = NULL;
00775       *rootPP = addme;
00776       *lastPP = addme;
00777       return;
00778     }                       /* if the list is empty  */
00779 
00780   if (target->sy_next != NULL)
00781     {
00782       target->sy_next->sy_previous = addme;
00783     }
00784   else
00785     {
00786       know (*lastPP == target);
00787       *lastPP = addme;
00788     }                       /* if we have a next  */
00789 
00790   addme->sy_next = target->sy_next;
00791   target->sy_next = addme;
00792   addme->sy_previous = target;
00793 
00794   debug_verify_symchain (symbol_rootP, symbol_lastP);
00795 }
00796 
00797 /* Set the chain pointers of SYMBOL to null.  */
00798 
00799 void
00800 symbol_clear_list_pointers (symbolS *symbolP)
00801 {
00802   if (LOCAL_SYMBOL_CHECK (symbolP))
00803     abort ();
00804   symbolP->sy_next = NULL;
00805   symbolP->sy_previous = NULL;
00806 }
00807 
00808 /* Remove SYMBOLP from the list.  */
00809 
00810 void
00811 symbol_remove (symbolS *symbolP, symbolS **rootPP, symbolS **lastPP)
00812 {
00813   if (LOCAL_SYMBOL_CHECK (symbolP))
00814     abort ();
00815 
00816   if (symbolP == *rootPP)
00817     {
00818       *rootPP = symbolP->sy_next;
00819     }                       /* if it was the root  */
00820 
00821   if (symbolP == *lastPP)
00822     {
00823       *lastPP = symbolP->sy_previous;
00824     }                       /* if it was the tail  */
00825 
00826   if (symbolP->sy_next != NULL)
00827     {
00828       symbolP->sy_next->sy_previous = symbolP->sy_previous;
00829     }                       /* if not last  */
00830 
00831   if (symbolP->sy_previous != NULL)
00832     {
00833       symbolP->sy_previous->sy_next = symbolP->sy_next;
00834     }                       /* if not first  */
00835 
00836   debug_verify_symchain (*rootPP, *lastPP);
00837 }
00838 
00839 /* Link symbol ADDME before symbol TARGET in the chain.  */
00840 
00841 void
00842 symbol_insert (symbolS *addme, symbolS *target,
00843               symbolS **rootPP, symbolS **lastPP ATTRIBUTE_UNUSED)
00844 {
00845   if (LOCAL_SYMBOL_CHECK (addme))
00846     abort ();
00847   if (LOCAL_SYMBOL_CHECK (target))
00848     abort ();
00849 
00850   if (target->sy_previous != NULL)
00851     {
00852       target->sy_previous->sy_next = addme;
00853     }
00854   else
00855     {
00856       know (*rootPP == target);
00857       *rootPP = addme;
00858     }                       /* if not first  */
00859 
00860   addme->sy_previous = target->sy_previous;
00861   target->sy_previous = addme;
00862   addme->sy_next = target;
00863 
00864   debug_verify_symchain (*rootPP, *lastPP);
00865 }
00866 
00867 void
00868 verify_symbol_chain (symbolS *rootP, symbolS *lastP)
00869 {
00870   symbolS *symbolP = rootP;
00871 
00872   if (symbolP == NULL)
00873     return;
00874 
00875   for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
00876     {
00877       assert (symbolP->bsym != NULL);
00878       assert (symbolP->sy_next->sy_previous == symbolP);
00879     }
00880 
00881   assert (lastP == symbolP);
00882 }
00883 
00884 #ifdef OBJ_COMPLEX_RELC
00885 
00886 static int
00887 use_complex_relocs_for (symbolS * symp)
00888 {
00889   switch (symp->sy_value.X_op)
00890     {
00891     case O_constant:
00892       return 0;
00893 
00894     case O_symbol:
00895     case O_symbol_rva:
00896     case O_uminus:
00897     case O_bit_not:
00898     case O_logical_not:
00899       if (  (S_IS_COMMON (symp->sy_value.X_add_symbol)
00900           || S_IS_LOCAL (symp->sy_value.X_add_symbol))
00901          &&
00902              (S_IS_DEFINED (symp->sy_value.X_add_symbol)
00903           && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section))
00904        return 0;
00905       break;
00906 
00907     case O_multiply:
00908     case O_divide:
00909     case O_modulus:
00910     case O_left_shift:
00911     case O_right_shift:
00912     case O_bit_inclusive_or:
00913     case O_bit_or_not:
00914     case O_bit_exclusive_or:
00915     case O_bit_and:
00916     case O_add:
00917     case O_subtract:
00918     case O_eq:
00919     case O_ne:
00920     case O_lt:
00921     case O_le:
00922     case O_ge:
00923     case O_gt:
00924     case O_logical_and:
00925     case O_logical_or:
00926 
00927       if (  (S_IS_COMMON (symp->sy_value.X_add_symbol)
00928           || S_IS_LOCAL (symp->sy_value.X_add_symbol))
00929          && 
00930            (S_IS_COMMON (symp->sy_value.X_op_symbol)
00931           || S_IS_LOCAL (symp->sy_value.X_op_symbol))
00932 
00933          && S_IS_DEFINED (symp->sy_value.X_add_symbol)
00934          && S_IS_DEFINED (symp->sy_value.X_op_symbol)
00935          && S_GET_SEGMENT (symp->sy_value.X_add_symbol) != expr_section
00936          && S_GET_SEGMENT (symp->sy_value.X_op_symbol) != expr_section)
00937        return 0;
00938       break;
00939       
00940     default:
00941       break;
00942     }
00943   return 1;
00944 }
00945 #endif
00946 
00947 static void
00948 report_op_error (symbolS *symp, symbolS *left, symbolS *right)
00949 {
00950   char *file;
00951   unsigned int line;
00952   segT seg_left = S_GET_SEGMENT (left);
00953   segT seg_right = right ? S_GET_SEGMENT (right) : 0;
00954 
00955   if (expr_symbol_where (symp, &file, &line))
00956     {
00957       if (seg_left == undefined_section)
00958        as_bad_where (file, line,
00959                     _("undefined symbol `%s' in operation"),
00960                     S_GET_NAME (left));
00961       if (seg_right == undefined_section)
00962        as_bad_where (file, line,
00963                     _("undefined symbol `%s' in operation"),
00964                     S_GET_NAME (right));
00965       if (seg_left != undefined_section
00966          && seg_right != undefined_section)
00967        {
00968          if (right)
00969            as_bad_where (file, line,
00970                        _("invalid sections for operation on `%s' and `%s'"),
00971                        S_GET_NAME (left), S_GET_NAME (right));
00972          else
00973            as_bad_where (file, line,
00974                        _("invalid section for operation on `%s'"),
00975                        S_GET_NAME (left));
00976        }
00977 
00978     }
00979   else
00980     {
00981       if (seg_left == undefined_section)
00982        as_bad (_("undefined symbol `%s' in operation setting `%s'"),
00983               S_GET_NAME (left), S_GET_NAME (symp));
00984       if (seg_right == undefined_section)
00985        as_bad (_("undefined symbol `%s' in operation setting `%s'"),
00986               S_GET_NAME (right), S_GET_NAME (symp));
00987       if (seg_left != undefined_section
00988          && seg_right != undefined_section)
00989        {
00990          if (right)
00991            as_bad (_("invalid sections for operation on `%s' and `%s' setting `%s'"),
00992                   S_GET_NAME (left), S_GET_NAME (right), S_GET_NAME (symp));
00993          else
00994            as_bad (_("invalid section for operation on `%s' setting `%s'"),
00995                   S_GET_NAME (left), S_GET_NAME (symp));
00996        }
00997     }
00998 }
00999 
01000 /* Resolve the value of a symbol.  This is called during the final
01001    pass over the symbol table to resolve any symbols with complex
01002    values.  */
01003 
01004 valueT
01005 resolve_symbol_value (symbolS *symp)
01006 {
01007   int resolved;
01008   valueT final_val = 0;
01009   segT final_seg;
01010 
01011   if (LOCAL_SYMBOL_CHECK (symp))
01012     {
01013       struct local_symbol *locsym = (struct local_symbol *) symp;
01014 
01015       final_val = locsym->lsy_value;
01016       if (local_symbol_resolved_p (locsym))
01017        return final_val;
01018 
01019       final_val += local_symbol_get_frag (locsym)->fr_address / OCTETS_PER_BYTE;
01020 
01021       if (finalize_syms)
01022        {
01023          locsym->lsy_value = final_val;
01024          local_symbol_mark_resolved (locsym);
01025        }
01026 
01027       return final_val;
01028     }
01029 
01030   if (symp->sy_resolved)
01031     {
01032       if (symp->sy_value.X_op == O_constant)
01033        return (valueT) symp->sy_value.X_add_number;
01034       else
01035        return 0;
01036     }
01037 
01038   resolved = 0;
01039   final_seg = S_GET_SEGMENT (symp);
01040 
01041   if (symp->sy_resolving)
01042     {
01043       if (finalize_syms)
01044        as_bad (_("symbol definition loop encountered at `%s'"),
01045               S_GET_NAME (symp));
01046       final_val = 0;
01047       resolved = 1;
01048     }
01049 #ifdef OBJ_COMPLEX_RELC
01050   else if (final_seg == expr_section
01051           && use_complex_relocs_for (symp))
01052     {
01053       symbolS * relc_symbol = NULL;
01054       char * relc_symbol_name = NULL;
01055 
01056       relc_symbol_name = symbol_relc_make_expr (& symp->sy_value);
01057 
01058       /* For debugging, print out conversion input & output.  */
01059 #ifdef DEBUG_SYMS
01060       print_expr (& symp->sy_value);
01061       if (relc_symbol_name)
01062        fprintf (stderr, "-> relc symbol: %s\n", relc_symbol_name);
01063 #endif
01064 
01065       if (relc_symbol_name != NULL)
01066        relc_symbol = symbol_new (relc_symbol_name, undefined_section,
01067                               0, & zero_address_frag);
01068 
01069       if (relc_symbol == NULL)
01070        {
01071          as_bad (_("cannot convert expression symbol %s to complex relocation"),
01072                 S_GET_NAME (symp));
01073          resolved = 0;
01074        }
01075       else
01076        {
01077          symbol_table_insert (relc_symbol);
01078 
01079          /* S_CLEAR_EXTERNAL (relc_symbol); */
01080          if (symp->bsym->flags & BSF_SRELC)
01081            relc_symbol->bsym->flags |= BSF_SRELC;
01082          else
01083            relc_symbol->bsym->flags |= BSF_RELC;   
01084          /* symp->bsym->flags |= BSF_RELC; */
01085          copy_symbol_attributes (symp, relc_symbol);
01086          symp->sy_value.X_op = O_symbol;
01087          symp->sy_value.X_add_symbol = relc_symbol;
01088          symp->sy_value.X_add_number = 0;
01089          resolved = 1;
01090        }
01091 
01092       final_seg = undefined_section;
01093       goto exit_dont_set_value;
01094     }
01095 #endif
01096   else
01097     {
01098       symbolS *add_symbol, *op_symbol;
01099       offsetT left, right;
01100       segT seg_left, seg_right;
01101       operatorT op;
01102       int move_seg_ok;
01103 
01104       symp->sy_resolving = 1;
01105 
01106       /* Help out with CSE.  */
01107       add_symbol = symp->sy_value.X_add_symbol;
01108       op_symbol = symp->sy_value.X_op_symbol;
01109       final_val = symp->sy_value.X_add_number;
01110       op = symp->sy_value.X_op;
01111 
01112       switch (op)
01113        {
01114        default:
01115          BAD_CASE (op);
01116          break;
01117 
01118        case O_absent:
01119          final_val = 0;
01120          /* Fall through.  */
01121 
01122        case O_constant:
01123          final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE;
01124          if (final_seg == expr_section)
01125            final_seg = absolute_section;
01126          resolved = 1;
01127          break;
01128 
01129        case O_symbol:
01130        case O_symbol_rva:
01131          left = resolve_symbol_value (add_symbol);
01132          seg_left = S_GET_SEGMENT (add_symbol);
01133          if (finalize_syms)
01134            symp->sy_value.X_op_symbol = NULL;
01135 
01136        do_symbol:
01137          if (S_IS_WEAKREFR (symp))
01138            {
01139              assert (final_val == 0);
01140              if (S_IS_WEAKREFR (add_symbol))
01141               {
01142                 assert (add_symbol->sy_value.X_op == O_symbol
01143                        && add_symbol->sy_value.X_add_number == 0);
01144                 add_symbol = add_symbol->sy_value.X_add_symbol;
01145                 assert (! S_IS_WEAKREFR (add_symbol));
01146                 symp->sy_value.X_add_symbol = add_symbol;
01147               }
01148            }
01149 
01150          if (symp->sy_mri_common)
01151            {
01152              /* This is a symbol inside an MRI common section.  The
01153                relocation routines are going to handle it specially.
01154                Don't change the value.  */
01155              resolved = symbol_resolved_p (add_symbol);
01156              break;
01157            }
01158 
01159          if (finalize_syms && final_val == 0)
01160            {
01161              if (LOCAL_SYMBOL_CHECK (add_symbol))
01162               add_symbol = local_symbol_convert ((struct local_symbol *)
01163                                              add_symbol);
01164              copy_symbol_attributes (symp, add_symbol);
01165            }
01166 
01167          /* If we have equated this symbol to an undefined or common
01168             symbol, keep X_op set to O_symbol, and don't change
01169             X_add_number.  This permits the routine which writes out
01170             relocation to detect this case, and convert the
01171             relocation to be against the symbol to which this symbol
01172             is equated.  */
01173          if (! S_IS_DEFINED (add_symbol)
01174 #if defined (OBJ_COFF) && defined (TE_PE)
01175              || S_IS_WEAK (add_symbol)
01176 #endif
01177              || S_IS_COMMON (add_symbol))
01178            {
01179              if (finalize_syms)
01180               {
01181                 symp->sy_value.X_op = O_symbol;
01182                 symp->sy_value.X_add_symbol = add_symbol;
01183                 symp->sy_value.X_add_number = final_val;
01184                 /* Use X_op_symbol as a flag.  */
01185                 symp->sy_value.X_op_symbol = add_symbol;
01186                 final_seg = seg_left;
01187               }
01188              final_val = 0;
01189              resolved = symbol_resolved_p (add_symbol);
01190              symp->sy_resolving = 0;
01191              goto exit_dont_set_value;
01192            }
01193          else if (finalize_syms
01194                  && ((final_seg == expr_section && seg_left != expr_section)
01195                      || symbol_shadow_p (symp)))
01196            {
01197              /* If the symbol is an expression symbol, do similarly
01198                as for undefined and common syms above.  Handles
01199                "sym +/- expr" where "expr" cannot be evaluated
01200                immediately, and we want relocations to be against
01201                "sym", eg. because it is weak.  */
01202              symp->sy_value.X_op = O_symbol;
01203              symp->sy_value.X_add_symbol = add_symbol;
01204              symp->sy_value.X_add_number = final_val;
01205              symp->sy_value.X_op_symbol = add_symbol;
01206              final_seg = seg_left;
01207              final_val += symp->sy_frag->fr_address + left;
01208              resolved = symbol_resolved_p (add_symbol);
01209              symp->sy_resolving = 0;
01210              goto exit_dont_set_value;
01211            }
01212          else
01213            {
01214              final_val += symp->sy_frag->fr_address + left;
01215              if (final_seg == expr_section || final_seg == undefined_section)
01216               final_seg = seg_left;
01217            }
01218 
01219          resolved = symbol_resolved_p (add_symbol);
01220          if (S_IS_WEAKREFR (symp))
01221            goto exit_dont_set_value;
01222          break;
01223 
01224        case O_uminus:
01225        case O_bit_not:
01226        case O_logical_not:
01227          left = resolve_symbol_value (add_symbol);
01228          seg_left = S_GET_SEGMENT (add_symbol);
01229 
01230          /* By reducing these to the relevant dyadic operator, we get
01231               !S -> S == 0  permitted on anything,
01232               -S -> 0 - S   only permitted on absolute
01233               ~S -> S ^ ~0  only permitted on absolute  */
01234          if (op != O_logical_not && seg_left != absolute_section
01235              && finalize_syms)
01236            report_op_error (symp, add_symbol, NULL);
01237 
01238          if (final_seg == expr_section || final_seg == undefined_section)
01239            final_seg = absolute_section;
01240 
01241          if (op == O_uminus)
01242            left = -left;
01243          else if (op == O_logical_not)
01244            left = !left;
01245          else
01246            left = ~left;
01247 
01248          final_val += left + symp->sy_frag->fr_address;
01249 
01250          resolved = symbol_resolved_p (add_symbol);
01251          break;
01252 
01253        case O_multiply:
01254        case O_divide:
01255        case O_modulus:
01256        case O_left_shift:
01257        case O_right_shift:
01258        case O_bit_inclusive_or:
01259        case O_bit_or_not:
01260        case O_bit_exclusive_or:
01261        case O_bit_and:
01262        case O_add:
01263        case O_subtract:
01264        case O_eq:
01265        case O_ne:
01266        case O_lt:
01267        case O_le:
01268        case O_ge:
01269        case O_gt:
01270        case O_logical_and:
01271        case O_logical_or:
01272          left = resolve_symbol_value (add_symbol);
01273          right = resolve_symbol_value (op_symbol);
01274          seg_left = S_GET_SEGMENT (add_symbol);
01275          seg_right = S_GET_SEGMENT (op_symbol);
01276 
01277          /* Simplify addition or subtraction of a constant by folding the
01278             constant into X_add_number.  */
01279          if (op == O_add)
01280            {
01281              if (seg_right == absolute_section)
01282               {
01283                 final_val += right;
01284                 goto do_symbol;
01285               }
01286              else if (seg_left == absolute_section)
01287               {
01288                 final_val += left;
01289                 add_symbol = op_symbol;
01290                 left = right;
01291                 seg_left = seg_right;
01292                 goto do_symbol;
01293               }
01294            }
01295          else if (op == O_subtract)
01296            {
01297              if (seg_right == absolute_section)
01298               {
01299                 final_val -= right;
01300                 goto do_symbol;
01301               }
01302            }
01303 
01304          move_seg_ok = 1;
01305          /* Equality and non-equality tests are permitted on anything.
01306             Subtraction, and other comparison operators are permitted if
01307             both operands are in the same section.  Otherwise, both
01308             operands must be absolute.  We already handled the case of
01309             addition or subtraction of a constant above.  This will
01310             probably need to be changed for an object file format which
01311             supports arbitrary expressions, such as IEEE-695.  */
01312          if (!(seg_left == absolute_section
01313                  && seg_right == absolute_section)
01314              && !(op == O_eq || op == O_ne)
01315              && !((op == O_subtract
01316                   || op == O_lt || op == O_le || op == O_ge || op == O_gt)
01317                  && seg_left == seg_right
01318                  && (seg_left != undefined_section
01319                      || add_symbol == op_symbol)))
01320            {
01321              /* Don't emit messages unless we're finalizing the symbol value,
01322                otherwise we may get the same message multiple times.  */
01323              if (finalize_syms)
01324               report_op_error (symp, add_symbol, op_symbol);
01325              /* However do not move the symbol into the absolute section
01326                if it cannot currently be resolved - this would confuse
01327                other parts of the assembler into believing that the
01328                expression had been evaluated to zero.  */
01329              else
01330               move_seg_ok = 0;
01331            }
01332 
01333          if (move_seg_ok
01334              && (final_seg == expr_section || final_seg == undefined_section))
01335            final_seg = absolute_section;
01336 
01337          /* Check for division by zero.  */
01338          if ((op == O_divide || op == O_modulus) && right == 0)
01339            {
01340              /* If seg_right is not absolute_section, then we've
01341                already issued a warning about using a bad symbol.  */
01342              if (seg_right == absolute_section && finalize_syms)
01343               {
01344                 char *file;
01345                 unsigned int line;
01346 
01347                 if (expr_symbol_where (symp, &file, &line))
01348                   as_bad_where (file, line, _("division by zero"));
01349                 else
01350                   as_bad (_("division by zero when setting `%s'"),
01351                          S_GET_NAME (symp));
01352               }
01353 
01354              right = 1;
01355            }
01356 
01357          switch (symp->sy_value.X_op)
01358            {
01359            case O_multiply:        left *= right; break;
01360            case O_divide:          left /= right; break;
01361            case O_modulus:         left %= right; break;
01362            case O_left_shift:             left <<= right; break;
01363            case O_right_shift:            left >>= right; break;
01364            case O_bit_inclusive_or:       left |= right; break;
01365            case O_bit_or_not:             left |= ~right; break;
01366            case O_bit_exclusive_or:       left ^= right; break;
01367            case O_bit_and:         left &= right; break;
01368            case O_add:                    left += right; break;
01369            case O_subtract:        left -= right; break;
01370            case O_eq:
01371            case O_ne:
01372              left = (left == right && seg_left == seg_right
01373                     && (seg_left != undefined_section
01374                        || add_symbol == op_symbol)
01375                     ? ~ (offsetT) 0 : 0);
01376              if (symp->sy_value.X_op == O_ne)
01377               left = ~left;
01378              break;
01379            case O_lt:       left = left <  right ? ~ (offsetT) 0 : 0; break;
01380            case O_le:       left = left <= right ? ~ (offsetT) 0 : 0; break;
01381            case O_ge:       left = left >= right ? ~ (offsetT) 0 : 0; break;
01382            case O_gt:       left = left >  right ? ~ (offsetT) 0 : 0; break;
01383            case O_logical_and:     left = left && right; break;
01384            case O_logical_or:      left = left || right; break;
01385            default:         abort ();
01386            }
01387 
01388          final_val += symp->sy_frag->fr_address + left;
01389          if (final_seg == expr_section || final_seg == undefined_section)
01390            {
01391              if (seg_left == undefined_section
01392                 || seg_right == undefined_section)
01393               final_seg = undefined_section;
01394              else if (seg_left == absolute_section)
01395               final_seg = seg_right;
01396              else
01397               final_seg = seg_left;
01398            }
01399          resolved = (symbol_resolved_p (add_symbol)
01400                     && symbol_resolved_p (op_symbol));
01401          break;
01402 
01403        case O_register:
01404        case O_big:
01405        case O_illegal:
01406          /* Give an error (below) if not in expr_section.  We don't
01407             want to worry about expr_section symbols, because they
01408             are fictional (they are created as part of expression
01409             resolution), and any problems may not actually mean
01410             anything.  */
01411          break;
01412        }
01413 
01414       symp->sy_resolving = 0;
01415     }
01416 
01417   if (finalize_syms)
01418     S_SET_VALUE (symp, final_val);
01419 
01420 exit_dont_set_value:
01421   /* Always set the segment, even if not finalizing the value.
01422      The segment is used to determine whether a symbol is defined.  */
01423     S_SET_SEGMENT (symp, final_seg);
01424 
01425   /* Don't worry if we can't resolve an expr_section symbol.  */
01426   if (finalize_syms)
01427     {
01428       if (resolved)
01429        symp->sy_resolved = 1;
01430       else if (S_GET_SEGMENT (symp) != expr_section)
01431        {
01432          as_bad (_("can't resolve value for symbol `%s'"),
01433                 S_GET_NAME (symp));
01434          symp->sy_resolved = 1;
01435        }
01436     }
01437 
01438   return final_val;
01439 }
01440 
01441 static void resolve_local_symbol (const char *, PTR);
01442 
01443 /* A static function passed to hash_traverse.  */
01444 
01445 static void
01446 resolve_local_symbol (const char *key ATTRIBUTE_UNUSED, PTR value)
01447 {
01448   if (value != NULL)
01449     resolve_symbol_value (value);
01450 }
01451 
01452 /* Resolve all local symbols.  */
01453 
01454 void
01455 resolve_local_symbol_values (void)
01456 {
01457   hash_traverse (local_hash, resolve_local_symbol);
01458 }
01459 
01460 /* Obtain the current value of a symbol without changing any
01461    sub-expressions used.  */
01462 
01463 int
01464 snapshot_symbol (symbolS **symbolPP, valueT *valueP, segT *segP, fragS **fragPP)
01465 {
01466   symbolS *symbolP = *symbolPP;
01467 
01468   if (LOCAL_SYMBOL_CHECK (symbolP))
01469     {
01470       struct local_symbol *locsym = (struct local_symbol *) symbolP;
01471 
01472       *valueP = locsym->lsy_value;
01473       *segP = locsym->lsy_section;
01474       *fragPP = local_symbol_get_frag (locsym);
01475     }
01476   else
01477     {
01478       expressionS expr = symbolP->sy_value;
01479 
01480       if (!symbolP->sy_resolved && expr.X_op != O_illegal)
01481        {
01482          int resolved;
01483 
01484          if (symbolP->sy_resolving)
01485            return 0;
01486          symbolP->sy_resolving = 1;
01487          resolved = resolve_expression (&expr);
01488          symbolP->sy_resolving = 0;
01489          if (!resolved)
01490            return 0;
01491 
01492          switch (expr.X_op)
01493            {
01494            case O_constant:
01495            case O_register:
01496              if (!symbol_equated_p (symbolP))
01497               break;
01498              /* Fall thru.  */
01499            case O_symbol:
01500            case O_symbol_rva:
01501              symbolP = expr.X_add_symbol;
01502              break;
01503            default:
01504              return 0;
01505            }
01506        }
01507 
01508       /* Never change a defined symbol.  */
01509       if (symbolP->bsym->section == undefined_section
01510          || symbolP->bsym->section == expr_section)
01511        *symbolPP = symbolP;
01512       *valueP = expr.X_add_number;
01513       *segP = symbolP->bsym->section;
01514       *fragPP = symbolP->sy_frag;
01515 
01516       if (*segP == expr_section)
01517        switch (expr.X_op)
01518          {
01519          case O_constant: *segP = absolute_section; break;
01520          case O_register: *segP = reg_section; break;
01521          default: break;
01522          }
01523     }
01524 
01525   return 1;
01526 }
01527 
01528 /* Dollar labels look like a number followed by a dollar sign.  Eg, "42$".
01529    They are *really* local.  That is, they go out of scope whenever we see a
01530    label that isn't local.  Also, like fb labels, there can be multiple
01531    instances of a dollar label.  Therefor, we name encode each instance with
01532    the instance number, keep a list of defined symbols separate from the real
01533    symbol table, and we treat these buggers as a sparse array.  */
01534 
01535 static long *dollar_labels;
01536 static long *dollar_label_instances;
01537 static char *dollar_label_defines;
01538 static unsigned long dollar_label_count;
01539 static unsigned long dollar_label_max;
01540 
01541 int
01542 dollar_label_defined (long label)
01543 {
01544   long *i;
01545 
01546   know ((dollar_labels != NULL) || (dollar_label_count == 0));
01547 
01548   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
01549     if (*i == label)
01550       return dollar_label_defines[i - dollar_labels];
01551 
01552   /* If we get here, label isn't defined.  */
01553   return 0;
01554 }
01555 
01556 static long
01557 dollar_label_instance (long label)
01558 {
01559   long *i;
01560 
01561   know ((dollar_labels != NULL) || (dollar_label_count == 0));
01562 
01563   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
01564     if (*i == label)
01565       return (dollar_label_instances[i - dollar_labels]);
01566 
01567   /* If we get here, we haven't seen the label before.
01568      Therefore its instance count is zero.  */
01569   return 0;
01570 }
01571 
01572 void
01573 dollar_label_clear (void)
01574 {
01575   memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
01576 }
01577 
01578 #define DOLLAR_LABEL_BUMP_BY 10
01579 
01580 void
01581 define_dollar_label (long label)
01582 {
01583   long *i;
01584 
01585   for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
01586     if (*i == label)
01587       {
01588        ++dollar_label_instances[i - dollar_labels];
01589        dollar_label_defines[i - dollar_labels] = 1;
01590        return;
01591       }
01592 
01593   /* If we get to here, we don't have label listed yet.  */
01594 
01595   if (dollar_labels == NULL)
01596     {
01597       dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
01598       dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
01599       dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
01600       dollar_label_max = DOLLAR_LABEL_BUMP_BY;
01601       dollar_label_count = 0;
01602     }
01603   else if (dollar_label_count == dollar_label_max)
01604     {
01605       dollar_label_max += DOLLAR_LABEL_BUMP_BY;
01606       dollar_labels = (long *) xrealloc ((char *) dollar_labels,
01607                                     dollar_label_max * sizeof (long));
01608       dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
01609                                      dollar_label_max * sizeof (long));
01610       dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
01611     }                       /* if we needed to grow  */
01612 
01613   dollar_labels[dollar_label_count] = label;
01614   dollar_label_instances[dollar_label_count] = 1;
01615   dollar_label_defines[dollar_label_count] = 1;
01616   ++dollar_label_count;
01617 }
01618 
01619 /* Caller must copy returned name: we re-use the area for the next name.
01620 
01621    The mth occurence of label n: is turned into the symbol "Ln^Am"
01622    where n is the label number and m is the instance number. "L" makes
01623    it a label discarded unless debugging and "^A"('\1') ensures no
01624    ordinary symbol SHOULD get the same name as a local label
01625    symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
01626 
01627    fb labels get the same treatment, except that ^B is used in place
01628    of ^A.  */
01629 
01630 char *                      /* Return local label name.  */
01631 dollar_label_name (register long n,       /* we just saw "n$:" : n a number.  */
01632                  register int augend      /* 0 for current instance, 1 for new instance.  */)
01633 {
01634   long i;
01635   /* Returned to caller, then copied.  Used for created names ("4f").  */
01636   static char symbol_name_build[24];
01637   register char *p;
01638   register char *q;
01639   char symbol_name_temporary[20];  /* Build up a number, BACKWARDS.  */
01640 
01641   know (n >= 0);
01642   know (augend == 0 || augend == 1);
01643   p = symbol_name_build;
01644 #ifdef LOCAL_LABEL_PREFIX
01645   *p++ = LOCAL_LABEL_PREFIX;
01646 #endif
01647   *p++ = 'L';
01648 
01649   /* Next code just does sprintf( {}, "%d", n);  */
01650   /* Label number.  */
01651   q = symbol_name_temporary;
01652   for (*q++ = 0, i = n; i; ++q)
01653     {
01654       *q = i % 10 + '0';
01655       i /= 10;
01656     }
01657   while ((*p = *--q) != '\0')
01658     ++p;
01659 
01660   *p++ = DOLLAR_LABEL_CHAR;        /* ^A  */
01661 
01662   /* Instance number.  */
01663   q = symbol_name_temporary;
01664   for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
01665     {
01666       *q = i % 10 + '0';
01667       i /= 10;
01668     }
01669   while ((*p++ = *--q) != '\0');;
01670 
01671   /* The label, as a '\0' ended string, starts at symbol_name_build.  */
01672   return symbol_name_build;
01673 }
01674 
01675 /* Somebody else's idea of local labels. They are made by "n:" where n
01676    is any decimal digit. Refer to them with
01677     "nb" for previous (backward) n:
01678    or "nf" for next (forward) n:.
01679 
01680    We do a little better and let n be any number, not just a single digit, but
01681    since the other guy's assembler only does ten, we treat the first ten
01682    specially.
01683 
01684    Like someone else's assembler, we have one set of local label counters for
01685    entire assembly, not one set per (sub)segment like in most assemblers. This
01686    implies that one can refer to a label in another segment, and indeed some
01687    crufty compilers have done just that.
01688 
01689    Since there could be a LOT of these things, treat them as a sparse
01690    array.  */
01691 
01692 #define FB_LABEL_SPECIAL (10)
01693 
01694 static long fb_low_counter[FB_LABEL_SPECIAL];
01695 static long *fb_labels;
01696 static long *fb_label_instances;
01697 static long fb_label_count;
01698 static long fb_label_max;
01699 
01700 /* This must be more than FB_LABEL_SPECIAL.  */
01701 #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
01702 
01703 static void
01704 fb_label_init (void)
01705 {
01706   memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
01707 }
01708 
01709 /* Add one to the instance number of this fb label.  */
01710 
01711 void
01712 fb_label_instance_inc (long label)
01713 {
01714   long *i;
01715 
01716   if (label < FB_LABEL_SPECIAL)
01717     {
01718       ++fb_low_counter[label];
01719       return;
01720     }
01721 
01722   if (fb_labels != NULL)
01723     {
01724       for (i = fb_labels + FB_LABEL_SPECIAL;
01725           i < fb_labels + fb_label_count; ++i)
01726        {
01727          if (*i == label)
01728            {
01729              ++fb_label_instances[i - fb_labels];
01730              return;
01731            }                /* if we find it  */
01732        }                    /* for each existing label  */
01733     }
01734 
01735   /* If we get to here, we don't have label listed yet.  */
01736 
01737   if (fb_labels == NULL)
01738     {
01739       fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
01740       fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
01741       fb_label_max = FB_LABEL_BUMP_BY;
01742       fb_label_count = FB_LABEL_SPECIAL;
01743 
01744     }
01745   else if (fb_label_count == fb_label_max)
01746     {
01747       fb_label_max += FB_LABEL_BUMP_BY;
01748       fb_labels = (long *) xrealloc ((char *) fb_labels,
01749                                  fb_label_max * sizeof (long));
01750       fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
01751                                          fb_label_max * sizeof (long));
01752     }                       /* if we needed to grow  */
01753 
01754   fb_labels[fb_label_count] = label;
01755   fb_label_instances[fb_label_count] = 1;
01756   ++fb_label_count;
01757 }
01758 
01759 static long
01760 fb_label_instance (long label)
01761 {
01762   long *i;
01763 
01764   if (label < FB_LABEL_SPECIAL)
01765     {
01766       return (fb_low_counter[label]);
01767     }
01768 
01769   if (fb_labels != NULL)
01770     {
01771       for (i = fb_labels + FB_LABEL_SPECIAL;
01772           i < fb_labels + fb_label_count; ++i)
01773        {
01774          if (*i == label)
01775            {
01776              return (fb_label_instances[i - fb_labels]);
01777            }                /* if we find it  */
01778        }                    /* for each existing label  */
01779     }
01780 
01781   /* We didn't find the label, so this must be a reference to the
01782      first instance.  */
01783   return 0;
01784 }
01785 
01786 /* Caller must copy returned name: we re-use the area for the next name.
01787 
01788    The mth occurence of label n: is turned into the symbol "Ln^Bm"
01789    where n is the label number and m is the instance number. "L" makes
01790    it a label discarded unless debugging and "^B"('\2') ensures no
01791    ordinary symbol SHOULD get the same name as a local label
01792    symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
01793 
01794    dollar labels get the same treatment, except that ^A is used in
01795    place of ^B.  */
01796 
01797 char *                      /* Return local label name.  */
01798 fb_label_name (long n,      /* We just saw "n:", "nf" or "nb" : n a number.  */
01799               long augend   /* 0 for nb, 1 for n:, nf.  */)
01800 {
01801   long i;
01802   /* Returned to caller, then copied.  Used for created names ("4f").  */
01803   static char symbol_name_build[24];
01804   register char *p;
01805   register char *q;
01806   char symbol_name_temporary[20];  /* Build up a number, BACKWARDS.  */
01807 
01808   know (n >= 0);
01809 #ifdef TC_MMIX
01810   know ((unsigned long) augend <= 2 /* See mmix_fb_label.  */);
01811 #else
01812   know ((unsigned long) augend <= 1);
01813 #endif
01814   p = symbol_name_build;
01815 #ifdef LOCAL_LABEL_PREFIX
01816   *p++ = LOCAL_LABEL_PREFIX;
01817 #endif
01818   *p++ = 'L';
01819 
01820   /* Next code just does sprintf( {}, "%d", n);  */
01821   /* Label number.  */
01822   q = symbol_name_temporary;
01823   for (*q++ = 0, i = n; i; ++q)
01824     {
01825       *q = i % 10 + '0';
01826       i /= 10;
01827     }
01828   while ((*p = *--q) != '\0')
01829     ++p;
01830 
01831   *p++ = LOCAL_LABEL_CHAR;         /* ^B  */
01832 
01833   /* Instance number.  */
01834   q = symbol_name_temporary;
01835   for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
01836     {
01837       *q = i % 10 + '0';
01838       i /= 10;
01839     }
01840   while ((*p++ = *--q) != '\0');;
01841 
01842   /* The label, as a '\0' ended string, starts at symbol_name_build.  */
01843   return (symbol_name_build);
01844 }
01845 
01846 /* Decode name that may have been generated by foo_label_name() above.
01847    If the name wasn't generated by foo_label_name(), then return it
01848    unaltered.  This is used for error messages.  */
01849 
01850 char *
01851 decode_local_label_name (char *s)
01852 {
01853   char *p;
01854   char *symbol_decode;
01855   int label_number;
01856   int instance_number;
01857   char *type;
01858   const char *message_format;
01859   int index = 0;
01860 
01861 #ifdef LOCAL_LABEL_PREFIX
01862   if (s[index] == LOCAL_LABEL_PREFIX)
01863     ++index;
01864 #endif
01865 
01866   if (s[index] != 'L')
01867     return s;
01868 
01869   for (label_number = 0, p = s + index + 1; ISDIGIT (*p); ++p)
01870     label_number = (10 * label_number) + *p - '0';
01871 
01872   if (*p == DOLLAR_LABEL_CHAR)
01873     type = "dollar";
01874   else if (*p == LOCAL_LABEL_CHAR)
01875     type = "fb";
01876   else
01877     return s;
01878 
01879   for (instance_number = 0, p++; ISDIGIT (*p); ++p)
01880     instance_number = (10 * instance_number) + *p - '0';
01881 
01882   message_format = _("\"%d\" (instance number %d of a %s label)");
01883   symbol_decode = obstack_alloc (&notes, strlen (message_format) + 30);
01884   sprintf (symbol_decode, message_format, label_number, instance_number, type);
01885 
01886   return symbol_decode;
01887 }
01888 
01889 /* Get the value of a symbol.  */
01890 
01891 valueT
01892 S_GET_VALUE (symbolS *s)
01893 {
01894   if (LOCAL_SYMBOL_CHECK (s))
01895     return resolve_symbol_value (s);
01896 
01897   if (!s->sy_resolved)
01898     {
01899       valueT val = resolve_symbol_value (s);
01900       if (!finalize_syms)
01901        return val;
01902     }
01903   if (S_IS_WEAKREFR (s))
01904     return S_GET_VALUE (s->sy_value.X_add_symbol);
01905 
01906   if (s->sy_value.X_op != O_constant)
01907     {
01908       if (! s->sy_resolved
01909          || s->sy_value.X_op != O_symbol
01910          || (S_IS_DEFINED (s) && ! S_IS_COMMON (s)))
01911        as_bad (_("attempt to get value of unresolved symbol `%s'"),
01912               S_GET_NAME (s));
01913     }
01914   return (valueT) s->sy_value.X_add_number;
01915 }
01916 
01917 /* Set the value of a symbol.  */
01918 
01919 void
01920 S_SET_VALUE (symbolS *s, valueT val)
01921 {
01922   if (LOCAL_SYMBOL_CHECK (s))
01923     {
01924       ((struct local_symbol *) s)->lsy_value = val;
01925       return;
01926     }
01927 
01928   s->sy_value.X_op = O_constant;
01929   s->sy_value.X_add_number = (offsetT) val;
01930   s->sy_value.X_unsigned = 0;
01931   S_CLEAR_WEAKREFR (s);
01932 }
01933 
01934 void
01935 copy_symbol_attributes (symbolS *dest, symbolS *src)
01936 {
01937   if (LOCAL_SYMBOL_CHECK (dest))
01938     dest = local_symbol_convert ((struct local_symbol *) dest);
01939   if (LOCAL_SYMBOL_CHECK (src))
01940     src = local_symbol_convert ((struct local_symbol *) src);
01941 
01942   /* In an expression, transfer the settings of these flags.
01943      The user can override later, of course.  */
01944 #define COPIED_SYMFLAGS     (BSF_FUNCTION | BSF_OBJECT)
01945   dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
01946 
01947 #ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
01948   OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
01949 #endif
01950 
01951 #ifdef TC_COPY_SYMBOL_ATTRIBUTES
01952   TC_COPY_SYMBOL_ATTRIBUTES (dest, src);
01953 #endif
01954 }
01955 
01956 int
01957 S_IS_FUNCTION (symbolS *s)
01958 {
01959   flagword flags;
01960 
01961   if (LOCAL_SYMBOL_CHECK (s))
01962     return 0;
01963 
01964   flags = s->bsym->flags;
01965 
01966   return (flags & BSF_FUNCTION) != 0;
01967 }
01968 
01969 int
01970 S_IS_EXTERNAL (symbolS *s)
01971 {
01972   flagword flags;
01973 
01974   if (LOCAL_SYMBOL_CHECK (s))
01975     return 0;
01976 
01977   flags = s->bsym->flags;
01978 
01979   /* Sanity check.  */
01980   if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
01981     abort ();
01982 
01983   return (flags & BSF_GLOBAL) != 0;
01984 }
01985 
01986 int
01987 S_IS_WEAK (symbolS *s)
01988 {
01989   if (LOCAL_SYMBOL_CHECK (s))
01990     return 0;
01991   /* Conceptually, a weakrefr is weak if the referenced symbol is.  We
01992      could probably handle a WEAKREFR as always weak though.  E.g., if
01993      the referenced symbol has lost its weak status, there's no reason
01994      to keep handling the weakrefr as if it was weak.  */
01995   if (S_IS_WEAKREFR (s))
01996     return S_IS_WEAK (s->sy_value.X_add_symbol);
01997   return (s->bsym->flags & BSF_WEAK) != 0;
01998 }
01999 
02000 int
02001 S_IS_WEAKREFR (symbolS *s)
02002 {
02003   if (LOCAL_SYMBOL_CHECK (s))
02004     return 0;
02005   return s->sy_weakrefr != 0;
02006 }
02007 
02008 int
02009 S_IS_WEAKREFD (symbolS *s)
02010 {
02011   if (LOCAL_SYMBOL_CHECK (s))
02012     return 0;
02013   return s->sy_weakrefd != 0;
02014 }
02015 
02016 int
02017 S_IS_COMMON (symbolS *s)
02018 {
02019   if (LOCAL_SYMBOL_CHECK (s))
02020     return 0;
02021   return bfd_is_com_section (s->bsym->section);
02022 }
02023 
02024 int
02025 S_IS_DEFINED (symbolS *s)
02026 {
02027   if (LOCAL_SYMBOL_CHECK (s))
02028     return ((struct local_symbol *) s)->lsy_section != undefined_section;
02029   return s->bsym->section != undefined_section;
02030 }
02031 
02032 
02033 #ifndef EXTERN_FORCE_RELOC
02034 #define EXTERN_FORCE_RELOC IS_ELF
02035 #endif
02036 
02037 /* Return true for symbols that should not be reduced to section
02038    symbols or eliminated from expressions, because they may be
02039    overridden by the linker.  */
02040 int
02041 S_FORCE_RELOC (symbolS *s, int strict)
02042 {
02043   if (LOCAL_SYMBOL_CHECK (s))
02044     return ((struct local_symbol *) s)->lsy_section == undefined_section;
02045 
02046   return ((strict
02047           && ((s->bsym->flags & BSF_WEAK) != 0
02048               || (EXTERN_FORCE_RELOC
02049                  && (s->bsym->flags & BSF_GLOBAL) != 0)))
02050          || s->bsym->section == undefined_section
02051          || bfd_is_com_section (s->bsym->section));
02052 }
02053 
02054 int
02055 S_IS_DEBUG (symbolS *s)
02056 {
02057   if (LOCAL_SYMBOL_CHECK (s))
02058     return 0;
02059   if (s->bsym->flags & BSF_DEBUGGING)
02060     return 1;
02061   return 0;
02062 }
02063 
02064 int
02065 S_IS_LOCAL (symbolS *s)
02066 {
02067   flagword flags;
02068   const char *name;
02069 
02070   if (LOCAL_SYMBOL_CHECK (s))
02071     return 1;
02072 
02073   flags = s->bsym->flags;
02074 
02075   /* Sanity check.  */
02076   if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
02077     abort ();
02078 
02079   if (bfd_get_section (s->bsym) == reg_section)
02080     return 1;
02081 
02082   if (flag_strip_local_absolute
02083       /* Keep BSF_FILE symbols in order to allow debuggers to identify
02084         the source file even when the object file is stripped.  */
02085       && (flags & (BSF_GLOBAL | BSF_FILE)) == 0
02086       && bfd_get_section (s->bsym) == absolute_section)
02087     return 1;
02088 
02089   name = S_GET_NAME (s);
02090   return (name != NULL
02091          && ! S_IS_DEBUG (s)
02092          && (strchr (name, DOLLAR_LABEL_CHAR)
02093              || strchr (name, LOCAL_LABEL_CHAR)
02094              || (! flag_keep_locals
02095                 && (bfd_is_local_label (stdoutput, s->bsym)
02096                     || (flag_mri
02097                        && name[0] == '?'
02098                        && name[1] == '?')))));
02099 }
02100 
02101 int
02102 S_IS_STABD (symbolS *s)
02103 {
02104   return S_GET_NAME (s) == 0;
02105 }
02106 
02107 int
02108 S_IS_VOLATILE (const symbolS *s)
02109 {
02110   if (LOCAL_SYMBOL_CHECK (s))
02111     return 0;
02112   return s->sy_volatile;
02113 }
02114 
02115 int
02116 S_IS_FORWARD_REF (const symbolS *s)
02117 {
02118   if (LOCAL_SYMBOL_CHECK (s))
02119     return 0;
02120   return s->sy_forward_ref;
02121 }
02122 
02123 const char *
02124 S_GET_NAME (symbolS *s)
02125 {
02126   if (LOCAL_SYMBOL_CHECK (s))
02127     return ((struct local_symbol *) s)->lsy_name;
02128   return s->bsym->name;
02129 }
02130 
02131 segT
02132 S_GET_SEGMENT (symbolS *s)
02133 {
02134   if (LOCAL_SYMBOL_CHECK (s))
02135     return ((struct local_symbol *) s)->lsy_section;
02136   return s->bsym->section;
02137 }
02138 
02139 void
02140 S_SET_SEGMENT (symbolS *s, segT seg)
02141 {
02142   /* Don't reassign section symbols.  The direct reason is to prevent seg
02143      faults assigning back to const global symbols such as *ABS*, but it
02144      shouldn't happen anyway.  */
02145 
02146   if (LOCAL_SYMBOL_CHECK (s))
02147     {
02148       if (seg == reg_section)
02149        s = local_symbol_convert ((struct local_symbol *) s);
02150       else
02151        {
02152          ((struct local_symbol *) s)->lsy_section = seg;
02153          return;
02154        }
02155     }
02156 
02157   if (s->bsym->flags & BSF_SECTION_SYM)
02158     {
02159       if (s->bsym->section != seg)
02160        abort ();
02161     }
02162   else
02163     s->bsym->section = seg;
02164 }
02165 
02166 void
02167 S_SET_EXTERNAL (symbolS *s)
02168 {
02169   if (LOCAL_SYMBOL_CHECK (s))
02170     s = local_symbol_convert ((struct local_symbol *) s);
02171   if ((s->bsym->flags & BSF_WEAK) != 0)
02172     {
02173       /* Let .weak override .global.  */
02174       return;
02175     }
02176   if (s->bsym->flags & BSF_SECTION_SYM)
02177     {
02178       char * file;
02179       unsigned int line;
02180 
02181       /* Do not reassign section symbols.  */
02182       as_where (& file, & line);
02183       as_warn_where (file, line,
02184                    _("section symbols are already global"));
02185       return;
02186     }
02187   s->bsym->flags |= BSF_GLOBAL;
02188   s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK);
02189 
02190 #ifdef USE_UNIQUE
02191   if (! an_external_name && S_GET_NAME(s)[0] != '.')
02192     an_external_name = S_GET_NAME (s);
02193 #endif
02194 }
02195 
02196 void
02197 S_CLEAR_EXTERNAL (symbolS *s)
02198 {
02199   if (LOCAL_SYMBOL_CHECK (s))
02200     return;
02201   if ((s->bsym->flags & BSF_WEAK) != 0)
02202     {
02203       /* Let .weak override.  */
02204       return;
02205     }
02206   s->bsym->flags |= BSF_LOCAL;
02207   s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
02208 }
02209 
02210 void
02211 S_SET_WEAK (symbolS *s)
02212 {
02213   if (LOCAL_SYMBOL_CHECK (s))
02214     s = local_symbol_convert ((struct local_symbol *) s);
02215 #ifdef obj_set_weak_hook
02216   obj_set_weak_hook (s);
02217 #endif
02218   s->bsym->flags |= BSF_WEAK;
02219   s->bsym->flags &= ~(BSF_GLOBAL | BSF_LOCAL);
02220 }
02221 
02222 void
02223 S_SET_WEAKREFR (symbolS *s)
02224 {
02225   if (LOCAL_SYMBOL_CHECK (s))
02226     s = local_symbol_convert ((struct local_symbol *) s);
02227   s->sy_weakrefr = 1;
02228   /* If the alias was already used, make sure we mark the target as
02229      used as well, otherwise it might be dropped from the symbol
02230      table.  This may have unintended side effects if the alias is
02231      later redirected to another symbol, such as keeping the unused
02232      previous target in the symbol table.  Since it will be weak, it's
02233      not a big deal.  */
02234   if (s->sy_used)
02235     symbol_mark_used (s->sy_value.X_add_symbol);
02236 }
02237 
02238 void
02239 S_CLEAR_WEAKREFR (symbolS *s)
02240 {
02241   if (LOCAL_SYMBOL_CHECK (s))
02242     return;
02243   s->sy_weakrefr = 0;
02244 }
02245 
02246 void
02247 S_SET_WEAKREFD (symbolS *s)
02248 {
02249   if (LOCAL_SYMBOL_CHECK (s))
02250     s = local_symbol_convert ((struct local_symbol *) s);
02251   s->sy_weakrefd = 1;
02252   S_SET_WEAK (s);
02253 }
02254 
02255 void
02256 S_CLEAR_WEAKREFD (symbolS *s)
02257 {
02258   if (LOCAL_SYMBOL_CHECK (s))
02259     return;
02260   if (s->sy_weakrefd)
02261     {
02262       s->sy_weakrefd = 0;
02263       /* If a weakref target symbol is weak, then it was never
02264         referenced directly before, not even in a .global directive,
02265         so decay it to local.  If it remains undefined, it will be
02266         later turned into a global, like any other undefined
02267         symbol.  */
02268       if (s->bsym->flags & BSF_WEAK)
02269        {
02270 #ifdef obj_clear_weak_hook
02271          obj_clear_weak_hook (s);
02272 #endif
02273          s->bsym->flags &= ~BSF_WEAK;
02274          s->bsym->flags |= BSF_LOCAL;
02275        }
02276     }
02277 }
02278 
02279 void
02280 S_SET_THREAD_LOCAL (symbolS *s)
02281 {
02282   if (LOCAL_SYMBOL_CHECK (s))
02283     s = local_symbol_convert ((struct local_symbol *) s);
02284   if (bfd_is_com_section (s->bsym->section)
02285       && (s->bsym->flags & BSF_THREAD_LOCAL) != 0)
02286     return;
02287   s->bsym->flags |= BSF_THREAD_LOCAL;
02288   if ((s->bsym->flags & BSF_FUNCTION) != 0)
02289     as_bad (_("Accessing function `%s' as thread-local object"),
02290            S_GET_NAME (s));
02291   else if (! bfd_is_und_section (s->bsym->section)
02292           && (s->bsym->section->flags & SEC_THREAD_LOCAL) == 0)
02293     as_bad (_("Accessing `%s' as thread-local object"),
02294            S_GET_NAME (s));
02295 }
02296 
02297 void
02298 S_SET_NAME (symbolS *s, const char *name)
02299 {
02300   if (LOCAL_SYMBOL_CHECK (s))
02301     {
02302       ((struct local_symbol *) s)->lsy_name = name;
02303       return;
02304     }
02305   s->bsym->name = name;
02306 }
02307 
02308 void
02309 S_SET_VOLATILE (symbolS *s)
02310 {
02311   if (LOCAL_SYMBOL_CHECK (s))
02312     s = local_symbol_convert ((struct local_symbol *) s);
02313   s->sy_volatile = 1;
02314 }
02315 
02316 void
02317 S_CLEAR_VOLATILE (symbolS *s)
02318 {
02319   if (!LOCAL_SYMBOL_CHECK (s))
02320     s->sy_volatile = 0;
02321 }
02322 
02323 void
02324 S_SET_FORWARD_REF (symbolS *s)
02325 {
02326   if (LOCAL_SYMBOL_CHECK (s))
02327     s = local_symbol_convert ((struct local_symbol *) s);
02328   s->sy_forward_ref = 1;
02329 }
02330 
02331 /* Return the previous symbol in a chain.  */
02332 
02333 symbolS *
02334 symbol_previous (symbolS *s)
02335 {
02336   if (LOCAL_SYMBOL_CHECK (s))
02337     abort ();
02338   return s->sy_previous;
02339 }
02340 
02341 /* Return the next symbol in a chain.  */
02342 
02343 symbolS *
02344 symbol_next (symbolS *s)
02345 {
02346   if (LOCAL_SYMBOL_CHECK (s))
02347     abort ();
02348   return s->sy_next;
02349 }
02350 
02351 /* Return a pointer to the value of a symbol as an expression.  */
02352 
02353 expressionS *
02354 symbol_get_value_expression (symbolS *s)
02355 {
02356   if (LOCAL_SYMBOL_CHECK (s))
02357     s = local_symbol_convert ((struct local_symbol *) s);
02358   return &s->sy_value;
02359 }
02360 
02361 /* Set the value of a symbol to an expression.  */
02362 
02363 void
02364 symbol_set_value_expression (symbolS *s, const expressionS *exp)
02365 {
02366   if (LOCAL_SYMBOL_CHECK (s))
02367     s = local_symbol_convert ((struct local_symbol *) s);
02368   s->sy_value = *exp;
02369   S_CLEAR_WEAKREFR (s);
02370 }
02371 
02372 /* Return a pointer to the X_add_number component of a symbol.  */
02373 
02374 offsetT *
02375 symbol_X_add_number (symbolS *s)
02376 {
02377   if (LOCAL_SYMBOL_CHECK (s))
02378     return (offsetT *) &((struct local_symbol *) s)->lsy_value;
02379 
02380   return &s->sy_value.X_add_number;
02381 }
02382 
02383 /* Set the value of SYM to the current position in the current segment.  */
02384 
02385 void
02386 symbol_set_value_now (symbolS *sym)
02387 {
02388   S_SET_SEGMENT (sym, now_seg);
02389   S_SET_VALUE (sym, frag_now_fix ());
02390   symbol_set_frag (sym, frag_now);
02391 }
02392 
02393 /* Set the frag of a symbol.  */
02394 
02395 void
02396 symbol_set_frag (symbolS *s, fragS *f)
02397 {
02398   if (LOCAL_SYMBOL_CHECK (s))
02399     {
02400       local_symbol_set_frag ((struct local_symbol *) s, f);
02401       return;
02402     }
02403   s->sy_frag = f;
02404   S_CLEAR_WEAKREFR (s);
02405 }
02406 
02407 /* Return the frag of a symbol.  */
02408 
02409 fragS *
02410 symbol_get_frag (symbolS *s)
02411 {
02412   if (LOCAL_SYMBOL_CHECK (s))
02413     return local_symbol_get_frag ((struct local_symbol *) s);
02414   return s->sy_frag;
02415 }
02416 
02417 /* Mark a symbol as having been used.  */
02418 
02419 void
02420 symbol_mark_used (symbolS *s)
02421 {
02422   if (LOCAL_SYMBOL_CHECK (s))
02423     return;
02424   s->sy_used = 1;
02425   if (S_IS_WEAKREFR (s))
02426     symbol_mark_used (s->sy_value.X_add_symbol);
02427 }
02428 
02429 /* Clear the mark of whether a symbol has been used.  */
02430 
02431 void
02432 symbol_clear_used (symbolS *s)
02433 {
02434   if (LOCAL_SYMBOL_CHECK (s))
02435     s = local_symbol_convert ((struct local_symbol *) s);
02436   s->sy_used = 0;
02437 }
02438 
02439 /* Return whether a symbol has been used.  */
02440 
02441 int
02442 symbol_used_p (symbolS *s)
02443 {
02444   if (LOCAL_SYMBOL_CHECK (s))
02445     return 1;
02446   return s->sy_used;
02447 }
02448 
02449 /* Mark a symbol as having been used in a reloc.  */
02450 
02451 void
02452 symbol_mark_used_in_reloc (symbolS *s)
02453 {
02454   if (LOCAL_SYMBOL_CHECK (s))
02455     s = local_symbol_convert ((struct local_symbol *) s);
02456   s->sy_used_in_reloc = 1;
02457 }
02458 
02459 /* Clear the mark of whether a symbol has been used in a reloc.  */
02460 
02461 void
02462 symbol_clear_used_in_reloc (symbolS *s)
02463 {
02464   if (LOCAL_SYMBOL_CHECK (s))
02465     return;
02466   s->sy_used_in_reloc = 0;
02467 }
02468 
02469 /* Return whether a symbol has been used in a reloc.  */
02470 
02471 int
02472 symbol_used_in_reloc_p (symbolS *s)
02473 {
02474   if (LOCAL_SYMBOL_CHECK (s))
02475     return 0;
02476   return s->sy_used_in_reloc;
02477 }
02478 
02479 /* Mark a symbol as an MRI common symbol.  */
02480 
02481 void
02482 symbol_mark_mri_common (symbolS *s)
02483 {
02484   if (LOCAL_SYMBOL_CHECK (s))
02485     s = local_symbol_convert ((struct local_symbol *) s);
02486   s->sy_mri_common = 1;
02487 }
02488 
02489 /* Clear the mark of whether a symbol is an MRI common symbol.  */
02490 
02491 void
02492 symbol_clear_mri_common (symbolS *s)
02493 {
02494   if (LOCAL_SYMBOL_CHECK (s))
02495     return;
02496   s->sy_mri_common = 0;
02497 }
02498 
02499 /* Return whether a symbol is an MRI common symbol.  */
02500 
02501 int
02502 symbol_mri_common_p (symbolS *s)
02503 {
02504   if (LOCAL_SYMBOL_CHECK (s))
02505     return 0;
02506   return s->sy_mri_common;
02507 }
02508 
02509 /* Mark a symbol as having been written.  */
02510 
02511 void
02512 symbol_mark_written (symbolS *s)
02513 {
02514   if (LOCAL_SYMBOL_CHECK (s))
02515     return;
02516   s->written = 1;
02517 }
02518 
02519 /* Clear the mark of whether a symbol has been written.  */
02520 
02521 void
02522 symbol_clear_written (symbolS *s)
02523 {
02524   if (LOCAL_SYMBOL_CHECK (s))
02525     return;
02526   s->written = 0;
02527 }
02528 
02529 /* Return whether a symbol has been written.  */
02530 
02531 int
02532 symbol_written_p (symbolS *s)
02533 {
02534   if (LOCAL_SYMBOL_CHECK (s))
02535     return 0;
02536   return s->written;
02537 }
02538 
02539 /* Mark a symbol has having been resolved.  */
02540 
02541 void
02542 symbol_mark_resolved (symbolS *s)
02543 {
02544   if (LOCAL_SYMBOL_CHECK (s))
02545     {
02546       local_symbol_mark_resolved ((struct local_symbol *) s);
02547       return;
02548     }
02549   s->sy_resolved = 1;
02550 }
02551 
02552 /* Return whether a symbol has been resolved.  */
02553 
02554 int
02555 symbol_resolved_p (symbolS *s)
02556 {
02557   if (LOCAL_SYMBOL_CHECK (s))
02558     return local_symbol_resolved_p ((struct local_symbol *) s);
02559   return s->sy_resolved;
02560 }
02561 
02562 /* Return whether a symbol is a section symbol.  */
02563 
02564 int
02565 symbol_section_p (symbolS *s ATTRIBUTE_UNUSED)
02566 {
02567   if (LOCAL_SYMBOL_CHECK (s))
02568     return 0;
02569   return (s->bsym->flags & BSF_SECTION_SYM) != 0;
02570 }
02571 
02572 /* Return whether a symbol is equated to another symbol.  */
02573 
02574 int
02575 symbol_equated_p (symbolS *s)
02576 {
02577   if (LOCAL_SYMBOL_CHECK (s))
02578     return 0;
02579   return s->sy_value.X_op == O_symbol;
02580 }
02581 
02582 /* Return whether a symbol is equated to another symbol, and should be
02583    treated specially when writing out relocs.  */
02584 
02585 int
02586 symbol_equated_reloc_p (symbolS *s)
02587 {
02588   if (LOCAL_SYMBOL_CHECK (s))
02589     return 0;
02590   /* X_op_symbol, normally not used for O_symbol, is set by
02591      resolve_symbol_value to flag expression syms that have been
02592      equated.  */
02593   return (s->sy_value.X_op == O_symbol
02594 #if defined (OBJ_COFF) && defined (TE_PE)
02595          && ! S_IS_WEAK (s)
02596 #endif
02597          && ((s->sy_resolved && s->sy_value.X_op_symbol != NULL)
02598              || ! S_IS_DEFINED (s)
02599              || S_IS_COMMON (s)));
02600 }
02601 
02602 /* Return whether a symbol has a constant value.  */
02603 
02604 int
02605 symbol_constant_p (symbolS *s)
02606 {
02607   if (LOCAL_SYMBOL_CHECK (s))
02608     return 1;
02609   return s->sy_value.X_op == O_constant;
02610 }
02611 
02612 /* Return whether a symbol was cloned and thus removed from the global
02613    symbol list.  */
02614 
02615 int
02616 symbol_shadow_p (symbolS *s)
02617 {
02618   if (LOCAL_SYMBOL_CHECK (s))
02619     return 0;
02620   return s->sy_next == s;
02621 }
02622 
02623 /* Return the BFD symbol for a symbol.  */
02624 
02625 asymbol *
02626 symbol_get_bfdsym (symbolS *s)
02627 {
02628   if (LOCAL_SYMBOL_CHECK (s))
02629     s = local_symbol_convert ((struct local_symbol *) s);
02630   return s->bsym;
02631 }
02632 
02633 /* Set the BFD symbol for a symbol.  */
02634 
02635 void
02636 symbol_set_bfdsym (symbolS *s, asymbol *bsym)
02637 {
02638   if (LOCAL_SYMBOL_CHECK (s))
02639     s = local_symbol_convert ((struct local_symbol *) s);
02640   /* Usually, it is harmless to reset a symbol to a BFD section
02641      symbol. For example, obj_elf_change_section sets the BFD symbol
02642      of an old symbol with the newly created section symbol. But when
02643      we have multiple sections with the same name, the newly created
02644      section may have the same name as an old section. We check if the
02645      old symbol has been already marked as a section symbol before
02646      resetting it.  */
02647   if ((s->bsym->flags & BSF_SECTION_SYM) == 0)
02648     s->bsym = bsym;
02649   /* else XXX - What do we do now ?  */
02650 }
02651 
02652 #ifdef OBJ_SYMFIELD_TYPE
02653 
02654 /* Get a pointer to the object format information for a symbol.  */
02655 
02656 OBJ_SYMFIELD_TYPE *
02657 symbol_get_obj (symbolS *s)
02658 {
02659   if (LOCAL_SYMBOL_CHECK (s))
02660     s = local_symbol_convert ((struct local_symbol *) s);
02661   return &s->sy_obj;
02662 }
02663 
02664 /* Set the object format information for a symbol.  */
02665 
02666 void
02667 symbol_set_obj (symbolS *s, OBJ_SYMFIELD_TYPE *o)
02668 {
02669   if (LOCAL_SYMBOL_CHECK (s))
02670     s = local_symbol_convert ((struct local_symbol *) s);
02671   s->sy_obj = *o;
02672 }
02673 
02674 #endif /* OBJ_SYMFIELD_TYPE */
02675 
02676 #ifdef TC_SYMFIELD_TYPE
02677 
02678 /* Get a pointer to the processor information for a symbol.  */
02679 
02680 TC_SYMFIELD_TYPE *
02681 symbol_get_tc (symbolS *s)
02682 {
02683   if (LOCAL_SYMBOL_CHECK (s))
02684     s = local_symbol_convert ((struct local_symbol *) s);
02685   return &s->sy_tc;
02686 }
02687 
02688 /* Set the processor information for a symbol.  */
02689 
02690 void
02691 symbol_set_tc (symbolS *s, TC_SYMFIELD_TYPE *o)
02692 {
02693   if (LOCAL_SYMBOL_CHECK (s))
02694     s = local_symbol_convert ((struct local_symbol *) s);
02695   s->sy_tc = *o;
02696 }
02697 
02698 #endif /* TC_SYMFIELD_TYPE */
02699 
02700 void
02701 symbol_begin (void)
02702 {
02703   symbol_lastP = NULL;
02704   symbol_rootP = NULL;             /* In case we have 0 symbols (!!)  */
02705   sy_hash = hash_new ();
02706   local_hash = hash_new ();
02707 
02708   memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
02709 #if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
02710   abs_symbol.bsym = bfd_abs_section.symbol;
02711 #endif
02712   abs_symbol.sy_value.X_op = O_constant;
02713   abs_symbol.sy_frag = &zero_address_frag;
02714 
02715   if (LOCAL_LABELS_FB)
02716     fb_label_init ();
02717 }
02718 
02719 int indent_level;
02720 
02721 /* Maximum indent level.
02722    Available for modification inside a gdb session.  */
02723 static int max_indent_level = 8;
02724 
02725 void
02726 print_symbol_value_1 (FILE *file, symbolS *sym)
02727 {
02728   const char *name = S_GET_NAME (sym);
02729   if (!name || !name[0])
02730     name = "(unnamed)";
02731   fprintf (file, "sym %lx %s", (unsigned long) sym, name);
02732 
02733   if (LOCAL_SYMBOL_CHECK (sym))
02734     {
02735       struct local_symbol *locsym = (struct local_symbol *) sym;
02736       if (local_symbol_get_frag (locsym) != &zero_address_frag
02737          && local_symbol_get_frag (locsym) != NULL)
02738        fprintf (file, " frag %lx", (long) local_symbol_get_frag (locsym));
02739       if (local_symbol_resolved_p (locsym))
02740        fprintf (file, " resolved");
02741       fprintf (file, " local");
02742     }
02743   else
02744     {
02745       if (sym->sy_frag != &zero_address_frag)
02746        fprintf (file, " frag %lx", (long) sym->sy_frag);
02747       if (sym->written)
02748        fprintf (file, " written");
02749       if (sym->sy_resolved)
02750        fprintf (file, " resolved");
02751       else if (sym->sy_resolving)
02752        fprintf (file, " resolving");
02753       if (sym->sy_used_in_reloc)
02754        fprintf (file, " used-in-reloc");
02755       if (sym->sy_used)
02756        fprintf (file, " used");
02757       if (S_IS_LOCAL (sym))
02758        fprintf (file, " local");
02759       if (S_IS_EXTERNAL (sym))
02760        fprintf (file, " extern");
02761       if (S_IS_WEAK (sym))
02762        fprintf (file, " weak");
02763       if (S_IS_DEBUG (sym))
02764        fprintf (file, " debug");
02765       if (S_IS_DEFINED (sym))
02766        fprintf (file, " defined");
02767     }
02768   if (S_IS_WEAKREFR (sym))
02769     fprintf (file, " weakrefr");
02770   if (S_IS_WEAKREFD (sym))
02771     fprintf (file, " weakrefd");
02772   fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
02773   if (symbol_resolved_p (sym))
02774     {
02775       segT s = S_GET_SEGMENT (sym);
02776 
02777       if (s != undefined_section
02778          && s != expr_section)
02779        fprintf (file, " %lx", (long) S_GET_VALUE (sym));
02780     }
02781   else if (indent_level < max_indent_level
02782           && S_GET_SEGMENT (sym) != undefined_section)
02783     {
02784       indent_level++;
02785       fprintf (file, "\n%*s<", indent_level * 4, "");
02786       if (LOCAL_SYMBOL_CHECK (sym))
02787        fprintf (file, "constant %lx",
02788                (long) ((struct local_symbol *) sym)->lsy_value);
02789       else
02790        print_expr_1 (file, &sym->sy_value);
02791       fprintf (file, ">");
02792       indent_level--;
02793     }
02794   fflush (file);
02795 }
02796 
02797 void
02798 print_symbol_value (symbolS *sym)
02799 {
02800   indent_level = 0;
02801   print_symbol_value_1 (stderr, sym);
02802   fprintf (stderr, "\n");
02803 }
02804 
02805 static void
02806 print_binary (FILE *file, const char *name, expressionS *exp)
02807 {
02808   indent_level++;
02809   fprintf (file, "%s\n%*s<", name, indent_level * 4, "");
02810   print_symbol_value_1 (file, exp->X_add_symbol);
02811   fprintf (file, ">\n%*s<", indent_level * 4, "");
02812   print_symbol_value_1 (file, exp->X_op_symbol);
02813   fprintf (file, ">");
02814   indent_level--;
02815 }
02816 
02817 void
02818 print_expr_1 (FILE *file, expressionS *exp)
02819 {
02820   fprintf (file, "expr %lx ", (long) exp);
02821   switch (exp->X_op)
02822     {
02823     case O_illegal:
02824       fprintf (file, "illegal");
02825       break;
02826     case O_absent:
02827       fprintf (file, "absent");
02828       break;
02829     case O_constant:
02830       fprintf (file, "constant %lx", (long) exp->X_add_number);
02831       break;
02832     case O_symbol:
02833       indent_level++;
02834       fprintf (file, "symbol\n%*s<", indent_level * 4, "");
02835       print_symbol_value_1 (file, exp->X_add_symbol);
02836       fprintf (file, ">");
02837     maybe_print_addnum:
02838       if (exp->X_add_number)
02839        fprintf (file, "\n%*s%lx", indent_level * 4, "",
02840                (long) exp->X_add_number);
02841       indent_level--;
02842       break;
02843     case O_register:
02844       fprintf (file, "register #%d", (int) exp->X_add_number);
02845       break;
02846     case O_big:
02847       fprintf (file, "big");
02848       break;
02849     case O_uminus:
02850       fprintf (file, "uminus -<");
02851       indent_level++;
02852       print_symbol_value_1 (file, exp->X_add_symbol);
02853       fprintf (file, ">");
02854       goto maybe_print_addnum;
02855     case O_bit_not:
02856       fprintf (file, "bit_not");
02857       break;
02858     case O_multiply:
02859       print_binary (file, "multiply", exp);
02860       break;
02861     case O_divide:
02862       print_binary (file, "divide", exp);
02863       break;
02864     case O_modulus:
02865       print_binary (file, "modulus", exp);
02866       break;
02867     case O_left_shift:
02868       print_binary (file, "lshift", exp);
02869       break;
02870     case O_right_shift:
02871       print_binary (file, "rshift", exp);
02872       break;
02873     case O_bit_inclusive_or:
02874       print_binary (file, "bit_ior", exp);
02875       break;
02876     case O_bit_exclusive_or:
02877       print_binary (file, "bit_xor", exp);
02878       break;
02879     case O_bit_and:
02880       print_binary (file, "bit_and", exp);
02881       break;
02882     case O_eq:
02883       print_binary (file, "eq", exp);
02884       break;
02885     case O_ne:
02886       print_binary (file, "ne", exp);
02887       break;
02888     case O_lt:
02889       print_binary (file, "lt", exp);
02890       break;
02891     case O_le:
02892       print_binary (file, "le", exp);
02893       break;
02894     case O_ge:
02895       print_binary (file, "ge", exp);
02896       break;
02897     case O_gt:
02898       print_binary (file, "gt", exp);
02899       break;
02900     case O_logical_and:
02901       print_binary (file, "logical_and", exp);
02902       break;
02903     case O_logical_or:
02904       print_binary (file, "logical_or", exp);
02905       break;
02906     case O_add:
02907       indent_level++;
02908       fprintf (file, "add\n%*s<", indent_level * 4, "");
02909       print_symbol_value_1 (file, exp->X_add_symbol);
02910       fprintf (file, ">\n%*s<", indent_level * 4, "");
02911       print_symbol_value_1 (file, exp->X_op_symbol);
02912       fprintf (file, ">");
02913       goto maybe_print_addnum;
02914     case O_subtract:
02915       indent_level++;
02916       fprintf (file, "subtract\n%*s<", indent_level * 4, "");
02917       print_symbol_value_1 (file, exp->X_add_symbol);
02918       fprintf (file, ">\n%*s<", indent_level * 4, "");
02919       print_symbol_value_1 (file, exp->X_op_symbol);
02920       fprintf (file, ">");
02921       goto maybe_print_addnum;
02922     default:
02923       fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
02924       break;
02925     }
02926   fflush (stdout);
02927 }
02928 
02929 void
02930 print_expr (expressionS *exp)
02931 {
02932   print_expr_1 (stderr, exp);
02933   fprintf (stderr, "\n");
02934 }
02935 
02936 void
02937 symbol_print_statistics (FILE *file)
02938 {
02939   hash_print_statistics (file, "symbol table", sy_hash);
02940   hash_print_statistics (file, "mini local symbol table", local_hash);
02941   fprintf (file, "%lu mini local symbols created, %lu converted\n",
02942           local_symbol_count, local_symbol_conversion_count);
02943 }
02944 
02945 #ifdef OBJ_COMPLEX_RELC
02946 
02947 /* Convert given symbol to a new complex-relocation symbol name.  This
02948    may be a recursive function, since it might be called for non-leaf
02949    nodes (plain symbols) in the expression tree.  The caller owns the
02950    returning string, so should free it eventually.  Errors are
02951    indicated via as_bad and a NULL return value.  The given symbol
02952    is marked with sy_used_in_reloc.  */
02953 
02954 char *
02955 symbol_relc_make_sym (symbolS * sym)
02956 {
02957   char * terminal = NULL;
02958   const char * sname;
02959   char typetag;
02960   int sname_len;
02961 
02962   assert (sym != NULL);
02963 
02964   /* Recurse to symbol_relc_make_expr if this symbol
02965      is defined as an expression or a plain value.  */
02966   if (   S_GET_SEGMENT (sym) == expr_section
02967       || S_GET_SEGMENT (sym) == absolute_section)
02968     return symbol_relc_make_expr (& sym->sy_value);
02969 
02970   /* This may be a "fake symbol" L0\001, referring to ".".
02971      Write out a special null symbol to refer to this position.  */
02972   if (! strcmp (S_GET_NAME (sym), FAKE_LABEL_NAME))
02973     return xstrdup (".");
02974 
02975   /* We hope this is a plain leaf symbol.  Construct the encoding
02976      as {S,s}II...:CCCCCCC....
02977      where 'S'/'s' means section symbol / plain symbol
02978      III is decimal for the symbol name length
02979      CCC is the symbol name itself.  */
02980   symbol_mark_used_in_reloc (sym);
02981 
02982   sname = S_GET_NAME (sym);
02983   sname_len = strlen (sname);
02984   typetag = symbol_section_p (sym) ? 'S' : 's';
02985 
02986   terminal = xmalloc (1 /* S or s */
02987                     + 8 /* sname_len in decimal */
02988                     + 1 /* _ spacer */
02989                     + sname_len /* name itself */
02990                     + 1 /* \0 */ );
02991 
02992   sprintf (terminal, "%c%d:%s", typetag, sname_len, sname);
02993   return terminal;
02994 }
02995 
02996 /* Convert given value to a new complex-relocation symbol name.  This
02997    is a non-recursive function, since it is be called for leaf nodes
02998    (plain values) in the expression tree.  The caller owns the
02999    returning string, so should free() it eventually.  No errors.  */
03000 
03001 char *
03002 symbol_relc_make_value (offsetT val)
03003 {
03004   char * terminal = xmalloc (28);  /* Enough for long long.  */
03005 
03006   terminal[0] = '#';
03007   sprintf_vma (& terminal[1], val);
03008   return terminal;
03009 }
03010 
03011 /* Convert given expression to a new complex-relocation symbol name.
03012    This is a recursive function, since it traverses the entire given
03013    expression tree.  The caller owns the returning string, so should
03014    free() it eventually.  Errors are indicated via as_bad() and a NULL
03015    return value.  */
03016 
03017 char *
03018 symbol_relc_make_expr (expressionS * exp)
03019 {
03020   char * opstr = NULL; /* Operator prefix string.  */
03021   int    arity = 0;    /* Arity of this operator.  */
03022   char * operands[3];  /* Up to three operands.  */
03023   char * concat_string = NULL;
03024 
03025   operands[0] = operands[1] = operands[2] = NULL;
03026 
03027   assert (exp != NULL);
03028 
03029   /* Match known operators -> fill in opstr, arity, operands[] and fall
03030      through to construct subexpression fragments; may instead return 
03031      string directly for leaf nodes.  */
03032 
03033   /* See expr.h for the meaning of all these enums.  Many operators 
03034      have an unnatural arity (X_add_number implicitly added).  The
03035      conversion logic expands them to explicit "+" subexpressions.   */
03036 
03037   switch (exp->X_op)
03038     {
03039     default:
03040       as_bad ("Unknown expression operator (enum %d)", exp->X_op);
03041       break;
03042 
03043       /* Leaf nodes.  */
03044     case O_constant:
03045       return symbol_relc_make_value (exp->X_add_number);
03046 
03047     case O_symbol:
03048       if (exp->X_add_number) 
03049        { 
03050          arity = 2; 
03051          opstr = "+"; 
03052          operands[0] = symbol_relc_make_sym (exp->X_add_symbol);
03053          operands[1] = symbol_relc_make_value (exp->X_add_number);
03054          break;
03055        }
03056       else
03057        return symbol_relc_make_sym (exp->X_add_symbol);
03058 
03059       /* Helper macros for nesting nodes.  */
03060 
03061 #define HANDLE_XADD_OPT1(str_)                                        \
03062       if (exp->X_add_number)                                          \
03063         {                                                      \
03064           arity = 2;                                           \
03065           opstr = "+:" str_;                                          \
03066           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);     \
03067           operands[1] = symbol_relc_make_value (exp->X_add_number);   \
03068           break;                                               \
03069         }                                                      \
03070       else                                                     \
03071         {                                                      \
03072           arity = 1;                                           \
03073           opstr = str_;                                               \
03074           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);     \
03075         }                                                      \
03076       break
03077       
03078 #define HANDLE_XADD_OPT2(str_)                                        \
03079       if (exp->X_add_number)                                          \
03080         {                                                      \
03081           arity = 3;                                           \
03082           opstr = "+:" str_;                                          \
03083           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);     \
03084           operands[1] = symbol_relc_make_sym (exp->X_op_symbol);      \
03085           operands[2] = symbol_relc_make_value (exp->X_add_number);   \
03086         }                                                      \
03087       else                                                     \
03088         {                                                      \
03089           arity = 2;                                           \
03090           opstr = str_;                                               \
03091           operands[0] = symbol_relc_make_sym (exp->X_add_symbol);     \
03092           operands[1] = symbol_relc_make_sym (exp->X_op_symbol);      \
03093         }                                                      \
03094       break
03095 
03096       /* Nesting nodes.  */
03097 
03098     case O_uminus:          HANDLE_XADD_OPT1 ("0-");
03099     case O_bit_not:         HANDLE_XADD_OPT1 ("~");
03100     case O_logical_not:     HANDLE_XADD_OPT1 ("!");
03101     case O_multiply:        HANDLE_XADD_OPT2 ("*");
03102     case O_divide:          HANDLE_XADD_OPT2 ("/");
03103     case O_modulus:         HANDLE_XADD_OPT2 ("%");
03104     case O_left_shift:      HANDLE_XADD_OPT2 ("<<");
03105     case O_right_shift:     HANDLE_XADD_OPT2 (">>");
03106     case O_bit_inclusive_or:       HANDLE_XADD_OPT2 ("|");
03107     case O_bit_exclusive_or:       HANDLE_XADD_OPT2 ("^");
03108     case O_bit_and:         HANDLE_XADD_OPT2 ("&");
03109     case O_add:             HANDLE_XADD_OPT2 ("+");
03110     case O_subtract:        HANDLE_XADD_OPT2 ("-");
03111     case O_eq:              HANDLE_XADD_OPT2 ("==");
03112     case O_ne:              HANDLE_XADD_OPT2 ("!=");
03113     case O_lt:              HANDLE_XADD_OPT2 ("<");
03114     case O_le:              HANDLE_XADD_OPT2 ("<=");
03115     case O_ge:              HANDLE_XADD_OPT2 (">=");
03116     case O_gt:              HANDLE_XADD_OPT2 (">");
03117     case O_logical_and:     HANDLE_XADD_OPT2 ("&&");
03118     case O_logical_or:      HANDLE_XADD_OPT2 ("||");
03119     }
03120 
03121   /* Validate & reject early.  */
03122   if (arity >= 1 && ((operands[0] == NULL) || (strlen (operands[0]) == 0)))
03123     opstr = NULL;
03124   if (arity >= 2 && ((operands[1] == NULL) || (strlen (operands[1]) == 0)))
03125     opstr = NULL;
03126   if (arity >= 3 && ((operands[2] == NULL) || (strlen (operands[2]) == 0)))
03127     opstr = NULL;
03128 
03129   if (opstr == NULL)
03130     concat_string = NULL;
03131   else
03132     {
03133       /* Allocate new string; include inter-operand padding gaps etc.  */
03134       concat_string = xmalloc (strlen (opstr) 
03135                             + 1
03136                             + (arity >= 1 ? (strlen (operands[0]) + 1 ) : 0)
03137                             + (arity >= 2 ? (strlen (operands[1]) + 1 ) : 0)
03138                             + (arity >= 3 ? (strlen (operands[2]) + 0 ) : 0)
03139                             + 1);
03140       assert (concat_string != NULL);
03141       
03142       /* Format the thing.  */
03143       sprintf (concat_string, 
03144               (arity == 0 ? "%s" :
03145               arity == 1 ? "%s:%s" :
03146               arity == 2 ? "%s:%s:%s" :
03147               /* arity == 3 */ "%s:%s:%s:%s"),
03148               opstr, operands[0], operands[1], operands[2]);
03149     }
03150 
03151   /* Free operand strings (not opstr).  */
03152   if (arity >= 1) xfree (operands[0]);
03153   if (arity >= 2) xfree (operands[1]);
03154   if (arity >= 3) xfree (operands[2]);
03155 
03156   return concat_string;
03157 }
03158 
03159 #endif