aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2018-05-14 03:55:37 -0700
committerH.J. Lu <hjl.tools@gmail.com>2018-05-14 03:55:50 -0700
commit4ec0995016801cc5d5cf13baf6e10163861e6852 (patch)
treef2aa11725ad03aec8080cb88b6415c7fcdf2098f /ld
parent9bc935ef3380a2d471b9447e2bf8e61297654e2f (diff)
downloadbinutils-4ec0995016801cc5d5cf13baf6e10163861e6852.zip
binutils-4ec0995016801cc5d5cf13baf6e10163861e6852.tar.gz
binutils-4ec0995016801cc5d5cf13baf6e10163861e6852.tar.bz2
x86; Allow IFUNC pointer defined in PDE
If IFUNC symbol is defined in position-dependent executable, we should change it to the normal function and set its address to its PLT entry which should be resolved by R_*_IRELATIVE at run-time. All external references should be resolved to its PLT in executable. bfd/ PR ld/23169 * elf-ifunc.c (_bfd_elf_allocate_ifunc_dyn_relocs): Don't issue an error on IFUNC pointer defined in PDE. * elf32-i386.c (elf_i386_finish_dynamic_symbol): Call _bfd_x86_elf_link_fixup_ifunc_symbol. * elf64-x86-64.c (elf_x86_64_finish_dynamic_symbol): Likewise. * elfxx-x86.c (_bfd_x86_elf_link_fixup_ifunc_symbol): New function. * elfxx-x86.h (_bfd_x86_elf_link_fixup_ifunc_symbol): New. ld/ PR ld/23169 * testsuite/ld-ifunc/ifunc-9-i386.d: New file. * testsuite/ld-ifunc/ifunc-9-x86-64.d: Likewise. * testsuite/ld-ifunc/pr23169a.c: Likewise. * testsuite/ld-ifunc/pr23169a.rd: Likewise. * testsuite/ld-ifunc/pr23169b.c: Likewise. * testsuite/ld-ifunc/pr23169b.c: Likewise. * testsuite/ld-ifunc/pr23169c.rd: Likewise. * testsuite/ld-ifunc/pr23169c.rd: Likewise. * testsuite/ld-ifunc/ifunc-9-x86.d: Removed. * testsuite/ld-ifunc/ifunc.exp: Run PR ld/23169 tests.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog14
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-9-i386.d9
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-9-x86-64.d9
-rw-r--r--ld/testsuite/ld-ifunc/ifunc-9-x86.d3
-rw-r--r--ld/testsuite/ld-ifunc/ifunc.exp124
-rw-r--r--ld/testsuite/ld-ifunc/pr23169a.c9
-rw-r--r--ld/testsuite/ld-ifunc/pr23169a.rd6
-rw-r--r--ld/testsuite/ld-ifunc/pr23169b.c23
-rw-r--r--ld/testsuite/ld-ifunc/pr23169b.rd3
-rw-r--r--ld/testsuite/ld-ifunc/pr23169c.c13
-rw-r--r--ld/testsuite/ld-ifunc/pr23169c.rd6
11 files changed, 216 insertions, 3 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 178ca68..fbc4d59 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,19 @@
2018-05-14 H.J. Lu <hongjiu.lu@intel.com>
+ PR ld/23169
+ * testsuite/ld-ifunc/ifunc-9-i386.d: New file.
+ * testsuite/ld-ifunc/ifunc-9-x86-64.d: Likewise.
+ * testsuite/ld-ifunc/pr23169a.c: Likewise.
+ * testsuite/ld-ifunc/pr23169a.rd: Likewise.
+ * testsuite/ld-ifunc/pr23169b.c: Likewise.
+ * testsuite/ld-ifunc/pr23169b.c: Likewise.
+ * testsuite/ld-ifunc/pr23169c.rd: Likewise.
+ * testsuite/ld-ifunc/pr23169c.rd: Likewise.
+ * testsuite/ld-ifunc/ifunc-9-x86.d: Removed.
+ * testsuite/ld-ifunc/ifunc.exp: Run PR ld/23169 tests.
+
+2018-05-14 H.J. Lu <hongjiu.lu@intel.com>
+
PR ld/23162
* testsuite/ld-elf/pr23162.map: New file.
* testsuite/ld-elf/pr23162.rd: Likewise.
diff --git a/ld/testsuite/ld-ifunc/ifunc-9-i386.d b/ld/testsuite/ld-ifunc/ifunc-9-i386.d
new file mode 100644
index 0000000..754ee2d
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-9-i386.d
@@ -0,0 +1,9 @@
+#source: ifunc-9-x86.s
+#as: --32
+#ld: -m elf_i386 --export-dynamic
+#readelf: -r --wide
+#target: x86_64-*-* i?86-*-*
+
+Relocation section '.rel.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_386_IRELATIVE[ ]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-9-x86-64.d b/ld/testsuite/ld-ifunc/ifunc-9-x86-64.d
new file mode 100644
index 0000000..85c3a69
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/ifunc-9-x86-64.d
@@ -0,0 +1,9 @@
+#source: ifunc-9-x86.s
+#as: --64
+#ld: -melf_x86_64 --export-dynamic
+#readelf: -r --wide
+#target: x86_64-*-*
+
+Relocation section '.rela.plt' at .*
+[ ]+Offset[ ]+Info[ ]+Type[ ]+.*
+[0-9a-f]+[ ]+[0-9a-f]+[ ]+R_X86_64_IRELATIVE[ ]+[0-9a-f]*
diff --git a/ld/testsuite/ld-ifunc/ifunc-9-x86.d b/ld/testsuite/ld-ifunc/ifunc-9-x86.d
deleted file mode 100644
index 7390dd1..0000000
--- a/ld/testsuite/ld-ifunc/ifunc-9-x86.d
+++ /dev/null
@@ -1,3 +0,0 @@
-#ld: --export-dynamic
-#error: .*dynamic STT_GNU_IFUNC symbol `foo' with pointer equality in `.*.o' can not be used when making an executable; recompile with -fPIE and relink with -pie
-#target: x86_64-*-* i?86-*-*
diff --git a/ld/testsuite/ld-ifunc/ifunc.exp b/ld/testsuite/ld-ifunc/ifunc.exp
index d9cc381..9f4aa73 100644
--- a/ld/testsuite/ld-ifunc/ifunc.exp
+++ b/ld/testsuite/ld-ifunc/ifunc.exp
@@ -581,6 +581,76 @@ run_cc_link_tests [list \
{} \
"libpr18841cn.so" \
] \
+ [list \
+ "Build libpr23169a.so" \
+ "-shared" \
+ "-fPIC -O2 -g" \
+ { pr23169a.c } \
+ {} \
+ "libpr23169a.so" \
+ ] \
+ [list \
+ "Build libpr23169b.so" \
+ "-shared -Wl,-z,now" \
+ "-fPIC -O2 -g" \
+ { pr23169a.c } \
+ {} \
+ "libpr23169b.so" \
+ ] \
+ [list \
+ "Build pr23169a" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libpr23169a.so" \
+ "$NOPIE_CFLAGS -O2 -g" \
+ { pr23169b.c pr23169c.c } \
+ {{readelf {--dyn-syms} pr23169a.rd} \
+ {readelf {-r -W} pr23169b.rd}} \
+ "pr23169a" \
+ ] \
+ [list \
+ "Build pr23169b" \
+ "-pie -Wl,--no-as-needed tmpdir/libpr23169a.so" \
+ "-fPIE -O2 -g" \
+ { pr23169b.c pr23169c.c } \
+ {{readelf {--dyn-syms} pr23169c.rd} \
+ {readelf {-r -W} pr23169b.rd}} \
+ "pr23169b" \
+ ] \
+ [list \
+ "Build pr23169c" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libpr23169a.so" \
+ "-fPIE -O2 -g" \
+ { pr23169b.c pr23169c.c } \
+ {{readelf {--dyn-syms} pr23169c.rd} \
+ {readelf {-r -W} pr23169b.rd}} \
+ "pr23169c" \
+ ] \
+ [list \
+ "Build pr23169d" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed,-z,now tmpdir/libpr23169b.so" \
+ "$NOPIE_CFLAGS -O2 -g" \
+ { pr23169b.c pr23169c.c } \
+ {{readelf {--dyn-syms} pr23169a.rd} \
+ {readelf {-r -W} pr23169b.rd}} \
+ "pr23169d" \
+ ] \
+ [list \
+ "Build pr23169e" \
+ "-pie -Wl,--no-as-needed,-z,now tmpdir/libpr23169b.so" \
+ "-fPIE -O2 -g" \
+ { pr23169b.c pr23169c.c } \
+ {{readelf {--dyn-syms} pr23169c.rd} \
+ {readelf {-r -W} pr23169b.rd}} \
+ "pr23169e" \
+ ] \
+ [list \
+ "Build pr23169f" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed,-z,now tmpdir/libpr23169b.so" \
+ "-fPIE -O2 -g" \
+ { pr23169b.c pr23169c.c } \
+ {{readelf {--dyn-syms} pr23169c.rd} \
+ {readelf {-r -W} pr23169b.rd}} \
+ "pr23169f" \
+ ] \
]
run_ld_link_exec_tests [list \
@@ -632,4 +702,58 @@ run_ld_link_exec_tests [list \
"pr18841cn" \
"pr18841.out" \
] \
+ [list \
+ "Run pr23169a" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libpr23169a.so" \
+ "" \
+ { pr23169b.c pr23169c.c } \
+ "pr23169a" \
+ "pass.out" \
+ "$NOPIE_CFLAGS -O2 -g" \
+ ] \
+ [list \
+ "Run pr23169b" \
+ "-pie -Wl,--no-as-needed tmpdir/libpr23169a.so" \
+ "" \
+ { pr23169b.c pr23169c.c } \
+ "pr23169b" \
+ "pass.out" \
+ "-fPIE -O2 -g" \
+ ] \
+ [list \
+ "Run pr23169c" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed tmpdir/libpr23169a.so" \
+ "" \
+ { pr23169b.c pr23169c.c } \
+ "pr23169c" \
+ "pass.out" \
+ "-fPIE -O2 -g" \
+ ] \
+ [list \
+ "Run pr23169d" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed,-z,now tmpdir/libpr23169b.so" \
+ "" \
+ { pr23169b.c pr23169c.c } \
+ "pr23169d" \
+ "pass.out" \
+ "$NOPIE_CFLAGS -O2 -g" \
+ ] \
+ [list \
+ "Run pr23169e" \
+ "-pie -Wl,--no-as-needed,-z,now tmpdir/libpr23169b.so" \
+ "" \
+ { pr23169b.c pr23169c.c } \
+ "pr23169e" \
+ "pass.out" \
+ "-fPIE -O2 -g" \
+ ] \
+ [list \
+ "Run pr23169f" \
+ "$NOPIE_LDFLAGS -Wl,--no-as-needed,-z,now tmpdir/libpr23169b.so" \
+ "" \
+ { pr23169b.c pr23169c.c } \
+ "pr23169f" \
+ "pass.out" \
+ "-fPIE -O2 -g" \
+ ] \
]
diff --git a/ld/testsuite/ld-ifunc/pr23169a.c b/ld/testsuite/ld-ifunc/pr23169a.c
new file mode 100644
index 0000000..02bf220
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/pr23169a.c
@@ -0,0 +1,9 @@
+int (*func_p) (void);
+extern int func (void);
+
+void
+foo (void)
+{
+ if (func_p != &func || func_p () != 0xbadbeef)
+ __builtin_abort ();
+}
diff --git a/ld/testsuite/ld-ifunc/pr23169a.rd b/ld/testsuite/ld-ifunc/pr23169a.rd
new file mode 100644
index 0000000..ca04d8f
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/pr23169a.rd
@@ -0,0 +1,6 @@
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +FUNC +GLOBAL +DEFAULT +[0-9]+ +func
+#...
diff --git a/ld/testsuite/ld-ifunc/pr23169b.c b/ld/testsuite/ld-ifunc/pr23169b.c
new file mode 100644
index 0000000..99790d4
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/pr23169b.c
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+extern int (*func_p) (void);
+extern int func (void);
+extern void foo (void);
+
+
+void
+bar (void)
+{
+ if (func_p != &func || func_p () != 0xbadbeef)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ func_p = &func;
+ foo ();
+ bar ();
+ printf ("PASS\n");
+ return 0;
+}
diff --git a/ld/testsuite/ld-ifunc/pr23169b.rd b/ld/testsuite/ld-ifunc/pr23169b.rd
new file mode 100644
index 0000000..d57a793
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/pr23169b.rd
@@ -0,0 +1,3 @@
+#failif
+[a-f0-9]+ +[0-9a-f]+ +R_.*_* +[a-f0-9]+ +func(| \+ 0)
+...
diff --git a/ld/testsuite/ld-ifunc/pr23169c.c b/ld/testsuite/ld-ifunc/pr23169c.c
new file mode 100644
index 0000000..b530108
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/pr23169c.c
@@ -0,0 +1,13 @@
+static int
+ifunc (void)
+{
+ return 0xbadbeef;
+}
+
+void func(void) __attribute__((ifunc("resolve_func")));
+
+static void *
+resolve_func (void)
+{
+ return ifunc;
+}
diff --git a/ld/testsuite/ld-ifunc/pr23169c.rd b/ld/testsuite/ld-ifunc/pr23169c.rd
new file mode 100644
index 0000000..1c4ba8a
--- /dev/null
+++ b/ld/testsuite/ld-ifunc/pr23169c.rd
@@ -0,0 +1,6 @@
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[a-f0-9]+ +[0-9]+ +IFUNC +GLOBAL +DEFAULT +[0-9]+ +func
+#...