add binutils 2.27 patch fixing pr17739 on sh

upstream fix was slightly too late to make it into the release. patch
was not included in mcm for previous binutils versions because it
depends on new upstream infrastructure. now gc-sections should be safe
to use on sh.
This commit is contained in:
Rich Felker 2016-11-07 16:13:21 -05:00
parent d08c2e8e02
commit 005f8e4a3f
1 changed files with 364 additions and 0 deletions

View File

@ -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