PR ld/13387
authorDave Anglin <dave.anglin@nrc.ca>
Sun, 6 Nov 2011 20:25:17 +0000 (20:25 +0000)
committerDave Anglin <dave.anglin@nrc.ca>
Sun, 6 Nov 2011 20:25:17 +0000 (20:25 +0000)
* elf32-hppa.c (elf32_hppa_hide_symbol): Make STT_GNU_IFUNC symbol
go through PLT.  Reset plt field with init_plt_offset.
(elf32_hppa_adjust_dynamic_symbol): Ensure that a PLT slot is
allocated for symbols referenced by a plabel.

bfd/ChangeLog
bfd/elf32-hppa.c

index ebf5b0f4bdf5d45a30a86fa4ba76520f8641d19d..ac69b7b045010b03c0573daa91f3535a167c8e7a 100644 (file)
@@ -1,3 +1,11 @@
+2011-11-06  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR ld/13387
+       * elf32-hppa.c (elf32_hppa_hide_symbol): Make STT_GNU_IFUNC symbol
+       go through PLT.  Reset plt field with init_plt_offset.
+       (elf32_hppa_adjust_dynamic_symbol): Ensure that a PLT slot is
+       allocated for symbols referenced by a plabel.
+
 2011-11-02  DJ Delorie  <dj@redhat.com>
 
        * elf32-rl78.c (rl78_elf_merge_private_bfd_data): Delete unused
index 7f0f2cb10e8608497281ed4eec4e2f4075df8e21..fcf51cf8d386691a080d47ffccfaa6d06e47f652 100644 (file)
@@ -1789,10 +1789,12 @@ elf32_hppa_hide_symbol (struct bfd_link_info *info,
        }
     }
 
-  if (! hppa_elf_hash_entry (eh)->plabel)
+  /* STT_GNU_IFUNC symbol must go through PLT.  */
+  if (! hppa_elf_hash_entry (eh)->plabel
+      && eh->type != STT_GNU_IFUNC)
     {
       eh->needs_plt = 0;
-      eh->plt = elf_hash_table (info)->init_plt_refcount;
+      eh->plt = elf_hash_table (info)->init_plt_offset;
     }
 }
 
@@ -1814,6 +1816,13 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (eh->type == STT_FUNC
       || eh->needs_plt)
     {
+      /* If the symbol is used by a plabel, we must allocate a PLT slot.
+        The refcounts are not reliable when it has been hidden since
+        hide_symbol can be called before the plabel flag is set.  */
+      if (hppa_elf_hash_entry (eh)->plabel
+         && eh->plt.refcount <= 0)
+       eh->plt.refcount = 1;
+
       if (eh->plt.refcount <= 0
          || (eh->def_regular
              && eh->root.type != bfd_link_hash_defweak