This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Another x86_64 disassembler crash
- From: "Jan Beulich" <JBeulich at novell dot com>
- To: "Daniel Jacobowitz" <drow at false dot org>,<binutils at sourceware dot org>
- Cc: <rcudavalli at mvista dot com>
- Date: Wed, 07 Dec 2005 09:55:18 +0100
- Subject: Re: Another x86_64 disassembler crash
- References: <20051206204522.GA9816@nevyn.them.org>
I would think that instead dofloat() should take care to set op_ad
correctly (just copying the respective initialization from
print_insn()); adding the check you suggest to set_op() would, as far as
I can tell, force the calling of the address resolution function for the
operand (rather than in order to attach a comment after all operands)
despite the addressing being rip-relative (after all, the test case
isn't invalid, despite not representing a sensible instruction stream,
which isn't presently getting tested for at all - there are almost no
tests for disassembling floating point stuff in gas/testsuite/gas/i386/
).
Jan
>>> Daniel Jacobowitz <drow@false.org> 06.12.05 21:45:22 >>>
I don't think I know enough about x86 disassembly to fix this, so if
anyone
could lend a hand...
Here's another invalid testcase (taken from a Linux kernel's .data
section)
which causes the x86_64 disassembler to crash. Only if you use a
cross
disassembler from a 32-bit host though - otherwise the invalid memory
reference goes undetected.
Here's what a 64-bit disassembler has to say with -D:
0000000000000000 <_binary_t1_o_start>:
0: 1d c8 0c 06 90 sbb $0x90060cc8,%eax
5: c8 0c 82 9c enterq $0x820c,$0x9c
9: dc 1d 0c 0a 85 0d fcompl 226822668(%rip)
f: 01 20 add %esp,(%rax)
A 32-bit disassembler crashes on fcompl. The problem is that op_ad ==
-1,
when we get to dofloat. dofloat calls OP_E. OP_E calls set_op, here:
if (!intel_syntax)
if (mod != 0 || (base & 7) == 5)
{
print_operand_value (scratchbuf, !riprel, disp);
oappend (scratchbuf);
if (riprel)
{
set_op (disp, 1);
oappend ("(%rip)");
}
}
And set_op stores to op_index[-1]. I think band-aiding the
disassembler to
return from set_op early if op_ad == -1 would be a safe fix, but I
can't for
the life of me work out what _ought_ to happen here.
--
Daniel Jacobowitz
CodeSourcery, LLC