aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-04-22 05:24:54 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-04-22 05:30:01 -0700
commitd5597ebccca6761fb641b7fc99b6e8b56fbac6e2 (patch)
treea70a40f8a62dc7d494881f71041791e753e8d942 /ld
parent712e55b92481d89d01877a0668d8140029feca88 (diff)
downloadbinutils-d5597ebccca6761fb641b7fc99b6e8b56fbac6e2.zip
binutils-d5597ebccca6761fb641b7fc99b6e8b56fbac6e2.tar.gz
binutils-d5597ebccca6761fb641b7fc99b6e8b56fbac6e2.tar.bz2
i386: Allow copy relocs for building PIE
This patch allows copy relocs for R_386_GOTOFF relocations in PIE. For extern int glob_a; int foo () { return glob_a; } compiler now can optimize it from call __x86.get_pc_thunk.ax addl $_GLOBAL_OFFSET_TABLE_, %eax movl glob_a@GOT(%eax), %eax movl (%eax), %eax ret to call __x86.get_pc_thunk.ax addl $_GLOBAL_OFFSET_TABLE_, %eax movl glob_a@GOTOFF(%eax), %eax ret bfd/ PR ld/18289 * elf32-i386.c (elf_i386_link_hash_entry): Add gotoff_ref. (elf_i386_link_hash_newfunc): Initialize gotoff_ref to 0. (elf_i386_create_dynamic_sections): Always allow copy relocs for building executables. (elf_i386_copy_indirect_symbol): Also copy gotoff_ref. (elf_i386_check_relocs): Set gotoff_ref for R_386_GOTOFF. (elf_i386_adjust_dynamic_symbol): Also allocate copy relocs for PIE and R_386_GOTOFF. (elf_i386_relocate_section): Allow R_386_GOTOFF in executable. ld/testsuite/ PR ld/18289 * ld-i386/copyreloc-lib.c: New file. * ld-i386/copyreloc-main.S: Likewise. * ld-i386/copyreloc-main.out: Likewise. * ld-i386/copyreloc-main1.rd: Likewise. * ld-i386/copyreloc-main2.rd: Likewise. * ld-i386/dummy.c: Likewise. * ld-i386/pr17689.out: Likewise. * ld-i386/pr17689.rd: Likewise. * ld-i386/pr17689a.c: Likewise. * ld-i386/pr17689b.S: Likewise. * ld-i386/pr17827.rd: Likewise. * ld-i386/pr17827ver.rd: Likewise. * ld-i386/i386.exp: Run copyreloc tests.
Diffstat (limited to 'ld')
-rw-r--r--ld/testsuite/ChangeLog17
-rw-r--r--ld/testsuite/ld-i386/copyreloc-lib.c1
-rw-r--r--ld/testsuite/ld-i386/copyreloc-main.S24
-rw-r--r--ld/testsuite/ld-i386/copyreloc-main.out0
-rw-r--r--ld/testsuite/ld-i386/copyreloc-main1.rd3
-rw-r--r--ld/testsuite/ld-i386/copyreloc-main2.rd4
-rw-r--r--ld/testsuite/ld-i386/dummy.c1
-rw-r--r--ld/testsuite/ld-i386/i386.exp96
-rw-r--r--ld/testsuite/ld-i386/pr17689.out2
-rw-r--r--ld/testsuite/ld-i386/pr17689.rd3
-rw-r--r--ld/testsuite/ld-i386/pr17689a.c10
-rw-r--r--ld/testsuite/ld-i386/pr17689a.t6
-rw-r--r--ld/testsuite/ld-i386/pr17689b.S44
-rw-r--r--ld/testsuite/ld-i386/pr17689ver.rd3
-rw-r--r--ld/testsuite/ld-i386/pr17827.rd4
15 files changed, 218 insertions, 0 deletions
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 240a444..ea6a863 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,20 @@
+2015-04-22 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR ld/18289
+ * ld-i386/copyreloc-lib.c: New file.
+ * ld-i386/copyreloc-main.S: Likewise.
+ * ld-i386/copyreloc-main.out: Likewise.
+ * ld-i386/copyreloc-main1.rd: Likewise.
+ * ld-i386/copyreloc-main2.rd: Likewise.
+ * ld-i386/dummy.c: Likewise.
+ * ld-i386/pr17689.out: Likewise.
+ * ld-i386/pr17689.rd: Likewise.
+ * ld-i386/pr17689a.c: Likewise.
+ * ld-i386/pr17689b.S: Likewise.
+ * ld-i386/pr17827.rd: Likewise.
+ * ld-i386/pr17827ver.rd: Likewise.
+ * ld-i386/i386.exp: Run copyreloc tests.
+
2015-04-20 H.J. Lu <hongjiu.lu@intel.com>
* ld-mmix/bspec1.d: Don't hardcode offset of .shstrtab section.
diff --git a/ld/testsuite/ld-i386/copyreloc-lib.c b/ld/testsuite/ld-i386/copyreloc-lib.c
new file mode 100644
index 0000000..cbbc5e2
--- /dev/null
+++ b/ld/testsuite/ld-i386/copyreloc-lib.c
@@ -0,0 +1 @@
+int a_glob = 2;
diff --git a/ld/testsuite/ld-i386/copyreloc-main.S b/ld/testsuite/ld-i386/copyreloc-main.S
new file mode 100644
index 0000000..98aef83
--- /dev/null
+++ b/ld/testsuite/ld-i386/copyreloc-main.S
@@ -0,0 +1,24 @@
+ .section .text.startup,"ax",@progbits
+ .p2align 4,,15
+ .globl main
+ .type main, @function
+main:
+ .cfi_startproc
+ call __x86.get_pc_thunk.ax
+ addl $_GLOBAL_OFFSET_TABLE_, %eax
+ cmpl $2, a_glob@GOTOFF(%eax)
+ setne %al
+ movzbl %al, %eax
+ ret
+ .cfi_endproc
+ .size main, .-main
+ .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:
+ .cfi_startproc
+ movl (%esp), %eax
+ ret
+ .cfi_endproc
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/copyreloc-main.out b/ld/testsuite/ld-i386/copyreloc-main.out
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ld/testsuite/ld-i386/copyreloc-main.out
diff --git a/ld/testsuite/ld-i386/copyreloc-main1.rd b/ld/testsuite/ld-i386/copyreloc-main1.rd
new file mode 100644
index 0000000..a6bd67c
--- /dev/null
+++ b/ld/testsuite/ld-i386/copyreloc-main1.rd
@@ -0,0 +1,3 @@
+#...
+[0-9a-f ]+R_386_COPY+[0-9a-f ]+ +a_glob
+#...
diff --git a/ld/testsuite/ld-i386/copyreloc-main2.rd b/ld/testsuite/ld-i386/copyreloc-main2.rd
new file mode 100644
index 0000000..ed61aa1
--- /dev/null
+++ b/ld/testsuite/ld-i386/copyreloc-main2.rd
@@ -0,0 +1,4 @@
+#failif
+#...
+[0-9a-f ]+R_386_NONE.*
+#...
diff --git a/ld/testsuite/ld-i386/dummy.c b/ld/testsuite/ld-i386/dummy.c
new file mode 100644
index 0000000..5c03287
--- /dev/null
+++ b/ld/testsuite/ld-i386/dummy.c
@@ -0,0 +1 @@
+/* An empty file. */
diff --git a/ld/testsuite/ld-i386/i386.exp b/ld/testsuite/ld-i386/i386.exp
index f214d89..8399cbc 100644
--- a/ld/testsuite/ld-i386/i386.exp
+++ b/ld/testsuite/ld-i386/i386.exp
@@ -335,6 +335,78 @@ if { [isnative]
{{readelf {-Wr} plt-main.rd}} \
"plt-main" \
] \
+ [list \
+ "Build copyreloc-lib.so" \
+ "-shared" \
+ "-fPIC" \
+ { copyreloc-lib.c } \
+ {} \
+ "copyreloc-lib.so" \
+ ] \
+ [list \
+ "Build copyreloc-main with PIE and GOTOFF (1)" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.S } \
+ {{readelf {-Wr} copyreloc-main1.rd}} \
+ "copyreloc-main" \
+ ] \
+ [list \
+ "Build copyreloc-main with PIE and GOTOFF (2)" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.S } \
+ {{readelf {-Wr} copyreloc-main2.rd}} \
+ "copyreloc-main" \
+ ] \
+ [list \
+ "Build pr17689.so" \
+ "-shared" \
+ "-fPIC" \
+ { pr17689a.c } \
+ {} \
+ "pr17689.so" \
+ ] \
+ [list \
+ "Build pr17689ver.so" \
+ "-shared -Wl,--version-script,pr17689a.t" \
+ "-fPIC" \
+ { pr17689a.c } \
+ {} \
+ "pr17689ver.so" \
+ ] \
+ [list \
+ "Build pr17689.a" \
+ "" \
+ "" \
+ { pr17689b.S } \
+ {} \
+ "pr17689.a" \
+ ] \
+ [list \
+ "Build pr17689 with PIE and GOTOFF" \
+ "tmpdir/pr17689b.o tmpdir/pr17689.so -pie" \
+ "" \
+ { dummy.c } \
+ {{readelf {-Wr} pr17689.rd}} \
+ "pr17689" \
+ ] \
+ [list \
+ "Build pr17689ver with PIE and GOTOFF" \
+ "tmpdir/pr17689b.o tmpdir/pr17689ver.so -pie" \
+ "" \
+ { dummy.c } \
+ {{readelf {-Wr} pr17689ver.rd}} \
+ "pr17689ver" \
+ ] \
+ [list \
+ "Build pr17827 with PIE and GOTOFF" \
+ "tmpdir/pr17689b.o tmpdir/pr17689.so -pie" \
+ "" \
+ { dummy.c } \
+ {{readelf {-Wr} pr17827.rd}} \
+ "pr17827" \
+ ] \
]
run_ld_link_exec_tests [] [list \
@@ -357,5 +429,29 @@ if { [isnative]
"plt-main.out" \
"-fPIC" \
] \
+ [list \
+ "Run copyreloc-main with PIE and GOTOFF" \
+ "tmpdir/copyreloc-lib.so -pie" \
+ "" \
+ { copyreloc-main.S } \
+ "copyreloc-main" \
+ "copyreloc-main.out" \
+ ] \
+ [list \
+ "Run pr17689 with PIE and GOTOFF" \
+ "tmpdir/pr17689b.o tmpdir/pr17689.so -pie" \
+ "" \
+ { dummy.c } \
+ "pr17689" \
+ "pr17689.out" \
+ ] \
+ [list \
+ "Run pr17689ver with PIE and GOTOFF" \
+ "tmpdir/pr17689b.o tmpdir/pr17689ver.so -pie" \
+ "" \
+ { dummy.c } \
+ "pr17689ver" \
+ "pr17689.out" \
+ ] \
]
}
diff --git a/ld/testsuite/ld-i386/pr17689.out b/ld/testsuite/ld-i386/pr17689.out
new file mode 100644
index 0000000..38e0352
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr17689.out
@@ -0,0 +1,2 @@
+PASS
+PASS
diff --git a/ld/testsuite/ld-i386/pr17689.rd b/ld/testsuite/ld-i386/pr17689.rd
new file mode 100644
index 0000000..dda1850
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr17689.rd
@@ -0,0 +1,3 @@
+#...
+[0-9a-f ]+R_386_COPY+[0-9a-f ]+ +bar
+#...
diff --git a/ld/testsuite/ld-i386/pr17689a.c b/ld/testsuite/ld-i386/pr17689a.c
new file mode 100644
index 0000000..5317668
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr17689a.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+char *bar = "PASS";
+extern char *bar_alias __attribute__ ((weak, alias ("bar")));
+
+void
+foo (char *x)
+{
+ printf ("%s\n", x);
+}
diff --git a/ld/testsuite/ld-i386/pr17689a.t b/ld/testsuite/ld-i386/pr17689a.t
new file mode 100644
index 0000000..7f0efef
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr17689a.t
@@ -0,0 +1,6 @@
+VERSION {
+ global:
+ bar_alias; bar; foo;
+ local:
+ *;
+};
diff --git a/ld/testsuite/ld-i386/pr17689b.S b/ld/testsuite/ld-i386/pr17689b.S
new file mode 100644
index 0000000..24daf36
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr17689b.S
@@ -0,0 +1,44 @@
+ .text
+ .globl main
+ .type main, @function
+main:
+ leal 4(%esp), %ecx
+ andl $-16, %esp
+ pushl -4(%ecx)
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %ecx
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ subl $12, %esp
+ pushl bar_alias@GOTOFF(%ebx)
+ call foo@PLT
+ popl %eax
+ movl ptr@GOTOFF(%ebx), %eax
+ pushl (%eax)
+ call foo@PLT
+ addl $16, %esp
+ leal -8(%ebp), %esp
+ xorl %eax, %eax
+ popl %ecx
+ popl %ebx
+ popl %ebp
+ leal -4(%ecx), %esp
+ ret
+ .size main, .-main
+ .globl ptr
+ .section .data.rel.local,"aw",@progbits
+ .align 4
+ .type ptr, @object
+ .size ptr, 4
+ptr:
+ .long bar_alias
+ .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+ .globl __x86.get_pc_thunk.bx
+ .hidden __x86.get_pc_thunk.bx
+ .type __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+ movl (%esp), %ebx
+ ret
+ .section .note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-i386/pr17689ver.rd b/ld/testsuite/ld-i386/pr17689ver.rd
new file mode 100644
index 0000000..6cebe73
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr17689ver.rd
@@ -0,0 +1,3 @@
+#...
+[0-9a-f ]+R_386_COPY+[0-9a-f ]+ +bar@VERSION
+#...
diff --git a/ld/testsuite/ld-i386/pr17827.rd b/ld/testsuite/ld-i386/pr17827.rd
new file mode 100644
index 0000000..ed61aa1
--- /dev/null
+++ b/ld/testsuite/ld-i386/pr17827.rd
@@ -0,0 +1,4 @@
+#failif
+#...
+[0-9a-f ]+R_386_NONE.*
+#...