This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
PATCH: Fix i386 disassembler with index == 0x4 in SIB (Re: objdump bug-report)
- From: "H. J. Lu" <hjl at lucon dot org>
- To: "Allan B. Cruse" <cruse at cs dot usfca dot edu>
- Cc: binutils at sources dot redhat dot com
- Date: Wed, 12 Jan 2005 11:10:52 -0800
- Subject: PATCH: Fix i386 disassembler with index == 0x4 in SIB (Re: objdump bug-report)
- References: <20050111210753.0C8CB219E0@nexus.cs.usfca.edu>
On Tue, Jan 11, 2005 at 01:07:53PM -0800, Allan B. Cruse wrote:
>
> //----------------------------------------------------------------
> // needsfix.s
> //
> // This program is erroneously disassembled by the 'objdump'
> // utility (version 2.15.92.0.2, dated 20040927) distributed
> // in Fedora Core 3 from Redhat. The mistake was discovered
> // by single-stepping through this code using an interactive
> // debugger and observing the effects on EAX register-value.
> // All four machine-instructions coded in hexadecimal behave
> // identically on my Pentium-III and Pentium-4 computers.
> //
> // (Assemblers would not ordinarily generate the three forms
> // of this instruction which get erroneously disassembled by
> // 'objdump', and Intel's documentation is very confusing as
> // to how the SIB-byte's 'shift' field affects these cases.)
> //
> // assemble using: $ as needfix.s -o needfix.o
> // then link with: $ ld needfix.o -o needfix
> //
> // programmer: ALLAN CRUSE
> // written on: 11 JAN 2005
> //----------------------------------------------------------------
>
> .data
> num1: .long 0x12345678
>
> .text
> _start: leal num1, %ebx
>
> # experiment #1 (correctly disassembled)
> xor %eax, %eax
> .byte 0x8B, 0x04, 0x23 # effect is: movl (%ebx), %eax
>
> # experiment #2 (incorectly disassembled)
> xor %eax, %eax
> .byte 0x8B, 0x04, 0x63 # effect is: movl (%ebx), %eax
>
> # experiment #3 (incorectly disassembled)
> xor %eax, %eax
> .byte 0x8B, 0x04, 0xA3 # effect is: movl (%ebx), %eax
>
> # experiment #4 (incorectly disassembled)
> xor %eax, %eax
> .byte 0x8B, 0x04, 0xE3 # effect is: movl (%ebx), %eax
>
> # exit()
> movl $1, %eax
> int $0x80
>
> .global _start
> .end
>
>
> #----- Output from: objdump -d needsfix
> #
> needsfix: file format elf32-i386
>
> Disassembly of section .text:
>
> 08048074 <_start>:
> 8048074: 8d 1d 98 90 04 08 lea 0x8049098,%ebx
> 804807a: 31 c0 xor %eax,%eax
> 804807c: 8b 04 23 mov (%ebx),%eax
> 804807f: 31 c0 xor %eax,%eax
> 8048081: 8b 04 63 mov (%ebx,2),%eax
> 8048084: 31 c0 xor %eax,%eax
> 8048086: 8b 04 a3 mov (%ebx,4),%eax
> 8048089: 31 c0 xor %eax,%eax
> 804808b: 8b 04 e3 mov (%ebx,8),%eax
> 804808e: b8 01 00 00 00 mov $0x1,%eax
> 8048093: cd 80 int $0x80
>
>
>
> #----- Output from: elfunasm needsfix
> #
> File 'fixsegs': executable file Intel-386
>
> Disassembly of section .text
>
> <_start>:
> CS:08048074 8D1D98900408 lea 0x08049098, %ebx
> CS:0804807A 31C0 xor %eax, %eax
> CS:0804807C 8B0423 mov (%ebx), %eax
> CS:0804807F 31C0 xor %eax, %eax
> CS:08048081 8B0463 mov (%ebx), %eax
> CS:08048084 31C0 xor %eax, %eax
> CS:08048086 8B04A3 mov (%ebx), %eax
> CS:08048089 31C0 xor %eax, %eax
> CS:0804808B 8B04E3 mov (%ebx), %eax
> CS:0804808E B801000000 mov $0x00000001, %eax
> CS:08048093 CD80 int $0x80
>
Thanks for your bug report. I will check in this patch to fix it.
H.J.
----
gas/testsuite/
2005-01-12 H.J. Lu <hongjiu.lu@intel.com>
* i386/i386.exp: Run "sib".
* gas/i386/sib.d: New file.
* gas/i386/sib.s: Likewise.
opcodes/
2005-01-12 H.J. Lu <hongjiu.lu@intel.com>
* i386-dis.c (OP_E): Ignore scale when index == 0x4 in SIB.
--- binutils/gas/testsuite/gas/i386/i386.exp.sib 2004-11-04 09:34:52.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/i386.exp 2005-01-12 10:56:17.244574211 -0800
@@ -57,6 +57,7 @@ if [expr ([istarget "i*86-*-*"] || [ist
run_dump_test "sse2"
run_dump_test "sub"
run_dump_test "prescott"
+ run_dump_test "sib"
if {![istarget "*-*-aix*"]
&& (![is_elf_format] || [istarget "*-*-linux*"]
--- binutils/gas/testsuite/gas/i386/sib.d.sib 2005-01-12 10:54:16.743398658 -0800
+++ binutils/gas/testsuite/gas/i386/sib.d 2005-01-12 11:04:40.044545548 -0800
@@ -0,0 +1,15 @@
+#objdump: -dw
+#name: i386 SIB
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <foo>:
+ 0: 8b 04 23 [ ]*mov [ ]*\(%ebx\),%eax
+ 3: 8b 04 63 [ ]*mov [ ]*\(%ebx\),%eax
+ 6: 8b 04 a3 [ ]*mov [ ]*\(%ebx\),%eax
+ 9: 8b 04 e3 [ ]*mov [ ]*\(%ebx\),%eax
+ c: 90 [ ]*nop [ ]*
+ d: 90 [ ]*nop [ ]*
+ ...
--- binutils/gas/testsuite/gas/i386/sib.s.sib 2005-01-12 10:54:14.263724294 -0800
+++ binutils/gas/testsuite/gas/i386/sib.s 2005-01-12 11:03:02.479357997 -0800
@@ -0,0 +1,11 @@
+#Test the special case of the index bits, 0x4, in SIB.
+
+ .text
+foo:
+ .byte 0x8B, 0x04, 0x23 # effect is: movl (%ebx), %eax
+ .byte 0x8B, 0x04, 0x63 # effect is: movl (%ebx), %eax
+ .byte 0x8B, 0x04, 0xA3 # effect is: movl (%ebx), %eax
+ .byte 0x8B, 0x04, 0xE3 # effect is: movl (%ebx), %eax
+ nop
+ nop
+ .p2align 4,0
--- binutils/opcodes/i386-dis.c.sib 2004-11-04 09:35:19.000000000 -0800
+++ binutils/opcodes/i386-dis.c 2005-01-12 10:50:01.790879515 -0800
@@ -3191,8 +3191,10 @@ OP_E (int bytemode, int sizeflag)
{
havesib = 1;
FETCH_DATA (the_info, codep + 1);
- scale = (*codep >> 6) & 3;
index = (*codep >> 3) & 7;
+ if (index != 0x4)
+ /* When INDEX == 0x4, scale is ignored. */
+ scale = (*codep >> 6) & 3;
base = *codep & 7;
USED_REX (REX_EXTY);
USED_REX (REX_EXTZ);