PR gas/827
* as.h (rs_dummy): Define. * symbols.c (symbol_X_add_number): New function. * symbols.h (symbol_X_add_number): Declare. * stabs.c (aout_process_stab): Tidy symbol frag setting. * read.c (assign_symbol): New function, split out from s_set. Use symbol_find_or_make. Leave fr_type of dummy frag as rs_dummy. Fix COFF hacks for multi-emulation gas. (s_set): Call assign_symbol. Remove "register" keyword. (set_zero_frag): New function. (pseudo_set): Always check for assignment to section syms. Always set segment and frag of symbol, and likewise extern for aout/bout. Handle assignment of sym=sym+/-const specially. Don't special case exp.X_add_number non-zero for O_symbol expressions. (equals): Use assign_symbol.
This commit is contained in:
parent
f0885a038a
commit
be95a9c15d
|
@ -1,3 +1,21 @@
|
|||
2005-04-09 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR gas/827
|
||||
* as.h (rs_dummy): Define.
|
||||
* symbols.c (symbol_X_add_number): New function.
|
||||
* symbols.h (symbol_X_add_number): Declare.
|
||||
* stabs.c (aout_process_stab): Tidy symbol frag setting.
|
||||
* read.c (assign_symbol): New function, split out from s_set.
|
||||
Use symbol_find_or_make. Leave fr_type of dummy frag as rs_dummy.
|
||||
Fix COFF hacks for multi-emulation gas.
|
||||
(s_set): Call assign_symbol. Remove "register" keyword.
|
||||
(set_zero_frag): New function.
|
||||
(pseudo_set): Always check for assignment to section syms.
|
||||
Always set segment and frag of symbol, and likewise extern for
|
||||
aout/bout. Handle assignment of sym=sym+/-const specially. Don't
|
||||
special case exp.X_add_number non-zero for O_symbol expressions.
|
||||
(equals): Use assign_symbol.
|
||||
|
||||
2005-04-08 Bob Wilson <bob.wilson@acm.org>
|
||||
|
||||
* config/tc-xtensa.c (xtensa_create_xproperty_segments): Skip
|
||||
|
|
5
gas/as.h
5
gas/as.h
|
@ -324,10 +324,13 @@ extern segT text_section, data_section, bss_section;
|
|||
|
||||
enum _relax_state
|
||||
{
|
||||
/* Dummy frag used by listing code. */
|
||||
rs_dummy = 0,
|
||||
|
||||
/* Variable chars to be repeated fr_offset times.
|
||||
Fr_symbol unused. Used with fr_offset == 0 for a
|
||||
constant length frag. */
|
||||
rs_fill = 1,
|
||||
rs_fill,
|
||||
|
||||
/* Align. The fr_offset field holds the power of 2 to which to
|
||||
align. The fr_var field holds the number of characters in the
|
||||
|
|
239
gas/read.c
239
gas/read.c
|
@ -2747,6 +2747,62 @@ end_repeat (int extra)
|
|||
buffer_limit = input_scrub_next_buffer (&input_line_pointer);
|
||||
}
|
||||
|
||||
static void
|
||||
assign_symbol (const char *name, int no_reassign)
|
||||
{
|
||||
symbolS *symbolP;
|
||||
|
||||
if (name[0] == '.' && name[1] == '\0')
|
||||
{
|
||||
/* Turn '. = mumble' into a .org mumble. */
|
||||
segT segment;
|
||||
expressionS exp;
|
||||
|
||||
segment = get_known_segmented_expression (&exp);
|
||||
|
||||
if (!need_pass_2)
|
||||
do_org (segment, &exp, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ((symbolP = symbol_find (name)) == NULL
|
||||
&& (symbolP = md_undefined_symbol (name)) == NULL)
|
||||
{
|
||||
symbolP = symbol_find_or_make (name);
|
||||
#ifndef NO_LISTING
|
||||
/* When doing symbol listings, play games with dummy fragments living
|
||||
outside the normal fragment chain to record the file and line info
|
||||
for this symbol. */
|
||||
if (listing & LISTING_SYMBOLS)
|
||||
{
|
||||
extern struct list_info_struct *listing_tail;
|
||||
fragS *dummy_frag = (fragS *) xcalloc (sizeof (fragS));
|
||||
dummy_frag->line = listing_tail;
|
||||
dummy_frag->fr_symbol = symbolP;
|
||||
symbol_set_frag (symbolP, dummy_frag);
|
||||
}
|
||||
#endif
|
||||
#if defined (OBJ_COFF) || defined (OBJ_MAYBE_COFF)
|
||||
#if defined (BFD_ASSEMBLER) && defined (OBJ_MAYBE_COFF)
|
||||
if (OUTPUT_FLAVOR == bfd_target_coff_flavour)
|
||||
#endif
|
||||
/* "set" symbols are local unless otherwise specified. */
|
||||
SF_SET_LOCAL (symbolP);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Permit register names to be redefined. */
|
||||
if (no_reassign
|
||||
&& S_IS_DEFINED (symbolP)
|
||||
&& S_GET_SEGMENT (symbolP) != reg_section)
|
||||
as_bad (_("symbol `%s' is already defined"), name);
|
||||
|
||||
pseudo_set (symbolP);
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
/* Handle the .equ, .equiv and .set directives. If EQUIV is 1, then
|
||||
this is .equiv, and it is an error if the symbol is already
|
||||
defined. */
|
||||
|
@ -2754,10 +2810,9 @@ end_repeat (int extra)
|
|||
void
|
||||
s_set (int equiv)
|
||||
{
|
||||
register char *name;
|
||||
register char delim;
|
||||
register char *end_name;
|
||||
register symbolS *symbolP;
|
||||
char *name;
|
||||
char delim;
|
||||
char *end_name;
|
||||
|
||||
/* Especial apologies for the random logic:
|
||||
this just grew, and could be parsed much more simply!
|
||||
|
@ -2788,59 +2843,8 @@ s_set (int equiv)
|
|||
input_line_pointer++;
|
||||
*end_name = 0;
|
||||
|
||||
if (name[0] == '.' && name[1] == '\0')
|
||||
{
|
||||
/* Turn '. = mumble' into a .org mumble. */
|
||||
register segT segment;
|
||||
expressionS exp;
|
||||
|
||||
segment = get_known_segmented_expression (&exp);
|
||||
|
||||
if (!need_pass_2)
|
||||
do_org (segment, &exp, 0);
|
||||
|
||||
assign_symbol (name, equiv);
|
||||
*end_name = delim;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((symbolP = symbol_find (name)) == NULL
|
||||
&& (symbolP = md_undefined_symbol (name)) == NULL)
|
||||
{
|
||||
#ifndef NO_LISTING
|
||||
/* When doing symbol listings, play games with dummy fragments living
|
||||
outside the normal fragment chain to record the file and line info
|
||||
for this symbol. */
|
||||
if (listing & LISTING_SYMBOLS)
|
||||
{
|
||||
extern struct list_info_struct *listing_tail;
|
||||
fragS *dummy_frag = (fragS *) xmalloc (sizeof (fragS));
|
||||
memset (dummy_frag, 0, sizeof (fragS));
|
||||
dummy_frag->fr_type = rs_fill;
|
||||
dummy_frag->line = listing_tail;
|
||||
symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
|
||||
dummy_frag->fr_symbol = symbolP;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
|
||||
|
||||
#ifdef OBJ_COFF
|
||||
/* "set" symbols are local unless otherwise specified. */
|
||||
SF_SET_LOCAL (symbolP);
|
||||
#endif /* OBJ_COFF */
|
||||
}
|
||||
|
||||
symbol_table_insert (symbolP);
|
||||
|
||||
*end_name = delim;
|
||||
|
||||
if (equiv
|
||||
&& S_IS_DEFINED (symbolP)
|
||||
&& S_GET_SEGMENT (symbolP) != reg_section)
|
||||
as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
|
||||
|
||||
pseudo_set (symbolP);
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3177,6 +3181,16 @@ discard_rest_of_line (void)
|
|||
know (is_end_of_line[(unsigned char) input_line_pointer[-1]]);
|
||||
}
|
||||
|
||||
/* Sets frag for given symbol to zero_address_frag, except when the
|
||||
symbol frag is already set to a dummy listing frag. */
|
||||
|
||||
static void
|
||||
set_zero_frag (symbolS *symbolP)
|
||||
{
|
||||
if (symbol_get_frag (symbolP)->fr_type != rs_dummy)
|
||||
symbol_set_frag (symbolP, &zero_address_frag);
|
||||
}
|
||||
|
||||
/* In: Pointer to a symbol.
|
||||
Input_line_pointer->expression.
|
||||
|
||||
|
@ -3188,14 +3202,12 @@ void
|
|||
pseudo_set (symbolS *symbolP)
|
||||
{
|
||||
expressionS exp;
|
||||
segT seg;
|
||||
#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
|
||||
int ext;
|
||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
||||
|
||||
know (symbolP); /* NULL pointer is logic error. */
|
||||
#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
|
||||
ext = S_IS_EXTERNAL (symbolP);
|
||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
||||
|
||||
(void) expression (&exp);
|
||||
|
||||
|
@ -3220,6 +3232,15 @@ pseudo_set (symbolS *symbolP)
|
|||
- S_GET_VALUE (exp.X_op_symbol));
|
||||
}
|
||||
|
||||
if (symbol_section_p (symbolP))
|
||||
{
|
||||
as_bad ("attempt to set value of section symbol");
|
||||
return;
|
||||
}
|
||||
#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
|
||||
ext = S_IS_EXTERNAL (symbolP);
|
||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
||||
|
||||
switch (exp.X_op)
|
||||
{
|
||||
case O_illegal:
|
||||
|
@ -3229,53 +3250,55 @@ pseudo_set (symbolS *symbolP)
|
|||
/* Fall through. */
|
||||
case O_constant:
|
||||
S_SET_SEGMENT (symbolP, absolute_section);
|
||||
#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
|
||||
if (ext)
|
||||
S_SET_EXTERNAL (symbolP);
|
||||
else
|
||||
S_CLEAR_EXTERNAL (symbolP);
|
||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
||||
S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
|
||||
if (exp.X_op != O_constant)
|
||||
symbol_set_frag (symbolP, &zero_address_frag);
|
||||
set_zero_frag (symbolP);
|
||||
break;
|
||||
|
||||
case O_register:
|
||||
S_SET_SEGMENT (symbolP, reg_section);
|
||||
S_SET_VALUE (symbolP, (valueT) exp.X_add_number);
|
||||
symbol_set_frag (symbolP, &zero_address_frag);
|
||||
set_zero_frag (symbolP);
|
||||
break;
|
||||
|
||||
case O_symbol:
|
||||
if (S_GET_SEGMENT (exp.X_add_symbol) == undefined_section
|
||||
|| exp.X_add_number != 0)
|
||||
symbol_set_value_expression (symbolP, &exp);
|
||||
else if (symbol_section_p (symbolP))
|
||||
as_bad ("attempt to set value of section symbol");
|
||||
else
|
||||
seg = S_GET_SEGMENT (exp.X_add_symbol);
|
||||
/* For x=undef+const, create an expression symbol.
|
||||
For x=x+const, just update x except when x is an undefined symbol
|
||||
For x=defined+const, evaluate x. */
|
||||
if (symbolP == exp.X_add_symbol
|
||||
&& (seg != undefined_section
|
||||
|| !symbol_constant_p (symbolP)))
|
||||
{
|
||||
*symbol_X_add_number (symbolP) += exp.X_add_number;
|
||||
break;
|
||||
}
|
||||
else if (seg != undefined_section)
|
||||
{
|
||||
symbolS *s = exp.X_add_symbol;
|
||||
|
||||
S_SET_SEGMENT (symbolP, S_GET_SEGMENT (s));
|
||||
S_SET_SEGMENT (symbolP, seg);
|
||||
S_SET_VALUE (symbolP, exp.X_add_number + S_GET_VALUE (s));
|
||||
symbol_set_frag (symbolP, symbol_get_frag (s));
|
||||
copy_symbol_attributes (symbolP, s);
|
||||
break;
|
||||
}
|
||||
/* Fall thru */
|
||||
|
||||
default:
|
||||
/* The value is some complex expression.
|
||||
Set segment and frag back to that of a newly created symbol. */
|
||||
S_SET_SEGMENT (symbolP, undefined_section);
|
||||
symbol_set_value_expression (symbolP, &exp);
|
||||
set_zero_frag (symbolP);
|
||||
break;
|
||||
}
|
||||
|
||||
#if (defined (OBJ_AOUT) || defined (OBJ_BOUT)) && ! defined (BFD_ASSEMBLER)
|
||||
if (ext)
|
||||
S_SET_EXTERNAL (symbolP);
|
||||
else
|
||||
S_CLEAR_EXTERNAL (symbolP);
|
||||
#endif /* OBJ_AOUT or OBJ_BOUT */
|
||||
S_SET_VALUE (symbolP,
|
||||
exp.X_add_number + S_GET_VALUE (s));
|
||||
symbol_set_frag (symbolP, symbol_get_frag (s));
|
||||
copy_symbol_attributes (symbolP, s);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* The value is some complex expression.
|
||||
FIXME: Should we set the segment to anything? */
|
||||
symbol_set_value_expression (symbolP, &exp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* cons()
|
||||
|
@ -4884,7 +4907,6 @@ is_it_end_of_statement (void)
|
|||
void
|
||||
equals (char *sym_name, int reassign)
|
||||
{
|
||||
register symbolS *symbolP; /* Symbol we are working with. */
|
||||
char *stop = NULL;
|
||||
char stopc;
|
||||
|
||||
|
@ -4898,47 +4920,10 @@ equals (char *sym_name, int reassign)
|
|||
if (flag_mri)
|
||||
stop = mri_comment_field (&stopc);
|
||||
|
||||
if (sym_name[0] == '.' && sym_name[1] == '\0')
|
||||
{
|
||||
/* Turn '. = mumble' into a .org mumble. */
|
||||
register segT segment;
|
||||
expressionS exp;
|
||||
|
||||
segment = get_known_segmented_expression (&exp);
|
||||
if (!need_pass_2)
|
||||
do_org (segment, &exp, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef OBJ_COFF
|
||||
int local;
|
||||
|
||||
symbolP = symbol_find (sym_name);
|
||||
local = symbolP == NULL;
|
||||
if (local)
|
||||
#endif /* OBJ_COFF */
|
||||
symbolP = symbol_find_or_make (sym_name);
|
||||
/* Permit register names to be redefined. */
|
||||
if (!reassign
|
||||
&& S_IS_DEFINED (symbolP)
|
||||
&& S_GET_SEGMENT (symbolP) != reg_section)
|
||||
as_bad (_("symbol `%s' is already defined"), S_GET_NAME (symbolP));
|
||||
|
||||
#ifdef OBJ_COFF
|
||||
/* "set" symbols are local unless otherwise specified. */
|
||||
if (local)
|
||||
SF_SET_LOCAL (symbolP);
|
||||
#endif /* OBJ_COFF */
|
||||
|
||||
pseudo_set (symbolP);
|
||||
}
|
||||
assign_symbol (sym_name, !reassign);
|
||||
|
||||
if (flag_mri)
|
||||
{
|
||||
/* Check garbage after the expression. */
|
||||
demand_empty_rest_of_line ();
|
||||
mri_comment_end (stop, stopc);
|
||||
}
|
||||
}
|
||||
|
||||
/* .incbin -- include a file verbatim at the current location. */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Generic stabs parsing for gas.
|
||||
Copyright 1989, 1990, 1991, 1993, 1995, 1996, 1997, 1998, 2000, 2001
|
||||
2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
|
@ -150,11 +150,10 @@ aout_process_stab (what, string, type, other, desc)
|
|||
ends in "\" and the debug info is continued in the next .stabs
|
||||
directive) from being separated by other random symbols. */
|
||||
symbol = symbol_create (string, undefined_section, 0,
|
||||
(struct frag *) NULL);
|
||||
&zero_address_frag);
|
||||
if (what == 's' || what == 'n')
|
||||
{
|
||||
/* Pick up the value from the input line. */
|
||||
symbol_set_frag (symbol, &zero_address_frag);
|
||||
pseudo_set (symbol);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -2022,6 +2022,19 @@ symbol_set_value_expression (symbolS *s, const expressionS *exp)
|
|||
s->sy_value = *exp;
|
||||
}
|
||||
|
||||
/* Return a pointer to the X_add_number component of a symbol. */
|
||||
|
||||
valueT *
|
||||
symbol_X_add_number (symbolS *s)
|
||||
{
|
||||
#ifdef BFD_ASSEMBLER
|
||||
if (LOCAL_SYMBOL_CHECK (s))
|
||||
return &((struct local_symbol *) s)->lsy_value;
|
||||
#endif
|
||||
|
||||
return &s->sy_value.X_add_number;
|
||||
}
|
||||
|
||||
/* Set the value of SYM to the current position in the current segment. */
|
||||
|
||||
void
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* symbols.h -
|
||||
Copyright 1987, 1990, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001,
|
||||
2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GAS, the GNU Assembler.
|
||||
|
||||
|
@ -175,6 +175,7 @@ extern symbolS *symbol_next (symbolS *);
|
|||
|
||||
extern expressionS *symbol_get_value_expression (symbolS *);
|
||||
extern void symbol_set_value_expression (symbolS *, const expressionS *);
|
||||
extern valueT *symbol_X_add_number (symbolS *);
|
||||
extern void symbol_set_value_now (symbolS *);
|
||||
extern void symbol_set_frag (symbolS *, fragS *);
|
||||
extern fragS *symbol_get_frag (symbolS *);
|
||||
|
|
Loading…
Reference in New Issue