PowerPC fix for ifunc broken by d1eca1e4
authorAlan Modra <amodra@gmail.com>
Mon, 18 Aug 2014 08:44:56 +0000 (18:14 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 18 Aug 2014 11:30:46 +0000 (21:00 +0930)
This probably could be fixed by making changes in relocate_section for
ifunc, but it's simpler to disable the optimisation for ifunc.

* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Don't attempt to
use dynrelocs for ifunc.
* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Similarly.

bfd/ChangeLog
bfd/elf32-ppc.c
bfd/elf64-ppc.c

index 3c2ed57..d7265d4 100644 (file)
@@ -1,5 +1,11 @@
 2014-08-18  Alan Modra  <amodra@gmail.com>
 
+       * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Don't attempt to
+       use dynrelocs for ifunc.
+       * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Similarly.
+
+2014-08-18  Alan Modra  <amodra@gmail.com>
+
        PR 17287
        * elflink.c (on_needed_list): Only consider libraries that have
        been loaded.
index e20e804..97f4724 100644 (file)
@@ -5512,9 +5512,12 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
        {
          /* Taking a function's address in a read/write section
             doesn't require us to define the function symbol in the
-            executable on a global entry stub.  A dynamic reloc can
+            executable on a plt call stub.  A dynamic reloc can
             be used instead.  */
          if (h->pointer_equality_needed
+             && h->type != STT_GNU_IFUNC
+             && !htab->is_vxworks
+             && !ppc_elf_hash_entry (h)->has_sda_refs
              && !readonly_dynrelocs (h))
            {
              h->pointer_equality_needed = 0;
index 0efc602..ca2dd4c 100644 (file)
@@ -7002,6 +7002,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
             executable on a global entry stub.  A dynamic reloc can
             be used instead.  */
          if (h->pointer_equality_needed
+             && h->type != STT_GNU_IFUNC
              && !readonly_dynrelocs (h))
            {
              h->pointer_equality_needed = 0;