mirror of
https://github.com/pmmp/musl-cross-make.git
synced 2024-11-24 10:46:11 +00:00
005f8e4a3f
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.
365 lines
10 KiB
Diff
365 lines
10 KiB
Diff
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
|
|
|