This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
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, ®, 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, ®, 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, ®, 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