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: Another x86_64 disassembler crash


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


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