This is the mail archive of the binutils@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]

[committed] Fix extraction of SOP, SFU and COPR identifiers


This patch fixes a compile error that occurs of an inadvertent symbol
injection when a register follows an absolute identifier.  For example,
the string "4 %r5" would cause the symbol r5 to be added to the symbol
table in cases where %r5 is in fact a register.

I added a new function pa_get_number to handle the instruction cases where the
above problem occurs.  This allowed the hack in pa_get_absolute_expression
to be removed.

Tested on hppa2.0w-hp-hpux11.11 and committed to trunk.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2012-10-14  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	* config/tc-hppa.c (pa_get_number): New.
	(pa_get_absolute_expression): Simplify.
	(pa_ip): Use pa_get_number instead of pa_get_absolute_expression
	to get SOP, SFU and COPR identifiers.

Index: config/tc-hppa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-hppa.c,v
retrieving revision 1.154
diff -u -3 -p -r1.154 tc-hppa.c
--- config/tc-hppa.c	14 Oct 2012 23:27:38 -0000	1.154
+++ config/tc-hppa.c	14 Oct 2012 23:46:36 -0000
@@ -2552,50 +2552,54 @@ pa_get_absolute_expression (struct pa_it
   save_in = input_line_pointer;
   input_line_pointer = *strp;
   expression (&insn->exp);
-  /* This is not perfect, but is a huge improvement over doing nothing.
+  expr_end = input_line_pointer;
+  input_line_pointer = save_in;
+  if (insn->exp.X_op != O_constant)
+    {
+      /* We have a non-match in strict mode.  */
+      if (!strict)
+	as_bad (_("Bad segment (should be absolute)."));
+      return 0;
+    }
+  return evaluate_absolute (insn);
+}
 
-     The PA assembly syntax is ambiguous in a variety of ways.  Consider
-     this string "4 %r5"  Is that the number 4 followed by the register
-     r5, or is that 4 MOD r5?
+/* Get an absolute number.  The input string is terminated at the
+   first whitespace character.  */
 
-     If we get a modulo expression when looking for an absolute, we try
-     again cutting off the input string at the first whitespace character.  */
-  if (insn->exp.X_op == O_modulus)
-    {
-      char *s, c;
+static int
+pa_get_number (struct pa_it *insn, char **strp)
+{
+  char *save_in;
+  char *s, c;
+  int result;
 
-      input_line_pointer = *strp;
-      s = *strp;
-      while (*s != ',' && *s != ' ' && *s != '\t')
-	s++;
+  save_in = input_line_pointer;
+  input_line_pointer = *strp;
 
-      c = *s;
-      *s = 0;
+  /* The PA assembly syntax is ambiguous in a variety of ways.  Consider
+     this string "4 %r5"  Is that the number 4 followed by the register
+     r5, or is that 4 MOD r5?  This situation occurs for example in the
+     coprocessor load and store instructions.  Previously, calling
+     pa_get_absolute_expression directly results in r5 being entered
+     in the symbol table.
+
+     So, when looking for an absolute number, we cut off the input string
+     at the first whitespace character.  Thus, expressions should generally
+     contain no whitespace.  */
+
+  s = *strp;
+  while (*s != ',' && *s != ' ' && *s != '\t')
+    s++;
 
-      pa_get_absolute_expression (insn, strp);
+  c = *s;
+  *s = 0;
+
+  result = pa_get_absolute_expression (insn, strp);
 
-      input_line_pointer = save_in;
-      *s = c;
-      return evaluate_absolute (insn);
-    }
-  /* When in strict mode we have a non-match, fix up the pointers
-     and return to our caller.  */
-  if (insn->exp.X_op != O_constant && strict)
-    {
-      expr_end = input_line_pointer;
-      input_line_pointer = save_in;
-      return 0;
-    }
-  if (insn->exp.X_op != O_constant)
-    {
-      as_bad (_("Bad segment (should be absolute)."));
-      expr_end = input_line_pointer;
-      input_line_pointer = save_in;
-      return 0;
-    }
-  expr_end = input_line_pointer;
   input_line_pointer = save_in;
-  return evaluate_absolute (insn);
+  *s = c;
+  return result;
 }
 
 /* Given an argument location specification return the associated
@@ -5292,7 +5296,7 @@ pa_ip (char *str)
 	    case 'v':
 	      if (*s++ != ',')
 		as_bad (_("Invalid SFU identifier"));
-	      num = pa_get_absolute_expression (&the_insn, &s);
+	      num = pa_get_number (&the_insn, &s);
 	      if (strict && the_insn.exp.X_op != O_constant)
 		break;
 	      s = expr_end;
@@ -5301,7 +5305,7 @@ pa_ip (char *str)
 
 	    /* Handle a 20 bit SOP field for spop0.  */
 	    case 'O':
-	      num = pa_get_absolute_expression (&the_insn, &s);
+	      num = pa_get_number (&the_insn, &s);
 	      if (strict && the_insn.exp.X_op != O_constant)
 		break;
 	      s = expr_end;
@@ -5311,7 +5315,7 @@ pa_ip (char *str)
 
 	    /* Handle a 15bit SOP field for spop1.  */
 	    case 'o':
-	      num = pa_get_absolute_expression (&the_insn, &s);
+	      num = pa_get_number (&the_insn, &s);
 	      if (strict && the_insn.exp.X_op != O_constant)
 		break;
 	      s = expr_end;
@@ -5320,7 +5324,7 @@ pa_ip (char *str)
 
 	    /* Handle a 10bit SOP field for spop3.  */
 	    case '0':
-	      num = pa_get_absolute_expression (&the_insn, &s);
+	      num = pa_get_number (&the_insn, &s);
 	      if (strict && the_insn.exp.X_op != O_constant)
 		break;
 	      s = expr_end;
@@ -5330,7 +5334,7 @@ pa_ip (char *str)
 
 	    /* Handle a 15 bit SOP field for spop2.  */
 	    case '1':
-	      num = pa_get_absolute_expression (&the_insn, &s);
+	      num = pa_get_number (&the_insn, &s);
 	      if (strict && the_insn.exp.X_op != O_constant)
 		break;
 	      s = expr_end;
@@ -5342,7 +5346,7 @@ pa_ip (char *str)
 	    case 'u':
 	      if (*s++ != ',')
 		as_bad (_("Invalid COPR identifier"));
-	      num = pa_get_absolute_expression (&the_insn, &s);
+	      num = pa_get_number (&the_insn, &s);
 	      if (strict && the_insn.exp.X_op != O_constant)
 		break;
 	      s = expr_end;
@@ -5351,7 +5355,7 @@ pa_ip (char *str)
 
 	    /* Handle a 22bit SOP field for copr.  */
 	    case '2':
-	      num = pa_get_absolute_expression (&the_insn, &s);
+	      num = pa_get_number (&the_insn, &s);
 	      if (strict && the_insn.exp.X_op != O_constant)
 		break;
 	      s = expr_end;


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