diff --git a/patches/binutils-2.27/0002-pr17739-sh-gc-sections-bug.diff b/patches/binutils-2.27/0002-pr17739-sh-gc-sections-bug.diff new file mode 100644 index 0000000..b1fc193 --- /dev/null +++ b/patches/binutils-2.27/0002-pr17739-sh-gc-sections-bug.diff @@ -0,0 +1,364 @@ +From a94d834c9d0108f0bb50ddc311554d1bed320f54 Mon Sep 17 00:00:00 2001 +From: Nick Clifton +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 +