12159047fSniklas /* symbols.c -symbol table-
2b55d4692Sfgsch Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3c074d1c9Sdrahn 1999, 2000, 2001, 2002, 2003
42159047fSniklas Free Software Foundation, Inc.
52159047fSniklas
62159047fSniklas This file is part of GAS, the GNU Assembler.
72159047fSniklas
82159047fSniklas GAS is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2, or (at your option)
112159047fSniklas any later version.
122159047fSniklas
132159047fSniklas GAS is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas
182159047fSniklas You should have received a copy of the GNU General Public License
19b305b0f1Sespie along with GAS; see the file COPYING. If not, write to the Free
20b305b0f1Sespie Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21b305b0f1Sespie 02111-1307, USA. */
222159047fSniklas
23b55d4692Sfgsch /* #define DEBUG_SYMS / * to debug symbol list maintenance. */
242159047fSniklas
252159047fSniklas #include "as.h"
262159047fSniklas
27c074d1c9Sdrahn #include "safe-ctype.h"
282159047fSniklas #include "obstack.h" /* For "symbols.h" */
292159047fSniklas #include "subsegs.h"
302159047fSniklas
31b305b0f1Sespie #include "struc-symbol.h"
32b305b0f1Sespie
332159047fSniklas /* This is non-zero if symbols are case sensitive, which is the
342159047fSniklas default. */
352159047fSniklas int symbols_case_sensitive = 1;
362159047fSniklas
372159047fSniklas #ifndef WORKING_DOT_WORD
382159047fSniklas extern int new_broken_words;
392159047fSniklas #endif
402159047fSniklas
412159047fSniklas /* symbol-name => struct symbol pointer */
422159047fSniklas static struct hash_control *sy_hash;
432159047fSniklas
44b305b0f1Sespie /* Table of local symbols. */
45b305b0f1Sespie static struct hash_control *local_hash;
46b305b0f1Sespie
472159047fSniklas /* Below are commented in "symbols.h". */
482159047fSniklas symbolS *symbol_rootP;
492159047fSniklas symbolS *symbol_lastP;
502159047fSniklas symbolS abs_symbol;
512159047fSniklas
522159047fSniklas #ifdef DEBUG_SYMS
532159047fSniklas #define debug_verify_symchain verify_symbol_chain
542159047fSniklas #else
550c6d0228Sniklas #define debug_verify_symchain(root, last) ((void) 0)
562159047fSniklas #endif
572159047fSniklas
58b55d4692Sfgsch #define DOLLAR_LABEL_CHAR '\001'
59b55d4692Sfgsch #define LOCAL_LABEL_CHAR '\002'
60b55d4692Sfgsch
612159047fSniklas struct obstack notes;
622159047fSniklas
63*007c2a45Smiod static char *save_symbol_name (const char *);
64*007c2a45Smiod static void fb_label_init (void);
65*007c2a45Smiod static long dollar_label_instance (long);
66*007c2a45Smiod static long fb_label_instance (long);
67b305b0f1Sespie
68*007c2a45Smiod static void print_binary (FILE *, const char *, expressionS *);
69*007c2a45Smiod static void report_op_error (symbolS *, symbolS *, symbolS *);
702159047fSniklas
71b55d4692Sfgsch /* Return a pointer to a new symbol. Die if we can't make a new
722159047fSniklas symbol. Fill in the symbol's values. Add symbol to end of symbol
732159047fSniklas chain.
742159047fSniklas
752159047fSniklas This function should be called in the general case of creating a
762159047fSniklas symbol. However, if the output file symbol table has already been
772159047fSniklas set, and you are certain that this symbol won't be wanted in the
782159047fSniklas output file, you can call symbol_create. */
792159047fSniklas
802159047fSniklas symbolS *
symbol_new(const char * name,segT segment,valueT valu,fragS * frag)81*007c2a45Smiod symbol_new (const char *name, segT segment, valueT valu, fragS *frag)
822159047fSniklas {
832159047fSniklas symbolS *symbolP = symbol_create (name, segment, valu, frag);
842159047fSniklas
85b55d4692Sfgsch /* Link to end of symbol chain. */
862159047fSniklas #ifdef BFD_ASSEMBLER
872159047fSniklas {
882159047fSniklas extern int symbol_table_frozen;
892159047fSniklas if (symbol_table_frozen)
902159047fSniklas abort ();
912159047fSniklas }
922159047fSniklas #endif
932159047fSniklas symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
942159047fSniklas
952159047fSniklas return symbolP;
962159047fSniklas }
972159047fSniklas
98b305b0f1Sespie /* Save a symbol name on a permanent obstack, and convert it according
99b305b0f1Sespie to the object file format. */
100b305b0f1Sespie
101b305b0f1Sespie static char *
save_symbol_name(const char * name)102*007c2a45Smiod save_symbol_name (const char *name)
103b305b0f1Sespie {
104b305b0f1Sespie unsigned int name_length;
105b305b0f1Sespie char *ret;
106b305b0f1Sespie
107b55d4692Sfgsch name_length = strlen (name) + 1; /* +1 for \0. */
108b305b0f1Sespie obstack_grow (¬es, name, name_length);
109b305b0f1Sespie ret = obstack_finish (¬es);
110b305b0f1Sespie
111b305b0f1Sespie #ifdef STRIP_UNDERSCORE
112b305b0f1Sespie if (ret[0] == '_')
113b305b0f1Sespie ++ret;
114b305b0f1Sespie #endif
115b305b0f1Sespie
116b305b0f1Sespie #ifdef tc_canonicalize_symbol_name
117b305b0f1Sespie ret = tc_canonicalize_symbol_name (ret);
118b305b0f1Sespie #endif
119b305b0f1Sespie
120b305b0f1Sespie if (! symbols_case_sensitive)
121b305b0f1Sespie {
122c074d1c9Sdrahn char *s;
123b305b0f1Sespie
124c074d1c9Sdrahn for (s = ret; *s != '\0'; s++)
125c074d1c9Sdrahn *s = TOUPPER (*s);
126b305b0f1Sespie }
127b305b0f1Sespie
128b305b0f1Sespie return ret;
129b305b0f1Sespie }
130b305b0f1Sespie
1312159047fSniklas symbolS *
symbol_create(const char * name,segT segment,valueT valu,fragS * frag)132*007c2a45Smiod symbol_create (const char *name, /* It is copied, the caller can destroy/modify. */
133*007c2a45Smiod segT segment, /* Segment identifier (SEG_<something>). */
134*007c2a45Smiod valueT valu, /* Symbol value. */
135*007c2a45Smiod fragS *frag /* Associated fragment. */)
1362159047fSniklas {
1372159047fSniklas char *preserved_copy_of_name;
1382159047fSniklas symbolS *symbolP;
1392159047fSniklas
140b305b0f1Sespie preserved_copy_of_name = save_symbol_name (name);
1412159047fSniklas
1422159047fSniklas symbolP = (symbolS *) obstack_alloc (¬es, sizeof (symbolS));
1432159047fSniklas
1442159047fSniklas /* symbol must be born in some fixed state. This seems as good as any. */
1452159047fSniklas memset (symbolP, 0, sizeof (symbolS));
1462159047fSniklas
1472159047fSniklas #ifdef BFD_ASSEMBLER
1482159047fSniklas symbolP->bsym = bfd_make_empty_symbol (stdoutput);
149191aa565Sniklas if (symbolP->bsym == NULL)
150191aa565Sniklas as_perror ("%s", "bfd_make_empty_symbol");
1512159047fSniklas symbolP->bsym->udata.p = (PTR) symbolP;
1522159047fSniklas #endif
1532159047fSniklas S_SET_NAME (symbolP, preserved_copy_of_name);
1542159047fSniklas
1552159047fSniklas S_SET_SEGMENT (symbolP, segment);
1562159047fSniklas S_SET_VALUE (symbolP, valu);
1572159047fSniklas symbol_clear_list_pointers (symbolP);
1582159047fSniklas
1592159047fSniklas symbolP->sy_frag = frag;
1602159047fSniklas #ifndef BFD_ASSEMBLER
1612159047fSniklas symbolP->sy_number = ~0;
1622159047fSniklas symbolP->sy_name_offset = (unsigned int) ~0;
1632159047fSniklas #endif
1642159047fSniklas
1652159047fSniklas obj_symbol_new_hook (symbolP);
1662159047fSniklas
1672159047fSniklas #ifdef tc_symbol_new_hook
1682159047fSniklas tc_symbol_new_hook (symbolP);
1692159047fSniklas #endif
1702159047fSniklas
1712159047fSniklas return symbolP;
1722159047fSniklas }
1732159047fSniklas
174b305b0f1Sespie #ifdef BFD_ASSEMBLER
175b305b0f1Sespie
176b305b0f1Sespie /* Local symbol support. If we can get away with it, we keep only a
177b305b0f1Sespie small amount of information for local symbols. */
178b305b0f1Sespie
179*007c2a45Smiod static symbolS *local_symbol_convert (struct local_symbol *);
180b305b0f1Sespie
181b305b0f1Sespie /* Used for statistics. */
182b305b0f1Sespie
183b305b0f1Sespie static unsigned long local_symbol_count;
184b305b0f1Sespie static unsigned long local_symbol_conversion_count;
185b305b0f1Sespie
186b305b0f1Sespie /* This macro is called with a symbol argument passed by reference.
187b305b0f1Sespie It returns whether this is a local symbol. If necessary, it
188b305b0f1Sespie changes its argument to the real symbol. */
189b305b0f1Sespie
190b305b0f1Sespie #define LOCAL_SYMBOL_CHECK(s) \
191b305b0f1Sespie (s->bsym == NULL \
192b305b0f1Sespie ? (local_symbol_converted_p ((struct local_symbol *) s) \
193b305b0f1Sespie ? (s = local_symbol_get_real_symbol ((struct local_symbol *) s), \
194b305b0f1Sespie 0) \
195b305b0f1Sespie : 1) \
196b305b0f1Sespie : 0)
197b305b0f1Sespie
198b305b0f1Sespie /* Create a local symbol and insert it into the local hash table. */
199b305b0f1Sespie
200*007c2a45Smiod struct local_symbol *
local_symbol_make(const char * name,segT section,valueT value,fragS * frag)201*007c2a45Smiod local_symbol_make (const char *name, segT section, valueT value, fragS *frag)
202b305b0f1Sespie {
203b305b0f1Sespie char *name_copy;
204b305b0f1Sespie struct local_symbol *ret;
205b305b0f1Sespie
206b305b0f1Sespie ++local_symbol_count;
207b305b0f1Sespie
208b305b0f1Sespie name_copy = save_symbol_name (name);
209b305b0f1Sespie
210b305b0f1Sespie ret = (struct local_symbol *) obstack_alloc (¬es, sizeof *ret);
211b305b0f1Sespie ret->lsy_marker = NULL;
212b305b0f1Sespie ret->lsy_name = name_copy;
213b305b0f1Sespie ret->lsy_section = section;
214b305b0f1Sespie local_symbol_set_frag (ret, frag);
215c074d1c9Sdrahn ret->lsy_value = value;
216b305b0f1Sespie
217b305b0f1Sespie hash_jam (local_hash, name_copy, (PTR) ret);
218b305b0f1Sespie
219b305b0f1Sespie return ret;
220b305b0f1Sespie }
221b305b0f1Sespie
222b305b0f1Sespie /* Convert a local symbol into a real symbol. Note that we do not
223b305b0f1Sespie reclaim the space used by the local symbol. */
224b305b0f1Sespie
225b305b0f1Sespie static symbolS *
local_symbol_convert(struct local_symbol * locsym)226*007c2a45Smiod local_symbol_convert (struct local_symbol *locsym)
227b305b0f1Sespie {
228b305b0f1Sespie symbolS *ret;
229b305b0f1Sespie
230b305b0f1Sespie assert (locsym->lsy_marker == NULL);
231b305b0f1Sespie if (local_symbol_converted_p (locsym))
232b305b0f1Sespie return local_symbol_get_real_symbol (locsym);
233b305b0f1Sespie
234b305b0f1Sespie ++local_symbol_conversion_count;
235b305b0f1Sespie
236c074d1c9Sdrahn ret = symbol_new (locsym->lsy_name, locsym->lsy_section, locsym->lsy_value,
237b305b0f1Sespie local_symbol_get_frag (locsym));
238b305b0f1Sespie
239b305b0f1Sespie if (local_symbol_resolved_p (locsym))
240b305b0f1Sespie ret->sy_resolved = 1;
241b305b0f1Sespie
242b305b0f1Sespie /* Local symbols are always either defined or used. */
243b305b0f1Sespie ret->sy_used = 1;
244b305b0f1Sespie
245c074d1c9Sdrahn #ifdef TC_LOCAL_SYMFIELD_CONVERT
246c074d1c9Sdrahn TC_LOCAL_SYMFIELD_CONVERT (locsym, ret);
247c074d1c9Sdrahn #endif
248c074d1c9Sdrahn
249b305b0f1Sespie symbol_table_insert (ret);
250b305b0f1Sespie
251b305b0f1Sespie local_symbol_mark_converted (locsym);
252b305b0f1Sespie local_symbol_set_real_symbol (locsym, ret);
253b305b0f1Sespie
254b305b0f1Sespie hash_jam (local_hash, locsym->lsy_name, NULL);
255b305b0f1Sespie
256b305b0f1Sespie return ret;
257b305b0f1Sespie }
258b305b0f1Sespie
259b305b0f1Sespie #else /* ! BFD_ASSEMBLER */
260b305b0f1Sespie
261b305b0f1Sespie #define LOCAL_SYMBOL_CHECK(s) 0
262b305b0f1Sespie #define local_symbol_convert(s) ((symbolS *) s)
263b305b0f1Sespie
264b305b0f1Sespie #endif /* ! BFD_ASSEMBLER */
265b305b0f1Sespie
266b55d4692Sfgsch /* We have just seen "<name>:".
267b55d4692Sfgsch Creates a struct symbol unless it already exists.
2682159047fSniklas
269b55d4692Sfgsch Gripes if we are redefining a symbol incompatibly (and ignores it). */
270b55d4692Sfgsch
2712159047fSniklas symbolS *
colon(const char * sym_name)272*007c2a45Smiod colon (/* Just seen "x:" - rattle symbols & frags. */
273*007c2a45Smiod const char *sym_name /* Symbol name, as a cannonical string. */
274*007c2a45Smiod /* We copy this string: OK to alter later. */)
2752159047fSniklas {
276b55d4692Sfgsch register symbolS *symbolP; /* Symbol we are working with. */
2772159047fSniklas
2782159047fSniklas /* Sun local labels go out of scope whenever a non-local symbol is
2792159047fSniklas defined. */
280b305b0f1Sespie if (LOCAL_LABELS_DOLLAR)
281b305b0f1Sespie {
282b305b0f1Sespie int local;
283b305b0f1Sespie
284b305b0f1Sespie #ifdef BFD_ASSEMBLER
285b305b0f1Sespie local = bfd_is_local_label_name (stdoutput, sym_name);
286b305b0f1Sespie #else
287b305b0f1Sespie local = LOCAL_LABEL (sym_name);
288b305b0f1Sespie #endif
289b305b0f1Sespie
290b305b0f1Sespie if (! local)
2912159047fSniklas dollar_label_clear ();
292b305b0f1Sespie }
2932159047fSniklas
2942159047fSniklas #ifndef WORKING_DOT_WORD
2952159047fSniklas if (new_broken_words)
2962159047fSniklas {
2972159047fSniklas struct broken_word *a;
2982159047fSniklas int possible_bytes;
2992159047fSniklas fragS *frag_tmp;
3002159047fSniklas char *frag_opcode;
3012159047fSniklas
3022159047fSniklas extern const int md_short_jump_size;
3032159047fSniklas extern const int md_long_jump_size;
304c074d1c9Sdrahn
305c074d1c9Sdrahn if (now_seg == absolute_section)
306c074d1c9Sdrahn {
307c074d1c9Sdrahn as_bad (_("cannot define symbol `%s' in absolute section"), sym_name);
308c074d1c9Sdrahn return NULL;
309c074d1c9Sdrahn }
310c074d1c9Sdrahn
3112159047fSniklas possible_bytes = (md_short_jump_size
3122159047fSniklas + new_broken_words * md_long_jump_size);
3132159047fSniklas
3142159047fSniklas frag_tmp = frag_now;
3152159047fSniklas frag_opcode = frag_var (rs_broken_word,
3162159047fSniklas possible_bytes,
3172159047fSniklas possible_bytes,
3182159047fSniklas (relax_substateT) 0,
3192159047fSniklas (symbolS *) broken_words,
320b305b0f1Sespie (offsetT) 0,
3212159047fSniklas NULL);
3222159047fSniklas
323b55d4692Sfgsch /* We want to store the pointer to where to insert the jump
324b55d4692Sfgsch table in the fr_opcode of the rs_broken_word frag. This
325b55d4692Sfgsch requires a little hackery. */
3262159047fSniklas while (frag_tmp
3272159047fSniklas && (frag_tmp->fr_type != rs_broken_word
3282159047fSniklas || frag_tmp->fr_opcode))
3292159047fSniklas frag_tmp = frag_tmp->fr_next;
3302159047fSniklas know (frag_tmp);
3312159047fSniklas frag_tmp->fr_opcode = frag_opcode;
3322159047fSniklas new_broken_words = 0;
3332159047fSniklas
3342159047fSniklas for (a = broken_words; a && a->dispfrag == 0; a = a->next_broken_word)
3352159047fSniklas a->dispfrag = frag_tmp;
3362159047fSniklas }
3372159047fSniklas #endif /* WORKING_DOT_WORD */
3382159047fSniklas
3392159047fSniklas if ((symbolP = symbol_find (sym_name)) != 0)
3402159047fSniklas {
3412159047fSniklas #ifdef RESOLVE_SYMBOL_REDEFINITION
3422159047fSniklas if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
3432159047fSniklas return symbolP;
3442159047fSniklas #endif
345b55d4692Sfgsch /* Now check for undefined symbols. */
346b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (symbolP))
347b305b0f1Sespie {
348b305b0f1Sespie #ifdef BFD_ASSEMBLER
349b305b0f1Sespie struct local_symbol *locsym = (struct local_symbol *) symbolP;
350b305b0f1Sespie
351b305b0f1Sespie if (locsym->lsy_section != undefined_section
352b305b0f1Sespie && (local_symbol_get_frag (locsym) != frag_now
353b305b0f1Sespie || locsym->lsy_section != now_seg
354c074d1c9Sdrahn || locsym->lsy_value != frag_now_fix ()))
355b305b0f1Sespie {
356c074d1c9Sdrahn as_bad (_("symbol `%s' is already defined"), sym_name);
357b305b0f1Sespie return symbolP;
358b305b0f1Sespie }
359b305b0f1Sespie
360b305b0f1Sespie locsym->lsy_section = now_seg;
361b305b0f1Sespie local_symbol_set_frag (locsym, frag_now);
362c074d1c9Sdrahn locsym->lsy_value = frag_now_fix ();
363b305b0f1Sespie #endif
364b305b0f1Sespie }
365b305b0f1Sespie else if (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
3662159047fSniklas {
3672159047fSniklas if (S_GET_VALUE (symbolP) == 0)
3682159047fSniklas {
3692159047fSniklas symbolP->sy_frag = frag_now;
3702159047fSniklas #ifdef OBJ_VMS
3710c6d0228Sniklas S_SET_OTHER (symbolP, const_flag);
3722159047fSniklas #endif
3732159047fSniklas S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
3742159047fSniklas S_SET_SEGMENT (symbolP, now_seg);
3752159047fSniklas #ifdef N_UNDF
3762159047fSniklas know (N_UNDF == 0);
3772159047fSniklas #endif /* if we have one, it better be zero. */
3782159047fSniklas
3792159047fSniklas }
3802159047fSniklas else
3812159047fSniklas {
382b55d4692Sfgsch /* There are still several cases to check:
383b55d4692Sfgsch
384b55d4692Sfgsch A .comm/.lcomm symbol being redefined as initialized
385b55d4692Sfgsch data is OK
386b55d4692Sfgsch
387b55d4692Sfgsch A .comm/.lcomm symbol being redefined with a larger
388b55d4692Sfgsch size is also OK
389b55d4692Sfgsch
390b55d4692Sfgsch This only used to be allowed on VMS gas, but Sun cc
391b55d4692Sfgsch on the sparc also depends on it. */
3922159047fSniklas
3932159047fSniklas if (((!S_IS_DEBUG (symbolP)
394b305b0f1Sespie && (!S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))
3952159047fSniklas && S_IS_EXTERNAL (symbolP))
3962159047fSniklas || S_GET_SEGMENT (symbolP) == bss_section)
3972159047fSniklas && (now_seg == data_section
3982159047fSniklas || now_seg == S_GET_SEGMENT (symbolP)))
3992159047fSniklas {
400b55d4692Sfgsch /* Select which of the 2 cases this is. */
4012159047fSniklas if (now_seg != data_section)
4022159047fSniklas {
403b55d4692Sfgsch /* New .comm for prev .comm symbol.
404b55d4692Sfgsch
405b55d4692Sfgsch If the new size is larger we just change its
406b55d4692Sfgsch value. If the new size is smaller, we ignore
407b55d4692Sfgsch this symbol. */
4082159047fSniklas if (S_GET_VALUE (symbolP)
4092159047fSniklas < ((unsigned) frag_now_fix ()))
4102159047fSniklas {
4112159047fSniklas S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
4122159047fSniklas }
4132159047fSniklas }
4142159047fSniklas else
4152159047fSniklas {
4162159047fSniklas /* It is a .comm/.lcomm being converted to initialized
4172159047fSniklas data. */
4182159047fSniklas symbolP->sy_frag = frag_now;
4192159047fSniklas #ifdef OBJ_VMS
4200c6d0228Sniklas S_SET_OTHER (symbolP, const_flag);
4210c6d0228Sniklas #endif
4222159047fSniklas S_SET_VALUE (symbolP, (valueT) frag_now_fix ());
423b55d4692Sfgsch S_SET_SEGMENT (symbolP, now_seg); /* Keep N_EXT bit. */
4242159047fSniklas }
4252159047fSniklas }
4262159047fSniklas else
4272159047fSniklas {
428b305b0f1Sespie #if (!defined (OBJ_AOUT) && !defined (OBJ_MAYBE_AOUT) \
429b305b0f1Sespie && !defined (OBJ_BOUT) && !defined (OBJ_MAYBE_BOUT))
430b305b0f1Sespie static const char *od_buf = "";
4312159047fSniklas #else
432b305b0f1Sespie char od_buf[100];
433b305b0f1Sespie od_buf[0] = '\0';
434b305b0f1Sespie #ifdef BFD_ASSEMBLER
435b305b0f1Sespie if (OUTPUT_FLAVOR == bfd_target_aout_flavour)
436b305b0f1Sespie #endif
437b305b0f1Sespie sprintf (od_buf, "%d.%d.",
438b305b0f1Sespie S_GET_OTHER (symbolP),
439b305b0f1Sespie S_GET_DESC (symbolP));
440b305b0f1Sespie #endif
441c074d1c9Sdrahn as_bad (_("symbol `%s' is already defined as \"%s\"/%s%ld"),
4422159047fSniklas sym_name,
4432159047fSniklas segment_name (S_GET_SEGMENT (symbolP)),
444b305b0f1Sespie od_buf,
4452159047fSniklas (long) S_GET_VALUE (symbolP));
4462159047fSniklas }
4472159047fSniklas } /* if the undefined symbol has no value */
4482159047fSniklas }
4492159047fSniklas else
4502159047fSniklas {
451b55d4692Sfgsch /* Don't blow up if the definition is the same. */
4522159047fSniklas if (!(frag_now == symbolP->sy_frag
4532159047fSniklas && S_GET_VALUE (symbolP) == frag_now_fix ()
4542159047fSniklas && S_GET_SEGMENT (symbolP) == now_seg))
455c074d1c9Sdrahn as_bad (_("symbol `%s' is already defined"), sym_name);
456b55d4692Sfgsch }
4572159047fSniklas
4582159047fSniklas }
459b305b0f1Sespie #ifdef BFD_ASSEMBLER
460b305b0f1Sespie else if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, sym_name))
461b305b0f1Sespie {
462b305b0f1Sespie symbolP = (symbolS *) local_symbol_make (sym_name, now_seg,
463b305b0f1Sespie (valueT) frag_now_fix (),
464b305b0f1Sespie frag_now);
465b305b0f1Sespie }
466b305b0f1Sespie #endif /* BFD_ASSEMBLER */
4672159047fSniklas else
4682159047fSniklas {
4692159047fSniklas symbolP = symbol_new (sym_name, now_seg, (valueT) frag_now_fix (),
4702159047fSniklas frag_now);
4712159047fSniklas #ifdef OBJ_VMS
4722159047fSniklas S_SET_OTHER (symbolP, const_flag);
4732159047fSniklas #endif /* OBJ_VMS */
4742159047fSniklas
4752159047fSniklas symbol_table_insert (symbolP);
476b55d4692Sfgsch }
4772159047fSniklas
4782159047fSniklas if (mri_common_symbol != NULL)
4792159047fSniklas {
4802159047fSniklas /* This symbol is actually being defined within an MRI common
4812159047fSniklas section. This requires special handling. */
482b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (symbolP))
483b305b0f1Sespie symbolP = local_symbol_convert ((struct local_symbol *) symbolP);
4842159047fSniklas symbolP->sy_value.X_op = O_symbol;
4852159047fSniklas symbolP->sy_value.X_add_symbol = mri_common_symbol;
4862159047fSniklas symbolP->sy_value.X_add_number = S_GET_VALUE (mri_common_symbol);
4872159047fSniklas symbolP->sy_frag = &zero_address_frag;
4882159047fSniklas S_SET_SEGMENT (symbolP, expr_section);
4892159047fSniklas symbolP->sy_mri_common = 1;
4902159047fSniklas }
4912159047fSniklas
4922159047fSniklas #ifdef tc_frob_label
4932159047fSniklas tc_frob_label (symbolP);
4942159047fSniklas #endif
495b305b0f1Sespie #ifdef obj_frob_label
496b305b0f1Sespie obj_frob_label (symbolP);
497b305b0f1Sespie #endif
4982159047fSniklas
4992159047fSniklas return symbolP;
5002159047fSniklas }
5012159047fSniklas
502b55d4692Sfgsch /* Die if we can't insert the symbol. */
5032159047fSniklas
5042159047fSniklas void
symbol_table_insert(symbolS * symbolP)505*007c2a45Smiod symbol_table_insert (symbolS *symbolP)
5062159047fSniklas {
5072159047fSniklas register const char *error_string;
5082159047fSniklas
5092159047fSniklas know (symbolP);
5102159047fSniklas know (S_GET_NAME (symbolP));
5112159047fSniklas
512b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (symbolP))
513b305b0f1Sespie {
514b305b0f1Sespie error_string = hash_jam (local_hash, S_GET_NAME (symbolP),
515b305b0f1Sespie (PTR) symbolP);
516b305b0f1Sespie if (error_string != NULL)
517c074d1c9Sdrahn as_fatal (_("inserting \"%s\" into symbol table failed: %s"),
518b305b0f1Sespie S_GET_NAME (symbolP), error_string);
519b305b0f1Sespie return;
520b305b0f1Sespie }
521b305b0f1Sespie
5222159047fSniklas if ((error_string = hash_jam (sy_hash, S_GET_NAME (symbolP), (PTR) symbolP)))
5232159047fSniklas {
524c074d1c9Sdrahn as_fatal (_("inserting \"%s\" into symbol table failed: %s"),
5252159047fSniklas S_GET_NAME (symbolP), error_string);
5262159047fSniklas } /* on error */
527b55d4692Sfgsch }
5282159047fSniklas
529b55d4692Sfgsch /* If a symbol name does not exist, create it as undefined, and insert
530b55d4692Sfgsch it into the symbol table. Return a pointer to it. */
531b55d4692Sfgsch
5322159047fSniklas symbolS *
symbol_find_or_make(const char * name)533*007c2a45Smiod symbol_find_or_make (const char *name)
5342159047fSniklas {
5352159047fSniklas register symbolS *symbolP;
5362159047fSniklas
5372159047fSniklas symbolP = symbol_find (name);
5382159047fSniklas
5392159047fSniklas if (symbolP == NULL)
5402159047fSniklas {
541b305b0f1Sespie #ifdef BFD_ASSEMBLER
542b305b0f1Sespie if (! flag_keep_locals && bfd_is_local_label_name (stdoutput, name))
543b305b0f1Sespie {
544b305b0f1Sespie symbolP = md_undefined_symbol ((char *) name);
545b305b0f1Sespie if (symbolP != NULL)
546b305b0f1Sespie return symbolP;
547b305b0f1Sespie
548b305b0f1Sespie symbolP = (symbolS *) local_symbol_make (name, undefined_section,
549b305b0f1Sespie (valueT) 0,
550b305b0f1Sespie &zero_address_frag);
551b305b0f1Sespie return symbolP;
552b305b0f1Sespie }
553b305b0f1Sespie #endif
554b305b0f1Sespie
5552159047fSniklas symbolP = symbol_make (name);
5562159047fSniklas
5572159047fSniklas symbol_table_insert (symbolP);
5582159047fSniklas } /* if symbol wasn't found */
5592159047fSniklas
5602159047fSniklas return (symbolP);
561b55d4692Sfgsch }
5622159047fSniklas
5632159047fSniklas symbolS *
symbol_make(const char * name)564*007c2a45Smiod symbol_make (const char *name)
5652159047fSniklas {
5662159047fSniklas symbolS *symbolP;
5672159047fSniklas
5682159047fSniklas /* Let the machine description default it, e.g. for register names. */
5692159047fSniklas symbolP = md_undefined_symbol ((char *) name);
5702159047fSniklas
5712159047fSniklas if (!symbolP)
5722159047fSniklas symbolP = symbol_new (name, undefined_section, (valueT) 0, &zero_address_frag);
5732159047fSniklas
5742159047fSniklas return (symbolP);
575b55d4692Sfgsch }
5762159047fSniklas
577*007c2a45Smiod symbolS *
symbol_temp_new(segT seg,valueT ofs,fragS * frag)578*007c2a45Smiod symbol_temp_new (segT seg, valueT ofs, fragS *frag)
579*007c2a45Smiod {
580*007c2a45Smiod return symbol_new (FAKE_LABEL_NAME, seg, ofs, frag);
581*007c2a45Smiod }
582*007c2a45Smiod
583*007c2a45Smiod symbolS *
symbol_temp_new_now(void)584*007c2a45Smiod symbol_temp_new_now (void)
585*007c2a45Smiod {
586*007c2a45Smiod return symbol_temp_new (now_seg, frag_now_fix (), frag_now);
587*007c2a45Smiod }
588*007c2a45Smiod
589*007c2a45Smiod symbolS *
symbol_temp_make(void)590*007c2a45Smiod symbol_temp_make (void)
591*007c2a45Smiod {
592*007c2a45Smiod return symbol_make (FAKE_LABEL_NAME);
593*007c2a45Smiod }
594*007c2a45Smiod
595b55d4692Sfgsch /* Implement symbol table lookup.
596b55d4692Sfgsch In: A symbol's name as a string: '\0' can't be part of a symbol name.
597b55d4692Sfgsch Out: NULL if the name was not in the symbol table, else the address
598b55d4692Sfgsch of a struct symbol associated with that name. */
5992159047fSniklas
6002159047fSniklas symbolS *
symbol_find(const char * name)601*007c2a45Smiod symbol_find (const char *name)
6022159047fSniklas {
6032159047fSniklas #ifdef STRIP_UNDERSCORE
6042159047fSniklas return (symbol_find_base (name, 1));
6052159047fSniklas #else /* STRIP_UNDERSCORE */
6062159047fSniklas return (symbol_find_base (name, 0));
6072159047fSniklas #endif /* STRIP_UNDERSCORE */
608b55d4692Sfgsch }
6092159047fSniklas
6102159047fSniklas symbolS *
symbol_find_exact(const char * name)611*007c2a45Smiod symbol_find_exact (const char *name)
612c074d1c9Sdrahn {
613c074d1c9Sdrahn #ifdef BFD_ASSEMBLER
614c074d1c9Sdrahn {
615c074d1c9Sdrahn struct local_symbol *locsym;
616c074d1c9Sdrahn
617c074d1c9Sdrahn locsym = (struct local_symbol *) hash_find (local_hash, name);
618c074d1c9Sdrahn if (locsym != NULL)
619c074d1c9Sdrahn return (symbolS *) locsym;
620c074d1c9Sdrahn }
621c074d1c9Sdrahn #endif
622c074d1c9Sdrahn
623c074d1c9Sdrahn return ((symbolS *) hash_find (sy_hash, name));
624c074d1c9Sdrahn }
625c074d1c9Sdrahn
626c074d1c9Sdrahn symbolS *
symbol_find_base(const char * name,int strip_underscore)627*007c2a45Smiod symbol_find_base (const char *name, int strip_underscore)
6282159047fSniklas {
6292159047fSniklas if (strip_underscore && *name == '_')
6302159047fSniklas name++;
6312159047fSniklas
6322159047fSniklas #ifdef tc_canonicalize_symbol_name
6332159047fSniklas {
6342159047fSniklas char *copy;
635b305b0f1Sespie size_t len = strlen (name) + 1;
6362159047fSniklas
637b305b0f1Sespie copy = (char *) alloca (len);
638b305b0f1Sespie memcpy (copy, name, len);
6392159047fSniklas name = tc_canonicalize_symbol_name (copy);
6402159047fSniklas }
6412159047fSniklas #endif
6422159047fSniklas
6432159047fSniklas if (! symbols_case_sensitive)
6442159047fSniklas {
645b305b0f1Sespie char *copy;
646b305b0f1Sespie const char *orig;
647b305b0f1Sespie unsigned char c;
6482159047fSniklas
649b305b0f1Sespie orig = name;
650b305b0f1Sespie name = copy = (char *) alloca (strlen (name) + 1);
651b305b0f1Sespie
652b305b0f1Sespie while ((c = *orig++) != '\0')
653b305b0f1Sespie {
654c074d1c9Sdrahn *copy++ = TOUPPER (c);
6552159047fSniklas }
656b305b0f1Sespie *copy = '\0';
657b305b0f1Sespie }
658b305b0f1Sespie
659c074d1c9Sdrahn return symbol_find_exact (name);
6602159047fSniklas }
6612159047fSniklas
662b55d4692Sfgsch /* Once upon a time, symbols were kept in a singly linked list. At
663b55d4692Sfgsch least coff needs to be able to rearrange them from time to time, for
664b55d4692Sfgsch which a doubly linked list is much more convenient. Loic did these
665b55d4692Sfgsch as macros which seemed dangerous to me so they're now functions.
666b55d4692Sfgsch xoxorich. */
6672159047fSniklas
6682159047fSniklas /* Link symbol ADDME after symbol TARGET in the chain. */
669b55d4692Sfgsch
6702159047fSniklas void
symbol_append(symbolS * addme,symbolS * target,symbolS ** rootPP,symbolS ** lastPP)671*007c2a45Smiod symbol_append (symbolS *addme, symbolS *target,
672*007c2a45Smiod symbolS **rootPP, symbolS **lastPP)
6732159047fSniklas {
674b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (addme))
675b305b0f1Sespie abort ();
676b305b0f1Sespie if (target != NULL && LOCAL_SYMBOL_CHECK (target))
677b305b0f1Sespie abort ();
678b305b0f1Sespie
6792159047fSniklas if (target == NULL)
6802159047fSniklas {
6812159047fSniklas know (*rootPP == NULL);
6822159047fSniklas know (*lastPP == NULL);
683b305b0f1Sespie addme->sy_next = NULL;
684b305b0f1Sespie #ifdef SYMBOLS_NEED_BACKPOINTERS
685b305b0f1Sespie addme->sy_previous = NULL;
686b305b0f1Sespie #endif
6872159047fSniklas *rootPP = addme;
6882159047fSniklas *lastPP = addme;
6892159047fSniklas return;
6902159047fSniklas } /* if the list is empty */
6912159047fSniklas
6922159047fSniklas if (target->sy_next != NULL)
6932159047fSniklas {
6942159047fSniklas #ifdef SYMBOLS_NEED_BACKPOINTERS
6952159047fSniklas target->sy_next->sy_previous = addme;
6962159047fSniklas #endif /* SYMBOLS_NEED_BACKPOINTERS */
6972159047fSniklas }
6982159047fSniklas else
6992159047fSniklas {
7002159047fSniklas know (*lastPP == target);
7012159047fSniklas *lastPP = addme;
7022159047fSniklas } /* if we have a next */
7032159047fSniklas
7042159047fSniklas addme->sy_next = target->sy_next;
7052159047fSniklas target->sy_next = addme;
7062159047fSniklas
7072159047fSniklas #ifdef SYMBOLS_NEED_BACKPOINTERS
7082159047fSniklas addme->sy_previous = target;
7092159047fSniklas #endif /* SYMBOLS_NEED_BACKPOINTERS */
710b305b0f1Sespie
711b305b0f1Sespie debug_verify_symchain (symbol_rootP, symbol_lastP);
7122159047fSniklas }
7132159047fSniklas
7142159047fSniklas /* Set the chain pointers of SYMBOL to null. */
715b55d4692Sfgsch
7162159047fSniklas void
symbol_clear_list_pointers(symbolS * symbolP)717*007c2a45Smiod symbol_clear_list_pointers (symbolS *symbolP)
7182159047fSniklas {
719b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (symbolP))
720b305b0f1Sespie abort ();
7212159047fSniklas symbolP->sy_next = NULL;
7222159047fSniklas #ifdef SYMBOLS_NEED_BACKPOINTERS
7232159047fSniklas symbolP->sy_previous = NULL;
7242159047fSniklas #endif
7252159047fSniklas }
7262159047fSniklas
7272159047fSniklas #ifdef SYMBOLS_NEED_BACKPOINTERS
7282159047fSniklas /* Remove SYMBOLP from the list. */
729b55d4692Sfgsch
7302159047fSniklas void
symbol_remove(symbolS * symbolP,symbolS ** rootPP,symbolS ** lastPP)731*007c2a45Smiod symbol_remove (symbolS *symbolP, symbolS **rootPP, symbolS **lastPP)
7322159047fSniklas {
733b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (symbolP))
734b305b0f1Sespie abort ();
735b305b0f1Sespie
7362159047fSniklas if (symbolP == *rootPP)
7372159047fSniklas {
7382159047fSniklas *rootPP = symbolP->sy_next;
7392159047fSniklas } /* if it was the root */
7402159047fSniklas
7412159047fSniklas if (symbolP == *lastPP)
7422159047fSniklas {
7432159047fSniklas *lastPP = symbolP->sy_previous;
7442159047fSniklas } /* if it was the tail */
7452159047fSniklas
7462159047fSniklas if (symbolP->sy_next != NULL)
7472159047fSniklas {
7482159047fSniklas symbolP->sy_next->sy_previous = symbolP->sy_previous;
7492159047fSniklas } /* if not last */
7502159047fSniklas
7512159047fSniklas if (symbolP->sy_previous != NULL)
7522159047fSniklas {
7532159047fSniklas symbolP->sy_previous->sy_next = symbolP->sy_next;
7542159047fSniklas } /* if not first */
7552159047fSniklas
7562159047fSniklas debug_verify_symchain (*rootPP, *lastPP);
7572159047fSniklas }
7582159047fSniklas
7592159047fSniklas /* Link symbol ADDME before symbol TARGET in the chain. */
760b55d4692Sfgsch
7612159047fSniklas void
symbol_insert(symbolS * addme,symbolS * target,symbolS ** rootPP,symbolS ** lastPP ATTRIBUTE_UNUSED)762*007c2a45Smiod symbol_insert (symbolS *addme, symbolS *target,
763*007c2a45Smiod symbolS **rootPP, symbolS **lastPP ATTRIBUTE_UNUSED)
7642159047fSniklas {
765b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (addme))
766b305b0f1Sespie abort ();
767b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (target))
768b305b0f1Sespie abort ();
769b305b0f1Sespie
7702159047fSniklas if (target->sy_previous != NULL)
7712159047fSniklas {
7722159047fSniklas target->sy_previous->sy_next = addme;
7732159047fSniklas }
7742159047fSniklas else
7752159047fSniklas {
7762159047fSniklas know (*rootPP == target);
7772159047fSniklas *rootPP = addme;
7782159047fSniklas } /* if not first */
7792159047fSniklas
7802159047fSniklas addme->sy_previous = target->sy_previous;
7812159047fSniklas target->sy_previous = addme;
7822159047fSniklas addme->sy_next = target;
7832159047fSniklas
7842159047fSniklas debug_verify_symchain (*rootPP, *lastPP);
7852159047fSniklas }
7862159047fSniklas
7872159047fSniklas #endif /* SYMBOLS_NEED_BACKPOINTERS */
7882159047fSniklas
7892159047fSniklas void
verify_symbol_chain(symbolS * rootP,symbolS * lastP)790*007c2a45Smiod verify_symbol_chain (symbolS *rootP, symbolS *lastP)
7912159047fSniklas {
7922159047fSniklas symbolS *symbolP = rootP;
7932159047fSniklas
7942159047fSniklas if (symbolP == NULL)
7952159047fSniklas return;
7962159047fSniklas
7972159047fSniklas for (; symbol_next (symbolP) != NULL; symbolP = symbol_next (symbolP))
7982159047fSniklas {
799b305b0f1Sespie #ifdef BFD_ASSEMBLER
800b305b0f1Sespie assert (symbolP->bsym != NULL);
801b305b0f1Sespie #endif
8022159047fSniklas #ifdef SYMBOLS_NEED_BACKPOINTERS
803b305b0f1Sespie assert (symbolP->sy_next->sy_previous == symbolP);
8042159047fSniklas #else
8052159047fSniklas /* Walk the list anyways, to make sure pointers are still good. */
8062159047fSniklas ;
8072159047fSniklas #endif /* SYMBOLS_NEED_BACKPOINTERS */
8082159047fSniklas }
8092159047fSniklas
8102159047fSniklas assert (lastP == symbolP);
8112159047fSniklas }
8122159047fSniklas
8132159047fSniklas void
verify_symbol_chain_2(symbolS * sym)814*007c2a45Smiod verify_symbol_chain_2 (symbolS *sym)
8152159047fSniklas {
8162159047fSniklas symbolS *p = sym, *n = sym;
8172159047fSniklas #ifdef SYMBOLS_NEED_BACKPOINTERS
8182159047fSniklas while (symbol_previous (p))
8192159047fSniklas p = symbol_previous (p);
8202159047fSniklas #endif
8212159047fSniklas while (symbol_next (n))
8222159047fSniklas n = symbol_next (n);
8232159047fSniklas verify_symbol_chain (p, n);
8242159047fSniklas }
8252159047fSniklas
826c074d1c9Sdrahn static void
report_op_error(symbolS * symp,symbolS * left,symbolS * right)827*007c2a45Smiod report_op_error (symbolS *symp, symbolS *left, symbolS *right)
828c074d1c9Sdrahn {
829c074d1c9Sdrahn char *file;
830c074d1c9Sdrahn unsigned int line;
831c074d1c9Sdrahn segT seg_left = S_GET_SEGMENT (left);
832c074d1c9Sdrahn segT seg_right = right ? S_GET_SEGMENT (right) : 0;
833c074d1c9Sdrahn
834c074d1c9Sdrahn if (expr_symbol_where (symp, &file, &line))
835c074d1c9Sdrahn {
836c074d1c9Sdrahn if (seg_left == undefined_section)
837c074d1c9Sdrahn as_bad_where (file, line,
838c074d1c9Sdrahn _("undefined symbol `%s' in operation"),
839c074d1c9Sdrahn S_GET_NAME (left));
840c074d1c9Sdrahn if (seg_right == undefined_section)
841c074d1c9Sdrahn as_bad_where (file, line,
842c074d1c9Sdrahn _("undefined symbol `%s' in operation"),
843c074d1c9Sdrahn S_GET_NAME (right));
844c074d1c9Sdrahn if (seg_left != undefined_section
845c074d1c9Sdrahn && seg_right != undefined_section)
846c074d1c9Sdrahn {
847c074d1c9Sdrahn if (right)
848c074d1c9Sdrahn as_bad_where (file, line,
849c074d1c9Sdrahn _("invalid sections for operation on `%s' and `%s'"),
850c074d1c9Sdrahn S_GET_NAME (left), S_GET_NAME (right));
851c074d1c9Sdrahn else
852c074d1c9Sdrahn as_bad_where (file, line,
853c074d1c9Sdrahn _("invalid section for operation on `%s'"),
854c074d1c9Sdrahn S_GET_NAME (left));
855c074d1c9Sdrahn }
856c074d1c9Sdrahn
857c074d1c9Sdrahn }
858c074d1c9Sdrahn else
859c074d1c9Sdrahn {
860c074d1c9Sdrahn if (seg_left == undefined_section)
861c074d1c9Sdrahn as_bad (_("undefined symbol `%s' in operation setting `%s'"),
862c074d1c9Sdrahn S_GET_NAME (left), S_GET_NAME (symp));
863c074d1c9Sdrahn if (seg_right == undefined_section)
864c074d1c9Sdrahn as_bad (_("undefined symbol `%s' in operation setting `%s'"),
865c074d1c9Sdrahn S_GET_NAME (right), S_GET_NAME (symp));
866c074d1c9Sdrahn if (seg_left != undefined_section
867c074d1c9Sdrahn && seg_right != undefined_section)
868c074d1c9Sdrahn {
869c074d1c9Sdrahn if (right)
870c074d1c9Sdrahn as_bad_where (file, line,
871c074d1c9Sdrahn _("invalid sections for operation on `%s' and `%s' setting `%s'"),
872c074d1c9Sdrahn S_GET_NAME (left), S_GET_NAME (right), S_GET_NAME (symp));
873c074d1c9Sdrahn else
874c074d1c9Sdrahn as_bad_where (file, line,
875c074d1c9Sdrahn _("invalid section for operation on `%s' setting `%s'"),
876c074d1c9Sdrahn S_GET_NAME (left), S_GET_NAME (symp));
877c074d1c9Sdrahn }
878c074d1c9Sdrahn }
879c074d1c9Sdrahn }
880c074d1c9Sdrahn
8812159047fSniklas /* Resolve the value of a symbol. This is called during the final
8822159047fSniklas pass over the symbol table to resolve any symbols with complex
8832159047fSniklas values. */
8842159047fSniklas
885b305b0f1Sespie valueT
resolve_symbol_value(symbolS * symp)886*007c2a45Smiod resolve_symbol_value (symbolS *symp)
8872159047fSniklas {
8882159047fSniklas int resolved;
889c074d1c9Sdrahn valueT final_val = 0;
890b305b0f1Sespie segT final_seg;
891b305b0f1Sespie
892b305b0f1Sespie #ifdef BFD_ASSEMBLER
893b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (symp))
894b305b0f1Sespie {
895b305b0f1Sespie struct local_symbol *locsym = (struct local_symbol *) symp;
896b305b0f1Sespie
897c074d1c9Sdrahn final_val = locsym->lsy_value;
898b305b0f1Sespie if (local_symbol_resolved_p (locsym))
899c074d1c9Sdrahn return final_val;
900b305b0f1Sespie
901c074d1c9Sdrahn final_val += local_symbol_get_frag (locsym)->fr_address / OCTETS_PER_BYTE;
902b305b0f1Sespie
903c074d1c9Sdrahn if (finalize_syms)
904b305b0f1Sespie {
905c074d1c9Sdrahn locsym->lsy_value = final_val;
906b305b0f1Sespie local_symbol_mark_resolved (locsym);
907b305b0f1Sespie }
908b305b0f1Sespie
909b305b0f1Sespie return final_val;
910b305b0f1Sespie }
911b305b0f1Sespie #endif
9122159047fSniklas
9132159047fSniklas if (symp->sy_resolved)
914b305b0f1Sespie {
915b305b0f1Sespie if (symp->sy_value.X_op == O_constant)
916b305b0f1Sespie return (valueT) symp->sy_value.X_add_number;
917b305b0f1Sespie else
918b305b0f1Sespie return 0;
919b305b0f1Sespie }
9202159047fSniklas
9212159047fSniklas resolved = 0;
922b305b0f1Sespie final_seg = S_GET_SEGMENT (symp);
9232159047fSniklas
9242159047fSniklas if (symp->sy_resolving)
9252159047fSniklas {
926c074d1c9Sdrahn if (finalize_syms)
927c074d1c9Sdrahn as_bad (_("symbol definition loop encountered at `%s'"),
928b55d4692Sfgsch S_GET_NAME (symp));
929b305b0f1Sespie final_val = 0;
9302159047fSniklas resolved = 1;
9312159047fSniklas }
9322159047fSniklas else
9332159047fSniklas {
934b305b0f1Sespie symbolS *add_symbol, *op_symbol;
935b305b0f1Sespie offsetT left, right;
9362159047fSniklas segT seg_left, seg_right;
937b305b0f1Sespie operatorT op;
9382159047fSniklas
9392159047fSniklas symp->sy_resolving = 1;
9402159047fSniklas
941b305b0f1Sespie /* Help out with CSE. */
942b305b0f1Sespie add_symbol = symp->sy_value.X_add_symbol;
943b305b0f1Sespie op_symbol = symp->sy_value.X_op_symbol;
944b305b0f1Sespie final_val = symp->sy_value.X_add_number;
945b305b0f1Sespie op = symp->sy_value.X_op;
9460c6d0228Sniklas
947b305b0f1Sespie switch (op)
9482159047fSniklas {
949b305b0f1Sespie default:
950b305b0f1Sespie BAD_CASE (op);
951b305b0f1Sespie break;
952b305b0f1Sespie
9532159047fSniklas case O_absent:
954b305b0f1Sespie final_val = 0;
9552159047fSniklas /* Fall through. */
956b305b0f1Sespie
9572159047fSniklas case O_constant:
958b305b0f1Sespie final_val += symp->sy_frag->fr_address / OCTETS_PER_BYTE;
959b305b0f1Sespie if (final_seg == expr_section)
960b305b0f1Sespie final_seg = absolute_section;
9612159047fSniklas resolved = 1;
9622159047fSniklas break;
9632159047fSniklas
9642159047fSniklas case O_symbol:
965b305b0f1Sespie case O_symbol_rva:
966c074d1c9Sdrahn left = resolve_symbol_value (add_symbol);
967c074d1c9Sdrahn seg_left = S_GET_SEGMENT (add_symbol);
968c074d1c9Sdrahn if (finalize_syms)
969c074d1c9Sdrahn symp->sy_value.X_op_symbol = NULL;
9702159047fSniklas
971c074d1c9Sdrahn do_symbol:
9722159047fSniklas if (symp->sy_mri_common)
9732159047fSniklas {
9742159047fSniklas /* This is a symbol inside an MRI common section. The
9752159047fSniklas relocation routines are going to handle it specially.
9762159047fSniklas Don't change the value. */
977b305b0f1Sespie resolved = symbol_resolved_p (add_symbol);
9782159047fSniklas break;
9792159047fSniklas }
9802159047fSniklas
981c074d1c9Sdrahn if (finalize_syms && final_val == 0)
982b305b0f1Sespie {
983b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (add_symbol))
984b305b0f1Sespie add_symbol = local_symbol_convert ((struct local_symbol *)
985b305b0f1Sespie add_symbol);
986b305b0f1Sespie copy_symbol_attributes (symp, add_symbol);
987b305b0f1Sespie }
988191aa565Sniklas
989c074d1c9Sdrahn /* If we have equated this symbol to an undefined or common
990c074d1c9Sdrahn symbol, keep X_op set to O_symbol, and don't change
991b305b0f1Sespie X_add_number. This permits the routine which writes out
992b305b0f1Sespie relocation to detect this case, and convert the
993b305b0f1Sespie relocation to be against the symbol to which this symbol
994b305b0f1Sespie is equated. */
995b305b0f1Sespie if (! S_IS_DEFINED (add_symbol) || S_IS_COMMON (add_symbol))
996b305b0f1Sespie {
997c074d1c9Sdrahn if (finalize_syms)
998b305b0f1Sespie {
999191aa565Sniklas symp->sy_value.X_op = O_symbol;
1000b305b0f1Sespie symp->sy_value.X_add_symbol = add_symbol;
1001b305b0f1Sespie symp->sy_value.X_add_number = final_val;
1002c074d1c9Sdrahn /* Use X_op_symbol as a flag. */
1003c074d1c9Sdrahn symp->sy_value.X_op_symbol = add_symbol;
1004c074d1c9Sdrahn final_seg = seg_left;
1005b305b0f1Sespie }
1006b305b0f1Sespie final_val = 0;
1007b305b0f1Sespie resolved = symbol_resolved_p (add_symbol);
1008c074d1c9Sdrahn symp->sy_resolving = 0;
1009c074d1c9Sdrahn goto exit_dont_set_value;
1010c074d1c9Sdrahn }
1011c074d1c9Sdrahn else if (finalize_syms && final_seg == expr_section
1012c074d1c9Sdrahn && seg_left != expr_section)
1013c074d1c9Sdrahn {
1014c074d1c9Sdrahn /* If the symbol is an expression symbol, do similarly
1015c074d1c9Sdrahn as for undefined and common syms above. Handles
1016c074d1c9Sdrahn "sym +/- expr" where "expr" cannot be evaluated
1017c074d1c9Sdrahn immediately, and we want relocations to be against
1018c074d1c9Sdrahn "sym", eg. because it is weak. */
1019c074d1c9Sdrahn symp->sy_value.X_op = O_symbol;
1020c074d1c9Sdrahn symp->sy_value.X_add_symbol = add_symbol;
1021c074d1c9Sdrahn symp->sy_value.X_add_number = final_val;
1022c074d1c9Sdrahn symp->sy_value.X_op_symbol = add_symbol;
1023c074d1c9Sdrahn final_seg = seg_left;
1024c074d1c9Sdrahn final_val += symp->sy_frag->fr_address + left;
1025c074d1c9Sdrahn resolved = symbol_resolved_p (add_symbol);
1026c074d1c9Sdrahn symp->sy_resolving = 0;
1027b305b0f1Sespie goto exit_dont_set_value;
1028b305b0f1Sespie }
1029b305b0f1Sespie else
1030b305b0f1Sespie {
1031b305b0f1Sespie final_val += symp->sy_frag->fr_address + left;
1032b305b0f1Sespie if (final_seg == expr_section || final_seg == undefined_section)
1033c074d1c9Sdrahn final_seg = seg_left;
1034b305b0f1Sespie }
1035191aa565Sniklas
1036b305b0f1Sespie resolved = symbol_resolved_p (add_symbol);
10372159047fSniklas break;
10382159047fSniklas
10392159047fSniklas case O_uminus:
10402159047fSniklas case O_bit_not:
1041191aa565Sniklas case O_logical_not:
1042c074d1c9Sdrahn left = resolve_symbol_value (add_symbol);
1043c074d1c9Sdrahn seg_left = S_GET_SEGMENT (add_symbol);
1044c074d1c9Sdrahn
1045c074d1c9Sdrahn /* By reducing these to the relevant dyadic operator, we get
1046c074d1c9Sdrahn !S -> S == 0 permitted on anything,
1047c074d1c9Sdrahn -S -> 0 - S only permitted on absolute
1048c074d1c9Sdrahn ~S -> S ^ ~0 only permitted on absolute */
1049c074d1c9Sdrahn if (op != O_logical_not && seg_left != absolute_section
1050c074d1c9Sdrahn && finalize_syms)
1051c074d1c9Sdrahn report_op_error (symp, add_symbol, NULL);
1052c074d1c9Sdrahn
1053c074d1c9Sdrahn if (final_seg == expr_section || final_seg == undefined_section)
1054c074d1c9Sdrahn final_seg = absolute_section;
1055b305b0f1Sespie
1056b305b0f1Sespie if (op == O_uminus)
1057b305b0f1Sespie left = -left;
1058b305b0f1Sespie else if (op == O_logical_not)
1059b305b0f1Sespie left = !left;
10602159047fSniklas else
1061b305b0f1Sespie left = ~left;
1062b305b0f1Sespie
1063b305b0f1Sespie final_val += left + symp->sy_frag->fr_address;
1064b305b0f1Sespie
1065b305b0f1Sespie resolved = symbol_resolved_p (add_symbol);
10662159047fSniklas break;
10672159047fSniklas
10682159047fSniklas case O_multiply:
10692159047fSniklas case O_divide:
10702159047fSniklas case O_modulus:
10712159047fSniklas case O_left_shift:
10722159047fSniklas case O_right_shift:
10732159047fSniklas case O_bit_inclusive_or:
10742159047fSniklas case O_bit_or_not:
10752159047fSniklas case O_bit_exclusive_or:
10762159047fSniklas case O_bit_and:
10770c6d0228Sniklas case O_add:
10782159047fSniklas case O_subtract:
10792159047fSniklas case O_eq:
10802159047fSniklas case O_ne:
10812159047fSniklas case O_lt:
10822159047fSniklas case O_le:
10832159047fSniklas case O_ge:
10842159047fSniklas case O_gt:
10852159047fSniklas case O_logical_and:
10862159047fSniklas case O_logical_or:
1087c074d1c9Sdrahn left = resolve_symbol_value (add_symbol);
1088c074d1c9Sdrahn right = resolve_symbol_value (op_symbol);
1089b305b0f1Sespie seg_left = S_GET_SEGMENT (add_symbol);
1090b305b0f1Sespie seg_right = S_GET_SEGMENT (op_symbol);
1091b305b0f1Sespie
1092b305b0f1Sespie /* Simplify addition or subtraction of a constant by folding the
1093b305b0f1Sespie constant into X_add_number. */
1094c074d1c9Sdrahn if (op == O_add)
1095b305b0f1Sespie {
1096b305b0f1Sespie if (seg_right == absolute_section)
1097b305b0f1Sespie {
1098b305b0f1Sespie final_val += right;
1099b305b0f1Sespie goto do_symbol;
1100b305b0f1Sespie }
1101c074d1c9Sdrahn else if (seg_left == absolute_section)
1102b305b0f1Sespie {
1103b305b0f1Sespie final_val += left;
1104b305b0f1Sespie add_symbol = op_symbol;
1105b305b0f1Sespie left = right;
1106c074d1c9Sdrahn seg_left = seg_right;
1107c074d1c9Sdrahn goto do_symbol;
1108c074d1c9Sdrahn }
1109c074d1c9Sdrahn }
1110c074d1c9Sdrahn else if (op == O_subtract)
1111c074d1c9Sdrahn {
1112c074d1c9Sdrahn if (seg_right == absolute_section)
1113c074d1c9Sdrahn {
1114c074d1c9Sdrahn final_val -= right;
1115b305b0f1Sespie goto do_symbol;
1116b305b0f1Sespie }
1117b305b0f1Sespie }
11180c6d0228Sniklas
1119c074d1c9Sdrahn /* Equality and non-equality tests are permitted on anything.
1120c074d1c9Sdrahn Subtraction, and other comparison operators are permitted if
1121c074d1c9Sdrahn both operands are in the same section. Otherwise, both
1122c074d1c9Sdrahn operands must be absolute. We already handled the case of
1123c074d1c9Sdrahn addition or subtraction of a constant above. This will
1124c074d1c9Sdrahn probably need to be changed for an object file format which
1125c074d1c9Sdrahn supports arbitrary expressions, such as IEEE-695.
11260c6d0228Sniklas
1127c074d1c9Sdrahn Don't emit messages unless we're finalizing the symbol value,
1128c074d1c9Sdrahn otherwise we may get the same message multiple times. */
1129c074d1c9Sdrahn if (finalize_syms
1130c074d1c9Sdrahn && !(seg_left == absolute_section
1131c074d1c9Sdrahn && seg_right == absolute_section)
1132c074d1c9Sdrahn && !(op == O_eq || op == O_ne)
1133c074d1c9Sdrahn && !((op == O_subtract
1134c074d1c9Sdrahn || op == O_lt || op == O_le || op == O_ge || op == O_gt)
1135c074d1c9Sdrahn && seg_left == seg_right
1136c074d1c9Sdrahn && (seg_left != undefined_section
1137c074d1c9Sdrahn || add_symbol == op_symbol)))
1138c074d1c9Sdrahn report_op_error (symp, add_symbol, op_symbol);
1139c074d1c9Sdrahn
1140c074d1c9Sdrahn if (final_seg == expr_section || final_seg == undefined_section)
1141c074d1c9Sdrahn final_seg = absolute_section;
11420c6d0228Sniklas
1143b305b0f1Sespie /* Check for division by zero. */
1144b305b0f1Sespie if ((op == O_divide || op == O_modulus) && right == 0)
1145b305b0f1Sespie {
1146b305b0f1Sespie /* If seg_right is not absolute_section, then we've
1147b305b0f1Sespie already issued a warning about using a bad symbol. */
1148c074d1c9Sdrahn if (seg_right == absolute_section && finalize_syms)
1149b305b0f1Sespie {
1150b305b0f1Sespie char *file;
1151b305b0f1Sespie unsigned int line;
1152b305b0f1Sespie
1153b305b0f1Sespie if (expr_symbol_where (symp, &file, &line))
1154b305b0f1Sespie as_bad_where (file, line, _("division by zero"));
1155b305b0f1Sespie else
1156c074d1c9Sdrahn as_bad (_("division by zero when setting `%s'"),
1157b305b0f1Sespie S_GET_NAME (symp));
1158b305b0f1Sespie }
1159b305b0f1Sespie
1160b305b0f1Sespie right = 1;
1161b305b0f1Sespie }
1162b305b0f1Sespie
11632159047fSniklas switch (symp->sy_value.X_op)
11642159047fSniklas {
1165b305b0f1Sespie case O_multiply: left *= right; break;
1166b305b0f1Sespie case O_divide: left /= right; break;
1167b305b0f1Sespie case O_modulus: left %= right; break;
1168b305b0f1Sespie case O_left_shift: left <<= right; break;
1169b305b0f1Sespie case O_right_shift: left >>= right; break;
1170b305b0f1Sespie case O_bit_inclusive_or: left |= right; break;
1171b305b0f1Sespie case O_bit_or_not: left |= ~right; break;
1172b305b0f1Sespie case O_bit_exclusive_or: left ^= right; break;
1173b305b0f1Sespie case O_bit_and: left &= right; break;
1174b305b0f1Sespie case O_add: left += right; break;
1175b305b0f1Sespie case O_subtract: left -= right; break;
1176c074d1c9Sdrahn case O_eq:
1177c074d1c9Sdrahn case O_ne:
1178c074d1c9Sdrahn left = (left == right && seg_left == seg_right
1179c074d1c9Sdrahn && (seg_left != undefined_section
1180c074d1c9Sdrahn || add_symbol == op_symbol)
1181c074d1c9Sdrahn ? ~ (offsetT) 0 : 0);
1182c074d1c9Sdrahn if (symp->sy_value.X_op == O_ne)
1183c074d1c9Sdrahn left = ~left;
1184c074d1c9Sdrahn break;
1185b305b0f1Sespie case O_lt: left = left < right ? ~ (offsetT) 0 : 0; break;
1186b305b0f1Sespie case O_le: left = left <= right ? ~ (offsetT) 0 : 0; break;
1187b305b0f1Sespie case O_ge: left = left >= right ? ~ (offsetT) 0 : 0; break;
1188b305b0f1Sespie case O_gt: left = left > right ? ~ (offsetT) 0 : 0; break;
1189b305b0f1Sespie case O_logical_and: left = left && right; break;
1190b305b0f1Sespie case O_logical_or: left = left || right; break;
11912159047fSniklas default: abort ();
11922159047fSniklas }
1193b305b0f1Sespie
1194b305b0f1Sespie final_val += symp->sy_frag->fr_address + left;
1195b305b0f1Sespie if (final_seg == expr_section || final_seg == undefined_section)
1196c074d1c9Sdrahn {
1197c074d1c9Sdrahn if (seg_left == undefined_section
1198c074d1c9Sdrahn || seg_right == undefined_section)
1199c074d1c9Sdrahn final_seg = undefined_section;
1200c074d1c9Sdrahn else if (seg_left == absolute_section)
1201c074d1c9Sdrahn final_seg = seg_right;
1202c074d1c9Sdrahn else
1203c074d1c9Sdrahn final_seg = seg_left;
1204c074d1c9Sdrahn }
1205b305b0f1Sespie resolved = (symbol_resolved_p (add_symbol)
1206b305b0f1Sespie && symbol_resolved_p (op_symbol));
12072159047fSniklas break;
12082159047fSniklas
12092159047fSniklas case O_register:
12102159047fSniklas case O_big:
12112159047fSniklas case O_illegal:
12122159047fSniklas /* Give an error (below) if not in expr_section. We don't
12132159047fSniklas want to worry about expr_section symbols, because they
12142159047fSniklas are fictional (they are created as part of expression
12152159047fSniklas resolution), and any problems may not actually mean
12162159047fSniklas anything. */
12172159047fSniklas break;
12182159047fSniklas }
1219b305b0f1Sespie
1220b305b0f1Sespie symp->sy_resolving = 0;
12212159047fSniklas }
12222159047fSniklas
1223c074d1c9Sdrahn if (finalize_syms)
1224b305b0f1Sespie S_SET_VALUE (symp, final_val);
1225b305b0f1Sespie
1226c074d1c9Sdrahn exit_dont_set_value:
1227c074d1c9Sdrahn /* Always set the segment, even if not finalizing the value.
1228c074d1c9Sdrahn The segment is used to determine whether a symbol is defined. */
1229b305b0f1Sespie #if defined (OBJ_AOUT) && ! defined (BFD_ASSEMBLER)
1230b305b0f1Sespie /* The old a.out backend does not handle S_SET_SEGMENT correctly
1231b305b0f1Sespie for a stab symbol, so we use this bad hack. */
1232b305b0f1Sespie if (final_seg != S_GET_SEGMENT (symp))
1233b305b0f1Sespie #endif
1234b305b0f1Sespie S_SET_SEGMENT (symp, final_seg);
1235b305b0f1Sespie
12362159047fSniklas /* Don't worry if we can't resolve an expr_section symbol. */
1237c074d1c9Sdrahn if (finalize_syms)
1238b305b0f1Sespie {
12392159047fSniklas if (resolved)
12402159047fSniklas symp->sy_resolved = 1;
12412159047fSniklas else if (S_GET_SEGMENT (symp) != expr_section)
12422159047fSniklas {
1243c074d1c9Sdrahn as_bad (_("can't resolve value for symbol `%s'"),
1244b55d4692Sfgsch S_GET_NAME (symp));
12452159047fSniklas symp->sy_resolved = 1;
12462159047fSniklas }
12472159047fSniklas }
12482159047fSniklas
1249b305b0f1Sespie return final_val;
1250b305b0f1Sespie }
1251b305b0f1Sespie
1252b305b0f1Sespie #ifdef BFD_ASSEMBLER
1253b305b0f1Sespie
1254*007c2a45Smiod static void resolve_local_symbol (const char *, PTR);
1255b305b0f1Sespie
1256b305b0f1Sespie /* A static function passed to hash_traverse. */
1257b305b0f1Sespie
1258b305b0f1Sespie static void
resolve_local_symbol(const char * key ATTRIBUTE_UNUSED,PTR value)1259*007c2a45Smiod resolve_local_symbol (const char *key ATTRIBUTE_UNUSED, PTR value)
1260b305b0f1Sespie {
1261b305b0f1Sespie if (value != NULL)
1262c074d1c9Sdrahn resolve_symbol_value (value);
1263b305b0f1Sespie }
1264b305b0f1Sespie
1265b305b0f1Sespie #endif
1266b305b0f1Sespie
1267b305b0f1Sespie /* Resolve all local symbols. */
1268b305b0f1Sespie
1269b305b0f1Sespie void
resolve_local_symbol_values(void)1270*007c2a45Smiod resolve_local_symbol_values (void)
1271b305b0f1Sespie {
1272b305b0f1Sespie #ifdef BFD_ASSEMBLER
1273b305b0f1Sespie hash_traverse (local_hash, resolve_local_symbol);
1274b305b0f1Sespie #endif
1275b305b0f1Sespie }
1276b305b0f1Sespie
12772159047fSniklas /* Dollar labels look like a number followed by a dollar sign. Eg, "42$".
12782159047fSniklas They are *really* local. That is, they go out of scope whenever we see a
12792159047fSniklas label that isn't local. Also, like fb labels, there can be multiple
12802159047fSniklas instances of a dollar label. Therefor, we name encode each instance with
12812159047fSniklas the instance number, keep a list of defined symbols separate from the real
12822159047fSniklas symbol table, and we treat these buggers as a sparse array. */
12832159047fSniklas
12842159047fSniklas static long *dollar_labels;
12852159047fSniklas static long *dollar_label_instances;
12862159047fSniklas static char *dollar_label_defines;
1287b305b0f1Sespie static unsigned long dollar_label_count;
12882159047fSniklas static unsigned long dollar_label_max;
12892159047fSniklas
12902159047fSniklas int
dollar_label_defined(long label)1291*007c2a45Smiod dollar_label_defined (long label)
12922159047fSniklas {
12932159047fSniklas long *i;
12942159047fSniklas
12952159047fSniklas know ((dollar_labels != NULL) || (dollar_label_count == 0));
12962159047fSniklas
12972159047fSniklas for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
12982159047fSniklas if (*i == label)
12992159047fSniklas return dollar_label_defines[i - dollar_labels];
13002159047fSniklas
1301b55d4692Sfgsch /* If we get here, label isn't defined. */
13022159047fSniklas return 0;
1303b55d4692Sfgsch }
13042159047fSniklas
1305b305b0f1Sespie static long
dollar_label_instance(long label)1306*007c2a45Smiod dollar_label_instance (long label)
13072159047fSniklas {
13082159047fSniklas long *i;
13092159047fSniklas
13102159047fSniklas know ((dollar_labels != NULL) || (dollar_label_count == 0));
13112159047fSniklas
13122159047fSniklas for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
13132159047fSniklas if (*i == label)
13142159047fSniklas return (dollar_label_instances[i - dollar_labels]);
13152159047fSniklas
1316b55d4692Sfgsch /* If we get here, we haven't seen the label before.
1317b55d4692Sfgsch Therefore its instance count is zero. */
13182159047fSniklas return 0;
13192159047fSniklas }
13202159047fSniklas
13212159047fSniklas void
dollar_label_clear(void)1322*007c2a45Smiod dollar_label_clear (void)
13232159047fSniklas {
13242159047fSniklas memset (dollar_label_defines, '\0', (unsigned int) dollar_label_count);
13252159047fSniklas }
13262159047fSniklas
13272159047fSniklas #define DOLLAR_LABEL_BUMP_BY 10
13282159047fSniklas
13292159047fSniklas void
define_dollar_label(long label)1330*007c2a45Smiod define_dollar_label (long label)
13312159047fSniklas {
13322159047fSniklas long *i;
13332159047fSniklas
13342159047fSniklas for (i = dollar_labels; i < dollar_labels + dollar_label_count; ++i)
13352159047fSniklas if (*i == label)
13362159047fSniklas {
13372159047fSniklas ++dollar_label_instances[i - dollar_labels];
13382159047fSniklas dollar_label_defines[i - dollar_labels] = 1;
13392159047fSniklas return;
13402159047fSniklas }
13412159047fSniklas
1342b55d4692Sfgsch /* If we get to here, we don't have label listed yet. */
13432159047fSniklas
13442159047fSniklas if (dollar_labels == NULL)
13452159047fSniklas {
13462159047fSniklas dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
13472159047fSniklas dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
13482159047fSniklas dollar_label_defines = xmalloc (DOLLAR_LABEL_BUMP_BY);
13492159047fSniklas dollar_label_max = DOLLAR_LABEL_BUMP_BY;
13502159047fSniklas dollar_label_count = 0;
13512159047fSniklas }
13522159047fSniklas else if (dollar_label_count == dollar_label_max)
13532159047fSniklas {
13542159047fSniklas dollar_label_max += DOLLAR_LABEL_BUMP_BY;
13552159047fSniklas dollar_labels = (long *) xrealloc ((char *) dollar_labels,
13562159047fSniklas dollar_label_max * sizeof (long));
13572159047fSniklas dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
13582159047fSniklas dollar_label_max * sizeof (long));
13592159047fSniklas dollar_label_defines = xrealloc (dollar_label_defines, dollar_label_max);
13602159047fSniklas } /* if we needed to grow */
13612159047fSniklas
13622159047fSniklas dollar_labels[dollar_label_count] = label;
13632159047fSniklas dollar_label_instances[dollar_label_count] = 1;
13642159047fSniklas dollar_label_defines[dollar_label_count] = 1;
13652159047fSniklas ++dollar_label_count;
13662159047fSniklas }
13672159047fSniklas
1368b55d4692Sfgsch /* Caller must copy returned name: we re-use the area for the next name.
1369b55d4692Sfgsch
1370b55d4692Sfgsch The mth occurence of label n: is turned into the symbol "Ln^Am"
1371b55d4692Sfgsch where n is the label number and m is the instance number. "L" makes
1372b55d4692Sfgsch it a label discarded unless debugging and "^A"('\1') ensures no
1373b55d4692Sfgsch ordinary symbol SHOULD get the same name as a local label
1374b55d4692Sfgsch symbol. The first "4:" is "L4^A1" - the m numbers begin at 1.
1375b55d4692Sfgsch
1376b55d4692Sfgsch fb labels get the same treatment, except that ^B is used in place
1377b55d4692Sfgsch of ^A. */
13782159047fSniklas
13792159047fSniklas char * /* Return local label name. */
dollar_label_name(register long n,register int augend)1380*007c2a45Smiod dollar_label_name (register long n, /* we just saw "n$:" : n a number. */
1381*007c2a45Smiod register int augend /* 0 for current instance, 1 for new instance. */)
13822159047fSniklas {
13832159047fSniklas long i;
1384b55d4692Sfgsch /* Returned to caller, then copied. Used for created names ("4f"). */
13852159047fSniklas static char symbol_name_build[24];
13862159047fSniklas register char *p;
13872159047fSniklas register char *q;
1388b55d4692Sfgsch char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */
13892159047fSniklas
13902159047fSniklas know (n >= 0);
13912159047fSniklas know (augend == 0 || augend == 1);
13922159047fSniklas p = symbol_name_build;
1393b305b0f1Sespie #ifdef LOCAL_LABEL_PREFIX
1394b305b0f1Sespie *p++ = LOCAL_LABEL_PREFIX;
1395b305b0f1Sespie #endif
13962159047fSniklas *p++ = 'L';
13972159047fSniklas
13982159047fSniklas /* Next code just does sprintf( {}, "%d", n); */
1399b55d4692Sfgsch /* Label number. */
14002159047fSniklas q = symbol_name_temporary;
14012159047fSniklas for (*q++ = 0, i = n; i; ++q)
14022159047fSniklas {
14032159047fSniklas *q = i % 10 + '0';
14042159047fSniklas i /= 10;
14052159047fSniklas }
14062159047fSniklas while ((*p = *--q) != '\0')
14072159047fSniklas ++p;
14082159047fSniklas
1409b55d4692Sfgsch *p++ = DOLLAR_LABEL_CHAR; /* ^A */
14102159047fSniklas
1411b55d4692Sfgsch /* Instance number. */
14122159047fSniklas q = symbol_name_temporary;
14132159047fSniklas for (*q++ = 0, i = dollar_label_instance (n) + augend; i; ++q)
14142159047fSniklas {
14152159047fSniklas *q = i % 10 + '0';
14162159047fSniklas i /= 10;
14172159047fSniklas }
14182159047fSniklas while ((*p++ = *--q) != '\0');;
14192159047fSniklas
14202159047fSniklas /* The label, as a '\0' ended string, starts at symbol_name_build. */
14212159047fSniklas return symbol_name_build;
14222159047fSniklas }
14232159047fSniklas
1424*007c2a45Smiod /* Somebody else's idea of local labels. They are made by "n:" where n
1425b55d4692Sfgsch is any decimal digit. Refer to them with
1426b55d4692Sfgsch "nb" for previous (backward) n:
1427b55d4692Sfgsch or "nf" for next (forward) n:.
1428b55d4692Sfgsch
1429b55d4692Sfgsch We do a little better and let n be any number, not just a single digit, but
1430b55d4692Sfgsch since the other guy's assembler only does ten, we treat the first ten
1431b55d4692Sfgsch specially.
1432b55d4692Sfgsch
1433b55d4692Sfgsch Like someone else's assembler, we have one set of local label counters for
1434b55d4692Sfgsch entire assembly, not one set per (sub)segment like in most assemblers. This
1435b55d4692Sfgsch implies that one can refer to a label in another segment, and indeed some
1436b55d4692Sfgsch crufty compilers have done just that.
1437b55d4692Sfgsch
1438b55d4692Sfgsch Since there could be a LOT of these things, treat them as a sparse
1439b55d4692Sfgsch array. */
14402159047fSniklas
14412159047fSniklas #define FB_LABEL_SPECIAL (10)
14422159047fSniklas
14432159047fSniklas static long fb_low_counter[FB_LABEL_SPECIAL];
14442159047fSniklas static long *fb_labels;
14452159047fSniklas static long *fb_label_instances;
14462159047fSniklas static long fb_label_count;
14472159047fSniklas static long fb_label_max;
14482159047fSniklas
1449b55d4692Sfgsch /* This must be more than FB_LABEL_SPECIAL. */
14502159047fSniklas #define FB_LABEL_BUMP_BY (FB_LABEL_SPECIAL + 6)
14512159047fSniklas
14522159047fSniklas static void
fb_label_init(void)1453*007c2a45Smiod fb_label_init (void)
14542159047fSniklas {
14552159047fSniklas memset ((void *) fb_low_counter, '\0', sizeof (fb_low_counter));
1456b55d4692Sfgsch }
14572159047fSniklas
1458b55d4692Sfgsch /* Add one to the instance number of this fb label. */
1459b55d4692Sfgsch
14602159047fSniklas void
fb_label_instance_inc(long label)1461*007c2a45Smiod fb_label_instance_inc (long label)
14622159047fSniklas {
14632159047fSniklas long *i;
14642159047fSniklas
14652159047fSniklas if (label < FB_LABEL_SPECIAL)
14662159047fSniklas {
14672159047fSniklas ++fb_low_counter[label];
14682159047fSniklas return;
14692159047fSniklas }
14702159047fSniklas
14712159047fSniklas if (fb_labels != NULL)
14722159047fSniklas {
14732159047fSniklas for (i = fb_labels + FB_LABEL_SPECIAL;
14742159047fSniklas i < fb_labels + fb_label_count; ++i)
14752159047fSniklas {
14762159047fSniklas if (*i == label)
14772159047fSniklas {
14782159047fSniklas ++fb_label_instances[i - fb_labels];
14792159047fSniklas return;
14802159047fSniklas } /* if we find it */
14812159047fSniklas } /* for each existing label */
14822159047fSniklas }
14832159047fSniklas
1484b55d4692Sfgsch /* If we get to here, we don't have label listed yet. */
14852159047fSniklas
14862159047fSniklas if (fb_labels == NULL)
14872159047fSniklas {
14882159047fSniklas fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
14892159047fSniklas fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
14902159047fSniklas fb_label_max = FB_LABEL_BUMP_BY;
14912159047fSniklas fb_label_count = FB_LABEL_SPECIAL;
14922159047fSniklas
14932159047fSniklas }
14942159047fSniklas else if (fb_label_count == fb_label_max)
14952159047fSniklas {
14962159047fSniklas fb_label_max += FB_LABEL_BUMP_BY;
14972159047fSniklas fb_labels = (long *) xrealloc ((char *) fb_labels,
14982159047fSniklas fb_label_max * sizeof (long));
14992159047fSniklas fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
15002159047fSniklas fb_label_max * sizeof (long));
15012159047fSniklas } /* if we needed to grow */
15022159047fSniklas
15032159047fSniklas fb_labels[fb_label_count] = label;
15042159047fSniklas fb_label_instances[fb_label_count] = 1;
15052159047fSniklas ++fb_label_count;
15062159047fSniklas }
15072159047fSniklas
15082159047fSniklas static long
fb_label_instance(long label)1509*007c2a45Smiod fb_label_instance (long label)
15102159047fSniklas {
15112159047fSniklas long *i;
15122159047fSniklas
15132159047fSniklas if (label < FB_LABEL_SPECIAL)
15142159047fSniklas {
15152159047fSniklas return (fb_low_counter[label]);
15162159047fSniklas }
15172159047fSniklas
15182159047fSniklas if (fb_labels != NULL)
15192159047fSniklas {
15202159047fSniklas for (i = fb_labels + FB_LABEL_SPECIAL;
15212159047fSniklas i < fb_labels + fb_label_count; ++i)
15222159047fSniklas {
15232159047fSniklas if (*i == label)
15242159047fSniklas {
15252159047fSniklas return (fb_label_instances[i - fb_labels]);
15262159047fSniklas } /* if we find it */
15272159047fSniklas } /* for each existing label */
15282159047fSniklas }
15292159047fSniklas
15302159047fSniklas /* We didn't find the label, so this must be a reference to the
15312159047fSniklas first instance. */
15322159047fSniklas return 0;
15332159047fSniklas }
15342159047fSniklas
1535b55d4692Sfgsch /* Caller must copy returned name: we re-use the area for the next name.
1536b55d4692Sfgsch
1537b55d4692Sfgsch The mth occurence of label n: is turned into the symbol "Ln^Bm"
1538b55d4692Sfgsch where n is the label number and m is the instance number. "L" makes
1539b55d4692Sfgsch it a label discarded unless debugging and "^B"('\2') ensures no
1540b55d4692Sfgsch ordinary symbol SHOULD get the same name as a local label
1541b55d4692Sfgsch symbol. The first "4:" is "L4^B1" - the m numbers begin at 1.
1542b55d4692Sfgsch
1543b55d4692Sfgsch dollar labels get the same treatment, except that ^A is used in
1544b55d4692Sfgsch place of ^B. */
15452159047fSniklas
15462159047fSniklas char * /* Return local label name. */
fb_label_name(long n,long augend)1547*007c2a45Smiod fb_label_name (long n, /* We just saw "n:", "nf" or "nb" : n a number. */
1548*007c2a45Smiod long augend /* 0 for nb, 1 for n:, nf. */)
15492159047fSniklas {
15502159047fSniklas long i;
1551b55d4692Sfgsch /* Returned to caller, then copied. Used for created names ("4f"). */
15522159047fSniklas static char symbol_name_build[24];
15532159047fSniklas register char *p;
15542159047fSniklas register char *q;
1555b55d4692Sfgsch char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */
15562159047fSniklas
15572159047fSniklas know (n >= 0);
15582159047fSniklas know (augend == 0 || augend == 1);
15592159047fSniklas p = symbol_name_build;
1560b55d4692Sfgsch #ifdef LOCAL_LABEL_PREFIX
1561b55d4692Sfgsch *p++ = LOCAL_LABEL_PREFIX;
1562b55d4692Sfgsch #endif
15632159047fSniklas *p++ = 'L';
15642159047fSniklas
15652159047fSniklas /* Next code just does sprintf( {}, "%d", n); */
1566b55d4692Sfgsch /* Label number. */
15672159047fSniklas q = symbol_name_temporary;
15682159047fSniklas for (*q++ = 0, i = n; i; ++q)
15692159047fSniklas {
15702159047fSniklas *q = i % 10 + '0';
15712159047fSniklas i /= 10;
15722159047fSniklas }
15732159047fSniklas while ((*p = *--q) != '\0')
15742159047fSniklas ++p;
15752159047fSniklas
1576b55d4692Sfgsch *p++ = LOCAL_LABEL_CHAR; /* ^B */
15772159047fSniklas
1578b55d4692Sfgsch /* Instance number. */
15792159047fSniklas q = symbol_name_temporary;
15802159047fSniklas for (*q++ = 0, i = fb_label_instance (n) + augend; i; ++q)
15812159047fSniklas {
15822159047fSniklas *q = i % 10 + '0';
15832159047fSniklas i /= 10;
15842159047fSniklas }
15852159047fSniklas while ((*p++ = *--q) != '\0');;
15862159047fSniklas
15872159047fSniklas /* The label, as a '\0' ended string, starts at symbol_name_build. */
15882159047fSniklas return (symbol_name_build);
1589b55d4692Sfgsch }
15902159047fSniklas
1591b55d4692Sfgsch /* Decode name that may have been generated by foo_label_name() above.
1592b55d4692Sfgsch If the name wasn't generated by foo_label_name(), then return it
1593b55d4692Sfgsch unaltered. This is used for error messages. */
15942159047fSniklas
15952159047fSniklas char *
decode_local_label_name(char * s)1596*007c2a45Smiod decode_local_label_name (char *s)
15972159047fSniklas {
15982159047fSniklas char *p;
15992159047fSniklas char *symbol_decode;
16002159047fSniklas int label_number;
16012159047fSniklas int instance_number;
16022159047fSniklas char *type;
1603b55d4692Sfgsch const char *message_format;
1604b55d4692Sfgsch int index = 0;
16052159047fSniklas
1606b55d4692Sfgsch #ifdef LOCAL_LABEL_PREFIX
1607b55d4692Sfgsch if (s[index] == LOCAL_LABEL_PREFIX)
1608b55d4692Sfgsch ++index;
1609b55d4692Sfgsch #endif
1610b55d4692Sfgsch
1611b55d4692Sfgsch if (s[index] != 'L')
16122159047fSniklas return s;
16132159047fSniklas
1614c074d1c9Sdrahn for (label_number = 0, p = s + index + 1; ISDIGIT (*p); ++p)
16152159047fSniklas label_number = (10 * label_number) + *p - '0';
16162159047fSniklas
1617b55d4692Sfgsch if (*p == DOLLAR_LABEL_CHAR)
16182159047fSniklas type = "dollar";
1619b55d4692Sfgsch else if (*p == LOCAL_LABEL_CHAR)
16202159047fSniklas type = "fb";
16212159047fSniklas else
16222159047fSniklas return s;
16232159047fSniklas
1624c074d1c9Sdrahn for (instance_number = 0, p++; ISDIGIT (*p); ++p)
16252159047fSniklas instance_number = (10 * instance_number) + *p - '0';
16262159047fSniklas
1627b55d4692Sfgsch message_format = _("\"%d\" (instance number %d of a %s label)");
16282159047fSniklas symbol_decode = obstack_alloc (¬es, strlen (message_format) + 30);
16292159047fSniklas sprintf (symbol_decode, message_format, label_number, instance_number, type);
16302159047fSniklas
16312159047fSniklas return symbol_decode;
16322159047fSniklas }
16332159047fSniklas
16342159047fSniklas /* Get the value of a symbol. */
16352159047fSniklas
16362159047fSniklas valueT
S_GET_VALUE(symbolS * s)1637*007c2a45Smiod S_GET_VALUE (symbolS *s)
16382159047fSniklas {
1639b305b0f1Sespie #ifdef BFD_ASSEMBLER
1640b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1641c074d1c9Sdrahn return resolve_symbol_value (s);
1642b305b0f1Sespie #endif
1643b305b0f1Sespie
1644c074d1c9Sdrahn if (!s->sy_resolved)
1645c074d1c9Sdrahn {
1646c074d1c9Sdrahn valueT val = resolve_symbol_value (s);
1647c074d1c9Sdrahn if (!finalize_syms)
1648c074d1c9Sdrahn return val;
1649c074d1c9Sdrahn }
16502159047fSniklas if (s->sy_value.X_op != O_constant)
1651191aa565Sniklas {
1652191aa565Sniklas static symbolS *recur;
1653191aa565Sniklas
1654191aa565Sniklas /* FIXME: In non BFD assemblers, S_IS_DEFINED and S_IS_COMMON
1655191aa565Sniklas may call S_GET_VALUE. We use a static symbol to avoid the
1656191aa565Sniklas immediate recursion. */
1657191aa565Sniklas if (recur == s)
1658191aa565Sniklas return (valueT) s->sy_value.X_add_number;
1659191aa565Sniklas recur = s;
1660191aa565Sniklas if (! s->sy_resolved
1661191aa565Sniklas || s->sy_value.X_op != O_symbol
1662191aa565Sniklas || (S_IS_DEFINED (s) && ! S_IS_COMMON (s)))
1663c074d1c9Sdrahn as_bad (_("attempt to get value of unresolved symbol `%s'"),
1664191aa565Sniklas S_GET_NAME (s));
1665191aa565Sniklas recur = NULL;
1666191aa565Sniklas }
16672159047fSniklas return (valueT) s->sy_value.X_add_number;
16682159047fSniklas }
16692159047fSniklas
16702159047fSniklas /* Set the value of a symbol. */
16712159047fSniklas
16722159047fSniklas void
S_SET_VALUE(symbolS * s,valueT val)1673*007c2a45Smiod S_SET_VALUE (symbolS *s, valueT val)
16742159047fSniklas {
1675b305b0f1Sespie #ifdef BFD_ASSEMBLER
1676b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1677b305b0f1Sespie {
1678c074d1c9Sdrahn ((struct local_symbol *) s)->lsy_value = val;
1679b305b0f1Sespie return;
1680b305b0f1Sespie }
1681b305b0f1Sespie #endif
1682b305b0f1Sespie
16832159047fSniklas s->sy_value.X_op = O_constant;
16842159047fSniklas s->sy_value.X_add_number = (offsetT) val;
16852159047fSniklas s->sy_value.X_unsigned = 0;
16862159047fSniklas }
16872159047fSniklas
16882159047fSniklas void
copy_symbol_attributes(symbolS * dest,symbolS * src)1689*007c2a45Smiod copy_symbol_attributes (symbolS *dest, symbolS *src)
16902159047fSniklas {
1691b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (dest))
1692b305b0f1Sespie dest = local_symbol_convert ((struct local_symbol *) dest);
1693b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (src))
1694b305b0f1Sespie src = local_symbol_convert ((struct local_symbol *) src);
1695b305b0f1Sespie
16962159047fSniklas #ifdef BFD_ASSEMBLER
16972159047fSniklas /* In an expression, transfer the settings of these flags.
16982159047fSniklas The user can override later, of course. */
1699b305b0f1Sespie #define COPIED_SYMFLAGS (BSF_FUNCTION | BSF_OBJECT)
17002159047fSniklas dest->bsym->flags |= src->bsym->flags & COPIED_SYMFLAGS;
17012159047fSniklas #endif
17022159047fSniklas
17032159047fSniklas #ifdef OBJ_COPY_SYMBOL_ATTRIBUTES
17042159047fSniklas OBJ_COPY_SYMBOL_ATTRIBUTES (dest, src);
17052159047fSniklas #endif
17062159047fSniklas }
17072159047fSniklas
17082159047fSniklas #ifdef BFD_ASSEMBLER
17092159047fSniklas
17102159047fSniklas int
S_IS_FUNCTION(symbolS * s)1711*007c2a45Smiod S_IS_FUNCTION (symbolS *s)
1712b305b0f1Sespie {
1713b305b0f1Sespie flagword flags;
1714b305b0f1Sespie
1715b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1716b305b0f1Sespie return 0;
1717b305b0f1Sespie
1718b305b0f1Sespie flags = s->bsym->flags;
1719b305b0f1Sespie
1720b305b0f1Sespie return (flags & BSF_FUNCTION) != 0;
1721b305b0f1Sespie }
1722b305b0f1Sespie
1723b305b0f1Sespie int
S_IS_EXTERNAL(symbolS * s)1724*007c2a45Smiod S_IS_EXTERNAL (symbolS *s)
17252159047fSniklas {
1726b305b0f1Sespie flagword flags;
1727b305b0f1Sespie
1728b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1729b305b0f1Sespie return 0;
1730b305b0f1Sespie
1731b305b0f1Sespie flags = s->bsym->flags;
17322159047fSniklas
1733b55d4692Sfgsch /* Sanity check. */
1734b305b0f1Sespie if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
17352159047fSniklas abort ();
17362159047fSniklas
17372159047fSniklas return (flags & BSF_GLOBAL) != 0;
17382159047fSniklas }
17392159047fSniklas
17402159047fSniklas int
S_IS_WEAK(symbolS * s)1741*007c2a45Smiod S_IS_WEAK (symbolS *s)
17422159047fSniklas {
1743b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1744b305b0f1Sespie return 0;
17452159047fSniklas return (s->bsym->flags & BSF_WEAK) != 0;
17462159047fSniklas }
17472159047fSniklas
17482159047fSniklas int
S_IS_COMMON(symbolS * s)1749*007c2a45Smiod S_IS_COMMON (symbolS *s)
17502159047fSniklas {
1751b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1752b305b0f1Sespie return 0;
17532159047fSniklas return bfd_is_com_section (s->bsym->section);
17542159047fSniklas }
17552159047fSniklas
17562159047fSniklas int
S_IS_DEFINED(symbolS * s)1757*007c2a45Smiod S_IS_DEFINED (symbolS *s)
17582159047fSniklas {
1759b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1760b305b0f1Sespie return ((struct local_symbol *) s)->lsy_section != undefined_section;
17612159047fSniklas return s->bsym->section != undefined_section;
17622159047fSniklas }
17632159047fSniklas
1764c074d1c9Sdrahn
1765c074d1c9Sdrahn #ifndef EXTERN_FORCE_RELOC
1766c074d1c9Sdrahn #define EXTERN_FORCE_RELOC IS_ELF
1767c074d1c9Sdrahn #endif
1768c074d1c9Sdrahn
1769c074d1c9Sdrahn /* Return true for symbols that should not be reduced to section
1770c074d1c9Sdrahn symbols or eliminated from expressions, because they may be
1771c074d1c9Sdrahn overridden by the linker. */
1772c074d1c9Sdrahn int
S_FORCE_RELOC(symbolS * s,int strict)1773*007c2a45Smiod S_FORCE_RELOC (symbolS *s, int strict)
1774c074d1c9Sdrahn {
1775c074d1c9Sdrahn if (LOCAL_SYMBOL_CHECK (s))
1776c074d1c9Sdrahn return ((struct local_symbol *) s)->lsy_section == undefined_section;
1777c074d1c9Sdrahn
1778c074d1c9Sdrahn return ((strict
1779c074d1c9Sdrahn && ((s->bsym->flags & BSF_WEAK) != 0
1780c074d1c9Sdrahn || (EXTERN_FORCE_RELOC
1781c074d1c9Sdrahn && (s->bsym->flags & BSF_GLOBAL) != 0)))
1782c074d1c9Sdrahn || s->bsym->section == undefined_section
1783c074d1c9Sdrahn || bfd_is_com_section (s->bsym->section));
1784c074d1c9Sdrahn }
1785c074d1c9Sdrahn
17862159047fSniklas int
S_IS_DEBUG(symbolS * s)1787*007c2a45Smiod S_IS_DEBUG (symbolS *s)
17882159047fSniklas {
1789b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1790b305b0f1Sespie return 0;
17912159047fSniklas if (s->bsym->flags & BSF_DEBUGGING)
17922159047fSniklas return 1;
17932159047fSniklas return 0;
17942159047fSniklas }
17952159047fSniklas
17962159047fSniklas int
S_IS_LOCAL(symbolS * s)1797*007c2a45Smiod S_IS_LOCAL (symbolS *s)
17982159047fSniklas {
1799b305b0f1Sespie flagword flags;
18002159047fSniklas const char *name;
18012159047fSniklas
1802b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1803b305b0f1Sespie return 1;
1804b305b0f1Sespie
1805b305b0f1Sespie flags = s->bsym->flags;
1806b305b0f1Sespie
1807b55d4692Sfgsch /* Sanity check. */
1808b305b0f1Sespie if ((flags & BSF_LOCAL) && (flags & BSF_GLOBAL))
18092159047fSniklas abort ();
18102159047fSniklas
18112159047fSniklas if (bfd_get_section (s->bsym) == reg_section)
18122159047fSniklas return 1;
18132159047fSniklas
1814b305b0f1Sespie if (flag_strip_local_absolute
1815b305b0f1Sespie && (flags & BSF_GLOBAL) == 0
1816b305b0f1Sespie && bfd_get_section (s->bsym) == absolute_section)
1817b305b0f1Sespie return 1;
1818b305b0f1Sespie
18192159047fSniklas name = S_GET_NAME (s);
18202159047fSniklas return (name != NULL
18212159047fSniklas && ! S_IS_DEBUG (s)
1822b55d4692Sfgsch && (strchr (name, DOLLAR_LABEL_CHAR)
1823b55d4692Sfgsch || strchr (name, LOCAL_LABEL_CHAR)
18242159047fSniklas || (! flag_keep_locals
1825b305b0f1Sespie && (bfd_is_local_label (stdoutput, s->bsym)
18262159047fSniklas || (flag_mri
18272159047fSniklas && name[0] == '?'
18282159047fSniklas && name[1] == '?')))));
18292159047fSniklas }
18302159047fSniklas
18312159047fSniklas int
S_IS_EXTERN(symbolS * s)1832*007c2a45Smiod S_IS_EXTERN (symbolS *s)
18332159047fSniklas {
18342159047fSniklas return S_IS_EXTERNAL (s);
18352159047fSniklas }
18362159047fSniklas
18372159047fSniklas int
S_IS_STABD(symbolS * s)1838*007c2a45Smiod S_IS_STABD (symbolS *s)
18392159047fSniklas {
18402159047fSniklas return S_GET_NAME (s) == 0;
18412159047fSniklas }
18422159047fSniklas
1843c074d1c9Sdrahn const char *
S_GET_NAME(symbolS * s)1844*007c2a45Smiod S_GET_NAME (symbolS *s)
18452159047fSniklas {
1846b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1847b305b0f1Sespie return ((struct local_symbol *) s)->lsy_name;
18482159047fSniklas return s->bsym->name;
18492159047fSniklas }
18502159047fSniklas
18512159047fSniklas segT
S_GET_SEGMENT(symbolS * s)1852*007c2a45Smiod S_GET_SEGMENT (symbolS *s)
18532159047fSniklas {
1854b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1855b305b0f1Sespie return ((struct local_symbol *) s)->lsy_section;
18562159047fSniklas return s->bsym->section;
18572159047fSniklas }
18582159047fSniklas
18592159047fSniklas void
S_SET_SEGMENT(symbolS * s,segT seg)1860*007c2a45Smiod S_SET_SEGMENT (symbolS *s, segT seg)
18612159047fSniklas {
1862b305b0f1Sespie /* Don't reassign section symbols. The direct reason is to prevent seg
1863b305b0f1Sespie faults assigning back to const global symbols such as *ABS*, but it
1864b305b0f1Sespie shouldn't happen anyway. */
1865b305b0f1Sespie
1866b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1867b305b0f1Sespie {
1868b305b0f1Sespie if (seg == reg_section)
1869b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
1870b305b0f1Sespie else
1871b305b0f1Sespie {
1872b305b0f1Sespie ((struct local_symbol *) s)->lsy_section = seg;
1873b305b0f1Sespie return;
1874b305b0f1Sespie }
1875b305b0f1Sespie }
1876b305b0f1Sespie
1877b305b0f1Sespie if (s->bsym->flags & BSF_SECTION_SYM)
1878b305b0f1Sespie {
1879b305b0f1Sespie if (s->bsym->section != seg)
1880b305b0f1Sespie abort ();
1881b305b0f1Sespie }
1882b305b0f1Sespie else
18832159047fSniklas s->bsym->section = seg;
18842159047fSniklas }
18852159047fSniklas
18862159047fSniklas void
S_SET_EXTERNAL(symbolS * s)1887*007c2a45Smiod S_SET_EXTERNAL (symbolS *s)
18882159047fSniklas {
1889b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1890b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
18912159047fSniklas if ((s->bsym->flags & BSF_WEAK) != 0)
18920c6d0228Sniklas {
18930c6d0228Sniklas /* Let .weak override .global. */
18940c6d0228Sniklas return;
18950c6d0228Sniklas }
1896b55d4692Sfgsch if (s->bsym->flags & BSF_SECTION_SYM)
1897b55d4692Sfgsch {
1898b55d4692Sfgsch char * file;
1899b55d4692Sfgsch unsigned int line;
1900b55d4692Sfgsch
1901b55d4692Sfgsch /* Do not reassign section symbols. */
1902b55d4692Sfgsch as_where (& file, & line);
1903b55d4692Sfgsch as_warn_where (file, line,
1904c074d1c9Sdrahn _("section symbols are already global"));
1905b55d4692Sfgsch return;
1906b55d4692Sfgsch }
19072159047fSniklas s->bsym->flags |= BSF_GLOBAL;
19082159047fSniklas s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK);
19092159047fSniklas }
19102159047fSniklas
19112159047fSniklas void
S_CLEAR_EXTERNAL(symbolS * s)1912*007c2a45Smiod S_CLEAR_EXTERNAL (symbolS *s)
19132159047fSniklas {
1914b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1915b305b0f1Sespie return;
19162159047fSniklas if ((s->bsym->flags & BSF_WEAK) != 0)
19170c6d0228Sniklas {
19180c6d0228Sniklas /* Let .weak override. */
19190c6d0228Sniklas return;
19200c6d0228Sniklas }
19212159047fSniklas s->bsym->flags |= BSF_LOCAL;
19222159047fSniklas s->bsym->flags &= ~(BSF_GLOBAL | BSF_WEAK);
19232159047fSniklas }
19242159047fSniklas
19252159047fSniklas void
S_SET_WEAK(symbolS * s)1926*007c2a45Smiod S_SET_WEAK (symbolS *s)
19272159047fSniklas {
1928b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1929b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
19302159047fSniklas s->bsym->flags |= BSF_WEAK;
19312159047fSniklas s->bsym->flags &= ~(BSF_GLOBAL | BSF_LOCAL);
19322159047fSniklas }
19332159047fSniklas
19342159047fSniklas void
S_SET_THREAD_LOCAL(symbolS * s)1935*007c2a45Smiod S_SET_THREAD_LOCAL (symbolS *s)
1936c074d1c9Sdrahn {
1937c074d1c9Sdrahn if (LOCAL_SYMBOL_CHECK (s))
1938c074d1c9Sdrahn s = local_symbol_convert ((struct local_symbol *) s);
1939c074d1c9Sdrahn if (bfd_is_com_section (s->bsym->section)
1940c074d1c9Sdrahn && (s->bsym->flags & BSF_THREAD_LOCAL) != 0)
1941c074d1c9Sdrahn return;
1942c074d1c9Sdrahn s->bsym->flags |= BSF_THREAD_LOCAL;
1943c074d1c9Sdrahn if ((s->bsym->flags & BSF_FUNCTION) != 0)
1944c074d1c9Sdrahn as_bad (_("Accessing function `%s' as thread-local object"),
1945c074d1c9Sdrahn S_GET_NAME (s));
1946c074d1c9Sdrahn else if (! bfd_is_und_section (s->bsym->section)
1947c074d1c9Sdrahn && (s->bsym->section->flags & SEC_THREAD_LOCAL) == 0)
1948c074d1c9Sdrahn as_bad (_("Accessing `%s' as thread-local object"),
1949c074d1c9Sdrahn S_GET_NAME (s));
1950c074d1c9Sdrahn }
1951c074d1c9Sdrahn
1952c074d1c9Sdrahn void
S_SET_NAME(symbolS * s,char * name)1953*007c2a45Smiod S_SET_NAME (symbolS *s, char *name)
19542159047fSniklas {
1955b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1956b305b0f1Sespie {
1957b305b0f1Sespie ((struct local_symbol *) s)->lsy_name = name;
1958b305b0f1Sespie return;
1959b305b0f1Sespie }
19602159047fSniklas s->bsym->name = name;
19612159047fSniklas }
19622159047fSniklas #endif /* BFD_ASSEMBLER */
19632159047fSniklas
1964b305b0f1Sespie #ifdef SYMBOLS_NEED_BACKPOINTERS
1965b305b0f1Sespie
1966b305b0f1Sespie /* Return the previous symbol in a chain. */
1967b305b0f1Sespie
1968b305b0f1Sespie symbolS *
symbol_previous(symbolS * s)1969*007c2a45Smiod symbol_previous (symbolS *s)
1970b305b0f1Sespie {
1971b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1972b305b0f1Sespie abort ();
1973b305b0f1Sespie return s->sy_previous;
1974b305b0f1Sespie }
1975b305b0f1Sespie
1976b305b0f1Sespie #endif /* SYMBOLS_NEED_BACKPOINTERS */
1977b305b0f1Sespie
1978b305b0f1Sespie /* Return the next symbol in a chain. */
1979b305b0f1Sespie
1980b305b0f1Sespie symbolS *
symbol_next(symbolS * s)1981*007c2a45Smiod symbol_next (symbolS *s)
1982b305b0f1Sespie {
1983b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1984b305b0f1Sespie abort ();
1985b305b0f1Sespie return s->sy_next;
1986b305b0f1Sespie }
1987b305b0f1Sespie
1988b305b0f1Sespie /* Return a pointer to the value of a symbol as an expression. */
1989b305b0f1Sespie
1990b305b0f1Sespie expressionS *
symbol_get_value_expression(symbolS * s)1991*007c2a45Smiod symbol_get_value_expression (symbolS *s)
1992b305b0f1Sespie {
1993b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
1994b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
1995b305b0f1Sespie return &s->sy_value;
1996b305b0f1Sespie }
1997b305b0f1Sespie
1998b305b0f1Sespie /* Set the value of a symbol to an expression. */
1999b305b0f1Sespie
2000b305b0f1Sespie void
symbol_set_value_expression(symbolS * s,const expressionS * exp)2001*007c2a45Smiod symbol_set_value_expression (symbolS *s, const expressionS *exp)
2002b305b0f1Sespie {
2003b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2004b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2005b305b0f1Sespie s->sy_value = *exp;
2006b305b0f1Sespie }
2007b305b0f1Sespie
2008*007c2a45Smiod /* Set the value of SYM to the current position in the current segment. */
2009*007c2a45Smiod
2010*007c2a45Smiod void
symbol_set_value_now(symbolS * sym)2011*007c2a45Smiod symbol_set_value_now (symbolS *sym)
2012*007c2a45Smiod {
2013*007c2a45Smiod S_SET_SEGMENT (sym, now_seg);
2014*007c2a45Smiod S_SET_VALUE (sym, frag_now_fix ());
2015*007c2a45Smiod symbol_set_frag (sym, frag_now);
2016*007c2a45Smiod }
2017*007c2a45Smiod
2018b305b0f1Sespie /* Set the frag of a symbol. */
2019b305b0f1Sespie
2020b305b0f1Sespie void
symbol_set_frag(symbolS * s,fragS * f)2021*007c2a45Smiod symbol_set_frag (symbolS *s, fragS *f)
2022b305b0f1Sespie {
2023b305b0f1Sespie #ifdef BFD_ASSEMBLER
2024b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2025b305b0f1Sespie {
2026b305b0f1Sespie local_symbol_set_frag ((struct local_symbol *) s, f);
2027b305b0f1Sespie return;
2028b305b0f1Sespie }
2029b305b0f1Sespie #endif
2030b305b0f1Sespie s->sy_frag = f;
2031b305b0f1Sespie }
2032b305b0f1Sespie
2033b305b0f1Sespie /* Return the frag of a symbol. */
2034b305b0f1Sespie
2035b305b0f1Sespie fragS *
symbol_get_frag(symbolS * s)2036*007c2a45Smiod symbol_get_frag (symbolS *s)
2037b305b0f1Sespie {
2038b305b0f1Sespie #ifdef BFD_ASSEMBLER
2039b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2040b305b0f1Sespie return local_symbol_get_frag ((struct local_symbol *) s);
2041b305b0f1Sespie #endif
2042b305b0f1Sespie return s->sy_frag;
2043b305b0f1Sespie }
2044b305b0f1Sespie
2045b305b0f1Sespie /* Mark a symbol as having been used. */
2046b305b0f1Sespie
2047b305b0f1Sespie void
symbol_mark_used(symbolS * s)2048*007c2a45Smiod symbol_mark_used (symbolS *s)
2049b305b0f1Sespie {
2050b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2051b305b0f1Sespie return;
2052b305b0f1Sespie s->sy_used = 1;
2053b305b0f1Sespie }
2054b305b0f1Sespie
2055b305b0f1Sespie /* Clear the mark of whether a symbol has been used. */
2056b305b0f1Sespie
2057b305b0f1Sespie void
symbol_clear_used(symbolS * s)2058*007c2a45Smiod symbol_clear_used (symbolS *s)
2059b305b0f1Sespie {
2060b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2061b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2062b305b0f1Sespie s->sy_used = 0;
2063b305b0f1Sespie }
2064b305b0f1Sespie
2065b305b0f1Sespie /* Return whether a symbol has been used. */
2066b305b0f1Sespie
2067b305b0f1Sespie int
symbol_used_p(symbolS * s)2068*007c2a45Smiod symbol_used_p (symbolS *s)
2069b305b0f1Sespie {
2070b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2071b305b0f1Sespie return 1;
2072b305b0f1Sespie return s->sy_used;
2073b305b0f1Sespie }
2074b305b0f1Sespie
2075b305b0f1Sespie /* Mark a symbol as having been used in a reloc. */
2076b305b0f1Sespie
2077b305b0f1Sespie void
symbol_mark_used_in_reloc(symbolS * s)2078*007c2a45Smiod symbol_mark_used_in_reloc (symbolS *s)
2079b305b0f1Sespie {
2080b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2081b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2082b305b0f1Sespie s->sy_used_in_reloc = 1;
2083b305b0f1Sespie }
2084b305b0f1Sespie
2085b305b0f1Sespie /* Clear the mark of whether a symbol has been used in a reloc. */
2086b305b0f1Sespie
2087b305b0f1Sespie void
symbol_clear_used_in_reloc(symbolS * s)2088*007c2a45Smiod symbol_clear_used_in_reloc (symbolS *s)
2089b305b0f1Sespie {
2090b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2091b305b0f1Sespie return;
2092b305b0f1Sespie s->sy_used_in_reloc = 0;
2093b305b0f1Sespie }
2094b305b0f1Sespie
2095b305b0f1Sespie /* Return whether a symbol has been used in a reloc. */
2096b305b0f1Sespie
2097b305b0f1Sespie int
symbol_used_in_reloc_p(symbolS * s)2098*007c2a45Smiod symbol_used_in_reloc_p (symbolS *s)
2099b305b0f1Sespie {
2100b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2101b305b0f1Sespie return 0;
2102b305b0f1Sespie return s->sy_used_in_reloc;
2103b305b0f1Sespie }
2104b305b0f1Sespie
2105b305b0f1Sespie /* Mark a symbol as an MRI common symbol. */
2106b305b0f1Sespie
2107b305b0f1Sespie void
symbol_mark_mri_common(symbolS * s)2108*007c2a45Smiod symbol_mark_mri_common (symbolS *s)
2109b305b0f1Sespie {
2110b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2111b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2112b305b0f1Sespie s->sy_mri_common = 1;
2113b305b0f1Sespie }
2114b305b0f1Sespie
2115b305b0f1Sespie /* Clear the mark of whether a symbol is an MRI common symbol. */
2116b305b0f1Sespie
2117b305b0f1Sespie void
symbol_clear_mri_common(symbolS * s)2118*007c2a45Smiod symbol_clear_mri_common (symbolS *s)
2119b305b0f1Sespie {
2120b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2121b305b0f1Sespie return;
2122b305b0f1Sespie s->sy_mri_common = 0;
2123b305b0f1Sespie }
2124b305b0f1Sespie
2125b305b0f1Sespie /* Return whether a symbol is an MRI common symbol. */
2126b305b0f1Sespie
2127b305b0f1Sespie int
symbol_mri_common_p(symbolS * s)2128*007c2a45Smiod symbol_mri_common_p (symbolS *s)
2129b305b0f1Sespie {
2130b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2131b305b0f1Sespie return 0;
2132b305b0f1Sespie return s->sy_mri_common;
2133b305b0f1Sespie }
2134b305b0f1Sespie
2135b305b0f1Sespie /* Mark a symbol as having been written. */
2136b305b0f1Sespie
2137b305b0f1Sespie void
symbol_mark_written(symbolS * s)2138*007c2a45Smiod symbol_mark_written (symbolS *s)
2139b305b0f1Sespie {
2140b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2141b305b0f1Sespie return;
2142b305b0f1Sespie s->written = 1;
2143b305b0f1Sespie }
2144b305b0f1Sespie
2145b305b0f1Sespie /* Clear the mark of whether a symbol has been written. */
2146b305b0f1Sespie
2147b305b0f1Sespie void
symbol_clear_written(symbolS * s)2148*007c2a45Smiod symbol_clear_written (symbolS *s)
2149b305b0f1Sespie {
2150b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2151b305b0f1Sespie return;
2152b305b0f1Sespie s->written = 0;
2153b305b0f1Sespie }
2154b305b0f1Sespie
2155b305b0f1Sespie /* Return whether a symbol has been written. */
2156b305b0f1Sespie
2157b305b0f1Sespie int
symbol_written_p(symbolS * s)2158*007c2a45Smiod symbol_written_p (symbolS *s)
2159b305b0f1Sespie {
2160b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2161b305b0f1Sespie return 0;
2162b305b0f1Sespie return s->written;
2163b305b0f1Sespie }
2164b305b0f1Sespie
2165b305b0f1Sespie /* Mark a symbol has having been resolved. */
2166b305b0f1Sespie
2167b305b0f1Sespie void
symbol_mark_resolved(symbolS * s)2168*007c2a45Smiod symbol_mark_resolved (symbolS *s)
2169b305b0f1Sespie {
2170b305b0f1Sespie #ifdef BFD_ASSEMBLER
2171b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2172b305b0f1Sespie {
2173b305b0f1Sespie local_symbol_mark_resolved ((struct local_symbol *) s);
2174b305b0f1Sespie return;
2175b305b0f1Sespie }
2176b305b0f1Sespie #endif
2177b305b0f1Sespie s->sy_resolved = 1;
2178b305b0f1Sespie }
2179b305b0f1Sespie
2180b305b0f1Sespie /* Return whether a symbol has been resolved. */
2181b305b0f1Sespie
2182b305b0f1Sespie int
symbol_resolved_p(symbolS * s)2183*007c2a45Smiod symbol_resolved_p (symbolS *s)
2184b305b0f1Sespie {
2185b305b0f1Sespie #ifdef BFD_ASSEMBLER
2186b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2187b305b0f1Sespie return local_symbol_resolved_p ((struct local_symbol *) s);
2188b305b0f1Sespie #endif
2189b305b0f1Sespie return s->sy_resolved;
2190b305b0f1Sespie }
2191b305b0f1Sespie
2192b305b0f1Sespie /* Return whether a symbol is a section symbol. */
2193b305b0f1Sespie
2194b305b0f1Sespie int
symbol_section_p(symbolS * s ATTRIBUTE_UNUSED)2195*007c2a45Smiod symbol_section_p (symbolS *s ATTRIBUTE_UNUSED)
2196b305b0f1Sespie {
2197b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2198b305b0f1Sespie return 0;
2199b305b0f1Sespie #ifdef BFD_ASSEMBLER
2200b305b0f1Sespie return (s->bsym->flags & BSF_SECTION_SYM) != 0;
2201b305b0f1Sespie #else
2202b55d4692Sfgsch /* FIXME. */
2203b305b0f1Sespie return 0;
2204b305b0f1Sespie #endif
2205b305b0f1Sespie }
2206b305b0f1Sespie
2207b305b0f1Sespie /* Return whether a symbol is equated to another symbol. */
2208b305b0f1Sespie
2209b305b0f1Sespie int
symbol_equated_p(symbolS * s)2210*007c2a45Smiod symbol_equated_p (symbolS *s)
2211b305b0f1Sespie {
2212b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2213b305b0f1Sespie return 0;
2214b305b0f1Sespie return s->sy_value.X_op == O_symbol;
2215b305b0f1Sespie }
2216b305b0f1Sespie
2217c074d1c9Sdrahn /* Return whether a symbol is equated to another symbol, and should be
2218c074d1c9Sdrahn treated specially when writing out relocs. */
2219c074d1c9Sdrahn
2220c074d1c9Sdrahn int
symbol_equated_reloc_p(symbolS * s)2221*007c2a45Smiod symbol_equated_reloc_p (symbolS *s)
2222c074d1c9Sdrahn {
2223c074d1c9Sdrahn if (LOCAL_SYMBOL_CHECK (s))
2224c074d1c9Sdrahn return 0;
2225c074d1c9Sdrahn /* X_op_symbol, normally not used for O_symbol, is set by
2226c074d1c9Sdrahn resolve_symbol_value to flag expression syms that have been
2227c074d1c9Sdrahn equated. */
2228c074d1c9Sdrahn return (s->sy_value.X_op == O_symbol
2229c074d1c9Sdrahn && ((s->sy_resolved && s->sy_value.X_op_symbol != NULL)
2230c074d1c9Sdrahn || ! S_IS_DEFINED (s)
2231c074d1c9Sdrahn || S_IS_COMMON (s)));
2232c074d1c9Sdrahn }
2233c074d1c9Sdrahn
2234b305b0f1Sespie /* Return whether a symbol has a constant value. */
2235b305b0f1Sespie
2236b305b0f1Sespie int
symbol_constant_p(symbolS * s)2237*007c2a45Smiod symbol_constant_p (symbolS *s)
2238b305b0f1Sespie {
2239b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2240b305b0f1Sespie return 1;
2241b305b0f1Sespie return s->sy_value.X_op == O_constant;
2242b305b0f1Sespie }
2243b305b0f1Sespie
2244b305b0f1Sespie #ifdef BFD_ASSEMBLER
2245b305b0f1Sespie
2246b305b0f1Sespie /* Return the BFD symbol for a symbol. */
2247b305b0f1Sespie
2248b305b0f1Sespie asymbol *
symbol_get_bfdsym(symbolS * s)2249*007c2a45Smiod symbol_get_bfdsym (symbolS *s)
2250b305b0f1Sespie {
2251b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2252b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2253b305b0f1Sespie return s->bsym;
2254b305b0f1Sespie }
2255b305b0f1Sespie
2256b305b0f1Sespie /* Set the BFD symbol for a symbol. */
2257b305b0f1Sespie
2258b305b0f1Sespie void
symbol_set_bfdsym(symbolS * s,asymbol * bsym)2259*007c2a45Smiod symbol_set_bfdsym (symbolS *s, asymbol *bsym)
2260b305b0f1Sespie {
2261b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2262b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2263b305b0f1Sespie s->bsym = bsym;
2264b305b0f1Sespie }
2265b305b0f1Sespie
2266b305b0f1Sespie #endif /* BFD_ASSEMBLER */
2267b305b0f1Sespie
2268b305b0f1Sespie #ifdef OBJ_SYMFIELD_TYPE
2269b305b0f1Sespie
2270b305b0f1Sespie /* Get a pointer to the object format information for a symbol. */
2271b305b0f1Sespie
2272b305b0f1Sespie OBJ_SYMFIELD_TYPE *
symbol_get_obj(symbolS * s)2273*007c2a45Smiod symbol_get_obj (symbolS *s)
2274b305b0f1Sespie {
2275b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2276b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2277b305b0f1Sespie return &s->sy_obj;
2278b305b0f1Sespie }
2279b305b0f1Sespie
2280b305b0f1Sespie /* Set the object format information for a symbol. */
2281b305b0f1Sespie
2282b305b0f1Sespie void
symbol_set_obj(symbolS * s,OBJ_SYMFIELD_TYPE * o)2283*007c2a45Smiod symbol_set_obj (symbolS *s, OBJ_SYMFIELD_TYPE *o)
2284b305b0f1Sespie {
2285b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2286b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2287b305b0f1Sespie s->sy_obj = *o;
2288b305b0f1Sespie }
2289b305b0f1Sespie
2290b305b0f1Sespie #endif /* OBJ_SYMFIELD_TYPE */
2291b305b0f1Sespie
2292b305b0f1Sespie #ifdef TC_SYMFIELD_TYPE
2293b305b0f1Sespie
2294b305b0f1Sespie /* Get a pointer to the processor information for a symbol. */
2295b305b0f1Sespie
2296b305b0f1Sespie TC_SYMFIELD_TYPE *
symbol_get_tc(symbolS * s)2297*007c2a45Smiod symbol_get_tc (symbolS *s)
2298b305b0f1Sespie {
2299b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2300b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2301b305b0f1Sespie return &s->sy_tc;
2302b305b0f1Sespie }
2303b305b0f1Sespie
2304b305b0f1Sespie /* Set the processor information for a symbol. */
2305b305b0f1Sespie
2306b305b0f1Sespie void
symbol_set_tc(symbolS * s,TC_SYMFIELD_TYPE * o)2307*007c2a45Smiod symbol_set_tc (symbolS *s, TC_SYMFIELD_TYPE *o)
2308b305b0f1Sespie {
2309b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (s))
2310b305b0f1Sespie s = local_symbol_convert ((struct local_symbol *) s);
2311b305b0f1Sespie s->sy_tc = *o;
2312b305b0f1Sespie }
2313b305b0f1Sespie
2314b305b0f1Sespie #endif /* TC_SYMFIELD_TYPE */
2315b305b0f1Sespie
23162159047fSniklas void
symbol_begin(void)2317*007c2a45Smiod symbol_begin (void)
23182159047fSniklas {
23192159047fSniklas symbol_lastP = NULL;
23202159047fSniklas symbol_rootP = NULL; /* In case we have 0 symbols (!!) */
23212159047fSniklas sy_hash = hash_new ();
2322b305b0f1Sespie #ifdef BFD_ASSEMBLER
2323b305b0f1Sespie local_hash = hash_new ();
2324b305b0f1Sespie #endif
23252159047fSniklas
23262159047fSniklas memset ((char *) (&abs_symbol), '\0', sizeof (abs_symbol));
23272159047fSniklas #ifdef BFD_ASSEMBLER
23282159047fSniklas #if defined (EMIT_SECTION_SYMBOLS) || !defined (RELOC_REQUIRES_SYMBOL)
23292159047fSniklas abs_symbol.bsym = bfd_abs_section.symbol;
23302159047fSniklas #endif
23312159047fSniklas #else
23322159047fSniklas /* Can't initialise a union. Sigh. */
23332159047fSniklas S_SET_SEGMENT (&abs_symbol, absolute_section);
23342159047fSniklas #endif
23352159047fSniklas abs_symbol.sy_value.X_op = O_constant;
23362159047fSniklas abs_symbol.sy_frag = &zero_address_frag;
23372159047fSniklas
23382159047fSniklas if (LOCAL_LABELS_FB)
23392159047fSniklas fb_label_init ();
23402159047fSniklas }
23412159047fSniklas
23422159047fSniklas int indent_level;
23432159047fSniklas
2344b305b0f1Sespie /* Maximum indent level.
2345b305b0f1Sespie Available for modification inside a gdb session. */
2346b305b0f1Sespie int max_indent_level = 8;
2347b305b0f1Sespie
23482159047fSniklas #if 0
23492159047fSniklas
23502159047fSniklas static void
2351*007c2a45Smiod indent (void)
23522159047fSniklas {
23532159047fSniklas printf ("%*s", indent_level * 4, "");
23542159047fSniklas }
23552159047fSniklas
23562159047fSniklas #endif
23572159047fSniklas
23582159047fSniklas void
print_symbol_value_1(FILE * file,symbolS * sym)2359*007c2a45Smiod print_symbol_value_1 (FILE *file, symbolS *sym)
23602159047fSniklas {
23612159047fSniklas const char *name = S_GET_NAME (sym);
23622159047fSniklas if (!name || !name[0])
23632159047fSniklas name = "(unnamed)";
23642159047fSniklas fprintf (file, "sym %lx %s", (unsigned long) sym, name);
2365b305b0f1Sespie
2366b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (sym))
2367b305b0f1Sespie {
2368b305b0f1Sespie #ifdef BFD_ASSEMBLER
2369b305b0f1Sespie struct local_symbol *locsym = (struct local_symbol *) sym;
2370b305b0f1Sespie if (local_symbol_get_frag (locsym) != &zero_address_frag
2371b305b0f1Sespie && local_symbol_get_frag (locsym) != NULL)
2372b305b0f1Sespie fprintf (file, " frag %lx", (long) local_symbol_get_frag (locsym));
2373b305b0f1Sespie if (local_symbol_resolved_p (locsym))
2374b305b0f1Sespie fprintf (file, " resolved");
2375b305b0f1Sespie fprintf (file, " local");
2376b305b0f1Sespie #endif
2377b305b0f1Sespie }
2378b305b0f1Sespie else
2379b305b0f1Sespie {
23802159047fSniklas if (sym->sy_frag != &zero_address_frag)
23812159047fSniklas fprintf (file, " frag %lx", (long) sym->sy_frag);
23822159047fSniklas if (sym->written)
23832159047fSniklas fprintf (file, " written");
23842159047fSniklas if (sym->sy_resolved)
23852159047fSniklas fprintf (file, " resolved");
23862159047fSniklas else if (sym->sy_resolving)
23872159047fSniklas fprintf (file, " resolving");
23882159047fSniklas if (sym->sy_used_in_reloc)
23892159047fSniklas fprintf (file, " used-in-reloc");
23902159047fSniklas if (sym->sy_used)
23912159047fSniklas fprintf (file, " used");
23922159047fSniklas if (S_IS_LOCAL (sym))
23932159047fSniklas fprintf (file, " local");
23942159047fSniklas if (S_IS_EXTERN (sym))
23952159047fSniklas fprintf (file, " extern");
23962159047fSniklas if (S_IS_DEBUG (sym))
23972159047fSniklas fprintf (file, " debug");
23982159047fSniklas if (S_IS_DEFINED (sym))
23992159047fSniklas fprintf (file, " defined");
2400b305b0f1Sespie }
24012159047fSniklas fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
2402b305b0f1Sespie if (symbol_resolved_p (sym))
24032159047fSniklas {
24042159047fSniklas segT s = S_GET_SEGMENT (sym);
24052159047fSniklas
24062159047fSniklas if (s != undefined_section
24072159047fSniklas && s != expr_section)
24082159047fSniklas fprintf (file, " %lx", (long) S_GET_VALUE (sym));
24092159047fSniklas }
2410b305b0f1Sespie else if (indent_level < max_indent_level
2411b305b0f1Sespie && S_GET_SEGMENT (sym) != undefined_section)
24122159047fSniklas {
24132159047fSniklas indent_level++;
24142159047fSniklas fprintf (file, "\n%*s<", indent_level * 4, "");
2415b305b0f1Sespie #ifdef BFD_ASSEMBLER
2416b305b0f1Sespie if (LOCAL_SYMBOL_CHECK (sym))
2417b305b0f1Sespie fprintf (file, "constant %lx",
2418c074d1c9Sdrahn (long) ((struct local_symbol *) sym)->lsy_value);
2419b305b0f1Sespie else
2420b305b0f1Sespie #endif
24212159047fSniklas print_expr_1 (file, &sym->sy_value);
24222159047fSniklas fprintf (file, ">");
24232159047fSniklas indent_level--;
24242159047fSniklas }
24252159047fSniklas fflush (file);
24262159047fSniklas }
24272159047fSniklas
24282159047fSniklas void
print_symbol_value(symbolS * sym)2429*007c2a45Smiod print_symbol_value (symbolS *sym)
24302159047fSniklas {
24312159047fSniklas indent_level = 0;
24322159047fSniklas print_symbol_value_1 (stderr, sym);
24332159047fSniklas fprintf (stderr, "\n");
24342159047fSniklas }
24352159047fSniklas
2436b305b0f1Sespie static void
print_binary(FILE * file,const char * name,expressionS * exp)2437*007c2a45Smiod print_binary (FILE *file, const char *name, expressionS *exp)
2438b305b0f1Sespie {
2439b305b0f1Sespie indent_level++;
2440b305b0f1Sespie fprintf (file, "%s\n%*s<", name, indent_level * 4, "");
2441b305b0f1Sespie print_symbol_value_1 (file, exp->X_add_symbol);
2442b305b0f1Sespie fprintf (file, ">\n%*s<", indent_level * 4, "");
2443b305b0f1Sespie print_symbol_value_1 (file, exp->X_op_symbol);
2444b305b0f1Sespie fprintf (file, ">");
2445b305b0f1Sespie indent_level--;
2446b305b0f1Sespie }
2447b305b0f1Sespie
24482159047fSniklas void
print_expr_1(FILE * file,expressionS * exp)2449*007c2a45Smiod print_expr_1 (FILE *file, expressionS *exp)
24502159047fSniklas {
24512159047fSniklas fprintf (file, "expr %lx ", (long) exp);
24522159047fSniklas switch (exp->X_op)
24532159047fSniklas {
24542159047fSniklas case O_illegal:
24552159047fSniklas fprintf (file, "illegal");
24562159047fSniklas break;
24572159047fSniklas case O_absent:
24582159047fSniklas fprintf (file, "absent");
24592159047fSniklas break;
24602159047fSniklas case O_constant:
24612159047fSniklas fprintf (file, "constant %lx", (long) exp->X_add_number);
24622159047fSniklas break;
24632159047fSniklas case O_symbol:
24642159047fSniklas indent_level++;
24652159047fSniklas fprintf (file, "symbol\n%*s<", indent_level * 4, "");
24662159047fSniklas print_symbol_value_1 (file, exp->X_add_symbol);
24672159047fSniklas fprintf (file, ">");
24682159047fSniklas maybe_print_addnum:
24692159047fSniklas if (exp->X_add_number)
24702159047fSniklas fprintf (file, "\n%*s%lx", indent_level * 4, "",
24712159047fSniklas (long) exp->X_add_number);
24722159047fSniklas indent_level--;
24732159047fSniklas break;
24742159047fSniklas case O_register:
24752159047fSniklas fprintf (file, "register #%d", (int) exp->X_add_number);
24762159047fSniklas break;
24772159047fSniklas case O_big:
24782159047fSniklas fprintf (file, "big");
24792159047fSniklas break;
24802159047fSniklas case O_uminus:
24812159047fSniklas fprintf (file, "uminus -<");
24822159047fSniklas indent_level++;
24832159047fSniklas print_symbol_value_1 (file, exp->X_add_symbol);
24842159047fSniklas fprintf (file, ">");
24852159047fSniklas goto maybe_print_addnum;
24862159047fSniklas case O_bit_not:
24872159047fSniklas fprintf (file, "bit_not");
24882159047fSniklas break;
24892159047fSniklas case O_multiply:
2490b305b0f1Sespie print_binary (file, "multiply", exp);
24912159047fSniklas break;
24922159047fSniklas case O_divide:
2493b305b0f1Sespie print_binary (file, "divide", exp);
24942159047fSniklas break;
24952159047fSniklas case O_modulus:
2496b305b0f1Sespie print_binary (file, "modulus", exp);
24972159047fSniklas break;
24982159047fSniklas case O_left_shift:
2499b305b0f1Sespie print_binary (file, "lshift", exp);
25002159047fSniklas break;
25012159047fSniklas case O_right_shift:
2502b305b0f1Sespie print_binary (file, "rshift", exp);
25032159047fSniklas break;
25042159047fSniklas case O_bit_inclusive_or:
2505b305b0f1Sespie print_binary (file, "bit_ior", exp);
25062159047fSniklas break;
25072159047fSniklas case O_bit_exclusive_or:
2508b305b0f1Sespie print_binary (file, "bit_xor", exp);
25092159047fSniklas break;
25102159047fSniklas case O_bit_and:
2511b305b0f1Sespie print_binary (file, "bit_and", exp);
25122159047fSniklas break;
25132159047fSniklas case O_eq:
2514b305b0f1Sespie print_binary (file, "eq", exp);
25152159047fSniklas break;
25162159047fSniklas case O_ne:
2517b305b0f1Sespie print_binary (file, "ne", exp);
25182159047fSniklas break;
25192159047fSniklas case O_lt:
2520b305b0f1Sespie print_binary (file, "lt", exp);
25212159047fSniklas break;
25222159047fSniklas case O_le:
2523b305b0f1Sespie print_binary (file, "le", exp);
25242159047fSniklas break;
25252159047fSniklas case O_ge:
2526b305b0f1Sespie print_binary (file, "ge", exp);
25272159047fSniklas break;
25282159047fSniklas case O_gt:
2529b305b0f1Sespie print_binary (file, "gt", exp);
25302159047fSniklas break;
25312159047fSniklas case O_logical_and:
2532b305b0f1Sespie print_binary (file, "logical_and", exp);
25332159047fSniklas break;
25342159047fSniklas case O_logical_or:
2535b305b0f1Sespie print_binary (file, "logical_or", exp);
25362159047fSniklas break;
25372159047fSniklas case O_add:
25382159047fSniklas indent_level++;
25392159047fSniklas fprintf (file, "add\n%*s<", indent_level * 4, "");
25402159047fSniklas print_symbol_value_1 (file, exp->X_add_symbol);
25412159047fSniklas fprintf (file, ">\n%*s<", indent_level * 4, "");
25422159047fSniklas print_symbol_value_1 (file, exp->X_op_symbol);
25432159047fSniklas fprintf (file, ">");
25442159047fSniklas goto maybe_print_addnum;
25452159047fSniklas case O_subtract:
25462159047fSniklas indent_level++;
25472159047fSniklas fprintf (file, "subtract\n%*s<", indent_level * 4, "");
25482159047fSniklas print_symbol_value_1 (file, exp->X_add_symbol);
25492159047fSniklas fprintf (file, ">\n%*s<", indent_level * 4, "");
25502159047fSniklas print_symbol_value_1 (file, exp->X_op_symbol);
25512159047fSniklas fprintf (file, ">");
25522159047fSniklas goto maybe_print_addnum;
25532159047fSniklas default:
25542159047fSniklas fprintf (file, "{unknown opcode %d}", (int) exp->X_op);
25552159047fSniklas break;
25562159047fSniklas }
25572159047fSniklas fflush (stdout);
25582159047fSniklas }
25592159047fSniklas
25602159047fSniklas void
print_expr(expressionS * exp)2561*007c2a45Smiod print_expr (expressionS *exp)
25622159047fSniklas {
25632159047fSniklas print_expr_1 (stderr, exp);
25642159047fSniklas fprintf (stderr, "\n");
25652159047fSniklas }
25662159047fSniklas
2567191aa565Sniklas void
symbol_print_statistics(FILE * file)2568*007c2a45Smiod symbol_print_statistics (FILE *file)
2569191aa565Sniklas {
2570191aa565Sniklas hash_print_statistics (file, "symbol table", sy_hash);
2571b305b0f1Sespie #ifdef BFD_ASSEMBLER
2572b305b0f1Sespie hash_print_statistics (file, "mini local symbol table", local_hash);
2573b305b0f1Sespie fprintf (file, "%lu mini local symbols created, %lu converted\n",
2574b305b0f1Sespie local_symbol_count, local_symbol_conversion_count);
2575b305b0f1Sespie #endif
2576191aa565Sniklas }
2577