PATCH: PR binutils/4429: Disassembler doesn't support PC relative in Intel mode

H. J. Lu hjl@lucon.org
Thu Apr 26 17:56:00 GMT 2007


This patch fixes disassembler to properly print PC relative addressing
in Intel mode. It also prints the explicit zero displacement. The old
one has

[hjl@gnu-2 binutils]$ cat y.s
        mov x(%rax),%rax
[hjl@gnu-2 binutils]$ gcc -c y.s
[hjl@gnu-2 binutils]$ objdump -dr y.o

y.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <.text>:
   0:   48 8b 80 00 00 00 00    mov    0x0(%rax),%rax
                        3: R_X86_64_32S x
[hjl@gnu-2 binutils]$ objdump -dr -Mintel y.o

y.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <.text>:
   0:   48 8b 80 00 00 00 00    mov    rax,QWORD PTR [rax]
                        3: R_X86_64_32S x
[hjl@gnu-2 binutils]$ 

Now, we have

[hjl@gnu-2 binutils]$ ./objdump -dr -Mintel y.o

y.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <.text>:
   0:   48 8b 80 00 00 00 00    mov    rax,QWORD PTR [rax+0x0]
                        3: R_X86_64_32S x
[hjl@gnu-2 binutils]$ 

I will check it in shortly.


H.J.
----
gas/testsuite/

2007-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/4429
	* gas/i386/i386.exp: Run "x86-64-addr32-intel" and
	"x86-64-rip-intel".

	* gas/i386/intelok.d: Updated.

	* gas/i386/x86-64-addr32-intel.d: New file.
	* gas/i386/x86-64-rip-intel.d: Likewise.

opcodes/

2007-04-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR binutils/4429
	* i386-dis.c (print_insn): Also swap the order of op_riprel
	when swapping op_index.  Break when the RIP relative address
	is printed.
	(OP_E): Properly handle RIP relative addressing and print the
	explicit zero displacement for Intel mode.

--- binutils/gas/testsuite/gas/i386/i386.exp.rip	2007-04-18 09:16:31.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/i386.exp	2007-04-26 10:30:23.000000000 -0700
@@ -138,9 +138,11 @@ if [expr ([istarget "i*86-*-*"] || [ista
 
     run_dump_test "x86_64"
     run_dump_test "x86-64-addr32"
+    run_dump_test "x86-64-addr32-intel"
     run_dump_test "x86-64-opcode"
     run_dump_test "x86-64-pcrel"
     run_dump_test "x86-64-rip"
+    run_dump_test "x86-64-rip-intel"
     run_dump_test "x86-64-stack"
     run_dump_test "x86-64-stack-intel"
     run_dump_test "x86-64-stack-suffix"
--- binutils/gas/testsuite/gas/i386/intelok.d.rip	2005-11-06 22:03:50.000000000 -0800
+++ binutils/gas/testsuite/gas/i386/intelok.d	2007-04-26 10:30:23.000000000 -0700
@@ -106,10 +106,10 @@ Disassembly of section .text:
 [ 	]*[0-9a-f]+:	8b 40 12[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+18\]
 [ 	]*[0-9a-f]+:	8b 04 85 02 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\*4\+(0x)?2\]
 [ 	]*[0-9a-f]+:	8b 04 85 02 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\*4\+(0x)?2\]
-[ 	]*[0-9a-f]+:	8b 04 45 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\*2\]
-[ 	]*[0-9a-f]+:	8b 04 45 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\*2\]
-[ 	]*[0-9a-f]+:	8b 04 8d 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[ecx\*4\]
-[ 	]*[0-9a-f]+:	8b 04 8d 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[ecx\*4\]
+[ 	]*[0-9a-f]+:	8b 04 45 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\*2\+(0x)?0]
+[ 	]*[0-9a-f]+:	8b 04 45 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\*2\+(0x)?0]
+[ 	]*[0-9a-f]+:	8b 04 8d 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[ecx\*4\+(0x)?0]
+[ 	]*[0-9a-f]+:	8b 04 8d 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[ecx\*4\+(0x)?0]
 [ 	]*[0-9a-f]+:	8b 40 01[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+1\]
 [ 	]*[0-9a-f]+:	8b 40 01[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+1\]
 [ 	]*[0-9a-f]+:	8b 44 08 fb[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+ecx\-5\]
@@ -153,11 +153,11 @@ Disassembly of section .text:
 [ 	]*[0-9a-f]+:	b8 00 00 00 00[ 	]+mov[ 	]+eax,0x0
 [ 	]*[0-9a-f]+:	b8 00 00 00 00[ 	]+mov[ 	]+eax,0x0
 [ 	]*[0-9a-f]+:	b8 00 00 00 00[ 	]+mov[ 	]+eax,0x0
-[ 	]*[0-9a-f]+:	8b 80 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\]
+[ 	]*[0-9a-f]+:	8b 80 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+(0x)?0\]
 [ 	]*[0-9a-f]+:	8b 40 01[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+1]
-[ 	]*[0-9a-f]+:	8b 80 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\]
+[ 	]*[0-9a-f]+:	8b 80 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+(0x)?0\]
 [ 	]*[0-9a-f]+:	8b 80 01 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+(0x)?1\]
-[ 	]*[0-9a-f]+:	8b 80 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\]
+[ 	]*[0-9a-f]+:	8b 80 00 00 00 00[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+(0x)?0\]
 [ 	]*[0-9a-f]+:	8b 40 01[ 	]+mov[ 	]+eax,(DWORD PTR )?\[eax\+1\]
 [ 	]*[0-9a-f]+:	a1 01 00 00 00[ 	]+mov[ 	]+eax,ds:0x1
 [ 	]*[0-9a-f]+:	a1 ff ff ff ff[ 	]+mov[ 	]+eax,ds:0xffffffff
--- binutils/gas/testsuite/gas/i386/x86-64-addr32-intel.d.rip	2007-04-26 10:30:23.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/x86-64-addr32-intel.d	2007-04-26 10:30:23.000000000 -0700
@@ -0,0 +1,23 @@
+#as: -J
+#objdump: -drwMintel
+#name: x86-64 32-bit addressing (Intel mode)
+#source: x86-64-addr32.s
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[	 ]*0:[	 ]+67 48 8d 80 00 00 00 00[	 ]+addr32[	 ]+lea[ 	]+rax,\[[re]ax\+(0x)?0\].*
+[	 ]*8:[	 ]+67 49 8d 80 00 00 00 00[	 ]+addr32[	 ]+lea[ 	]+rax,\[r8d?\+(0x)?0\].*
+[	 ]*10:[	 ]+67 48 8d 05 00 00 00 00[	 ]+addr32[	 ]+lea[ 	]+rax,\[[re]ip\+(0x)?0\].*
+[	 ]*18:[	 ]+67 48 8d 04 25 00 00 00 00[	 ]+addr32[	 ]+lea[ 	]+rax,ds:0x0.*
+[	 ]*21:[	 ]+67 a0 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+al,ds:0x600898
+[	 ]*27:[	 ]+67 66 a1 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+ax,ds:0x600898
+[	 ]*2e:[	 ]+67 a1 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+eax,ds:0x600898
+[	 ]*34:[	 ]+67 48 a1 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+rax,ds:0x600898
+[	 ]*3b:[	 ]+67 a2 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+ds:0x600898,al
+[	 ]*41:[	 ]+67 66 a3 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+ds:0x600898,ax
+[	 ]*48:[	 ]+67 a3 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+ds:0x600898,eax
+[	 ]*4e:[	 ]+67 48 a3 98 08 60 00[	 ]+addr32[	 ]+mov[ 	]+ds:0x600898,rax
+#pass
--- binutils/gas/testsuite/gas/i386/x86-64-rip-intel.d.rip	2007-04-26 10:30:23.000000000 -0700
+++ binutils/gas/testsuite/gas/i386/x86-64-rip-intel.d	2007-04-26 10:30:23.000000000 -0700
@@ -0,0 +1,15 @@
+#as: -J
+#objdump: -drwMintel
+#name: x86-64 rip addressing (Intel mode)
+#source: x86-64-rip.s
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <.text>:
+[	 ]*0:[	 ]+8d 05 00 00 00 00[	 ]+lea[	 ]+eax,\[rip\+0x0\][ 	]*(#.*)?
+[	 ]*6:[	 ]+8d 05 11 11 11 11[	 ]+lea[	 ]+eax,\[rip\+0x11111111\][ 	]*(#.*)?
+[	 ]*c:[	 ]+8d 05 01 00 00 00[	 ]+lea[	 ]+eax,\[rip\+0x1\][ 	]*(#.*)?
+[	 ]*12:[	 ]+8d 05 00 00 00 00[	 ]+lea[	 ]+eax,\[rip\+0x0\][ 	]*(#.*)?
+#pass
--- binutils/opcodes/i386-dis.c.rip	2007-04-18 09:16:29.000000000 -0700
+++ binutils/opcodes/i386-dis.c	2007-04-26 10:38:19.000000000 -0700
@@ -3773,6 +3773,8 @@ print_insn (bfd_vma pc, disassemble_info
      order as the intel book; everything else is printed in reverse order.  */
   if (intel_syntax || two_source_ops)
     {
+      bfd_vma riprel;
+
       for (i = 0; i < MAX_OPERANDS; ++i)
         op_txt[i] = op_out[i];
 
@@ -3781,6 +3783,9 @@ print_insn (bfd_vma pc, disassemble_info
           op_ad = op_index[i];
           op_index[i] = op_index[MAX_OPERANDS - 1 - i];
           op_index[MAX_OPERANDS - 1 - i] = op_ad;
+	  riprel = op_riprel[i];
+	  op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i];
+	  op_riprel[MAX_OPERANDS - 1 - i] = riprel;
 	}
     }
   else
@@ -3808,6 +3813,7 @@ print_insn (bfd_vma pc, disassemble_info
 	(*info->fprintf_func) (info->stream, "        # ");
 	(*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
 						+ op_address[op_index[i]]), info);
+	break;
       }
   return codep - priv.the_buffer;
 }
@@ -4835,11 +4841,16 @@ OP_E (int bytemode, int sizeflag)
 	      }
 	  }
 
-      if (havebase || (havesib && (index != 4 || scale != 0)))
+      if (havebase
+	  || (intel_syntax && riprel)
+	  || (havesib && (index != 4 || scale != 0)))
 	{
 	  *obufp++ = open_char;
 	  if (intel_syntax && riprel)
-	    oappend ("rip + ");
+	    {
+	      set_op (disp, 1);
+	      oappend ("rip");
+	    }
 	  *obufp = '\0';
 	  if (havebase)
 	    oappend (address_mode == mode_64bit && (sizeflag & AFLAG)
@@ -4864,9 +4875,10 @@ OP_E (int bytemode, int sizeflag)
 		  oappend (scratchbuf);
 		}
 	    }
-	  if (intel_syntax && disp)
+	  if (intel_syntax
+	      && (disp || modrm.mod != 0 || (base & 7) == 5))
 	    {
-	      if ((bfd_signed_vma) disp > 0)
+	      if ((bfd_signed_vma) disp >= 0)
 		{
 		  *obufp++ = '+';
 		  *obufp = '\0';



More information about the Binutils mailing list