x86-64: Zero-extend lower 32 bits displacement to 64 bits

Message ID CAMe9rOoAw7ifX+qjzcTeHHKhTyYkF=f4WxPUJCkZw6M1oowEVg@mail.gmail.com
State New
Headers show
Series
  • x86-64: Zero-extend lower 32 bits displacement to 64 bits
Related show

Commit Message

H.J. Lu via Binutils July 14, 2020, 4:54 p.m.
On Tue, Jul 14, 2020 at 5:55 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>

> On Tue, Jul 14, 2020 at 5:51 AM Jan Beulich <jbeulich@suse.com> wrote:

> >

> > On 14.07.2020 14:43, H.J. Lu wrote:

> > > On Mon, Jul 13, 2020 at 11:12 PM Jan Beulich <jbeulich@suse.com> wrote:

> > >> Nevertheless, I've meanwhile thought of a (contrived) case that was

> > >> broken with the code present:

> > >>

> > >>         addr32 mov $0x89abcdef, %rax

> > >>

> > >> would have got the immediate sign-extended from 32 to 64 bits.

> > >>

> > >

> > > I opened:

> > >

> > > https://sourceware.org/bugzilla/show_bug.cgi?id=26237

> > >

> > > There are multiple issues.

> >

> > Hmm, the former two lines there look correct to me, while the latter

> > two lines look to have been translated with a gas that didn't have

> > yesterday's change yet. IOW - I'm somewhat confused.

>

> The bug is against binutils 2.35, not master.

>


Here is the patch for master branch.  I will backport it to 2.35 branch
together with

https://sourceware.org/pipermail/binutils/2020-July/112356.html


-- 
H.J.

Comments

Jan Beulich July 15, 2020, 6:14 a.m. | #1
On 14.07.2020 18:54, H.J. Lu wrote:
> On Tue, Jul 14, 2020 at 5:55 AM H.J. Lu <hjl.tools@gmail.com> wrote:

>>

>> On Tue, Jul 14, 2020 at 5:51 AM Jan Beulich <jbeulich@suse.com> wrote:

>>>

>>> On 14.07.2020 14:43, H.J. Lu wrote:

>>>> On Mon, Jul 13, 2020 at 11:12 PM Jan Beulich <jbeulich@suse.com> wrote:

>>>>> Nevertheless, I've meanwhile thought of a (contrived) case that was

>>>>> broken with the code present:

>>>>>

>>>>>         addr32 mov $0x89abcdef, %rax

>>>>>

>>>>> would have got the immediate sign-extended from 32 to 64 bits.

>>>>>

>>>>

>>>> I opened:

>>>>

>>>> https://sourceware.org/bugzilla/show_bug.cgi?id=26237

>>>>

>>>> There are multiple issues.

>>>

>>> Hmm, the former two lines there look correct to me, while the latter

>>> two lines look to have been translated with a gas that didn't have

>>> yesterday's change yet. IOW - I'm somewhat confused.

>>

>> The bug is against binutils 2.35, not master.

>>

> 

> Here is the patch for master branch.


Ah, so your issue was just with disassembly. Yet then why not go a step
further and (at least in 64-bit mode) print

[ 	]*[a-f0-9]+:	67 48 89 1c 25 ef cd ab 89 	mov[ ]+%rbx,0x89abcdef
[ 	]*[a-f0-9]+:	67 89 04 25 11 22 33 ff 	mov[ ]+%eax,0xff332211

instead of

[ 	]*[a-f0-9]+:	67 48 89 1c 25 ef cd ab 89 	mov[ ]+%rbx,0x89abcdef\(,%eiz,1\)
[ 	]*[a-f0-9]+:	67 89 04 25 11 22 33 ff 	mov[ ]+%eax,0xff332211\(,%eiz,1\)

and keep the () part only for

[ 	]*[a-f0-9]+:	67 89 04 65 11 22 33 ff 	mov[ ]+%eax,0xff332211\(,%eiz,2\)

, as there's no SIB-less way to express a base-and-index-less address?

Jan

Patch

From 7366f8eedf075444a06bd0ba6c69e0aaf8b1ad23 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Tue, 14 Jul 2020 09:35:24 -0700
Subject: [PATCH] x86-64: Zero-extend lower 32 bits displacement to 64 bits

Since the addr32 (0x67) prefix zero-extends the lower 32 bits address to
64 bits, change disassembler to zero-extend the lower 32 bits displacement
to 64 bits when there is no base nor index registers.

gas/

	PR gas/26237
	* testsuite/gas/i386/addr32.s: Add tests for 32-bit wrapped around
	address.
	* testsuite/gas/i386/x86-64-addr32.s: Likewise.
	* testsuite/gas/i386/addr32.d: Updated.
	* testsuite/gas/i386/x86-64-addr32-intel.d: Likewise.
	* testsuite/gas/i386/x86-64-addr32.d: Likewise.
	* testsuite/gas/i386/ilp32/x86-64-addr32-intel.d: Likewise.
	* testsuite/gas/i386/ilp32/x86-64-addr32.d: Likewise.

opcodes/

	PR gas/26237
	* i386-dis.c (OP_E_memory): Without base nor index registers,
	32-bit displacement to 64 bits.
---
 gas/testsuite/gas/i386/addr32.d               |  6 +++++
 gas/testsuite/gas/i386/addr32.s               |  6 +++++
 .../gas/i386/ilp32/x86-64-addr32-intel.d      | 26 +------------------
 gas/testsuite/gas/i386/ilp32/x86-64-addr32.d  | 26 +------------------
 gas/testsuite/gas/i386/x86-64-addr32-intel.d  | 10 +++++--
 gas/testsuite/gas/i386/x86-64-addr32.d        | 10 +++++--
 gas/testsuite/gas/i386/x86-64-addr32.s        |  6 +++++
 opcodes/i386-dis.c                            |  9 +++++--
 8 files changed, 43 insertions(+), 56 deletions(-)

diff --git a/gas/testsuite/gas/i386/addr32.d b/gas/testsuite/gas/i386/addr32.d
index 8553fc3e0c..a355c30f3f 100644
--- a/gas/testsuite/gas/i386/addr32.d
+++ b/gas/testsuite/gas/i386/addr32.d
@@ -13,4 +13,10 @@  Disassembly of section .text:
 [	 ]*19:[	 ]+67 a3 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+%ax,0x600898
 [	 ]*1f:[	 ]+67 66 a3 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+%eax,0x600898
 [	 ]*26:[	 ]+67 66 c7 04 24 01 00 00 00[	 ]+movl[	 ]+\$0x1,\(%esp\)
+[	 ]*2f:[	 ]+67 66 a1 ef cd ab 89[	 ]+addr32[	 ]+mov[ 	]+0x89abcdef,%eax
+[	 ]*36:[	 ]+67 66 8b 1d ef cd ab 89[	 ]+addr32[	 ]+mov[ 	]+0x89abcdef,%ebx
+[	 ]*3e:[	 ]+67 66 b8 ef cd ab 89[	 ]+addr32[	 ]+mov[ 	]+\$0x89abcdef,%eax
+[	 ]*45:[	 ]+67 66 bb ef cd ab 89[	 ]+addr32[	 ]+mov[ 	]+\$0x89abcdef,%ebx
+[	 ]*4c:[	 ]+67 66 a3 ef cd ab 89[	 ]+addr32[	 ]+mov[ 	]+%eax,0x89abcdef
+[	 ]*53:[	 ]+67 66 89 1d ef cd ab 89[	 ]+addr32[	 ]+mov[ 	]+%ebx,0x89abcdef
 #pass
diff --git a/gas/testsuite/gas/i386/addr32.s b/gas/testsuite/gas/i386/addr32.s
index b899ebd5a3..0f45560602 100644
--- a/gas/testsuite/gas/i386/addr32.s
+++ b/gas/testsuite/gas/i386/addr32.s
@@ -7,3 +7,9 @@ 
 	addr32 mov	%ax,0x600898
 	addr32 mov	%eax,0x600898
 	addr32 movl	$0x1,(%esp)
+	addr32 mov	0x89abcdef,%eax
+	addr32 mov	0x89abcdef,%ebx
+	addr32 mov	$0x89abcdef,%eax
+	addr32 mov	$0x89abcdef,%ebx
+	addr32 mov	%eax,0x89abcdef
+	addr32 mov	%ebx,0x89abcdef
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-addr32-intel.d b/gas/testsuite/gas/i386/ilp32/x86-64-addr32-intel.d
index 86e8cf8039..d6d2e1d8b4 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-addr32-intel.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-addr32-intel.d
@@ -2,28 +2,4 @@ 
 #objdump: -drwMintel
 #source: ../x86-64-addr32.s
 #name: x86-64 (ILP32) 32-bit addressing (Intel mode)
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-0+ <.text>:
-[ 	]*[a-f0-9]+:	67 48 8d 80 00 00 00 00[ 	]+lea[ 	]+rax,\[eax\+0x0\].*
-[ 	]*[a-f0-9]+:	67 49 8d 80 00 00 00 00[ 	]+lea[ 	]+rax,\[r8d\+0x0\].*
-[ 	]*[a-f0-9]+:	67 48 8d 05 00 00 00 00[ 	]+lea[ 	]+rax,\[eip\+0x0\].*
-[ 	]*[a-f0-9]+:	67 48 8d 04 25 00 00 00 00 	lea[ ]+rax,\[eiz\*1\+0x0\].*
-[ 	]*[a-f0-9]+:	67 a0 98 08 60 00    	addr32 mov al,ds:0x600898
-[ 	]*[a-f0-9]+:	67 66 a1 98 08 60 00 	addr32 mov ax,ds:0x600898
-[ 	]*[a-f0-9]+:	67 a1 98 08 60 00    	addr32 mov eax,ds:0x600898
-[ 	]*[a-f0-9]+:	67 48 a1 98 08 60 00 	addr32 mov rax,ds:0x600898
-[ 	]*[a-f0-9]+:	67 48 a1 98 08 80 00 	addr32 mov rax,ds:0x800898
-[ 	]*[a-f0-9]+:	67 48 8b 1c 25 98 08 80 00 	mov[ ]+rbx,QWORD PTR \[eiz\*1\+0x800898\]
-[ 	]*[a-f0-9]+:	67 a2 98 08 60 00    	addr32 mov ds:0x600898,al
-[ 	]*[a-f0-9]+:	67 66 a3 98 08 60 00 	addr32 mov ds:0x600898,ax
-[ 	]*[a-f0-9]+:	67 a3 98 08 60 00    	addr32 mov ds:0x600898,eax
-[ 	]*[a-f0-9]+:	67 48 a3 98 08 60 00 	addr32 mov ds:0x600898,rax
-[ 	]*[a-f0-9]+:	67 48 a3 98 08 80 00 	addr32 mov ds:0x800898,rax
-[ 	]*[a-f0-9]+:	67 48 89 1c 25 98 08 80 00 	mov[ ]+QWORD PTR \[eiz\*1\+0x800898\],rbx
-[ 	]*[a-f0-9]+:	67 89 04 25 11 22 33 ff 	mov[ ]+DWORD PTR \[eiz\*1-0xccddef\],eax
-[ 	]*[a-f0-9]+:	67 89 04 65 11 22 33 ff 	mov[ ]+DWORD PTR \[eiz\*2-0xccddef\],eax
-#pass
+#dump: ../x86-64-addr32-intel.d
diff --git a/gas/testsuite/gas/i386/ilp32/x86-64-addr32.d b/gas/testsuite/gas/i386/ilp32/x86-64-addr32.d
index b866473acc..9c4d3729ce 100644
--- a/gas/testsuite/gas/i386/ilp32/x86-64-addr32.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-addr32.d
@@ -2,28 +2,4 @@ 
 #as: -J
 #objdump: -drw
 #name: x86-64 (ILP32) 32-bit addressing
-
-.*: +file format .*
-
-Disassembly of section .text:
-
-0+ <.text>:
-[ 	]*[a-f0-9]+:	67 48 8d 80 00 00 00 00[ 	]+lea[ 	]+0x0\(%eax\),%rax.*
-[ 	]*[a-f0-9]+:	67 49 8d 80 00 00 00 00[ 	]+lea[ 	]+0x0\(%r8d\),%rax.*
-[ 	]*[a-f0-9]+:	67 48 8d 05 00 00 00 00[ 	]+lea[ 	]+0x0\(%eip\),%rax.*
-[ 	]*[a-f0-9]+:	67 48 8d 04 25 00 00 00 00[ 	]+lea[ 	]+0x0\(,%eiz,1\),%rax.*
-[ 	]*[a-f0-9]+:	67 a0 98 08 60 00    	addr32 mov 0x600898,%al
-[ 	]*[a-f0-9]+:	67 66 a1 98 08 60 00 	addr32 mov 0x600898,%ax
-[ 	]*[a-f0-9]+:	67 a1 98 08 60 00    	addr32 mov 0x600898,%eax
-[ 	]*[a-f0-9]+:	67 48 a1 98 08 60 00 	addr32 mov 0x600898,%rax
-[ 	]*[a-f0-9]+:	67 48 a1 98 08 80 00 	addr32 mov 0x800898,%rax
-[ 	]*[a-f0-9]+:	67 48 8b 1c 25 98 08 80 00 	mov[ ]+0x800898\(,%eiz,1\),%rbx
-[ 	]*[a-f0-9]+:	67 a2 98 08 60 00    	addr32 mov %al,0x600898
-[ 	]*[a-f0-9]+:	67 66 a3 98 08 60 00 	addr32 mov %ax,0x600898
-[ 	]*[a-f0-9]+:	67 a3 98 08 60 00    	addr32 mov %eax,0x600898
-[ 	]*[a-f0-9]+:	67 48 a3 98 08 60 00 	addr32 mov %rax,0x600898
-[ 	]*[a-f0-9]+:	67 48 a3 98 08 80 00 	addr32 mov %rax,0x800898
-[ 	]*[a-f0-9]+:	67 48 89 1c 25 98 08 80 00 	mov[ ]+%rbx,0x800898\(,%eiz,1\)
-[ 	]*[a-f0-9]+:	67 89 04 25 11 22 33 ff 	mov[ ]+%eax,-0xccddef\(,%eiz,1\)
-[ 	]*[a-f0-9]+:	67 89 04 65 11 22 33 ff 	mov[ ]+%eax,-0xccddef\(,%eiz,2\)
-#pass
+#dump: ../x86-64-addr32.d
diff --git a/gas/testsuite/gas/i386/x86-64-addr32-intel.d b/gas/testsuite/gas/i386/x86-64-addr32-intel.d
index ec0966caf4..0988457b34 100644
--- a/gas/testsuite/gas/i386/x86-64-addr32-intel.d
+++ b/gas/testsuite/gas/i386/x86-64-addr32-intel.d
@@ -18,12 +18,18 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	67 48 a1 98 08 60 00 	addr32 mov rax,ds:0x600898
 [ 	]*[a-f0-9]+:	67 48 a1 98 08 80 00 	addr32 mov rax,ds:0x800898
 [ 	]*[a-f0-9]+:	67 48 8b 1c 25 98 08 80 00 	mov[ ]+rbx,QWORD PTR \[eiz\*1\+0x800898\]
+[ 	]*[a-f0-9]+:	67 48 a1 ef cd ab 89 	addr32 mov rax,ds:0x89abcdef
+[ 	]*[a-f0-9]+:	67 48 8b 1c 25 ef cd ab 89 	mov[ ]+rbx,QWORD PTR \[eiz\*1\+0x89abcdef\]
+[ 	]*[a-f0-9]+:	67 48 b8 ef cd ab 89 00 00 00 00 	addr32 movabs rax,0x89abcdef
+[ 	]*[a-f0-9]+:	67 48 bb ef cd ab 89 00 00 00 00 	addr32 movabs rbx,0x89abcdef
 [ 	]*[a-f0-9]+:	67 a2 98 08 60 00    	addr32 mov ds:0x600898,al
 [ 	]*[a-f0-9]+:	67 66 a3 98 08 60 00 	addr32 mov ds:0x600898,ax
 [ 	]*[a-f0-9]+:	67 a3 98 08 60 00    	addr32 mov ds:0x600898,eax
 [ 	]*[a-f0-9]+:	67 48 a3 98 08 60 00 	addr32 mov ds:0x600898,rax
 [ 	]*[a-f0-9]+:	67 48 a3 98 08 80 00 	addr32 mov ds:0x800898,rax
 [ 	]*[a-f0-9]+:	67 48 89 1c 25 98 08 80 00 	mov[ ]+QWORD PTR \[eiz\*1\+0x800898\],rbx
-[ 	]*[a-f0-9]+:	67 89 04 25 11 22 33 ff 	mov[ ]+DWORD PTR \[eiz\*1-0xccddef\],eax
-[ 	]*[a-f0-9]+:	67 89 04 65 11 22 33 ff 	mov[ ]+DWORD PTR \[eiz\*2-0xccddef\],eax
+[ 	]*[a-f0-9]+:	67 48 a3 ef cd ab 89 	addr32 mov ds:0x89abcdef,rax
+[ 	]*[a-f0-9]+:	67 48 89 1c 25 ef cd ab 89 	mov[ ]+QWORD PTR \[eiz\*1\+0x89abcdef\],rbx
+[ 	]*[a-f0-9]+:	67 89 04 25 11 22 33 ff 	mov[ ]+DWORD PTR \[eiz\*1\+0xff332211\],eax
+[ 	]*[a-f0-9]+:	67 89 04 65 11 22 33 ff 	mov[ ]+DWORD PTR \[eiz\*2\+0xff332211\],eax
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-addr32.d b/gas/testsuite/gas/i386/x86-64-addr32.d
index 6b73de951f..d9481a7439 100644
--- a/gas/testsuite/gas/i386/x86-64-addr32.d
+++ b/gas/testsuite/gas/i386/x86-64-addr32.d
@@ -17,12 +17,18 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	67 48 a1 98 08 60 00 	addr32 mov 0x600898,%rax
 [ 	]*[a-f0-9]+:	67 48 a1 98 08 80 00 	addr32 mov 0x800898,%rax
 [ 	]*[a-f0-9]+:	67 48 8b 1c 25 98 08 80 00 	mov[ ]+0x800898\(,%eiz,1\),%rbx
+[ 	]*[a-f0-9]+:	67 48 a1 ef cd ab 89 	addr32 mov 0x89abcdef,%rax
+[ 	]*[a-f0-9]+:	67 48 8b 1c 25 ef cd ab 89 	mov[ ]+0x89abcdef\(,%eiz,1\),%rbx
+[ 	]*[a-f0-9]+:	67 48 b8 ef cd ab 89 00 00 00 00 	addr32 movabs \$0x89abcdef,%rax
+[ 	]*[a-f0-9]+:	67 48 bb ef cd ab 89 00 00 00 00 	addr32 movabs \$0x89abcdef,%rbx
 [ 	]*[a-f0-9]+:	67 a2 98 08 60 00    	addr32 mov %al,0x600898
 [ 	]*[a-f0-9]+:	67 66 a3 98 08 60 00 	addr32 mov %ax,0x600898
 [ 	]*[a-f0-9]+:	67 a3 98 08 60 00    	addr32 mov %eax,0x600898
 [ 	]*[a-f0-9]+:	67 48 a3 98 08 60 00 	addr32 mov %rax,0x600898
 [ 	]*[a-f0-9]+:	67 48 a3 98 08 80 00 	addr32 mov %rax,0x800898
 [ 	]*[a-f0-9]+:	67 48 89 1c 25 98 08 80 00 	mov[ ]+%rbx,0x800898\(,%eiz,1\)
-[ 	]*[a-f0-9]+:	67 89 04 25 11 22 33 ff 	mov[ ]+%eax,-0xccddef\(,%eiz,1\)
-[ 	]*[a-f0-9]+:	67 89 04 65 11 22 33 ff 	mov[ ]+%eax,-0xccddef\(,%eiz,2\)
+[ 	]*[a-f0-9]+:	67 48 a3 ef cd ab 89 	addr32 mov %rax,0x89abcdef
+[ 	]*[a-f0-9]+:	67 48 89 1c 25 ef cd ab 89 	mov[ ]+%rbx,0x89abcdef\(,%eiz,1\)
+[ 	]*[a-f0-9]+:	67 89 04 25 11 22 33 ff 	mov[ ]+%eax,0xff332211\(,%eiz,1\)
+[ 	]*[a-f0-9]+:	67 89 04 65 11 22 33 ff 	mov[ ]+%eax,0xff332211\(,%eiz,2\)
 #pass
diff --git a/gas/testsuite/gas/i386/x86-64-addr32.s b/gas/testsuite/gas/i386/x86-64-addr32.s
index 5acdce9dae..9d3aa6afaa 100644
--- a/gas/testsuite/gas/i386/x86-64-addr32.s
+++ b/gas/testsuite/gas/i386/x86-64-addr32.s
@@ -10,11 +10,17 @@ 
 	addr32 mov	0x600898,%rax
 	addr32 mov	0x800898,%rax
 	addr32 mov	0x800898,%rbx
+	addr32 mov	0x89abcdef,%rax
+	addr32 mov	0x89abcdef,%rbx
+	addr32 mov	$0x89abcdef,%rax
+	addr32 mov	$0x89abcdef,%rbx
 	addr32 mov	%al,0x600898
 	addr32 mov	%ax,0x600898
 	addr32 mov	%eax,0x600898
 	addr32 mov	%rax,0x600898
 	addr32 mov	%rax,0x800898
 	addr32 mov	%rbx,0x800898
+	addr32 mov	%rax,0x89abcdef
+	addr32 mov	%rbx,0x89abcdef
 	mov		%eax, -0xccddef(,%eiz,)
 	mov		%eax, -0xccddef(,%eiz,2)
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index a6cc01381b..511e6321ce 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -11877,8 +11877,13 @@  OP_E_memory (int bytemode, int sizeflag)
 	{
 	  if (address_mode == mode_64bit)
 	    {
-	      /* Display eiz instead of addr32.  */
-	      needindex = addr32flag;
+	      if (addr32flag)
+		{
+		  /* Without base nor index registers, zero-extend the
+		     lower 32-bit displacement to 64 bits.  */
+		  disp = (unsigned int) disp;
+		  needindex = 1;
+		}
 	      needaddr32 = 1;
 	    }
 	  else
-- 
2.26.2