}
static symbolS *
-i386_intel_simplify_symbol (symbolS *sym, bool in_equate)
+i386_intel_simplify_symbol (symbolS *sym)
{
- if (symbol_resolving_p (sym))
- return sym;
+ symbolS *orig = sym;
+ offsetT off;
+ sym = symbol_equated_to (sym, &off);
+ if (sym == NULL || off != 0)
+ return orig;
segT seg = S_GET_SEGMENT (sym);
- if (seg != expr_section && seg != reg_section && !symbol_equated_p(sym))
+ if (seg == undefined_section
+ || (seg != expr_section && seg != reg_section && sym == orig))
return sym;
- for (;;)
- {
- /* While we're after equates, symbol_equated_p() isn't suitable here. */
- if (symbol_on_chain(sym, symbol_rootP, symbol_lastP))
- {
- in_equate = true;
- sym = symbol_clone (sym, 0);
- }
- else if (in_equate)
- {
- expressionS *e = symbol_get_value_expression (sym);
-
- if (e->X_op == O_symbol && !e->X_add_number)
- {
- sym = e->X_add_symbol;
- continue;
- }
- sym = make_expr_symbol (e);
- }
-
- break;
- }
-
- symbol_mark_resolving (sym);
- int ret = i386_intel_simplify (symbol_get_value_expression (sym), in_equate);
- if (ret == 2)
- S_SET_SEGMENT (sym, absolute_section);
- symbol_clear_resolving (sym);
-
- return ret ? sym : NULL;
+ /* i386_intel_simplify modifies its arg. We don't want to make
+ premature changes to symbols here, particularly for a symbol
+ equate. Changing a symbol may affect future uses of that
+ symbol. So copy the symbol value and make a new symbol after
+ i386_intel_simplify has done its work. Don't use structure
+ assignment to copy the value as that doesn't guarantee writing
+ any padding bytes, and we want to use memcmp below rather than
+ comparing every field. */
+ expressionS *e = symbol_get_value_expression (sym);
+ expressionS exp;
+ memcpy (&exp, e, sizeof exp);
+ int ret = i386_intel_simplify (&exp);
+ if (ret == 0)
+ return NULL;
+
+ if (memcmp (&exp, e, sizeof exp) != 0)
+ sym = make_expr_symbol (&exp);
+ return sym;
}
static int
-i386_intel_simplify (expressionS *e, bool in_equate)
+i386_intel_simplify (expressionS *e)
{
const reg_entry *the_reg = (this_operand >= 0
? i.op[this_operand].regs : NULL);
case O_index:
if (e->X_add_symbol)
{
- newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol);
if (!newsym
|| !i386_intel_check(the_reg, intel_state.base,
intel_state.index))
}
if (!intel_state.in_offset)
++intel_state.in_bracket;
- newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol);
if (!intel_state.in_offset)
--intel_state.in_bracket;
if (!newsym)
case O_offset:
intel_state.has_offset = 1;
++intel_state.in_offset;
- newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol);
--intel_state.in_offset;
if (!newsym || !i386_intel_check(the_reg, base, state_index))
return 0;
as_bad (_("invalid use of register"));
return 0;
}
- newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol);
if (!newsym)
return 0;
e->X_add_symbol = newsym;
as_bad (_("invalid use of register"));
return 0;
}
- newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol);
if (!newsym
|| !i386_intel_check(the_reg, intel_state.base,
intel_state.index))
expressionS *left = NULL, *right = NULL;
segT leftseg = NULL, rightseg = NULL;
- newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol);
if (newsym)
{
e->X_add_symbol = newsym;
}
}
- newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol);
if (newsym)
{
e->X_op_symbol = newsym;
if (!intel_state.in_scale++)
intel_state.scale_factor = 1;
- newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol);
if (newsym)
{
e->X_add_symbol = newsym;
other = symbol_get_value_expression (e->X_add_symbol);
}
- newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol);
}
if (newsym)
fallthrough:
if (e->X_add_symbol)
{
- newsym = i386_intel_simplify_symbol (e->X_add_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_add_symbol);
if (!newsym)
return 0;
e->X_add_symbol = newsym;
return 0;
if (e->X_op_symbol)
{
- newsym = i386_intel_simplify_symbol (e->X_op_symbol, in_equate);
+ newsym = i386_intel_simplify_symbol (e->X_op_symbol);
if (!newsym)
return 0;
e->X_op_symbol = newsym;
expr_mode = expr_operator_none;
memset (&exp, 0, sizeof(exp));
exp_seg = expression (&exp);
- ret = i386_intel_simplify (&exp, false);
+ ret = i386_intel_simplify (&exp);
intel_syntax = 1;
SKIP_WHITESPACE ();