This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Fix the MSP430 assembler so that it detects and reports extraneous text at the end of operands.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2bfa0cdfadd313f3cc35329a17ba3c62865208a3

commit 2bfa0cdfadd313f3cc35329a17ba3c62865208a3
Author: Nick Clifton <nickc@redhat.com>
Date:   Thu Oct 5 16:17:22 2017 +0100

    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:
---
 gas/ChangeLog                       |  13 +++++
 gas/config/tc-msp430.c              | 110 +++++++++++++++++++++++++++---------
 gas/testsuite/gas/msp430/msp430.exp |   1 +
 gas/testsuite/gas/msp430/pr22133.d  |   4 ++
 gas/testsuite/gas/msp430/pr22133.l  |   4 ++
 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)
+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]