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