* symbols.c (report_op_error): Remove unnecessary forward declaration.

Add "op" parameter.  Report operator and operand segments in error
	message, not operand symbols.
	(resolve_symbol_value): Always set segment for equated symbols, not
	just when finalizing.  Adjust report_op_error calls.
This commit is contained in:
Alan Modra 2011-02-28 04:45:59 +00:00
parent 8ab1f94d63
commit 5a0ade8b70
2 changed files with 62 additions and 45 deletions

View File

@ -1,3 +1,11 @@
2011-02-28 Alan Modra <amodra@gmail.com>
* symbols.c (report_op_error): Remove unnecessary forward declaration.
Add "op" parameter. Report operator and operand segments in error
message, not operand symbols.
(resolve_symbol_value): Always set segment for equated symbols, not
just when finalizing. Adjust report_op_error calls.
2011-02-25 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (reloc): Don't sign-check 4-byte relocations

View File

@ -1,7 +1,7 @@
/* symbols.c -symbol table-
Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
2011 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@ -72,7 +72,6 @@ static long dollar_label_instance (long);
static long fb_label_instance (long);
static void print_binary (FILE *, const char *, expressionS *);
static void report_op_error (symbolS *, symbolS *, symbolS *);
/* Return a pointer to a new symbol. Die if we can't make a new
symbol. Fill in the symbol's values. Add symbol to end of symbol
@ -970,55 +969,65 @@ use_complex_relocs_for (symbolS * symp)
#endif
static void
report_op_error (symbolS *symp, symbolS *left, symbolS *right)
report_op_error (symbolS *symp, symbolS *left, operatorT op, symbolS *right)
{
char *file;
unsigned int line;
segT seg_left = S_GET_SEGMENT (left);
segT seg_right = right ? S_GET_SEGMENT (right) : 0;
segT seg_left = left ? S_GET_SEGMENT (left) : 0;
segT seg_right = S_GET_SEGMENT (right);
const char *opname;
switch (op)
{
default:
abort ();
return;
case O_uminus: opname = "-"; break;
case O_bit_not: opname = "~"; break;
case O_logical_not: opname = "!"; break;
case O_multiply: opname = "*"; break;
case O_divide: opname = "/"; break;
case O_modulus: opname = "%"; break;
case O_left_shift: opname = "<<"; break;
case O_right_shift: opname = ">>"; break;
case O_bit_inclusive_or: opname = "|"; break;
case O_bit_or_not: opname = "|~"; break;
case O_bit_exclusive_or: opname = "^"; break;
case O_bit_and: opname = "&"; break;
case O_add: opname = "+"; break;
case O_subtract: opname = "-"; break;
case O_eq: opname = "=="; break;
case O_ne: opname = "!="; break;
case O_lt: opname = "<"; break;
case O_le: opname = "<="; break;
case O_ge: opname = ">="; break;
case O_gt: opname = ">"; break;
case O_logical_and: opname = "&&"; break;
case O_logical_or: opname = "||"; break;
}
if (expr_symbol_where (symp, &file, &line))
{
if (seg_left == undefined_section)
if (left)
as_bad_where (file, line,
_("undefined symbol `%s' in operation"),
S_GET_NAME (left));
if (seg_right == undefined_section)
_("invalid operands (%s and %s sections) for `%s'"),
seg_left->name, seg_right->name, opname);
else
as_bad_where (file, line,
_("undefined symbol `%s' in operation"),
S_GET_NAME (right));
if (seg_left != undefined_section
&& seg_right != undefined_section)
{
if (right)
as_bad_where (file, line,
_("invalid sections for operation on `%s' and `%s'"),
S_GET_NAME (left), S_GET_NAME (right));
else
as_bad_where (file, line,
_("invalid section for operation on `%s'"),
S_GET_NAME (left));
}
_("invalid operand (%s section) for `%s'"),
seg_right->name, opname);
}
else
{
if (seg_left == undefined_section)
as_bad (_("undefined symbol `%s' in operation setting `%s'"),
S_GET_NAME (left), S_GET_NAME (symp));
if (seg_right == undefined_section)
as_bad (_("undefined symbol `%s' in operation setting `%s'"),
S_GET_NAME (right), S_GET_NAME (symp));
if (seg_left != undefined_section
&& seg_right != undefined_section)
{
if (right)
as_bad (_("invalid sections for operation on `%s' and `%s' setting `%s'"),
S_GET_NAME (left), S_GET_NAME (right), S_GET_NAME (symp));
else
as_bad (_("invalid section for operation on `%s' setting `%s'"),
S_GET_NAME (left), S_GET_NAME (symp));
}
const char *sname = S_GET_NAME (symp);
if (left)
as_bad (_("invalid operands (%s and %s sections) for `%s' when setting `%s'"),
seg_left->name, seg_right->name, opname, sname);
else
as_bad (_("invalid operand (%s section) for `%s' when setting `%s'"),
seg_right->name, opname, sname);
}
}
@ -1211,8 +1220,8 @@ resolve_symbol_value (symbolS *symp)
symp->sy_value.X_add_number = final_val;
/* Use X_op_symbol as a flag. */
symp->sy_value.X_op_symbol = add_symbol;
final_seg = seg_left;
}
final_seg = seg_left;
final_val = 0;
resolved = symbol_resolved_p (add_symbol);
symp->sy_resolving = 0;
@ -1261,7 +1270,7 @@ resolve_symbol_value (symbolS *symp)
~S -> S ^ ~0 only permitted on absolute */
if (op != O_logical_not && seg_left != absolute_section
&& finalize_syms)
report_op_error (symp, add_symbol, NULL);
report_op_error (symp, NULL, op, add_symbol);
if (final_seg == expr_section || final_seg == undefined_section)
final_seg = absolute_section;
@ -1338,7 +1347,7 @@ resolve_symbol_value (symbolS *symp)
probably need to be changed for an object file format which
supports arbitrary expressions, such as IEEE-695. */
if (!(seg_left == absolute_section
&& seg_right == absolute_section)
&& seg_right == absolute_section)
&& !(op == O_eq || op == O_ne)
&& !((op == O_subtract
|| op == O_lt || op == O_le || op == O_ge || op == O_gt)
@ -1349,7 +1358,7 @@ resolve_symbol_value (symbolS *symp)
/* Don't emit messages unless we're finalizing the symbol value,
otherwise we may get the same message multiple times. */
if (finalize_syms)
report_op_error (symp, add_symbol, op_symbol);
report_op_error (symp, add_symbol, op, op_symbol);
/* However do not move the symbol into the absolute section
if it cannot currently be resolved - this would confuse
other parts of the assembler into believing that the