This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] i386: Allow "lea foo@GOT, %reg" in PIC


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2a5684011edabf5804abb9e11253a9747587b284

commit 2a5684011edabf5804abb9e11253a9747587b284
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Feb 15 11:39:30 2017 -0800

    i386: Allow "lea foo@GOT, %reg" in PIC
    
    "lea foo@GOT, %reg" is OK in PIC since it only loads the GOT offset
    into register, which can be used later with a GOT base register to
    get the value in the GOT entry.
    
    bfd/
    
    	PR ld/21168
    	* elf32-i386.c (elf_i386_relocate_section): Allow
    	"lea foo@GOT, %reg" in PIC.
    
    ld/
    
    	PR ld/21168
    	* testsuite/ld-i386/i386.exp: Run pr21168.
    	* testsuite/ld-i386/pr21168a.c: New file.
    	* testsuite/ld-i386/pr21168b.S: Likewise.

Diff:
---
 bfd/ChangeLog                   |  6 ++++++
 bfd/elf32-i386.c                | 12 ++++++++----
 ld/ChangeLog                    |  7 +++++++
 ld/testsuite/ld-i386/i386.exp   | 22 ++++++++++++++++++++++
 ld/testsuite/ld-i386/pr21168a.c | 14 ++++++++++++++
 ld/testsuite/ld-i386/pr21168b.S | 29 +++++++++++++++++++++++++++++
 6 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index cbea9a9..789915c 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
 2017-02-15  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR ld/21168
+	* elf32-i386.c (elf_i386_relocate_section): Allow
+	"lea foo@GOT, %reg" in PIC.
+
+2017-02-15  H.J. Lu  <hongjiu.lu@intel.com>
+
 	PR ld/20244
 	* elf32-i386.c (elf_i386_relocate_section): Properly get IFUNC
 	symbol name when reporting R_386_GOT32/R_386_GOT32X relocation
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 3bee4ca..e6e70d8 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -4074,7 +4074,9 @@ elf_i386_relocate_section (bfd *output_bfd,
 			      - gotplt->output_section->vma
 			      - gotplt->output_offset);
 
-	      if ((*(contents + rel->r_offset - 1) & 0xc7) == 0x5)
+	      if (rel->r_offset > 1
+		  && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5
+		  && *(contents + rel->r_offset - 2) != 0x8d)
 		{
 		  if (bfd_link_pic (info))
 		    goto disallow_got32;
@@ -4345,13 +4347,15 @@ r_386_got32:
 
 	  relocation = (htab->elf.sgot->output_section->vma
 			+ htab->elf.sgot->output_offset + off);
-	  if ((*(contents + rel->r_offset - 1) & 0xc7) == 0x5)
+	  if (rel->r_offset > 1
+	      && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5
+	      && *(contents + rel->r_offset - 2) != 0x8d)
 	    {
 	      if (bfd_link_pic (info))
 		{
 		  /* For PIC, disallow R_386_GOT32 without a base
-		     register since we don't know what the GOT base
-		     is.  */
+		     register, except for "lea foo@GOT, %reg", since
+		     we don't know what the GOT base is.  */
 		  const char *name;
 
 disallow_got32:
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 3f88091..f875a8b 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,12 @@
 2017-02-15  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR ld/21168
+	* testsuite/ld-i386/i386.exp: Run pr21168.
+	* testsuite/ld-i386/pr21168a.c: New file.
+	* testsuite/ld-i386/pr21168b.S: Likewise.
+
+2017-02-15  H.J. Lu  <hongjiu.lu@intel.com>
+
 	PR ld/20244
 	* testsuite/ld-i386/i386.exp: Run pr20244-4a, pr20244-4b and
 	pr20244-4c.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 7680ff5..c489227 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -835,6 +835,20 @@ if { [isnative]
 	    "-fPIC -O2 -g" \
 	    { ifunc-1a.c ifunc-1b.S ifunc-1c.S ifunc-1d.S } \
 	] \
+	[list \
+	    "Build pr21168a.o" \
+	    "" \
+	    "" \
+	    { pr21168a.c } \
+	] \
+	[list \
+	    "Build pr21168.so" \
+	    "-shared" \
+	    "" \
+	    { pr21168b.S } \
+	    "" \
+	    "pr21168.so" \
+	] \
     ]
 
     run_ld_link_exec_tests [list \
@@ -856,6 +870,14 @@ if { [isnative]
 	    "ifunc-1b" \
 	    "pass.out" \
 	] \
+	[list \
+	    "Run pr21168" \
+	    "tmpdir/pr21168a.o tmpdir/pr21168.so" \
+	    "" \
+	    { dummy.c } \
+	    "pr21168" \
+	    "pass.out" \
+	] \
     ]
 }
 
diff --git a/ld/testsuite/ld-i386/pr21168a.c b/ld/testsuite/ld-i386/pr21168a.c
new file mode 100644
index 0000000..a6c0da1
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr21168a.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+
+int foo = 1;
+
+extern int *bar (void);
+extern int bar_ifunc (void);
+
+int
+main (void)
+{
+  if (bar () == &foo && bar_ifunc () == 0xbadbeef)
+    printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-i386/pr21168b.S b/ld/testsuite/ld-i386/pr21168b.S
new file mode 100644
index 0000000..a4ea5c9
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr21168b.S
@@ -0,0 +1,29 @@
+	.text
+	.globl	bar
+	.type	bar, @function
+bar:
+	call	__x86.get_pc_thunk.ax
+	addl	$_GLOBAL_OFFSET_TABLE_, %eax
+	lea	foo@GOT, %ecx
+	mov	(%eax,%ecx,1), %eax
+	ret
+	.globl	bar_ifunc
+	.type	bar_ifunc, @function
+bar_ifunc:
+	call	__x86.get_pc_thunk.ax
+	addl	$_GLOBAL_OFFSET_TABLE_, %eax
+	lea	ifunc@GOT, %ecx
+	mov	(%eax,%ecx,1), %eax
+	ret
+	.type ifunc, @gnu_indirect_function
+ifunc:
+	mov	$0xbadbeef, %eax
+	ret
+	.section	.text.__x86.get_pc_thunk.ax,"axG",@progbits,__x86.get_pc_thunk.ax,comdat
+	.globl	__x86.get_pc_thunk.ax
+	.hidden	__x86.get_pc_thunk.ax
+	.type	__x86.get_pc_thunk.ax, @function
+__x86.get_pc_thunk.ax:
+	movl	(%esp), %eax
+	ret
+	.section	.note.GNU-stack,"",@progbits


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]