[Top][All Lists]
[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);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- bug in binutils/opcodes/i386-dis.c,
James L Peterson <=