|
@@ -0,0 +1,364 @@
|
|
|
+From a94d834c9d0108f0bb50ddc311554d1bed320f54 Mon Sep 17 00:00:00 2001
|
|
|
+From: Nick Clifton <nickc@redhat.com>
|
|
|
+Date: Tue, 2 Aug 2016 11:56:55 +0100
|
|
|
+Subject: [PATCH] Fix SH GOT allocation in the presence of linker garbage collection.
|
|
|
+
|
|
|
+ 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/elf32-sh.c | 215 ---------------------------------------
|
|
|
+ ld/emulparams/shelf.sh | 3 +
|
|
|
+ ld/emulparams/shelf32.sh | 3 +
|
|
|
+ ld/emulparams/shelf_nto.sh | 3 +
|
|
|
+ ld/emulparams/shelf_vxworks.sh | 4 +
|
|
|
+ ld/emulparams/shlelf32_linux.sh | 4 +-
|
|
|
+ ld/emulparams/shlelf_linux.sh | 3 +
|
|
|
+ ld/emulparams/shlelf_nto.sh | 3 +
|
|
|
+ 10 files changed, 46 insertions(+), 216 deletions(-)
|
|
|
+
|
|
|
+diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
|
|
|
+index 52a5fd1..84c5b1e 100644
|
|
|
+--- a/bfd/elf32-sh.c
|
|
|
++++ b/bfd/elf32-sh.c
|
|
|
+@@ -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
|
|
|
+diff --git a/ld/emulparams/shelf.sh b/ld/emulparams/shelf.sh
|
|
|
+index 83680a6..d3f4752 100644
|
|
|
+--- a/ld/emulparams/shelf.sh
|
|
|
++++ b/ld/emulparams/shelf.sh
|
|
|
+@@ -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
|
|
|
+diff --git a/ld/emulparams/shelf32.sh b/ld/emulparams/shelf32.sh
|
|
|
+index 966bd30..bf362c5 100644
|
|
|
+--- a/ld/emulparams/shelf32.sh
|
|
|
++++ b/ld/emulparams/shelf32.sh
|
|
|
+@@ -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 = .);'
|
|
|
+
|
|
|
+diff --git a/ld/emulparams/shelf_nto.sh b/ld/emulparams/shelf_nto.sh
|
|
|
+index c4d71aa..46efd87 100644
|
|
|
+--- a/ld/emulparams/shelf_nto.sh
|
|
|
++++ b/ld/emulparams/shelf_nto.sh
|
|
|
+@@ -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
|
|
|
+diff --git a/ld/emulparams/shelf_vxworks.sh b/ld/emulparams/shelf_vxworks.sh
|
|
|
+index 77619cb..759ffac 100644
|
|
|
+--- a/ld/emulparams/shelf_vxworks.sh
|
|
|
++++ b/ld/emulparams/shelf_vxworks.sh
|
|
|
+@@ -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) }"
|
|
|
+diff --git a/ld/emulparams/shlelf32_linux.sh b/ld/emulparams/shlelf32_linux.sh
|
|
|
+index 81aea39..0327e57 100644
|
|
|
+--- a/ld/emulparams/shlelf32_linux.sh
|
|
|
++++ b/ld/emulparams/shlelf32_linux.sh
|
|
|
+@@ -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 = .);'
|
|
|
+
|
|
|
+diff --git a/ld/emulparams/shlelf_linux.sh b/ld/emulparams/shlelf_linux.sh
|
|
|
+index c14aae2..4e2a581 100644
|
|
|
+--- a/ld/emulparams/shlelf_linux.sh
|
|
|
++++ b/ld/emulparams/shlelf_linux.sh
|
|
|
+@@ -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 = .);';
|
|
|
+
|
|
|
+diff --git a/ld/emulparams/shlelf_nto.sh b/ld/emulparams/shlelf_nto.sh
|
|
|
+index 16f6508..f8ffc13 100644
|
|
|
+--- a/ld/emulparams/shlelf_nto.sh
|
|
|
++++ b/ld/emulparams/shlelf_nto.sh
|
|
|
+@@ -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
|
|
|
+--
|
|
|
+1.7.1
|
|
|
+
|