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