From 8ded2ddc8bac501c1ee0706cb3d3ef3fb1c10b85 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 27 May 2015 14:32:24 -0700
Subject: [PATCH] Convert PLT reloc only if pointer equality isn't needed
When pointer equality needed, we can't replace PLT relocations with
GOT relocations for -z now. This patch checks if pointer equality is
needed before converting PLT relocations to GOT relocations.
bfd/
PR binutils/18458
* elf32-i386.c (elf_i386_check_relocs): Create .plt.got section
for now binding only if pointer equality isn't needed.
(elf_i386_allocate_dynrelocs): Use .plt.got section for now
binding only if pointer equality isn't needed.
* elf64-x86-64.c (elf_x86_64_check_relocs): Create .plt.got
section for now binding only if pointer equality isn't needed.
(elf_x86_64_allocate_dynrelocs): Use .plt.got section for now
binding only if pointer equality isn't needed.
ld/testsuite/
PR binutils/18458
* ld-elf/shared.exp (build_tests): Build libpr18458a.so and
libpr18458b.so.
(run_tests): Run pr18458 test.
* ld-elf/pr18458a.c: New file.
* ld-elf/pr18458b.c: Likewise.
* ld-elf/pr18458c.c: Likewise.
---
bfd/ChangeLog | 12 ++++++++++++
bfd/elf32-i386.c | 5 +++--
bfd/elf64-x86-64.c | 5 +++--
ld/testsuite/ChangeLog | 10 ++++++++++
ld/testsuite/ld-elf/pr18458a.c | 6 ++++++
ld/testsuite/ld-elf/pr18458b.c | 6 ++++++
ld/testsuite/ld-elf/pr18458c.c | 18 ++++++++++++++++++
ld/testsuite/ld-elf/shared.exp | 9 +++++++++
8 files changed, 67 insertions(+), 4 deletions(-)
create mode 100644 ld/testsuite/ld-elf/pr18458a.c
create mode 100644 ld/testsuite/ld-elf/pr18458b.c
create mode 100644 ld/testsuite/ld-elf/pr18458c.c
@@ -1,3 +1,15 @@
+2015-05-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/18458
+ * elf32-i386.c (elf_i386_check_relocs): Create .plt.got section
+ for now binding only if pointer equality isn't needed.
+ (elf_i386_allocate_dynrelocs): Use .plt.got section for now
+ binding only if pointer equality isn't needed.
+ * elf64-x86-64.c (elf_x86_64_check_relocs): Create .plt.got
+ section for now binding only if pointer equality isn't needed.
+ (elf_x86_64_allocate_dynrelocs): Use .plt.got section for now
+ binding only if pointer equality isn't needed.
+
2015-05-26 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/18437
@@ -1885,7 +1885,8 @@ do_size:
if (use_plt_got
&& h != NULL
&& h->plt.refcount > 0
- && ((info->flags & DF_BIND_NOW) || h->got.refcount > 0)
+ && (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed)
+ || h->got.refcount > 0)
&& htab->plt_got == NULL)
{
/* Create the GOT procedure linkage table. */
@@ -2323,7 +2324,7 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
bfd_boolean use_plt_got;
- if ((info->flags & DF_BIND_NOW))
+ if ((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed)
{
/* Don't use the regular PLT for DF_BIND_NOW. */
h->plt.offset = (bfd_vma) -1;
@@ -2080,7 +2080,8 @@ do_size:
if (use_plt_got
&& h != NULL
&& h->plt.refcount > 0
- && ((info->flags & DF_BIND_NOW) || h->got.refcount > 0)
+ && (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed)
+ || h->got.refcount > 0)
&& htab->plt_got == NULL)
{
/* Create the GOT procedure linkage table. */
@@ -2542,7 +2543,7 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
{
bfd_boolean use_plt_got;
- if ((info->flags & DF_BIND_NOW))
+ if ((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed)
{
/* Don't use the regular PLT for DF_BIND_NOW. */
h->plt.offset = (bfd_vma) -1;
@@ -1,3 +1,13 @@
+2015-05-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR binutils/18458
+ * ld-elf/shared.exp (build_tests): Build libpr18458a.so and
+ libpr18458b.so.
+ (run_tests): Run pr18458 test.
+ * ld-elf/pr18458a.c: New file.
+ * ld-elf/pr18458b.c: Likewise.
+ * ld-elf/pr18458c.c: Likewise.
+
2015-05-16 H.J. Lu <hongjiu.lu@intel.com>
* ld-i386/i386.exp: Run PR ld/17689 tests with -z now.
new file mode 100644
@@ -0,0 +1,6 @@
+#include <stdio.h>
+void
+a (void)
+{
+ printf("PASS\n");
+}
new file mode 100644
@@ -0,0 +1,6 @@
+extern void a (void);
+void
+b (void)
+{
+ a();
+}
new file mode 100644
@@ -0,0 +1,18 @@
+extern void a(void);
+extern void b(void);
+
+void dummy (void)
+{
+ a();
+}
+int
+compare (void (*f)(void))
+{
+ return a == f;
+}
+int
+main (void)
+{
+ b ();
+ return 0;
+}
@@ -267,6 +267,12 @@ set build_tests {
{"Build pr16457"
"tmpdir/libpr16452b.so -Wl,-rpath=tmpdir" ""
{pr16452b.c} {{objdump {-p} pr16457.od}} "pr16457"}
+ {"Build libpr18458a.so"
+ "-shared -Wl,-z,now" "-fPIC"
+ {pr18458a.c} {} "libpr18458a.so"}
+ {"Build libpr18458b.so"
+ "-shared -Wl,-z,now tmpdir/libpr18458a.so" "-fPIC"
+ {pr18458b.c} {} "libpr18458b.so"}
}
run_cc_link_tests $build_tests
@@ -417,6 +423,9 @@ set run_tests {
{"Run pr2404"
"tmpdir/pr2404b.o tmpdir/libpr2404a.so" ""
{dummy.c} "pr2404" "pr2404.out"}
+ {"Run pr18458"
+ "tmpdir/libpr18458a.so tmpdir/libpr18458b.so -z now" ""
+ {pr18458c.c} "pr18458" "pass.out"}
}
# NetBSD ELF systems do not currently support the .*_array sections.
--
1.9.3