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]

Re: PATCH: PR gas/10704: as segfault in memory lookup intel syntax


On Tue, Oct 06, 2009 at 08:44:42PM -0700, H.J. Lu wrote:
> On Tue, Oct 6, 2009 at 1:40 AM, Jan Beulich <JBeulich@novell.com> wrote:
> > Basically, all
> > uses outside of parse_operands() appear to need immediate
> > resolution.

I came to the same conclusion.

> This patch fixes the testcase. Does it look OK?

Not without taking care of Jan's comment above.  You will need
something like your patch though.

> +  for (i = 0; i < num_operands; i++)

Fails for IA64_OPND_SOF and IA64_OPND_SOF since operand 0 isn't
yet parsed.

Here's a merge of your patch with what I already had for the other
easy to fix uses of parse_operand.  I stopped when I hit the hard part
that you've tackled..

	* config/tc-is64.c (parse_operand): Use expression rather than
	expression_and_evalute.
	(parse_operand_and_eval): New function.  Replace all uses of
	parse_operand outside of parse_operands with this function.
	(parse_operans_maybe_eval): New function.  Replace uses of
	parse_operand in parse_operands, except for the dummy, with
	this function.

Index: gas/config/tc-ia64.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ia64.c,v
retrieving revision 1.209
diff -u -p -r1.209 tc-ia64.c
--- gas/config/tc-ia64.c	3 Sep 2009 13:20:31 -0000	1.209
+++ gas/config/tc-ia64.c	7 Oct 2009 04:38:05 -0000
@@ -784,7 +784,7 @@ typedef void (*vbyte_func) (int, char *,
 
 /* Forward declarations:  */
 static void dot_alias (int);
-static int parse_operand (expressionS *, int);
+static int parse_operand_and_eval (expressionS *, int);
 static void emit_one_bundle (void);
 static bfd_reloc_code_real_type ia64_gen_real_reloc_type (struct symbol *,
 							  bfd_reloc_code_real_type);
@@ -2891,7 +2891,7 @@ ia64_convert_frag (fragS *frag)
 static int
 parse_predicate_and_operand (expressionS *e, unsigned *qp, const char *po)
 {
-  int sep = parse_operand (e, ',');
+  int sep = parse_operand_and_eval (e, ',');
 
   *qp = e->X_add_number - REG_P;
   if (e->X_op != O_register || *qp > 63)
@@ -2902,7 +2902,7 @@ parse_predicate_and_operand (expressionS
   else if (*qp == 0)
     as_warn (_("Pointless use of p0 as first operand to .%s"), po);
   if (sep == ',')
-    sep = parse_operand (e, ',');
+    sep = parse_operand_and_eval (e, ',');
   else
     e->X_op = O_absent;
   return sep;
@@ -3155,7 +3155,7 @@ dot_fframe (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("fframe"))
     return;
 
-  sep = parse_operand (&e, ',');
+  sep = parse_operand_and_eval (&e, ',');
 
   if (e.X_op != O_constant)
     {
@@ -3175,7 +3175,7 @@ dot_vframe (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("vframe"))
     return;
 
-  sep = parse_operand (&e, ',');
+  sep = parse_operand_and_eval (&e, ',');
   reg = e.X_add_number - REG_GR;
   if (e.X_op != O_register || reg > 127)
     {
@@ -3202,7 +3202,7 @@ dot_vframesp (int psp)
   if (!in_prologue ("vframesp"))
     return;
 
-  sep = parse_operand (&e, ',');
+  sep = parse_operand_and_eval (&e, ',');
   if (e.X_op != O_constant)
     {
       as_bad (_("Operand to .vframesp must be a constant (sp-relative offset)"));
@@ -3222,9 +3222,9 @@ dot_save (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("save"))
     return;
 
-  sep = parse_operand (&e1, ',');
+  sep = parse_operand_and_eval (&e1, ',');
   if (sep == ',')
-    sep = parse_operand (&e2, ',');
+    sep = parse_operand_and_eval (&e2, ',');
   else
     e2.X_op = O_absent;
 
@@ -3311,7 +3311,7 @@ dot_restore (int dummy ATTRIBUTE_UNUSED)
   if (!in_body ("restore"))
     return;
 
-  sep = parse_operand (&e1, ',');
+  sep = parse_operand_and_eval (&e1, ',');
   if (e1.X_op != O_register || e1.X_add_number != REG_GR + 12)
     as_bad (_("First operand to .restore must be stack pointer (sp)"));
 
@@ -3319,7 +3319,7 @@ dot_restore (int dummy ATTRIBUTE_UNUSED)
     {
       expressionS e2;
 
-      sep = parse_operand (&e2, ',');
+      sep = parse_operand_and_eval (&e2, ',');
       if (e2.X_op != O_constant || e2.X_add_number < 0)
 	{
 	  as_bad (_("Second operand to .restore must be a constant >= 0"));
@@ -3360,7 +3360,7 @@ dot_restorereg (int pred)
     sep = parse_predicate_and_operand (&e, &qp, po);
   else
     {
-      sep = parse_operand (&e, ',');
+      sep = parse_operand_and_eval (&e, ',');
       qp = 0;
     }
   convert_expr_to_ab_reg (&e, &ab, &reg, po, 1 + pred);
@@ -3606,7 +3606,7 @@ dot_altrp (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("altrp"))
     return;
 
-  parse_operand (&e, 0);
+  parse_operand_and_eval (&e, 0);
   reg = e.X_add_number - REG_BR;
   if (e.X_op != O_register || reg > 7)
     {
@@ -3627,9 +3627,9 @@ dot_savemem (int psprel)
   if (!in_prologue (po))
     return;
 
-  sep = parse_operand (&e1, ',');
+  sep = parse_operand_and_eval (&e1, ',');
   if (sep == ',')
-    sep = parse_operand (&e2, ',');
+    sep = parse_operand_and_eval (&e2, ',');
   else
     e2.X_op = O_absent;
 
@@ -3727,7 +3727,7 @@ dot_saveg (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("save.g"))
     return;
 
-  sep = parse_operand (&e, ',');
+  sep = parse_operand_and_eval (&e, ',');
 
   grmask = e.X_add_number;
   if (e.X_op != O_constant
@@ -3743,7 +3743,7 @@ dot_saveg (int dummy ATTRIBUTE_UNUSED)
       unsigned reg;
       int n = popcount (grmask);
 
-      parse_operand (&e, 0);
+      parse_operand_and_eval (&e, 0);
       reg = e.X_add_number - REG_GR;
       if (e.X_op != O_register || reg > 127)
 	{
@@ -3769,7 +3769,7 @@ dot_savef (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("save.f"))
     return;
 
-  parse_operand (&e, 0);
+  parse_operand_and_eval (&e, 0);
 
   if (e.X_op != O_constant
       || e.X_add_number <= 0
@@ -3791,7 +3791,7 @@ dot_saveb (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("save.b"))
     return;
 
-  sep = parse_operand (&e, ',');
+  sep = parse_operand_and_eval (&e, ',');
 
   brmask = e.X_add_number;
   if (e.X_op != O_constant
@@ -3807,7 +3807,7 @@ dot_saveb (int dummy ATTRIBUTE_UNUSED)
       unsigned reg;
       int n = popcount (brmask);
 
-      parse_operand (&e, 0);
+      parse_operand_and_eval (&e, 0);
       reg = e.X_add_number - REG_GR;
       if (e.X_op != O_register || reg > 127)
 	{
@@ -3833,8 +3833,8 @@ dot_savegf (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("save.gf"))
     return;
 
-  if (parse_operand (&e1, ',') == ',')
-    parse_operand (&e2, 0);
+  if (parse_operand_and_eval (&e1, ',') == ',')
+    parse_operand_and_eval (&e2, 0);
   else
     e2.X_op = O_absent;
 
@@ -3871,7 +3871,7 @@ dot_spill (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("spill"))
     return;
 
-  parse_operand (&e, 0);
+  parse_operand_and_eval (&e, 0);
 
   if (e.X_op != O_constant)
     {
@@ -3896,13 +3896,13 @@ dot_spillreg (int pred)
     sep = parse_predicate_and_operand (&e, &qp, po);
   else
     {
-      sep = parse_operand (&e, ',');
+      sep = parse_operand_and_eval (&e, ',');
       qp = 0;
     }
   convert_expr_to_ab_reg (&e, &ab, &reg, po, 1 + pred);
 
   if (sep == ',')
-    sep = parse_operand (&e, ',');
+    sep = parse_operand_and_eval (&e, ',');
   else
     e.X_op = O_absent;
   convert_expr_to_xy_reg (&e, &xy, &treg, po, 2 + pred);
@@ -3933,13 +3933,13 @@ dot_spillmem (int psprel)
     sep = parse_predicate_and_operand (&e, &qp, po);
   else
     {
-      sep = parse_operand (&e, ',');
+      sep = parse_operand_and_eval (&e, ',');
       qp = 0;
     }
   convert_expr_to_ab_reg (&e, &ab, &reg, po, 1 + pred);
 
   if (sep == ',')
-    sep = parse_operand (&e, ',');
+    sep = parse_operand_and_eval (&e, ',');
   else
     e.X_op = O_absent;
   if (e.X_op != O_constant)
@@ -4014,7 +4014,7 @@ dot_label_state (int dummy ATTRIBUTE_UNU
   if (!in_body ("label_state"))
     return;
 
-  parse_operand (&e, 0);
+  parse_operand_and_eval (&e, 0);
   if (e.X_op == O_constant)
     save_prologue_count (e.X_add_number, unwind.prologue_count);
   else
@@ -4033,7 +4033,7 @@ dot_copy_state (int dummy ATTRIBUTE_UNUS
   if (!in_body ("copy_state"))
     return;
 
-  parse_operand (&e, 0);
+  parse_operand_and_eval (&e, 0);
   if (e.X_op == O_constant)
     unwind.prologue_count = get_saved_prologue_count (e.X_add_number);
   else
@@ -4053,9 +4053,9 @@ dot_unwabi (int dummy ATTRIBUTE_UNUSED)
   if (!in_prologue ("unwabi"))
     return;
 
-  sep = parse_operand (&e1, ',');
+  sep = parse_operand_and_eval (&e1, ',');
   if (sep == ',')
-    parse_operand (&e2, 0);
+    parse_operand_and_eval (&e2, 0);
   else
     e2.X_op = O_absent;
 
@@ -4198,7 +4198,7 @@ dot_prologue (int dummy ATTRIBUTE_UNUSED
   if (!is_it_end_of_statement ())
     {
       expressionS e;
-      int n, sep = parse_operand (&e, ',');
+      int n, sep = parse_operand_and_eval (&e, ',');
 
       if (e.X_op != O_constant
 	  || e.X_add_number < 0
@@ -4211,7 +4211,7 @@ dot_prologue (int dummy ATTRIBUTE_UNUSED
 	n = popcount (mask);
 
       if (sep == ',')
-	parse_operand (&e, 0);
+	parse_operand_and_eval (&e, 0);
       else
 	e.X_op = O_absent;
       if (e.X_op == O_constant
@@ -4947,7 +4947,7 @@ dot_pred_rel (int type)
       int sep, regno;
       expressionS pr, *pr1, *pr2;
 
-      sep = parse_operand (&pr, ',');
+      sep = parse_operand_and_eval (&pr, ',');
       if (pr.X_op == O_register
 	  && pr.X_add_number >= REG_P
 	  && pr.X_add_number <= REG_P + 63)
@@ -5851,13 +5851,54 @@ parse_operand (expressionS *e, int more)
   memset (e, 0, sizeof (*e));
   e->X_op = O_absent;
   SKIP_WHITESPACE ();
-  expression_and_evaluate (e);
+  expression (e);
   sep = *input_line_pointer;
   if (more && (sep == ',' || sep == more))
     ++input_line_pointer;
   return sep;
 }
 
+static int
+parse_operand_and_eval (expressionS *e, int more)
+{
+  int sep = parse_operand (e, more);
+  resolve_expression (e);
+  return sep;
+}
+
+static int
+parse_operand_maybe_eval (expressionS *e, int more, enum ia64_opnd op)
+{
+  int sep = parse_operand (e, more);
+  switch (op)
+    {
+    case IA64_OPND_IMM1:
+    case IA64_OPND_IMM8:
+    case IA64_OPND_IMM8U4:
+    case IA64_OPND_IMM8M1:
+    case IA64_OPND_IMM8M1U4:
+    case IA64_OPND_IMM8M1U8:
+    case IA64_OPND_IMM9a:
+    case IA64_OPND_IMM9b:
+    case IA64_OPND_IMM14:
+    case IA64_OPND_IMM22:
+    case IA64_OPND_IMMU62:
+    case IA64_OPND_IMMU64:
+    case IA64_OPND_TGT25:
+    case IA64_OPND_TGT25b:
+    case IA64_OPND_TGT25c:
+    case IA64_OPND_TGT64:
+    case IA64_OPND_TAG13:
+    case IA64_OPND_TAG13b:
+    case IA64_OPND_LDXMOV:
+      break;
+    default:
+      resolve_expression (e);
+      break;
+    }
+  return sep;
+}
+
 /* Returns the next entry in the opcode table that matches the one in
    IDESC, and frees the entry in IDESC.  If no matching entry is
    found, NULL is returned instead.  */
@@ -5912,7 +5953,8 @@ parse_operands (struct ia64_opcode *ides
     {
       if (i < NELEMS (CURR_SLOT.opnd)) 
 	{
-	  sep = parse_operand (CURR_SLOT.opnd + i, '=');
+	  sep = parse_operand_maybe_eval (CURR_SLOT.opnd + i, '=',
+					  idesc->operands[i]);
 	  if (CURR_SLOT.opnd[i].X_op == O_absent)
 	    break;
 	}
@@ -5966,7 +6008,8 @@ parse_operands (struct ia64_opcode *ides
       /* now we can parse the first arg:  */
       saved_input_pointer = input_line_pointer;
       input_line_pointer = first_arg;
-      sep = parse_operand (CURR_SLOT.opnd + 0, '=');
+      sep = parse_operand_maybe_eval (CURR_SLOT.opnd + 0, '=',
+				      idesc->operands[0]);
       if (sep != '=')
 	--num_outputs;	/* force error */
       input_line_pointer = saved_input_pointer;


-- 
Alan Modra
Australia Development Lab, IBM


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