From c9d665580ec705dab16bdf27147e584b44f70ed5 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Tue, 21 Jan 2014 15:12:19 -0500 Subject: Ensure that %func() expressions are outermost terms This is to avoid expressions like: %hi(foo) + 1, which will not do what you expect. The complex relocations can handle it, but the internal fixups can't. --- gas/ChangeLog | 7 +++++++ gas/config/tc-rl78.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 15fe29c..259c014 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2014-01-21 DJ Delorie + + * config/tc-rl78.c (require_end_of_expr): New. + (md_operand): Call it. + (rl78_cons_fix_new): Mark LO16, HI16, ahd HI8 internal relocations + as not overflowing. + 2014-01-17 Will Newton * config/tc-arm.c (do_vfp_nsyn_cvt_fpv8): Set OP to 1 diff --git a/gas/config/tc-rl78.c b/gas/config/tc-rl78.c index 651f3f6..2f59af8 100644 --- a/gas/config/tc-rl78.c +++ b/gas/config/tc-rl78.c @@ -347,6 +347,23 @@ md_number_to_chars (char * buf, valueT val, int n) number_to_chars_littleendian (buf, val, n); } +static void +require_end_of_expr (char *fname) +{ + while (* input_line_pointer == ' ' + || * input_line_pointer == '\t') + input_line_pointer ++; + + if (! * input_line_pointer + || strchr ("\n\r,", * input_line_pointer) + || strchr (comment_chars, * input_line_pointer) + || strchr (line_comment_chars, * input_line_pointer) + || strchr (line_separator_chars, * input_line_pointer)) + return; + + as_bad (_("%%%s() must be outermost term in expression"), fname); +} + static struct { char * fname; @@ -388,6 +405,8 @@ md_operand (expressionS * exp ATTRIBUTE_UNUSED) input_line_pointer ++; exp->X_md = reloc; + + require_end_of_expr (reloc_functions[i].fname); } void @@ -552,6 +571,7 @@ rl78_cons_fix_new (fragS * frag, expressionS * exp) { bfd_reloc_code_real_type type; + fixS *fixP; switch (size) { @@ -601,7 +621,21 @@ rl78_cons_fix_new (fragS * frag, type = BFD_RELOC_RL78_DIFF; } - fix_new_exp (frag, where, (int) size, exp, 0, type); + fixP = fix_new_exp (frag, where, (int) size, exp, 0, type); + switch (exp->X_md) + { + /* These are intended to have values larger than the container, + since the backend puts only the portion we need in it. + However, we don't have a backend-specific reloc for them as + they're handled with complex relocations. */ + case BFD_RELOC_RL78_LO16: + case BFD_RELOC_RL78_HI16: + case BFD_RELOC_RL78_HI8: + fixP->fx_no_overflow = 1; + break; + default: + break; + } } /* No relaxation just yet */ -- cgit v1.1