This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] BROKEN expression evaluation
- To: binutils at sources dot redhat dot com
- Subject: [patch] BROKEN expression evaluation
- From: Mikulas Patocka <mikulas at artax dot karlin dot mff dot cuni dot cz>
- Date: Mon, 12 Feb 2001 23:48:06 +0100 (CET)
- Reply-To: Mikulas Patocka <mikulas at artax dot karlin dot mff dot cuni dot cz>
Hi
Expression evaluation in gas is broken:
$ as
movl $0x10 >> 2 << 3, %eax
$ objdump --disassemble
a.out: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: b8 00 00 00 00 mov $0x0,%eax
$ as
movl $0x10 << 3 >> 2, %eax
$ objdump --disassemble
a.out: file format elf32-i386
Disassembly of section .text:
00000000 <.text>:
0: b8 ff ff ff ff mov $0xffffffff,%eax
$
The problem is caused by operator() function. If operator has more chars,
operator() exits with pointer pointing to the second char. If expr decides
that the operator has too low precedence, exits with pointer pointing to
the second char and parent expr sees only '<' or '>' instead of '<<' or
'>>'.
This patch should fix the bug, check it and commit it to CVS. I hope it
doesn't break anything else.
BTW. someone should write expression parser testsuite. It seems that gas
has more than enough parsing bugs.
Mikulas
--- gas/expr.c_ Mon Feb 12 22:06:52 2001
+++ gas/expr.c Mon Feb 12 22:51:10 2001
@@ -1654,6 +1654,8 @@
operatorT op_left;
operatorT op_right;
+ char *start_of_op;
+
know (rank >= 0);
retval = operand (resultP);
@@ -1661,6 +1663,7 @@
/* operand () gobbles spaces. */
know (*input_line_pointer != ' ');
+ start_of_op = input_line_pointer;
op_left = operator ();
while (op_left != O_illegal && op_rank[(int) op_left] > rank)
{
@@ -1706,6 +1709,7 @@
)
as_bad (_("operation combines symbols in different segments"));
+ start_of_op = input_line_pointer;
op_right = operator ();
know (op_right == O_illegal
@@ -1871,6 +1875,7 @@
op_left = op_right;
} /* While next operator is >= this rank. */
+ input_line_pointer = start_of_op;
/* The PA port needs this information. */
if (resultP->X_add_symbol)