Fix SH GOT allocation in the presence of linker garbage collection.
authorNick Clifton <nickc@redhat.com>
Tue, 2 Aug 2016 10:56:55 +0000 (11:56 +0100)
committerNick Clifton <nickc@redhat.com>
Tue, 2 Aug 2016 10:56:55 +0000 (11:56 +0100)
PR ld/17739
ld * emulparams/shelf.sh (CHECK_RELOCS_AFTER_OPEN_INPUT): Define with
valye 'yes'.
* emulparams/shelf32.sh: Likewise.
* emulparams/shelf32.sh: Likewise.
* emulparams/shelf_nto.sh: Likewise.
* emulparams/shelf_nto.sh: Likewise.
* emulparams/shelf_vxworks.sh: Likewise.
* emulparams/shelf_vxworks.sh: Likewise.
* emulparams/shlelf32_linux.sh: Likewise.
* emulparams/shlelf32_linux.sh: Likewise.
* emulparams/shlelf_linux.sh: Likewise.
* emulparams/shlelf_linux.sh: Likewise.
* emulparams/shlelf_nto.sh: Likewise.
* emulparams/shlelf_nto.sh: Likewise.

bfd * elf32-sh.c (sh_elf_gc_sweep_hook): Delete.
(elf_backend_sweep_hook): Delete.

bfd/ChangeLog
bfd/elf32-sh.c
ld/ChangeLog
ld/emulparams/shelf.sh
ld/emulparams/shelf32.sh
ld/emulparams/shelf_nto.sh
ld/emulparams/shelf_vxworks.sh
ld/emulparams/shlelf32_linux.sh
ld/emulparams/shlelf_linux.sh
ld/emulparams/shlelf_nto.sh

index 72e9282..91764b7 100644 (file)
@@ -1,3 +1,9 @@
+2016-08-02  Nick Clifton  <nickc@redhat.com>
+
+       PR ld/17739
+       * elf32-sh.c (sh_elf_gc_sweep_hook): Delete.
+       (elf_backend_sweep_hook): Delete.
+
 2016-08-01  Andrew Jenner  <andrew@codesourcery.com>
        Kwok Cheung Yeung  <kcy@codesourcery.com>
 
index 52a5fd1..84c5b1e 100644 (file)
@@ -5682,220 +5682,6 @@ sh_elf_gc_mark_hook (asection *sec,
   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
 }
 
-/* Update the got entry reference counts for the section being removed.  */
-
-static bfd_boolean
-sh_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
-                     asection *sec, const Elf_Internal_Rela *relocs)
-{
-  Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes;
-  bfd_signed_vma *local_got_refcounts;
-  union gotref *local_funcdesc;
-  const Elf_Internal_Rela *rel, *relend;
-
-  if (bfd_link_relocatable (info))
-    return TRUE;
-
-  elf_section_data (sec)->local_dynrel = NULL;
-
-  symtab_hdr = &elf_symtab_hdr (abfd);
-  sym_hashes = elf_sym_hashes (abfd);
-  local_got_refcounts = elf_local_got_refcounts (abfd);
-  local_funcdesc = sh_elf_local_funcdesc (abfd);
-
-  relend = relocs + sec->reloc_count;
-  for (rel = relocs; rel < relend; rel++)
-    {
-      unsigned long r_symndx;
-      unsigned int r_type;
-      struct elf_link_hash_entry *h = NULL;
-#ifdef INCLUDE_SHMEDIA
-      int seen_stt_datalabel = 0;
-#endif
-
-      r_symndx = ELF32_R_SYM (rel->r_info);
-      if (r_symndx >= symtab_hdr->sh_info)
-       {
-         struct elf_sh_link_hash_entry *eh;
-         struct elf_sh_dyn_relocs **pp;
-         struct elf_sh_dyn_relocs *p;
-
-         h = sym_hashes[r_symndx - symtab_hdr->sh_info];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-           {
-#ifdef INCLUDE_SHMEDIA
-             seen_stt_datalabel |= h->type == STT_DATALABEL;
-#endif
-             h = (struct elf_link_hash_entry *) h->root.u.i.link;
-           }
-         eh = (struct elf_sh_link_hash_entry *) h;
-         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
-           if (p->sec == sec)
-             {
-               /* Everything must go for SEC.  */
-               *pp = p->next;
-               break;
-             }
-       }
-
-      r_type = ELF32_R_TYPE (rel->r_info);
-      switch (sh_elf_optimized_tls_reloc (info, r_type, h != NULL))
-       {
-       case R_SH_TLS_LD_32:
-         if (sh_elf_hash_table (info)->tls_ldm_got.refcount > 0)
-           sh_elf_hash_table (info)->tls_ldm_got.refcount -= 1;
-         break;
-
-       case R_SH_GOT32:
-       case R_SH_GOT20:
-       case R_SH_GOTOFF:
-       case R_SH_GOTOFF20:
-       case R_SH_GOTPC:
-#ifdef INCLUDE_SHMEDIA
-       case R_SH_GOT_LOW16:
-       case R_SH_GOT_MEDLOW16:
-       case R_SH_GOT_MEDHI16:
-       case R_SH_GOT_HI16:
-       case R_SH_GOT10BY4:
-       case R_SH_GOT10BY8:
-       case R_SH_GOTOFF_LOW16:
-       case R_SH_GOTOFF_MEDLOW16:
-       case R_SH_GOTOFF_MEDHI16:
-       case R_SH_GOTOFF_HI16:
-       case R_SH_GOTPC_LOW16:
-       case R_SH_GOTPC_MEDLOW16:
-       case R_SH_GOTPC_MEDHI16:
-       case R_SH_GOTPC_HI16:
-#endif
-       case R_SH_TLS_GD_32:
-       case R_SH_TLS_IE_32:
-       case R_SH_GOTFUNCDESC:
-       case R_SH_GOTFUNCDESC20:
-         if (h != NULL)
-           {
-#ifdef INCLUDE_SHMEDIA
-             if (seen_stt_datalabel)
-               {
-                 struct elf_sh_link_hash_entry *eh;
-                 eh = (struct elf_sh_link_hash_entry *) h;
-                 if (eh->datalabel_got.refcount > 0)
-                   eh->datalabel_got.refcount -= 1;
-               }
-             else
-#endif
-               if (h->got.refcount > 0)
-                 h->got.refcount -= 1;
-           }
-         else if (local_got_refcounts != NULL)
-           {
-#ifdef INCLUDE_SHMEDIA
-             if (rel->r_addend & 1)
-               {
-                 if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
-                   local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
-               }
-             else
-#endif
-               if (local_got_refcounts[r_symndx] > 0)
-                 local_got_refcounts[r_symndx] -= 1;
-           }
-         break;
-
-       case R_SH_FUNCDESC:
-         if (h != NULL)
-           sh_elf_hash_entry (h)->abs_funcdesc_refcount -= 1;
-         else if (sh_elf_hash_table (info)->fdpic_p && !bfd_link_pic (info))
-           sh_elf_hash_table (info)->srofixup->size -= 4;
-
-         /* Fall through.  */
-
-       case R_SH_GOTOFFFUNCDESC:
-       case R_SH_GOTOFFFUNCDESC20:
-         if (h != NULL)
-           sh_elf_hash_entry (h)->funcdesc.refcount -= 1;
-         else
-           local_funcdesc[r_symndx].refcount -= 1;
-         break;
-
-       case R_SH_DIR32:
-         if (sh_elf_hash_table (info)->fdpic_p && !bfd_link_pic (info)
-             && (sec->flags & SEC_ALLOC) != 0)
-           sh_elf_hash_table (info)->srofixup->size -= 4;
-         /* Fall thru */
-
-       case R_SH_REL32:
-         if (bfd_link_pic (info))
-           break;
-         /* Fall thru */
-
-       case R_SH_PLT32:
-#ifdef INCLUDE_SHMEDIA
-       case R_SH_PLT_LOW16:
-       case R_SH_PLT_MEDLOW16:
-       case R_SH_PLT_MEDHI16:
-       case R_SH_PLT_HI16:
-#endif
-         if (h != NULL)
-           {
-             if (h->plt.refcount > 0)
-               h->plt.refcount -= 1;
-           }
-         break;
-
-       case R_SH_GOTPLT32:
-#ifdef INCLUDE_SHMEDIA
-       case R_SH_GOTPLT_LOW16:
-       case R_SH_GOTPLT_MEDLOW16:
-       case R_SH_GOTPLT_MEDHI16:
-       case R_SH_GOTPLT_HI16:
-       case R_SH_GOTPLT10BY4:
-       case R_SH_GOTPLT10BY8:
-#endif
-         if (h != NULL)
-           {
-             struct elf_sh_link_hash_entry *eh;
-             eh = (struct elf_sh_link_hash_entry *) h;
-             if (eh->gotplt_refcount > 0)
-               {
-                 eh->gotplt_refcount -= 1;
-                 if (h->plt.refcount > 0)
-                   h->plt.refcount -= 1;
-               }
-#ifdef INCLUDE_SHMEDIA
-             else if (seen_stt_datalabel)
-               {
-                 if (eh->datalabel_got.refcount > 0)
-                   eh->datalabel_got.refcount -= 1;
-               }
-#endif
-             else if (h->got.refcount > 0)
-               h->got.refcount -= 1;
-           }
-         else if (local_got_refcounts != NULL)
-           {
-#ifdef INCLUDE_SHMEDIA
-             if (rel->r_addend & 1)
-               {
-                 if (local_got_refcounts[symtab_hdr->sh_info + r_symndx] > 0)
-                   local_got_refcounts[symtab_hdr->sh_info + r_symndx] -= 1;
-               }
-             else
-#endif
-               if (local_got_refcounts[r_symndx] > 0)
-                 local_got_refcounts[r_symndx] -= 1;
-           }
-         break;
-
-       default:
-         break;
-       }
-    }
-
-  return TRUE;
-}
-
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
@@ -7455,7 +7241,6 @@ sh_elf_encode_eh_address (bfd *abfd,
                                        sh_elf_merge_private_data
 
 #define elf_backend_gc_mark_hook       sh_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook      sh_elf_gc_sweep_hook
 #define elf_backend_check_relocs       sh_elf_check_relocs
 #define elf_backend_copy_indirect_symbol \
                                        sh_elf_copy_indirect_symbol
index 99bb6df..8dec408 100644 (file)
@@ -1,3 +1,21 @@
+2016-08-02  Nick Clifton  <nickc@redhat.com>
+
+       PR ld/17739
+       * emulparams/shelf.sh (CHECK_RELOCS_AFTER_OPEN_INPUT): Define with
+       valye 'yes'.
+       * emulparams/shelf32.sh: Likewise.
+       * emulparams/shelf32.sh: Likewise.
+       * emulparams/shelf_nto.sh: Likewise.
+       * emulparams/shelf_nto.sh: Likewise.
+       * emulparams/shelf_vxworks.sh: Likewise.
+       * emulparams/shelf_vxworks.sh: Likewise.
+       * emulparams/shlelf32_linux.sh: Likewise.
+       * emulparams/shlelf32_linux.sh: Likewise.
+       * emulparams/shlelf_linux.sh: Likewise.
+       * emulparams/shlelf_linux.sh: Likewise.
+       * emulparams/shlelf_nto.sh: Likewise.
+       * emulparams/shlelf_nto.sh: Likewise.
+
 2016-07-27  Maciej W. Rozycki  <macro@imgtec.com>
 
        * testsuite/ld-mips-elf/micromips-branch-absolute.d: Update
index 83680a6..d3f4752 100644 (file)
@@ -11,6 +11,9 @@ MACHINE=
 TEMPLATE_NAME=elf32
 GENERATE_SHLIB_SCRIPT=yes
 EMBEDDED=yes
+# PR 17739.  Delay checking relocs until after all files have
+# been opened and linker garbage collection has taken place.
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes
 
 # These are for compatibility with the COFF toolchain.
 ENTRY=start
index 966bd30..bf362c5 100644 (file)
@@ -11,6 +11,9 @@ ALIGNMENT=8
 TEMPLATE_NAME=elf32
 GENERATE_SHLIB_SCRIPT=yes
 EMBEDDED=yes
+# PR 17739.  Delay checking relocs until after all files have
+# been opened and linker garbage collection has taken place.
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes
 
 DATA_START_SYMBOLS='PROVIDE (___data = .);'
 
index c4d71aa..46efd87 100644 (file)
@@ -9,3 +9,6 @@ TEMPLATE_NAME=elf32
 GENERATE_SHLIB_SCRIPT=yes
 TEXT_START_SYMBOLS='_btext = .;'
 ENTRY=_start
+# PR 17739.  Delay checking relocs until after all files have
+# been opened and linker garbage collection has taken place.
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes
index 77619cb..759ffac 100644 (file)
@@ -14,6 +14,10 @@ TEMPLATE_NAME=elf32
 GENERATE_SHLIB_SCRIPT=yes
 ENTRY=__start
 SYMPREFIX=_
+# PR 17739.  Delay checking relocs until after all files have
+# been opened and linker garbage collection has taken place.
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes
+
 GOT=".got          ${RELOCATING-0} : {
   PROVIDE(__GLOBAL_OFFSET_TABLE_ = .);
   *(.got.plt) *(.got) }"
index 81aea39..0327e57 100644 (file)
@@ -13,7 +13,9 @@ ALIGNMENT=8
 TEMPLATE_NAME=elf32
 GENERATE_SHLIB_SCRIPT=yes
 GENERATE_PIE_SCRIPT=yes
-
+# PR 17739.  Delay checking relocs until after all files have
+# been opened and linker garbage collection has taken place.
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes
 
 DATA_START_SYMBOLS='PROVIDE (___data = .);'
 
index c14aae2..4e2a581 100644 (file)
@@ -12,6 +12,9 @@ MACHINE=
 TEMPLATE_NAME=elf32
 GENERATE_SHLIB_SCRIPT=yes
 GENERATE_PIE_SCRIPT=yes
+# PR 17739.  Delay checking relocs until after all files have
+# been opened and linker garbage collection has taken place.
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes
 
 DATA_START_SYMBOLS='PROVIDE (__data_start = .);';
 
index 16f6508..f8ffc13 100644 (file)
@@ -9,3 +9,6 @@ TEMPLATE_NAME=elf32
 GENERATE_SHLIB_SCRIPT=yes
 TEXT_START_SYMBOLS='_btext = .;'
 ENTRY=_start
+# PR 17739.  Delay checking relocs until after all files have
+# been opened and linker garbage collection has taken place.
+CHECK_RELOCS_AFTER_OPEN_INPUT=yes