diff options
Diffstat (limited to 'gas/symbols.c')
-rw-r--r-- | gas/symbols.c | 99 |
1 files changed, 54 insertions, 45 deletions
diff --git a/gas/symbols.c b/gas/symbols.c index 9a4e2be..91d0cdb 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -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 |