Convert PLT reloc only if pointer equality isn't needed
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 27 May 2015 21:32:24 +0000 (14:32 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 27 May 2015 21:32:24 +0000 (14:32 -0700)
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
bfd/elf32-i386.c
bfd/elf64-x86-64.c
ld/testsuite/ChangeLog
ld/testsuite/ld-elf/pr18458a.c [new file with mode: 0644]
ld/testsuite/ld-elf/pr18458b.c [new file with mode: 0644]
ld/testsuite/ld-elf/pr18458c.c [new file with mode: 0644]
ld/testsuite/ld-elf/shared.exp

index 87a0bffb45945601f6030a6561eeaf9b7a06e5a8..a8a0ad9a7098d5e95e7ae48b8e1bc9c637921590 100644 (file)
@@ -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
index 23d50e1193dee6cd5416684545164d4b3e87aff8..f3aee96822f659383c04f06100cff179eec136f2 100644 (file)
@@ -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;
index 4428f97e9b4773acdbfbaecf96889d106d9d8afc..072c00b7193cee37c2a2fb3e7e4e0658279647d3 100644 (file)
@@ -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;
index e6a551c7728850bb82fb97ebbf7eeb785c1c1339..779fc035c1a6368e6e2e2fa67c21e1623917cc9a 100644 (file)
@@ -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.
diff --git a/ld/testsuite/ld-elf/pr18458a.c b/ld/testsuite/ld-elf/pr18458a.c
new file mode 100644 (file)
index 0000000..d6aa49f
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdio.h>
+void 
+a (void)
+{
+  printf("PASS\n");
+}
diff --git a/ld/testsuite/ld-elf/pr18458b.c b/ld/testsuite/ld-elf/pr18458b.c
new file mode 100644 (file)
index 0000000..33c1cb6
--- /dev/null
@@ -0,0 +1,6 @@
+extern void a (void);
+void
+b (void)
+{
+  a();
+}
diff --git a/ld/testsuite/ld-elf/pr18458c.c b/ld/testsuite/ld-elf/pr18458c.c
new file mode 100644 (file)
index 0000000..d40f98c
--- /dev/null
@@ -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;
+}
index 8aa7a323c13688941438167dffd7ec78fba80d2a..bcbe8e211e9a2c9dfc3830b5457f60e5d4574882 100644 (file)
@@ -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.