/* symbols.c -symbol table-
- Copyright (C) 1987-2014 Free Software Foundation, Inc.
+ Copyright (C) 1987-2018 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
#include "obstack.h" /* For "symbols.h" */
#include "subsegs.h"
#include "struc-symbol.h"
+#include "write.h"
/* This is non-zero if symbols are case sensitive, which is the
default. */
const char * an_external_name;
#endif
-static char *save_symbol_name (const char *);
+static const char *save_symbol_name (const char *);
static void fb_label_init (void);
static long dollar_label_instance (long);
static long fb_label_instance (long);
/* Save a symbol name on a permanent obstack, and convert it according
to the object file format. */
-static char *
+static const char *
save_symbol_name (const char *name)
{
size_t name_length;
char *ret;
+ gas_assert (name != NULL);
name_length = strlen (name) + 1; /* +1 for \0. */
obstack_grow (¬es, name, name_length);
ret = (char *) obstack_finish (¬es);
valueT valu, /* Symbol value. */
fragS *frag /* Associated fragment. */)
{
- char *preserved_copy_of_name;
+ const char *preserved_copy_of_name;
symbolS *symbolP;
preserved_copy_of_name = save_symbol_name (name);
struct local_symbol *
local_symbol_make (const char *name, segT section, valueT val, fragS *frag)
{
- char *name_copy;
+ const char *name_copy;
struct local_symbol *ret;
++local_symbol_count;
symbolS *
colon (/* Just seen "x:" - rattle symbols & frags. */
- const char *sym_name /* Symbol name, as a cannonical string. */
+ const char *sym_name /* Symbol name, as a canonical string. */
/* We copy this string: OK to alter later. */)
{
- register symbolS *symbolP; /* Symbol we are working with. */
+ symbolS *symbolP; /* Symbol we are working with. */
/* Sun local labels go out of scope whenever a non-local symbol is
defined. */
}
else
{
-#if (!defined (OBJ_AOUT) && !defined (OBJ_MAYBE_AOUT) \
- && !defined (OBJ_BOUT) && !defined (OBJ_MAYBE_BOUT))
+#if (!defined (OBJ_AOUT) && !defined (OBJ_MAYBE_AOUT))
static const char *od_buf = "";
#else
char od_buf[100];
void
symbol_table_insert (symbolS *symbolP)
{
- register const char *error_string;
+ const char *error_string;
know (symbolP);
know (S_GET_NAME (symbolP));
symbolS *
symbol_find_or_make (const char *name)
{
- register symbolS *symbolP;
+ symbolS *symbolP;
symbolP = symbol_find (name);
symbolS *
symbol_find_noref (const char *name, int noref)
{
+ symbolS * result;
+ char * copy = NULL;
+
#ifdef tc_canonicalize_symbol_name
{
- char *copy;
- size_t len = strlen (name) + 1;
-
- copy = (char *) alloca (len);
- memcpy (copy, name, len);
+ copy = xstrdup (name);
name = tc_canonicalize_symbol_name (copy);
}
#endif
if (! symbols_case_sensitive)
{
- char *copy;
const char *orig;
+ char *copy2 = NULL;
unsigned char c;
orig = name;
- name = copy = (char *) alloca (strlen (name) + 1);
+ if (copy != NULL)
+ copy2 = copy;
+ name = copy = XNEWVEC (char, strlen (name) + 1);
while ((c = *orig++) != '\0')
- {
- *copy++ = TOUPPER (c);
- }
+ *copy++ = TOUPPER (c);
*copy = '\0';
+
+ if (copy2 != NULL)
+ free (copy2);
+ copy = (char *) name;
}
- return symbol_find_exact_noref (name, noref);
+ result = symbol_find_exact_noref (name, noref);
+ if (copy != NULL)
+ free (copy);
+ return result;
}
/* Once upon a time, symbols were kept in a singly linked list. At
static void
report_op_error (symbolS *symp, symbolS *left, operatorT op, symbolS *right)
{
- char *file;
+ const char *file;
unsigned int line;
segT seg_left = left ? S_GET_SEGMENT (left) : 0;
segT seg_right = S_GET_SEGMENT (right);
resolved = symbol_resolved_p (add_symbol);
if (S_IS_WEAKREFR (symp))
- goto exit_dont_set_value;
+ {
+ symp->sy_flags.sy_resolving = 0;
+ goto exit_dont_set_value;
+ }
break;
case O_uminus:
operands must be absolute. We already handled the case of
addition or subtraction of a constant above. This will
probably need to be changed for an object file format which
- supports arbitrary expressions, such as IEEE-695. */
+ supports arbitrary expressions. */
if (!(seg_left == absolute_section
&& seg_right == absolute_section)
&& !(op == O_eq || op == O_ne)
already issued a warning about using a bad symbol. */
if (seg_right == absolute_section && finalize_syms)
{
- char *file;
+ const char *file;
unsigned int line;
if (expr_symbol_where (symp, &file, &line))
case O_gt: left = left > right ? ~ (offsetT) 0 : 0; break;
case O_logical_and: left = left && right; break;
case O_logical_or: left = left || right; break;
- default: abort ();
+
+ case O_illegal:
+ case O_absent:
+ case O_constant:
+ /* See PR 20895 for a reproducer. */
+ as_bad (_("Invalid operation on symbol"));
+ goto exit_dont_set_value;
+
+ default:
+ abort ();
}
final_val += symp->sy_frag->fr_address + left;
case O_register:
if (!symbol_equated_p (symbolP))
break;
- /* Fall thru. */
+ /* Fallthru. */
case O_symbol:
case O_symbol_rva:
symbolP = exp.X_add_symbol;
}
*symbolPP = symbolP;
- *valueP = exp.X_add_number;
- *segP = symbolP->bsym->section;
- *fragPP = symbolP->sy_frag;
+
+ /* A bogus input file can result in resolve_expression()
+ generating a local symbol, so we have to check again. */
+ if (LOCAL_SYMBOL_CHECK (symbolP))
+ {
+ struct local_symbol *locsym = (struct local_symbol *) symbolP;
+
+ *valueP = locsym->lsy_value;
+ *segP = locsym->lsy_section;
+ *fragPP = local_symbol_get_frag (locsym);
+ }
+ else
+ {
+ *valueP = exp.X_add_number;
+ *segP = symbolP->bsym->section;
+ *fragPP = symbolP->sy_frag;
+ }
if (*segP == expr_section)
switch (exp.X_op)
if (dollar_labels == NULL)
{
- dollar_labels = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
- dollar_label_instances = (long *) xmalloc (DOLLAR_LABEL_BUMP_BY * sizeof (long));
- dollar_label_defines = (char *) xmalloc (DOLLAR_LABEL_BUMP_BY);
+ dollar_labels = XNEWVEC (long, DOLLAR_LABEL_BUMP_BY);
+ dollar_label_instances = XNEWVEC (long, DOLLAR_LABEL_BUMP_BY);
+ dollar_label_defines = XNEWVEC (char, DOLLAR_LABEL_BUMP_BY);
dollar_label_max = DOLLAR_LABEL_BUMP_BY;
dollar_label_count = 0;
}
else if (dollar_label_count == dollar_label_max)
{
dollar_label_max += DOLLAR_LABEL_BUMP_BY;
- dollar_labels = (long *) xrealloc ((char *) dollar_labels,
- dollar_label_max * sizeof (long));
- dollar_label_instances = (long *) xrealloc ((char *) dollar_label_instances,
- dollar_label_max * sizeof (long));
- dollar_label_defines = (char *) xrealloc (dollar_label_defines, dollar_label_max);
+ dollar_labels = XRESIZEVEC (long, dollar_labels, dollar_label_max);
+ dollar_label_instances = XRESIZEVEC (long, dollar_label_instances,
+ dollar_label_max);
+ dollar_label_defines = XRESIZEVEC (char, dollar_label_defines,
+ dollar_label_max);
} /* if we needed to grow */
dollar_labels[dollar_label_count] = label;
/* Caller must copy returned name: we re-use the area for the next name.
- The mth occurence of label n: is turned into the symbol "Ln^Am"
+ The mth occurrence of label n: is turned into the symbol "Ln^Am"
where n is the label number and m is the instance number. "L" makes
it a label discarded unless debugging and "^A"('\1') ensures no
ordinary symbol SHOULD get the same name as a local label
of ^A. */
char * /* Return local label name. */
-dollar_label_name (register long n, /* we just saw "n$:" : n a number. */
- register int augend /* 0 for current instance, 1 for new instance. */)
+dollar_label_name (long n, /* we just saw "n$:" : n a number. */
+ int augend /* 0 for current instance, 1 for new instance. */)
{
long i;
/* Returned to caller, then copied. Used for created names ("4f"). */
static char symbol_name_build[24];
- register char *p;
- register char *q;
+ char *p;
+ char *q;
char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */
know (n >= 0);
if (fb_labels == NULL)
{
- fb_labels = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
- fb_label_instances = (long *) xmalloc (FB_LABEL_BUMP_BY * sizeof (long));
+ fb_labels = XNEWVEC (long, FB_LABEL_BUMP_BY);
+ fb_label_instances = XNEWVEC (long, FB_LABEL_BUMP_BY);
fb_label_max = FB_LABEL_BUMP_BY;
fb_label_count = FB_LABEL_SPECIAL;
else if (fb_label_count == fb_label_max)
{
fb_label_max += FB_LABEL_BUMP_BY;
- fb_labels = (long *) xrealloc ((char *) fb_labels,
- fb_label_max * sizeof (long));
- fb_label_instances = (long *) xrealloc ((char *) fb_label_instances,
- fb_label_max * sizeof (long));
+ fb_labels = XRESIZEVEC (long, fb_labels, fb_label_max);
+ fb_label_instances = XRESIZEVEC (long, fb_label_instances, fb_label_max);
} /* if we needed to grow */
fb_labels[fb_label_count] = label;
/* Caller must copy returned name: we re-use the area for the next name.
- The mth occurence of label n: is turned into the symbol "Ln^Bm"
+ The mth occurrence of label n: is turned into the symbol "Ln^Bm"
where n is the label number and m is the instance number. "L" makes
it a label discarded unless debugging and "^B"('\2') ensures no
ordinary symbol SHOULD get the same name as a local label
long i;
/* Returned to caller, then copied. Used for created names ("4f"). */
static char symbol_name_build[24];
- register char *p;
- register char *q;
+ char *p;
+ char *q;
char symbol_name_temporary[20]; /* Build up a number, BACKWARDS. */
know (n >= 0);
char *symbol_decode;
int label_number;
int instance_number;
- char *type;
+ const char *type;
const char *message_format;
int lindex = 0;
int
S_FORCE_RELOC (symbolS *s, int strict)
{
+ segT sec;
if (LOCAL_SYMBOL_CHECK (s))
- return ((struct local_symbol *) s)->lsy_section == undefined_section;
-
- return ((strict
+ sec = ((struct local_symbol *) s)->lsy_section;
+ else
+ {
+ if ((strict
&& ((s->bsym->flags & BSF_WEAK) != 0
|| (EXTERN_FORCE_RELOC
&& (s->bsym->flags & BSF_GLOBAL) != 0)))
- || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0
- || s->bsym->section == undefined_section
- || bfd_is_com_section (s->bsym->section));
+ || (s->bsym->flags & BSF_GNU_INDIRECT_FUNCTION) != 0)
+ return TRUE;
+ sec = s->bsym->section;
+ }
+ return bfd_is_und_section (sec) || bfd_is_com_section (sec);
}
int
&& ! S_IS_DEBUG (s)
&& (strchr (name, DOLLAR_LABEL_CHAR)
|| strchr (name, LOCAL_LABEL_CHAR)
+#if FAKE_LABEL_CHAR != DOLLAR_LABEL_CHAR
+ || strchr (name, FAKE_LABEL_CHAR)
+#endif
|| TC_LABEL_IS_LOCAL (name)
|| (! flag_keep_locals
&& (bfd_is_local_label (stdoutput, s->bsym)
}
if (s->bsym->flags & BSF_SECTION_SYM)
{
- char * file;
- unsigned int line;
-
/* Do not reassign section symbols. */
- as_where (& file, & line);
- as_warn_where (file, line,
- _("section symbols are already global"));
+ as_warn (_("section symbols are already global"));
return;
}
#ifndef TC_GLOBAL_REGISTER_SYMBOL_OK
|| S_GET_SEGMENT (sym) == absolute_section)
return symbol_relc_make_expr (& sym->sy_value);
- /* This may be a "fake symbol" L0\001, referring to ".".
+ /* This may be a "fake symbol", referring to ".".
Write out a special null symbol to refer to this position. */
if (! strcmp (S_GET_NAME (sym), FAKE_LABEL_NAME))
return xstrdup (".");
sname_len = strlen (sname);
typetag = symbol_section_p (sym) ? 'S' : 's';
- terminal = xmalloc (1 /* S or s */
- + 8 /* sname_len in decimal */
- + 1 /* _ spacer */
- + sname_len /* name itself */
- + 1 /* \0 */ );
+ terminal = XNEWVEC (char, (1 /* S or s */
+ + 8 /* sname_len in decimal */
+ + 1 /* _ spacer */
+ + sname_len /* name itself */
+ + 1 /* \0 */ ));
sprintf (terminal, "%c%d:%s", typetag, sname_len, sname);
return terminal;
char *
symbol_relc_make_value (offsetT val)
{
- char * terminal = xmalloc (28); /* Enough for long long. */
+ char * terminal = XNEWVEC (char, 28); /* Enough for long long. */
terminal[0] = '#';
bfd_sprintf_vma (stdoutput, terminal + 1, val);
char *
symbol_relc_make_expr (expressionS * exp)
{
- char * opstr = NULL; /* Operator prefix string. */
+ const char * opstr = NULL; /* Operator prefix string. */
int arity = 0; /* Arity of this operator. */
char * operands[3]; /* Up to three operands. */
char * concat_string = NULL;
if (opstr == NULL)
concat_string = NULL;
+ else if (arity == 0)
+ concat_string = xstrdup (opstr);
+ else if (arity == 1)
+ concat_string = concat (opstr, ":", operands[0], (char *) NULL);
+ else if (arity == 2)
+ concat_string = concat (opstr, ":", operands[0], ":", operands[1],
+ (char *) NULL);
else
- {
- /* Allocate new string; include inter-operand padding gaps etc. */
- concat_string = xmalloc (strlen (opstr)
- + 1
- + (arity >= 1 ? (strlen (operands[0]) + 1 ) : 0)
- + (arity >= 2 ? (strlen (operands[1]) + 1 ) : 0)
- + (arity >= 3 ? (strlen (operands[2]) + 0 ) : 0)
- + 1);
- gas_assert (concat_string != NULL);
-
- /* Format the thing. */
- sprintf (concat_string,
- (arity == 0 ? "%s" :
- arity == 1 ? "%s:%s" :
- arity == 2 ? "%s:%s:%s" :
- /* arity == 3 */ "%s:%s:%s:%s"),
- opstr, operands[0], operands[1], operands[2]);
- }
+ concat_string = concat (opstr, ":", operands[0], ":", operands[1], ":",
+ operands[2], (char *) NULL);
/* Free operand strings (not opstr). */
if (arity >= 1) xfree (operands[0]);