bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug in binutils/opcodes/i386-dis.c


From: James L Peterson
Subject: bug in binutils/opcodes/i386-dis.c
Date: Wed, 31 Oct 2001 10:12:06 -0600

Working on a Red-Hat Linux system, using binutils directly from
the binutils sources in address@hidden:/cvs/src
cross-compiled for the x86-64 platform (but still running on my
32-bit Linux), I am having the following problem:

Objdump does not find symbols well.

In debugging our code, we are often stepping thru
the code one instruction at a time.  We find that
running "objdump -x -r -d" on our code helps us
to see where we are and what is coming up.  Also
the addresses given by objdump match the addresses
in memory, so it is fairly easy to match with the
source code.

One difficulty is that objdump does not seem to
resolve all addresses back to symbols very well.
Most addresses come back as <GdtEnd+0x...>.  In
fact, we get 45,793 symbols of this form.


    7000001060d7: e8 10 33 0a 00        callq  1a93ec <GdtEnd+0xa3364>
    7000001060dc: 4c 8b 30              mov    (%rax),%r14
    7000001060df: 49 8b 1e              mov    (%r14),%rbx
    7000001060e2: 48 81 c3 00 01 00 00  add    $0x100,%rbx
    7000001060e9: 4c 8b 65 d0           mov
0xffffffffffffffd0(%rbp),%r12
    7000001060ed: 4c 8b 7d d8           mov
0xffffffffffffffd8(%rbp),%r15
    7000001060f1: e8 22 00 00 00        callq  106118 <GdtEnd+0x90>
    7000001060f6: 48 89 c6              mov    %rax,%rsi


I tracked the problem down to find_symbol_for_address
(in objdump.c). It is being passed a vma which
is only 32-bits.

Following that back, we eventually get to the value being stored
in set_op (in binutils/opcodes/i386-dis.c) is only 32 bits, and
that comes from the call to set_op in OP_J which is computed as

disp = (start_pc + codep - start_codep + disp) & mask;

Now disp, start_pc, and mask are all bfd_vma types
(which are 64-bit long long's), but codep and start_codep
are "char *" pointers.  Looking at the assembly code that
is generated, we see that only 32-bit arithmetic is
used to compute the value start_pc+codep-start_codep
and then 64-bit arithmetic is used for disp and mask.


 806a049: a1 e4 94 0e 08        mov    0x80e94e4,%eax -- start_pc
 806a04e: 03 05 0c 93 0e 08     add    0x80e930c,%eax -- codep
 806a054: 2b 05 04 93 0e 08     sub    0x80e9304,%eax -- start_codep
 806a05a: 99                    cltd
 806a05b: 01 c3                 add    %eax,%ebx      -- disp
 806a05d: 11 d6                 adc    %edx,%esi
 806a05f: 23 5d f8              and    0xfffffff8(%ebp),%ebx -- & mask
 806a062: 23 75 fc              and    0xfffffffc(%ebp),%esi


If we precompute codep-start_codep and convert it to a bfd_vma,
then 64-bit arithmetic will be used for all of the parts that
need 64-bits.

  {
    bfd_vma off;
    off = codep - start_codep;
    disp = (start_pc + off + disp) & mask;
  }

This then produces much more useful output:

    7000001060d7: e8 10 33 0a 00        callq  7000001a93ec
<COSMgr::TheTypeMgrRef()>
    7000001060dc: 4c 8b 30              mov    (%rax),%r14
    7000001060df: 49 8b 1e              mov    (%r14),%rbx
    7000001060e2: 48 81 c3 00 01 00 00  add    $0x100,%rbx
    7000001060e9: 4c 8b 65 d0           mov
0xffffffffffffffd0(%rbp),%r12
    7000001060ed: 4c 8b 7d d8           mov
0xffffffffffffffd8(%rbp),%r15
    7000001060f1: e8 22 00 00 00        callq  700000106118
<StubAsyncTester::typeID()>
    7000001060f6: 48 89 c6              mov    %rax,%rsi



The diffs:

--- tc5/binutils/opcodes/i386-dis.c     Mon Sep  3 20:58:07 2001
+++ tc6/binutils/opcodes/i386-dis.c     Wed Oct 31 10:09:01 2001
@@ -3608,7 +3608,12 @@
       oappend (INTERNAL_DISASSEMBLER_ERROR);
       return;
     }
-  disp = (start_pc + codep - start_codep + disp) & mask;
+
+  { /* be sure that all arithmetic is in bfd_vma units (could be
64-bit) */
+    bfd_vma off;
+    off = codep - start_codep;
+    disp = (start_pc + off + disp) & mask;
+  }
   set_op (disp, 0);
   print_operand_value (scratchbuf, 1, disp);
   oappend (scratchbuf);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]