This is the mail archive of the binutils@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]

Re: [committed, PATCH] PR ld/20244: Subtract GOT base only with a base register


On Sat, Jun 11, 2016 at 9:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> When relocating R_386_GOT32 in "op $0, bar@GOT", we shouldn't subtract
> GOT base without a base register and we should disallow it without a
> base register for PIC.
>
> bfd/
>
>         PR ld/20244
>         * elf32-i386.c (elf_i386_relocate_section): When relocating
>         R_386_GOT32, return error without a base register for PIC and
>         subtract the .got.plt section address only with a base register.
>
> ld/
>
>         PR ld/20244
>         * testsuite/ld-i386/i386.exp: Run pr20244-1a and pr20244-1b.
>         * testsuite/ld-i386/pr20244-1.s: New file.
>         * testsuite/ld-i386/pr20244-1a.d: Likewise.
>         * testsuite/ld-i386/pr20244-1b.d: Likewise.
>         * testsuite/ld-i386/pr20244-1c.d: Likewise.

I checked in this patch for R_386_GOT32/R_386_GOT32X relocations
against IFUNC symbols without base register.

-- 
H.J.
From 712ec27916b5604d29d928dec060fd1ba0fd9edb Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 13 Jun 2016 11:06:10 -0700
Subject: [PATCH] Add the GOT base for GOT32 relocs against IFUNC

Add the GOT base for R_386_GOT32/R_386_GOT32X relocations against IFUNC
symbols if there is no base register and disallow them for PIC.

bfd/

	PR ld/20244
	* elf32-i386.c (elf_i386_relocate_section): Add the .got.plt
	section address for R_386_GOT32/R_386_GOT32X relocations against
	IFUNC symbols if there is no base register and return error for
	PIC.

ld/

	PR ld/20244
	* testsuite/ld-i386/i386.exp: Run pr20244-2a, pr20244-2b,
	pr20244-2c and pr20244-2d.
	* testsuite/ld-i386/no-plt.exp: Run pr20244-3a and pr20244-3b.
	* testsuite/ld-i386/pr20244-2.s: New file.
	* testsuite/ld-i386/pr20244-2a.d: Likewise.
	* testsuite/ld-i386/pr20244-2b.d: Likewise.
	* testsuite/ld-i386/pr20244-2c.d: Likewise.
	* testsuite/ld-i386/pr20244-2d.d: Likewise.
	* testsuite/ld-i386/pr20244-3a.c: Likewise.
	* testsuite/ld-i386/pr20244-3b.S: Likewise.
	* testsuite/ld-i386/pr20244-3c.S: Likewise.
	* testsuite/ld-i386/pr20244-3d.S: Likewise.
---
 bfd/ChangeLog                     |  8 +++++++
 bfd/elf32-i386.c                  | 22 +++++++++++++++-----
 ld/ChangeLog                      | 16 ++++++++++++++
 ld/testsuite/ld-i386/i386.exp     |  4 ++++
 ld/testsuite/ld-i386/no-plt.exp   | 33 +++++++++++++++++++++++++++++
 ld/testsuite/ld-i386/pr20244-2.s  | 17 +++++++++++++++
 ld/testsuite/ld-i386/pr20244-2a.d | 43 ++++++++++++++++++++++++++++++++++++++
 ld/testsuite/ld-i386/pr20244-2b.d | 11 ++++++++++
 ld/testsuite/ld-i386/pr20244-2c.d | 10 +++++++++
 ld/testsuite/ld-i386/pr20244-2d.d |  4 ++++
 ld/testsuite/ld-i386/pr20244-3a.c |  8 +++++++
 ld/testsuite/ld-i386/pr20244-3b.S | 30 ++++++++++++++++++++++++++
 ld/testsuite/ld-i386/pr20244-3c.S | 15 +++++++++++++
 ld/testsuite/ld-i386/pr20244-3d.S | 44 +++++++++++++++++++++++++++++++++++++++
 14 files changed, 260 insertions(+), 5 deletions(-)
 create mode 100644 ld/testsuite/ld-i386/pr20244-2.s
 create mode 100644 ld/testsuite/ld-i386/pr20244-2a.d
 create mode 100644 ld/testsuite/ld-i386/pr20244-2b.d
 create mode 100644 ld/testsuite/ld-i386/pr20244-2c.d
 create mode 100644 ld/testsuite/ld-i386/pr20244-2d.d
 create mode 100644 ld/testsuite/ld-i386/pr20244-3a.c
 create mode 100644 ld/testsuite/ld-i386/pr20244-3b.S
 create mode 100644 ld/testsuite/ld-i386/pr20244-3c.S
 create mode 100644 ld/testsuite/ld-i386/pr20244-3d.S

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 2a1ae13..9cfd09e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,13 @@
 2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR ld/20244
+	* elf32-i386.c (elf_i386_relocate_section): Add the .got.plt
+	section address for R_386_GOT32/R_386_GOT32X relocations against
+	IFUNC symbols if there is no base register and return error for
+	PIC.
+
+2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* elf32-i386.c (elf_i386_relocate_section): Simplify IFUNC
 	GOT32 adjustment for static executables.
 
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index fbbf4ab..a68ce1f 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -4039,9 +4039,20 @@ elf_i386_relocate_section (bfd *output_bfd,
 			      - gotplt->output_section->vma
 			      - gotplt->output_offset);
 
-	      /* Adjust for static executables.  */
-	      if (htab->elf.splt == NULL)
-		relocation += gotplt->output_offset;
+	      if ((*(contents + rel->r_offset - 1) & 0xc7) == 0x5)
+		{
+		  if (bfd_link_pic (info))
+		    goto disallow_got32;
+
+		  /* Add the GOT base if there is no base register.  */
+		  relocation += (gotplt->output_section->vma
+				 + gotplt->output_offset);
+		}
+	      else if (htab->elf.splt == NULL)
+		{
+		  /* Adjust for static executables.  */
+		  relocation += gotplt->output_offset;
+		}
 
 	      goto do_relocation;
 
@@ -4214,6 +4225,7 @@ r_386_got32:
 		     is.  */
 		  const char *name;
 
+disallow_got32:
 		  if (h == NULL)
 		    name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
 					     NULL);
@@ -4221,8 +4233,8 @@ r_386_got32:
 		    name = h->root.root.string;
 
 		  (*_bfd_error_handler)
-		    (_("%B: direct GOT relocation R_386_GOT32 against `%s' without base register can not be used when making a shared object"),
-		     input_bfd, name);
+		    (_("%B: direct GOT relocation %s against `%s' without base register can not be used when making a shared object"),
+		     input_bfd, howto->name, name);
 		  bfd_set_error (bfd_error_bad_value);
 		  return FALSE;
 		}
diff --git a/ld/ChangeLog b/ld/ChangeLog
index a8cceb8..e5614ba 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,21 @@
 2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>
 
+	PR ld/20244
+	* testsuite/ld-i386/i386.exp: Run pr20244-2a, pr20244-2b,
+	pr20244-2c and pr20244-2d.
+	* testsuite/ld-i386/no-plt.exp: Run pr20244-3a and pr20244-3b.
+	* testsuite/ld-i386/pr20244-2.s: New file.
+	* testsuite/ld-i386/pr20244-2a.d: Likewise.
+	* testsuite/ld-i386/pr20244-2b.d: Likewise.
+	* testsuite/ld-i386/pr20244-2c.d: Likewise.
+	* testsuite/ld-i386/pr20244-2d.d: Likewise.
+	* testsuite/ld-i386/pr20244-3a.c: Likewise.
+	* testsuite/ld-i386/pr20244-3b.S: Likewise.
+	* testsuite/ld-i386/pr20244-3c.S: Likewise.
+	* testsuite/ld-i386/pr20244-3d.S: Likewise.
+
+2016-06-13  H.J. Lu  <hongjiu.lu@intel.com>
+
 	* testsuite/ld-i386/i386.exp: Run ifunc-1a and ifunc-1b.
 	* testsuite/ld-i386/ifunc-1a.c: New file.
 	* testsuite/ld-i386/ifunc-1b.S: Likewise.
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index 93f11ef..8468920 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -403,6 +403,10 @@ run_dump_test "pr20117"
 run_dump_test "pr20244-1a"
 run_dump_test "pr20244-1b"
 run_dump_test "pr20244-1c"
+run_dump_test "pr20244-2a"
+run_dump_test "pr20244-2b"
+run_dump_test "pr20244-2c"
+run_dump_test "pr20244-2d"
 
 if { !([istarget "i?86-*-linux*"]
        || [istarget "i?86-*-gnu*"]
diff --git a/ld/testsuite/ld-i386/no-plt.exp b/ld/testsuite/ld-i386/no-plt.exp
index 87d64b9..c4af0a9 100644
--- a/ld/testsuite/ld-i386/no-plt.exp
+++ b/ld/testsuite/ld-i386/no-plt.exp
@@ -255,3 +255,36 @@ run_ld_link_exec_tests [] [list \
 	"pass.out" \
     ] \
 ]
+
+# Run-time tests which require working IFUNC support.
+if { [check_ifunc_available] } {
+    run_cc_link_tests [list \
+	[list \
+	    "Build pr20244-3a.o pr20244-3b.o pr20244-3c.o pr20244-3d.o" \
+	    "" \
+	    "-fPIC -O2 -g" \
+	    { pr20244-3a.c pr20244-3b.S pr20244-3c.S pr20244-3d.S } \
+	] \
+    ]
+
+    run_ld_link_exec_tests [] [list \
+	[list \
+	    "Run pr20244-3a" \
+	    "tmpdir/pr20244-3a.o tmpdir/pr20244-3b.o \
+	     tmpdir/pr20244-3c.o tmpdir/pr20244-3d.o" \
+	    "" \
+	    { dummy.c } \
+	    "pr20244-3a" \
+	    "pass.out" \
+	] \
+	[list \
+	    "Run pr20244-3b" \
+	    "--static tmpdir/pr20244-3a.o tmpdir/pr20244-3b.o \
+	    tmpdir/pr20244-3c.o tmpdir/pr20244-3d.o" \
+	    "" \
+	    { dummy.c } \
+	    "pr20244-3b" \
+	    "pass.out" \
+	] \
+    ]
+}
diff --git a/ld/testsuite/ld-i386/pr20244-2.s b/ld/testsuite/ld-i386/pr20244-2.s
new file mode 100644
index 0000000..283815a
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-2.s
@@ -0,0 +1,17 @@
+	.text
+	.globl	foo
+	.type	foo, @gnu_indirect_function
+foo:
+	ret
+	.text
+	.type	bar, @gnu_indirect_function
+bar:
+	ret
+	.globl	_start
+	.type	_start, @function
+_start:
+	call	*foo@GOT
+	jmp	*bar@GOT
+	movl	$0, bar@GOT
+	cmpl	$0, foo@GOT
+	movl	$bar@GOT, %ecx
diff --git a/ld/testsuite/ld-i386/pr20244-2a.d b/ld/testsuite/ld-i386/pr20244-2a.d
new file mode 100644
index 0000000..a04902f
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-2a.d
@@ -0,0 +1,43 @@
+#source: pr20244-2.s
+#as: --32
+#ld: -m elf_i386
+#objdump: --sym -dw
+#notarget: i?86-*-nacl* x86_64-*-nacl*
+
+.*: +file format .*
+
+SYMBOL TABLE:
+#...
+0+80480b1 l   i   .text	00000000 bar
+#...
+0+80480b2 g     F .text	00000000 _start
+#...
+0+80480b0 g   i   .text	00000000 foo
+#...
+
+
+Disassembly of section .plt:
+
+0+8048090 <.plt>:
+ +[a-f0-9]+:	ff 25 e0 90 04 08    	jmp    \*0x80490e0
+ +[a-f0-9]+:	68 00 00 00 00       	push   \$0x0
+ +[a-f0-9]+:	e9 00 00 00 00       	jmp    80480a0 <foo-0x10>
+ +[a-f0-9]+:	ff 25 e4 90 04 08    	jmp    \*0x80490e4
+ +[a-f0-9]+:	68 00 00 00 00       	push   \$0x0
+ +[a-f0-9]+:	e9 00 00 00 00       	jmp    80480b0 <foo>
+
+Disassembly of section .text:
+
+0+80480b0 <foo>:
+ +[a-f0-9]+:	c3                   	ret    
+
+0+80480b1 <bar>:
+ +[a-f0-9]+:	c3                   	ret    
+
+0+80480b2 <_start>:
+ +[a-f0-9]+:	ff 15 e0 90 04 08    	call   \*0x80490e0
+ +[a-f0-9]+:	ff 25 e4 90 04 08    	jmp    \*0x80490e4
+ +[a-f0-9]+:	c7 05 e4 90 04 08 00 00 00 00 	movl   \$0x0,0x80490e4
+ +[a-f0-9]+:	83 3d e0 90 04 08 00 	cmpl   \$0x0,0x80490e0
+ +[a-f0-9]+:	b9 10 00 00 00       	mov    \$0x10,%ecx
+#pass
diff --git a/ld/testsuite/ld-i386/pr20244-2b.d b/ld/testsuite/ld-i386/pr20244-2b.d
new file mode 100644
index 0000000..fc0fa17
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-2b.d
@@ -0,0 +1,11 @@
+#source: pr20244-2.s
+#as: --32
+#ld: -m elf_i386
+#objdump: -s -j .got.plt
+#notarget: i?86-*-nacl* x86_64-*-nacl*
+
+.*: +file format .*
+
+Contents of section .got.plt:
+ 80490d4 00000000 00000000 00000000 b0800408  ................
+ 80490e4 b1800408                             ....            
diff --git a/ld/testsuite/ld-i386/pr20244-2c.d b/ld/testsuite/ld-i386/pr20244-2c.d
new file mode 100644
index 0000000..54eee9f
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-2c.d
@@ -0,0 +1,10 @@
+#source: pr20244-2.s
+#as: --32
+#ld: -m elf_i386
+#readelf: -rW
+#notarget: i?86-*-nacl* x86_64-*-nacl*
+
+Relocation section '.rel.plt' at offset 0x74 contains 2 entries:
+ Offset     Info    Type                Sym. Value  Symbol's Name
+0+80490e4  0000002a R_386_IRELATIVE       
+0+80490e0  0000002a R_386_IRELATIVE       
diff --git a/ld/testsuite/ld-i386/pr20244-2d.d b/ld/testsuite/ld-i386/pr20244-2d.d
new file mode 100644
index 0000000..c423bf7
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-2d.d
@@ -0,0 +1,4 @@
+#source: pr20244-2.s
+#as: --32
+#ld: -pie -m elf_i386
+#error: direct GOT relocation R_386_GOT32X against `foo' without base register can not be used when making a shared object
diff --git a/ld/testsuite/ld-i386/pr20244-3a.c b/ld/testsuite/ld-i386/pr20244-3a.c
new file mode 100644
index 0000000..370275a
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-3a.c
@@ -0,0 +1,8 @@
+extern void check (void);
+
+int
+main ()
+{
+  check ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-i386/pr20244-3b.S b/ld/testsuite/ld-i386/pr20244-3b.S
new file mode 100644
index 0000000..83880da
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-3b.S
@@ -0,0 +1,30 @@
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"PASS"
+	.text
+	.p2align 4,,15
+	.globl	check
+	.type	check, @function
+check:
+	subl	$12, %esp
+	call	*get_func1@GOT
+	cmpl	$func1, %eax
+	jne	.L3
+	call	*func1@GOT
+	cmpl	$1, %eax
+	jne	.L3
+	call	*call_func1@GOT
+	cmpl	$1, %eax
+	jne	.L3
+	call	*call_func2@GOT
+	cmpl	$2, %eax
+	jne	.L3
+	subl	$12, %esp
+	pushl	$.LC0
+	call	*puts@GOT
+	addl	$28, %esp
+	ret
+.L3:
+	call	*abort@GOT
+	.size	check, .-check
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr20244-3c.S b/ld/testsuite/ld-i386/pr20244-3c.S
new file mode 100644
index 0000000..0b90013
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-3c.S
@@ -0,0 +1,15 @@
+	.text
+	.p2align 4,,15
+	.globl	get_func1
+	.type	get_func1, @function
+get_func1:
+	movl	func1@GOT, %eax
+	ret
+	.size	get_func1, .-get_func1
+	.p2align 4,,15
+	.globl	call_func1
+	.type	call_func1, @function
+call_func1:
+	jmp	*func1@GOT
+	.size	call_func1, .-call_func1
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr20244-3d.S b/ld/testsuite/ld-i386/pr20244-3d.S
new file mode 100644
index 0000000..a57f3fc
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr20244-3d.S
@@ -0,0 +1,44 @@
+	.text
+	.p2align 4,,15
+	.type	implementation1, @function
+implementation1:
+	movl	$1, %eax
+	ret
+	.size	implementation1, .-implementation1
+	.p2align 4,,15
+	.type	implementation2, @function
+implementation2:
+	movl	$2, %eax
+	ret
+	.size	implementation2, .-implementation2
+	.p2align 4,,15
+	.type	resolver2, @function
+resolver2:
+	movl	implementation2@GOT, %eax
+	ret
+	.size	resolver2, .-resolver2
+	.type	func2, @gnu_indirect_function
+	.set	func2,resolver2
+	.p2align 4,,15
+	.type	resolver1, @function
+resolver1:
+	movl	implementation1@GOT, %eax
+	ret
+	.size	resolver1, .-resolver1
+	.globl	func1
+	.type	func1, @gnu_indirect_function
+	.set	func1,resolver1
+	.p2align 4,,15
+	.globl	get_func2
+	.type	get_func2, @function
+get_func2:
+	movl	func2@GOT, %eax
+	ret
+	.size	get_func2, .-get_func2
+	.p2align 4,,15
+	.globl	call_func2
+	.type	call_func2, @function
+call_func2:
+	jmp	*func2@GOT
+	.size	call_func2, .-call_func2
+	.section	.note.GNU-stack,"",@progbits
-- 
2.5.5


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