Bug 10636 - x86-64 assembler misassemble 32bit absolute address
Summary: x86-64 assembler misassemble 32bit absolute address
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.21
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-09-12 22:55 IST by H.J. Lu
Modified: 2009-10-16 21:41 IST (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2009-09-12 22:55:57 IST
[hjl@gnu-6 lrb]$ cat s.s
        mov 0xFEE000F0,%eax
        mov 0xFEE000F0,%ebx
[hjl@gnu-6 lrb]$ gcc -c s.s
[hjl@gnu-6 lrb]$ objdump -dw s.o

s.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:   8b 04 25 f0 00 e0 fe    mov    0xfffffffffee000f0,%eax
   7:   8b 1c 25 f0 00 e0 fe    mov    0xfffffffffee000f0,%ebx
[hjl@gnu-6 lrb]$

Since the displacement is signed extended to 64bit, we need to
handle it properly.
Comment 1 cvs-commit@gcc.gnu.org 2009-09-14 13:58:01 IST
Subject: Bug 10636

CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl@sourceware.org	2009-09-14 13:57:45

Modified files:
	gas            : ChangeLog 
	gas/config     : tc-i386.c 
	gas/testsuite  : ChangeLog 
	gas/testsuite/gas/i386: i386.exp x86-64-addr32-intel.d 
	                        x86-64-addr32.d x86-64-addr32.s 
	                        x86-64-inval.l x86-64-inval.s 
	                        x86-64-prescott.d x86-64-prescott.s 
Added files:
	gas/testsuite/gas/i386: disp.d disp.s x86-64-disp.d 
	                        x86-64-disp.s 

Log message:
	gas/
	
	2009-09-14  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR gas/10636
	* config/tc-i386.c (optimize_disp): Set disp32 for 64bit only
	if there is an ADDR_PREFIX.
	(i386_finalize_displacement): Repor error if signed 32bit
	displacement is out of range.
	
	gas/testsuite/
	
	2009-09-14  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR gas/10636
	* gas/i386/disp.d: New.
	* gas/i386/disp.s: Likewise.
	* gas/i386/x86-64-disp.d: Likewise.
	* gas/i386/x86-64-disp.s: Likewise.
	
	* gas/i386/i386.exp: Run disp and x86-64-disp.
	
	* gas/i386/x86-64-addr32.s: Add high 32bit displacement tests.
	
	* gas/i386/x86-64-addr32.d: Updated.
	* gas/i386/x86-64-addr32-intel.d: Likewise.
	* gas/i386/x86-64-inval.l: Likewise.
	* gas/i386/x86-64-prescott.d: Likewise.
	
	* gas/i386/x86-64-inval.s: Add invalid displacement tests.
	
	* gas/i386/x86-64-prescott.s: Replace 0x90909090 displacement
	with 0x909090.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/ChangeLog.diff?cvsroot=src&r1=1.3952&r2=1.3953
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/config/tc-i386.c.diff?cvsroot=src&r1=1.393&r2=1.394
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1545&r2=1.1546
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/disp.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/disp.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-disp.d.diff?cvsroot=src&r1=NONE&r2=1.1
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-disp.s.diff?cvsroot=src&r1=NONE&r2=1.1
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/i386.exp.diff?cvsroot=src&r1=1.117&r2=1.118
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-addr32-intel.d.diff?cvsroot=src&r1=1.1&r2=1.2
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-addr32.d.diff?cvsroot=src&r1=1.5&r2=1.6
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-addr32.s.diff?cvsroot=src&r1=1.3&r2=1.4
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-inval.l.diff?cvsroot=src&r1=1.13&r2=1.14
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-inval.s.diff?cvsroot=src&r1=1.12&r2=1.13
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-prescott.d.diff?cvsroot=src&r1=1.3&r2=1.4
http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gas/testsuite/gas/i386/x86-64-prescott.s.diff?cvsroot=src&r1=1.2&r2=1.3

Comment 2 H.J. Lu 2009-09-14 22:06:35 IST
Fixed.
Comment 3 Mike Frysinger 2009-10-16 06:45:20 IST
so i guess it's expected that openssl will no longer assemble with this change ?

make[3]: Entering directory
`/var/tmp/portage/dev-libs/openssl-0.9.8k-r1/work/openssl-0.9.8k/crypto/md5'
x86_64-pc-linux-gnu-gcc -I.. -I../.. -I../../include -fPIC -DOPENSSL_PIC -DZLIB
-DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO
 -Wall -DMD32_REG_T=int -DOPENSSL_BN_ASM_MONT -DSHA1_ASM -DSHA256_ASM
-DSHA512_ASM -DMD5_ASM -DAES_ASM -O2 -march=k8 -pipe -g
-Wimplicit-function-declaration
 -Wa,--noexecstack -c  -o md5-x86_64.o md5-x86_64.s
md5-x86_64.s: Assembler messages:
md5-x86_64.s:41: Error: 0xd76aa478 out range of signed 32bit displacement
md5-x86_64.s:50: Error: 0xe8c7b756 out range of signed 32bit displacement
md5-x86_64.s:68: Error: 0xc1bdceee out range of signed 32bit displacement
md5-x86_64.s:77: Error: 0xf57c0faf out range of signed 32bit displacement
.....

41:    leal    3614090360(%rax,%r10,1),%eax
50:    leal    3905402710(%rdx,%r10,1),%edx
68:    leal    3250441966(%rbx,%r10,1),%ebx
77:    leal    4118548399(%rax,%r10,1),%eax
Comment 4 H.J. Lu 2009-10-16 13:35:50 IST
(In reply to comment #3)
> so i guess it's expected that openssl will no longer assemble with this change ?
> 
> 41:    leal    3614090360(%rax,%r10,1),%eax
> 50:    leal    3905402710(%rdx,%r10,1),%edx
> 68:    leal    3250441966(%rbx,%r10,1),%ebx
> 77:    leal    4118548399(%rax,%r10,1),%eax

These displacements can't be encoded with signed 32bit integers.
Comment 5 Mike Frysinger 2009-10-16 15:11:05 IST
thanks, just wanted to make sure the issue was with the assembly code

i'm not terribly great with x86 assembly.  could you suggest a fix ?  every
statement that is failing (44 of them) are exactly the same form but a different
constant.
Comment 6 H.J. Lu 2009-10-16 15:36:55 IST
(In reply to comment #5)
> thanks, just wanted to make sure the issue was with the assembly code
> 
> i'm not terribly great with x86 assembly.  could you suggest a fix ?  every
> statement that is failing (44 of them) are exactly the same form but a different
> constant.

First verify if they really should be negative values. If yes, change
them to negative values. If no, rewrite them.
Comment 7 Mike Frysinger 2009-10-16 16:19:12 IST
i'm pretty sure they should all be unsigned
Comment 8 H.J. Lu 2009-10-16 16:39:16 IST
(In reply to comment #7)
> i'm pretty sure they should all be unsigned

How does code work since hardware treats them as signed for calculation?
Comment 9 Mike Frysinger 2009-10-16 21:41:18 IST
i have no idea.  i'm not an openssl expert let alone x86 assembly.  guess i'll
just file a bug report upstream and let them handle it.