From: Nick Clifton Date: Thu, 5 Oct 2017 15:17:22 +0000 (+0100) Subject: Fix the MSP430 assembler so that it detects and reports extraneous text at the end... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2bfa0cdfadd313f3cc35329a17ba3c62865208a3;p=binutils-gdb.git Fix the MSP430 assembler so that it detects and reports extraneous text at the end of operands. PR 22133 * config/tc-msp430.c (parse_exp): Skip an 'h' suffix to constant expressions. (msp430_srcoperand): Check that the entire text was parsed by parse_exp. (msp430_operands): Likewise. * testsuite/gas/msp430/pr22133.s: New test file. * testsuite/gas/msp430/pr22133.d: New test driver. * testsuite/gas/msp430/pr22133.s: Expected error output. * testsuite/gas/msp430/msp430.exp: Run the new test. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index df8edc1dc4f..ed40a79a107 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2017-10-05 Nick Clifton + + PR 22133 + * config/tc-msp430.c (parse_exp): Skip an 'h' suffix to constant + expressions. + (msp430_srcoperand): Check that the entire text was parsed by + parse_exp. + (msp430_operands): Likewise. + * testsuite/gas/msp430/pr22133.s: New test file. + * testsuite/gas/msp430/pr22133.d: New test driver. + * testsuite/gas/msp430/pr22133.s: Expected error output. + * testsuite/gas/msp430/msp430.exp: Run the new test. + 2017-10-04 H.J. Lu PR gas/21167 diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c index 62a34ed669e..6f3acdf7275 100644 --- a/gas/config/tc-msp430.c +++ b/gas/config/tc-msp430.c @@ -415,6 +415,13 @@ parse_exp (char * s, expressionS * op) expression (op); if (op->X_op == O_absent) as_bad (_("missing operand")); + /* Our caller is likely to check that the entire expression was parsed. + If we have found a hex constant with an 'h' suffix, ilp will be left + pointing at the 'h', so skip it here. */ + if (input_line_pointer != NULL + && op->X_op == O_constant + && (*input_line_pointer == 'h' || *input_line_pointer == 'H')) + ++ input_line_pointer; return input_line_pointer; } @@ -625,7 +632,7 @@ msp430_profiler (int dummy ATTRIBUTE_UNUSED) /* Now get profiling info. */ halt = extract_operand (input_line_pointer, str, 1024); /* Process like ".word xxx" directive. */ - parse_exp (str, & exp); + (void) parse_exp (str, & exp); emit_expr (& exp, 2); input_line_pointer = halt; } @@ -1709,6 +1716,7 @@ msp430_srcoperand (struct msp430_operand_s * op, bfd_boolean allow_20bit_values, bfd_boolean constants_allowed) { + char * end; char *__tl = l; /* Check if an immediate #VALUE. The hash sign should be only at the beginning! */ @@ -1765,7 +1773,12 @@ msp430_srcoperand (struct msp430_operand_s * op, op->mode = OP_EXP; op->vshift = vshift; - parse_exp (__tl, &(op->exp)); + end = parse_exp (__tl, &(op->exp)); + if (end != NULL && *end != 0 && *end != ')' ) + { + as_bad (_("extra characters '%s' at end of immediate expression '%s'"), end, l); + return 1; + } if (op->exp.X_op == O_constant) { int x = op->exp.X_add_number; @@ -1962,7 +1975,12 @@ msp430_srcoperand (struct msp430_operand_s * op, op->am = 1; /* mode As == 01 bin. */ op->ol = 1; /* Immediate value followed by instruction. */ __tl = h + 1; - parse_exp (__tl, &(op->exp)); + end = parse_exp (__tl, &(op->exp)); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at the end of absolute operand '%s'"), end, l); + return 1; + } op->mode = OP_EXP; op->vshift = 0; if (op->exp.X_op == O_constant) @@ -2073,7 +2091,12 @@ msp430_srcoperand (struct msp430_operand_s * op, *h = 0; op->mode = OP_EXP; op->vshift = 0; - parse_exp (__tl, &(op->exp)); + end = parse_exp (__tl, &(op->exp)); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at end of operand '%s'"), end, l); + return 1; + } if (op->exp.X_op == O_constant) { int x = op->exp.X_add_number; @@ -2135,23 +2158,20 @@ msp430_srcoperand (struct msp430_operand_s * op, } /* Symbolic mode 'mov a, b' == 'mov x(pc), y(pc)'. */ - do + op->mode = OP_EXP; + op->reg = 0; /* PC relative... be careful. */ + /* An expression starting with a minus sign is a constant, not an address. */ + op->am = (*l == '-' ? 3 : 1); + op->ol = 1; + op->vshift = 0; + __tl = l; + end = parse_exp (__tl, &(op->exp)); + if (end != NULL && * end != 0) { - op->mode = OP_EXP; - op->reg = 0; /* PC relative... be careful. */ - /* An expression starting with a minus sign is a constant, not an address. */ - op->am = (*l == '-' ? 3 : 1); - op->ol = 1; - op->vshift = 0; - __tl = l; - parse_exp (__tl, &(op->exp)); - return 0; + as_bad (_("extra characters '%s' at end of operand '%s'"), end, l); + return 1; } - while (0); - - /* Unreachable. */ - as_bad (_("unknown addressing mode for operand %s"), l); - return 1; + return 0; } @@ -2178,7 +2198,7 @@ msp430_dstoperand (struct msp430_operand_s * op, op->am = 1; op->ol = 1; op->vshift = 0; - parse_exp (__tl, &(op->exp)); + (void) parse_exp (__tl, &(op->exp)); if (op->exp.X_op != O_constant || op->exp.X_add_number != 0) { @@ -2475,6 +2495,7 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) int insn_length = 0; char l1[MAX_OP_LEN], l2[MAX_OP_LEN]; char *frag; + char *end; int where; struct msp430_operand_s op1, op2; int res = 0; @@ -3106,7 +3127,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) as_bad (_("expected #n as first argument of %s"), opcode->name); break; } - parse_exp (l1 + 1, &(op1.exp)); + end = parse_exp (l1 + 1, &(op1.exp)); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at end of constant expression '%s'"), end, l1); + break; + } if (op1.exp.X_op != O_constant) { as_bad (_("expected constant expression as first argument of %s"), @@ -3177,7 +3203,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) as_bad (_("expected #n as first argument of %s"), opcode->name); break; } - parse_exp (l1 + 1, &(op1.exp)); + end = parse_exp (l1 + 1, &(op1.exp)); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); + break; + } if (op1.exp.X_op != O_constant) { as_bad (_("expected constant expression as first argument of %s"), @@ -3240,7 +3271,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) if (*l1 == '#') { - parse_exp (l1 + 1, &(op1.exp)); + end = parse_exp (l1 + 1, &(op1.exp)); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); + break; + } if (op1.exp.X_op == O_constant) { @@ -3352,7 +3388,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) /* The RPT instruction only accepted immediates and registers. */ if (*l1 == '#') { - parse_exp (l1 + 1, &(op1.exp)); + end = parse_exp (l1 + 1, &(op1.exp)); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); + break; + } if (op1.exp.X_op != O_constant) { as_bad (_("expected constant value as argument to RPT")); @@ -3720,7 +3761,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) if (*m == '$') m++; - parse_exp (m, &exp); + end = parse_exp (m, &exp); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); + break; + } /* In order to handle something like: @@ -3814,7 +3860,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) if (*m == '#' || *m == '$') m++; - parse_exp (m, & exp); + end = parse_exp (m, & exp); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); + break; + } if (exp.X_op == O_symbol) { /* Relaxation required. */ @@ -3860,7 +3911,12 @@ msp430_operands (struct msp430_opcode_s * opcode, char * line) if (*m == '#' || *m == '$') m++; - parse_exp (m, & exp); + end = parse_exp (m, & exp); + if (end != NULL && *end != 0) + { + as_bad (_("extra characters '%s' at end of operand '%s'"), end, l1); + break; + } if (exp.X_op == O_symbol) { /* Relaxation required. */ diff --git a/gas/testsuite/gas/msp430/msp430.exp b/gas/testsuite/gas/msp430/msp430.exp index 0dfb2711080..bf6c83dc005 100644 --- a/gas/testsuite/gas/msp430/msp430.exp +++ b/gas/testsuite/gas/msp430/msp430.exp @@ -26,4 +26,5 @@ if [expr [istarget "msp430-*-*"]] then { run_dump_test "errata_fixes" run_dump_test "high-data-bss-sym" { { as "-mdata-region=upper" } } run_dump_test "high-data-bss-sym" { { as "-mdata-region=either" } } + run_dump_test "pr22133" } diff --git a/gas/testsuite/gas/msp430/pr22133.d b/gas/testsuite/gas/msp430/pr22133.d new file mode 100644 index 00000000000..c8a4b394128 --- /dev/null +++ b/gas/testsuite/gas/msp430/pr22133.d @@ -0,0 +1,4 @@ +#name: Extraneous extra text at the end of operands +#source: pr22133.s +#as: +#error-output: pr22133.l diff --git a/gas/testsuite/gas/msp430/pr22133.l b/gas/testsuite/gas/msp430/pr22133.l new file mode 100644 index 00000000000..dce5121c1bd --- /dev/null +++ b/gas/testsuite/gas/msp430/pr22133.l @@ -0,0 +1,4 @@ +[^:]*: Assembler messages: +[^:]*:5: Error: extra characters '\(R13\)' at the end of absolute operand '&SRC\(R13\)' +[^:]*:5: Error: extra characters '\(R13\)' at the end of absolute operand '&DST\(R13\)' + diff --git a/gas/testsuite/gas/msp430/pr22133.s b/gas/testsuite/gas/msp430/pr22133.s new file mode 100644 index 00000000000..45ee8674f0a --- /dev/null +++ b/gas/testsuite/gas/msp430/pr22133.s @@ -0,0 +1,9 @@ + +.equiv SRC, 1800h +.equiv DST, 1880h + + mov &SRC(R13), &DST(R13) +# mov &SRC, &DST +# mov &1800h(R13), &DST(R13) +# mov &1800h(R13), &1800h(R13) +