diff options
author | Nick Clifton <nickc@redhat.com> | 2017-10-05 16:17:22 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2017-10-05 16:17:22 +0100 |
commit | 2bfa0cdfadd313f3cc35329a17ba3c62865208a3 (patch) | |
tree | d6fc935991b31ebd04dc78a00fc44b870d681d69 /gas | |
parent | 97953bab05cca82bd3119de4d5cf26103b649597 (diff) | |
download | fsf-binutils-gdb-2bfa0cdfadd313f3cc35329a17ba3c62865208a3.zip fsf-binutils-gdb-2bfa0cdfadd313f3cc35329a17ba3c62865208a3.tar.gz fsf-binutils-gdb-2bfa0cdfadd313f3cc35329a17ba3c62865208a3.tar.bz2 |
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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 13 | ||||
-rw-r--r-- | gas/config/tc-msp430.c | 110 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/msp430.exp | 1 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/pr22133.d | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/pr22133.l | 4 | ||||
-rw-r--r-- | gas/testsuite/gas/msp430/pr22133.s | 9 |
6 files changed, 114 insertions, 27 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index df8edc1..ed40a79 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2017-10-05 Nick Clifton <nickc@redhat.com> + + 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 <hongjiu.lu@intel.com> PR gas/21167 diff --git a/gas/config/tc-msp430.c b/gas/config/tc-msp430.c index 62a34ed..6f3acdf 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 0dfb271..bf6c83d 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 0000000..c8a4b39 --- /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 0000000..dce5121 --- /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 0000000..45ee867 --- /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) + |