123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- From a94d834c9d0108f0bb50ddc311554d1bed320f54 Mon Sep 17 00:00:00 2001
- From: Nick Clifton <[email protected]>
- 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
|