Support garbage collection against STT_GNU_IFUNC symbols.
[platform/upstream/binutils.git] / bfd / elf-ifunc.c
index b9b50c3..760fc26 100644 (file)
@@ -185,6 +185,17 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
       return FALSE;
     }
 
+  htab = elf_hash_table (info);
+
+  /* Support garbage collection against STT_GNU_IFUNC symbols.  */
+  if (h->plt.refcount <= 0 && h->got.refcount <= 0)
+    {
+      h->got = htab->init_got_offset;
+      h->plt = htab->init_plt_offset;
+      *head = NULL;
+      return TRUE;
+    }
+
   /* Return and discard space for dynamic relocations against it if
      it is never referenced in a non-shared object.  */
   if (!h->ref_regular)
@@ -192,7 +203,8 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
       if (h->plt.refcount > 0
          || h->got.refcount > 0)
        abort ();
-      h->got.offset = (bfd_vma) -1;
+      h->got = htab->init_got_offset;
+      h->plt = htab->init_plt_offset;
       *head = NULL;
       return TRUE;
     }
@@ -203,8 +215,6 @@ _bfd_elf_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
   else
     sizeof_reloc = bed->s->sizeof_rel;
 
-  htab = elf_hash_table (info);
-
   /* When building a static executable, use .iplt, .igot.plt and
      .rel[a].iplt sections for STT_GNU_IFUNC symbols.  */
   if (htab->splt != NULL)