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.
This commit is contained in:
Nick Clifton 2016-08-02 11:56:55 +01:00
parent 2d5bddc1eb
commit a94d834c9d
10 changed files with 46 additions and 216 deletions

View File

@ -1,3 +1,9 @@
2016-08-02 Nick Clifton <nickc@redhat.com>
PR ld/17739
* elf32-sh.c (sh_elf_gc_sweep_hook): Delete.
(elf_backend_sweep_hook): Delete.
2016-08-01 Andrew Jenner <andrew@codesourcery.com>
Kwok Cheung Yeung <kcy@codesourcery.com>

View File

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

View File

@ -1,3 +1,21 @@
2016-08-02 Nick Clifton <nickc@redhat.com>
PR ld/17739
* 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.
2016-07-27 Maciej W. Rozycki <macro@imgtec.com>
* testsuite/ld-mips-elf/micromips-branch-absolute.d: Update

View File

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

View File

@ -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 = .);'

View File

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

View File

@ -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) }"

View File

@ -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 = .);'

View File

@ -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 = .);';

View File

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