* elf32-hppa.c (elf32_hppa_gc_sweep_hook): Simplify dynamic reloc

removal.  Localize vars.  Remove unnecessary dynobj test.
	* elf32-i386 (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead
	of INFO.
	(allocate_dynrelocs): Adjust WILL_CALL_FINISH_DYNAMIC_SYMBOL uses,
	and optimize.
	(elf_i386_relocate_section): Likewise.
	(elf_i386_gc_sweep_hook): Simplify dyn reloc removal.  Localize vars.
	* elf32-s390.c (elf_s390_gc_sweep_hook): Likewise.
	* elf32-sh.c (sh_elf_gc_sweep_hook): Likewise.
	* elf64-s390.c (elf_s390_gc_sweep_hook): Likewise.
	* elf64-x86-64.c (elf64_x86_64_gc_sweep_hook): Likewise.
	* elf32-sparc.c (elf32_sparc_gc_sweep_hook): Likewise.  Remove
	local_dynrel for section too.  Don't touch HIPLT22, LOPLT10, PCPLT32
	or PCPLT10 relocs.  Don't subtract twice on PLT32 relocs.
	Formatting.
This commit is contained in:
Alan Modra 2003-02-19 14:14:16 +00:00
parent f4656909e9
commit 26e415943a
8 changed files with 712 additions and 811 deletions

View File

@ -1,5 +1,22 @@
2003-02-19 Alan Modra <amodra@bigpond.net.au>
* elf32-hppa.c (elf32_hppa_gc_sweep_hook): Simplify dynamic reloc
removal. Localize vars. Remove unnecessary dynobj test.
* elf32-i386 (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Pass SHARED instead
of INFO.
(allocate_dynrelocs): Adjust WILL_CALL_FINISH_DYNAMIC_SYMBOL uses,
and optimize.
(elf_i386_relocate_section): Likewise.
(elf_i386_gc_sweep_hook): Simplify dyn reloc removal. Localize vars.
* elf32-s390.c (elf_s390_gc_sweep_hook): Likewise.
* elf32-sh.c (sh_elf_gc_sweep_hook): Likewise.
* elf64-s390.c (elf_s390_gc_sweep_hook): Likewise.
* elf64-x86-64.c (elf64_x86_64_gc_sweep_hook): Likewise.
* elf32-sparc.c (elf32_sparc_gc_sweep_hook): Likewise. Remove
local_dynrel for section too. Don't touch HIPLT22, LOPLT10, PCPLT32
or PCPLT10 relocs. Don't subtract twice on PLT32 relocs.
Formatting.
* elf64-ppc.c (ELIMINATE_COPY_RELOCS): Define.
(ppc64_elf_check_relocs): Use it. Correct comment. Move SEC_ALLOC
test.

View File

@ -1685,10 +1685,6 @@ elf32_hppa_gc_sweep_hook (abfd, info, sec, relocs)
bfd_signed_vma *local_got_refcounts;
bfd_signed_vma *local_plt_refcounts;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
struct elf_link_hash_entry *h;
struct elf32_hppa_link_hash_table *htab;
bfd *dynobj;
elf_section_data (sec)->local_dynrel = NULL;
@ -1698,112 +1694,81 @@ elf32_hppa_gc_sweep_hook (abfd, info, sec, relocs)
local_plt_refcounts = local_got_refcounts;
if (local_plt_refcounts != NULL)
local_plt_refcounts += symtab_hdr->sh_info;
htab = hppa_link_hash_table (info);
dynobj = htab->elf.dynobj;
if (dynobj == NULL)
return TRUE;
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
switch ((unsigned int) ELF32_R_TYPE (rel->r_info))
{
case R_PARISC_DLTIND14F:
case R_PARISC_DLTIND14R:
case R_PARISC_DLTIND21L:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
{
unsigned long r_symndx;
unsigned int r_type;
struct elf_link_hash_entry *h = NULL;
case R_PARISC_PCREL12F:
case R_PARISC_PCREL17C:
case R_PARISC_PCREL17F:
case R_PARISC_PCREL22F:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf32_hppa_link_hash_entry *eh;
struct elf32_hppa_dyn_reloc_entry **pp;
struct elf32_hppa_dyn_reloc_entry *p;
case R_PARISC_PLABEL14R:
case R_PARISC_PLABEL21L:
case R_PARISC_PLABEL32:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf32_hppa_link_hash_entry *eh;
struct elf32_hppa_dyn_reloc_entry **pp;
struct elf32_hppa_dyn_reloc_entry *p;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
eh = (struct elf32_hppa_link_hash_entry *) h;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
/* Everything must go for SEC. */
*pp = p->next;
break;
}
}
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
r_type = ELF32_R_TYPE (rel->r_info);
switch (r_type)
{
case R_PARISC_DLTIND14F:
case R_PARISC_DLTIND14R:
case R_PARISC_DLTIND21L:
if (h != NULL)
{
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
eh = (struct elf32_hppa_link_hash_entry *) h;
case R_PARISC_PCREL12F:
case R_PARISC_PCREL17C:
case R_PARISC_PCREL17F:
case R_PARISC_PCREL22F:
if (h != NULL)
{
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
#if RELATIVE_DYNRELOCS
if (!IS_ABSOLUTE_RELOC (rtype))
p->relative_count -= 1;
#endif
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
else if (local_plt_refcounts != NULL)
{
if (local_plt_refcounts[r_symndx] > 0)
local_plt_refcounts[r_symndx] -= 1;
}
break;
case R_PARISC_PLABEL14R:
case R_PARISC_PLABEL21L:
case R_PARISC_PLABEL32:
if (h != NULL)
{
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
else if (local_plt_refcounts != NULL)
{
if (local_plt_refcounts[r_symndx] > 0)
local_plt_refcounts[r_symndx] -= 1;
}
break;
case R_PARISC_DIR32:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf32_hppa_link_hash_entry *eh;
struct elf32_hppa_dyn_reloc_entry **pp;
struct elf32_hppa_dyn_reloc_entry *p;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
eh = (struct elf32_hppa_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
#if RELATIVE_DYNRELOCS
if (!IS_ABSOLUTE_RELOC (R_PARISC_DIR32))
p->relative_count -= 1;
#endif
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
default:
break;
}
default:
break;
}
}
return TRUE;
}

View File

@ -1279,9 +1279,6 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs)
struct elf_link_hash_entry **sym_hashes;
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
int r_type;
struct elf_link_hash_entry *h;
elf_section_data (sec)->local_dynrel = NULL;
@ -1291,85 +1288,74 @@ elf_i386_gc_sweep_hook (abfd, info, sec, relocs)
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
switch ((r_type = elf_i386_tls_transition (info,
ELF32_R_TYPE (rel->r_info),
ELF32_R_SYM (rel->r_info)
>= symtab_hdr->sh_info)))
{
case R_386_TLS_LDM:
if (elf_i386_hash_table (info)->tls_ldm_got.refcount > 0)
elf_i386_hash_table (info)->tls_ldm_got.refcount -= 1;
break;
{
unsigned long r_symndx;
unsigned int r_type;
struct elf_link_hash_entry *h = NULL;
case R_386_TLS_GD:
case R_386_TLS_IE_32:
case R_386_TLS_IE:
case R_386_TLS_GOTIE:
case R_386_GOT32:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
if (r_type != R_386_TLS_IE)
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf_i386_link_hash_entry *eh;
struct elf_i386_dyn_relocs **pp;
struct elf_i386_dyn_relocs *p;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
eh = (struct elf_i386_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);
r_type = elf_i386_tls_transition (info, r_type, h != NULL);
switch (r_type)
{
case R_386_TLS_LDM:
if (elf_i386_hash_table (info)->tls_ldm_got.refcount > 0)
elf_i386_hash_table (info)->tls_ldm_got.refcount -= 1;
break;
/* Fall through */
case R_386_TLS_LE_32:
case R_386_TLS_LE:
if (!info->shared)
case R_386_TLS_GD:
case R_386_TLS_IE_32:
case R_386_TLS_IE:
case R_386_TLS_GOTIE:
case R_386_GOT32:
if (h != NULL)
{
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
/* Fall through */
case R_386_32:
case R_386_PC32:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf_i386_link_hash_entry *eh;
struct elf_i386_dyn_relocs **pp;
struct elf_i386_dyn_relocs *p;
case R_386_32:
case R_386_PC32:
if (info->shared)
break;
/* Fall through */
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
case R_386_PLT32:
if (h != NULL)
{
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
eh = (struct elf_i386_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
if (ELF32_R_TYPE (rel->r_info) == R_386_PC32)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
case R_386_PLT32:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
default:
break;
}
default:
break;
}
}
return TRUE;
}
@ -1523,9 +1509,9 @@ elf_i386_adjust_dynamic_symbol (info, h)
will be called from elflink.h. If elflink.h doesn't call our
finish_dynamic_symbol routine, we'll need to do something about
initializing any .plt and .got entries in elf_i386_relocate_section. */
#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \
#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \
((DYN) \
&& ((INFO)->shared \
&& ((SHARED) \
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \
&& ((H)->dynindx != -1 \
|| ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))
@ -1567,7 +1553,8 @@ allocate_dynrelocs (h, inf)
return FALSE;
}
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))
if (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
{
asection *s = htab->splt;
@ -1653,7 +1640,8 @@ allocate_dynrelocs (h, inf)
htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
else if (tls_type == GOT_TLS_GD)
htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel);
else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
else if (info->shared
|| WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
}
else
@ -2289,7 +2277,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
off = h->got.offset;
dyn = htab->elf.dynamic_sections_created;
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
|| (info->shared
&& (info->symbolic
|| h->dynindx == -1
@ -2626,7 +2614,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
BFD_ASSERT (rel->r_offset >= 2);
type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
switch (type)
{
{
case 0x8b:
/* movl */
BFD_ASSERT ((val & 0xc7) == 0x05);
@ -2648,7 +2636,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
default:
BFD_FAIL ();
break;
}
}
}
bfd_put_32 (output_bfd, -tpoff (info, relocation),
contents + rel->r_offset);
@ -2723,7 +2711,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
if ((off & 1) != 0)
off &= ~1;
else
else
{
Elf_Internal_Rela outrel;
bfd_byte *loc;

View File

@ -351,7 +351,7 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
/* A relocation function which doesn't do anything. */
static bfd_reloc_status_type
s390_tls_reloc (abfd, reloc_entry, symbol, data, input_section,
output_bfd, error_message)
output_bfd, error_message)
bfd *abfd ATTRIBUTE_UNUSED;
arelent *reloc_entry;
asymbol *symbol ATTRIBUTE_UNUSED;
@ -935,7 +935,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
&& local_got_refcounts == NULL)
{
bfd_size_type size;
size = symtab_hdr->sh_info;
size *= (sizeof (bfd_signed_vma) + sizeof(char));
local_got_refcounts = ((bfd_signed_vma *)
@ -969,20 +969,20 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
/* Got is created, nothing to be done. */
break;
case R_390_PLT16DBL:
case R_390_PLT32DBL:
case R_390_PLT16DBL:
case R_390_PLT32DBL:
case R_390_PLT32:
case R_390_PLTOFF16:
case R_390_PLTOFF32:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code which is
never referenced by a dynamic object, in which case we
don't need to generate a procedure linkage table entry
after all. */
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code which is
never referenced by a dynamic object, in which case we
don't need to generate a procedure linkage table entry
after all. */
/* If this is a local symbol, we resolve it directly without
creating a procedure linkage table entry. */
creating a procedure linkage table entry. */
if (h != NULL)
{
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
@ -1025,7 +1025,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
/* Fall through. */
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOTENT:
case R_390_TLS_GD32:
@ -1095,11 +1095,11 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
info->flags |= DF_STATIC_TLS;
/* Fall through. */
case R_390_8:
case R_390_16:
case R_390_8:
case R_390_16:
case R_390_32:
case R_390_PC16:
case R_390_PC16DBL:
case R_390_PC16:
case R_390_PC16DBL:
case R_390_PC32DBL:
case R_390_PC32:
if (h != NULL && !info->shared)
@ -1254,17 +1254,17 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
case R_390_GNU_VTINHERIT:
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return FALSE;
break;
case R_390_GNU_VTINHERIT:
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return FALSE;
break;
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_390_GNU_VTENTRY:
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
case R_390_GNU_VTENTRY:
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
default:
break;
@ -1327,9 +1327,6 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
struct elf_link_hash_entry **sym_hashes;
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
int r_type;
struct elf_link_hash_entry *h;
elf_section_data (sec)->local_dynrel = NULL;
@ -1340,16 +1337,31 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
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;
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf_s390_link_hash_entry *eh;
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
eh = (struct elf_s390_link_hash_entry *) h;
r_type = elf_s390_tls_transition (info,
ELF32_R_TYPE (rel->r_info),
r_symndx >= symtab_hdr->sh_info);
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);
r_type = elf_s390_tls_transition (info, r_type, h != NULL);
switch (r_type)
{
case R_390_TLS_LDM32:
@ -1380,14 +1392,7 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
if (r_type != R_390_TLS_IE32)
break;
/* Fall through. */
case R_390_TLS_LE32:
if (!info->shared)
break;
/* Fall through. */
break;
case R_390_8:
case R_390_12:
@ -1397,33 +1402,10 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
case R_390_PC16DBL:
case R_390_PC32DBL:
case R_390_PC32:
if (h != NULL)
{
struct elf_s390_link_hash_entry *eh;
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
eh = (struct elf_s390_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
if (ELF32_R_TYPE (rel->r_info) == R_390_PC16
|| ELF32_R_TYPE (rel->r_info) == R_390_PC16DBL
|| ELF32_R_TYPE (rel->r_info) == R_390_PC32DBL
|| ELF32_R_TYPE (rel->r_info) == R_390_PC32)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
if (info->shared)
break;
/* Fall through. */
case R_390_PLT16DBL:
case R_390_PLT32DBL:
case R_390_PLT32:
@ -1517,8 +1499,8 @@ elf_s390_adjust_dynamic_symbol (info, h)
&& h->root.type != bfd_link_hash_undefined))
{
/* This case can occur if we saw a PLT32 reloc in an input
file, but the symbol was never referred to by a dynamic
object, or if all references were garbage collected. In
file, but the symbol was never referred to by a dynamic
object, or if all references were garbage collected. In
such a case, we don't actually need to build a procedure
linkage table, and we can just do a PC32 reloc instead. */
h->plt.offset = (bfd_vma) -1;
@ -2081,10 +2063,10 @@ elf_s390_size_dynamic_sections (output_bfd, info)
}
if (relocs)
{
if (!add_dynamic_entry (DT_RELA, 0)
|| !add_dynamic_entry (DT_RELASZ, 0)
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
{
if (!add_dynamic_entry (DT_RELA, 0)
|| !add_dynamic_entry (DT_RELASZ, 0)
|| !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
return FALSE;
/* If any dynamic relocs apply to a read-only section,
@ -2204,8 +2186,8 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == (int) R_390_GNU_VTINHERIT
|| r_type == (int) R_390_GNU_VTENTRY)
continue;
|| r_type == (int) R_390_GNU_VTENTRY)
continue;
if (r_type >= (int) R_390_max)
{
bfd_set_error (bfd_error_bad_value);
@ -2261,7 +2243,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
{
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
input_section, rel->r_offset,
input_section, rel->r_offset,
(!info->shared || info->no_undefined
|| ELF_ST_VISIBILITY (h->other)))))
return FALSE;
@ -2292,7 +2274,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
Current offset - size first entry / entry size. */
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
PLT_ENTRY_SIZE;
/* Offset in GOT is PLT index plus GOT headers(3) times 4,
addr & GOT addr. */
relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
@ -2304,92 +2286,92 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
}
/* Fall through. */
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOTENT:
/* Relocation is to the entry for this symbol in the global
offset table. */
/* Relocation is to the entry for this symbol in the global
offset table. */
if (htab->sgot == NULL)
abort ();
if (h != NULL)
{
if (h != NULL)
{
bfd_boolean dyn;
off = h->got.offset;
off = h->got.offset;
dyn = htab->elf.dynamic_sections_created;
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
|| (info->shared
&& (info->symbolic
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
|| (info->shared
&& (info->symbolic
|| h->dynindx == -1
|| (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
{
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
because of a version file. We must initialize
this entry in the global offset table. Since the
offset must always be a multiple of 2, we use the
least significant bit to record whether we have
initialized it already.
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
{
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
because of a version file. We must initialize
this entry in the global offset table. Since the
offset must always be a multiple of 2, we use the
least significant bit to record whether we have
initialized it already.
When doing a dynamic link, we create a .rel.got
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
if ((off & 1) != 0)
off &= ~1;
else
{
When doing a dynamic link, we create a .rel.got
relocation entry to initialize the value. This
is done in the finish_dynamic_symbol routine. */
if ((off & 1) != 0)
off &= ~1;
else
{
bfd_put_32 (output_bfd, relocation,
htab->sgot->contents + off);
h->got.offset |= 1;
}
}
h->got.offset |= 1;
}
}
else
unresolved_reloc = FALSE;
}
else
{
}
else
{
if (local_got_offsets == NULL)
abort ();
off = local_got_offsets[r_symndx];
off = local_got_offsets[r_symndx];
/* The offset must always be a multiple of 4. We use
the least significant bit to record whether we have
already generated the necessary reloc. */
if ((off & 1) != 0)
off &= ~1;
else
{
bfd_put_32 (output_bfd, relocation,
/* The offset must always be a multiple of 4. We use
the least significant bit to record whether we have
already generated the necessary reloc. */
if ((off & 1) != 0)
off &= ~1;
else
{
bfd_put_32 (output_bfd, relocation,
htab->sgot->contents + off);
if (info->shared)
{
asection *srelgot;
Elf_Internal_Rela outrel;
if (info->shared)
{
asection *srelgot;
Elf_Internal_Rela outrel;
bfd_byte *loc;
srelgot = htab->srelgot;
srelgot = htab->srelgot;
if (srelgot == NULL)
abort ();
outrel.r_offset = (htab->sgot->output_section->vma
+ htab->sgot->output_offset
+ off);
outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
outrel.r_offset = (htab->sgot->output_section->vma
+ htab->sgot->output_offset
+ off);
outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
outrel.r_addend = relocation;
loc = srelgot->contents;
loc += srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
}
local_got_offsets[r_symndx] |= 1;
}
}
local_got_offsets[r_symndx] |= 1;
}
}
if (off >= (bfd_vma) -2)
abort ();
@ -2404,62 +2386,62 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
|| r_type == R_390_GOTPLTENT)
relocation += htab->sgot->output_section->vma;
break;
break;
case R_390_GOTOFF16:
case R_390_GOTOFF32:
/* Relocation is relative to the start of the global offset
table. */
case R_390_GOTOFF32:
/* Relocation is relative to the start of the global offset
table. */
/* Note that sgot->output_offset is not involved in this
calculation. We always want the start of .got. If we
defined _GLOBAL_OFFSET_TABLE in a different way, as is
permitted by the ABI, we might have to change this
calculation. */
relocation -= htab->sgot->output_section->vma;
break;
/* Note that sgot->output_offset is not involved in this
calculation. We always want the start of .got. If we
defined _GLOBAL_OFFSET_TABLE in a different way, as is
permitted by the ABI, we might have to change this
calculation. */
relocation -= htab->sgot->output_section->vma;
break;
case R_390_GOTPC:
case R_390_GOTPC:
case R_390_GOTPCDBL:
/* Use global offset table as symbol value. */
relocation = htab->sgot->output_section->vma;
/* Use global offset table as symbol value. */
relocation = htab->sgot->output_section->vma;
unresolved_reloc = FALSE;
break;
break;
case R_390_PLT16DBL:
case R_390_PLT32DBL:
case R_390_PLT32:
/* Relocation is to the entry for this symbol in the
procedure linkage table. */
case R_390_PLT16DBL:
case R_390_PLT32DBL:
case R_390_PLT32:
/* Relocation is to the entry for this symbol in the
procedure linkage table. */
/* Resolve a PLT32 reloc against a local symbol directly,
without using the procedure linkage table. */
if (h == NULL)
break;
/* Resolve a PLT32 reloc against a local symbol directly,
without using the procedure linkage table. */
if (h == NULL)
break;
if (h->plt.offset == (bfd_vma) -1
if (h->plt.offset == (bfd_vma) -1
|| htab->splt == NULL)
{
/* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when
using -Bsymbolic. */
break;
}
{
/* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when
using -Bsymbolic. */
break;
}
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset);
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset);
unresolved_reloc = FALSE;
break;
break;
case R_390_PLTOFF16:
case R_390_PLTOFF32:
/* Relocation is to the entry for this symbol in the
procedure linkage table relative to the start of the GOT. */
/* Relocation is to the entry for this symbol in the
procedure linkage table relative to the start of the GOT. */
/* For local symbols or if we didn't make a PLT entry for
this symbol resolve the symbol directly. */
if ( h == NULL
if ( h == NULL
|| h->plt.offset == (bfd_vma) -1
|| htab->splt == NULL)
{
@ -2467,28 +2449,28 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
break;
}
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset
- htab->sgot->output_section->vma);
unresolved_reloc = FALSE;
break;
break;
case R_390_8:
case R_390_16:
case R_390_32:
case R_390_PC16:
case R_390_PC16DBL:
case R_390_PC32DBL:
case R_390_PC32:
case R_390_8:
case R_390_16:
case R_390_32:
case R_390_PC16:
case R_390_PC16DBL:
case R_390_PC32DBL:
case R_390_PC32:
/* r_symndx will be zero only for relocs against symbols
from removed linkonce sections, or sections discarded by
a linker script. */
if (r_symndx == 0
|| (input_section->flags & SEC_ALLOC) == 0)
if (r_symndx == 0
|| (input_section->flags & SEC_ALLOC) == 0)
break;
if ((info->shared
if ((info->shared
&& ((r_type != R_390_PC16
&& r_type != R_390_PC16DBL
&& r_type != R_390_PC32DBL
@ -2508,9 +2490,9 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
& ELF_LINK_HASH_DEF_REGULAR) == 0)
|| h->root.type == bfd_link_hash_undefweak
|| h->root.type == bfd_link_hash_undefined)))
{
Elf_Internal_Rela outrel;
bfd_boolean skip, relocate;
{
Elf_Internal_Rela outrel;
bfd_boolean skip, relocate;
asection *sreloc;
bfd_byte *loc;
@ -2518,8 +2500,8 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
are copied into the output file to be resolved at run
time. */
skip = FALSE;
relocate = FALSE;
skip = FALSE;
relocate = FALSE;
outrel.r_offset =
_bfd_elf_section_offset (output_bfd, info, input_section,
@ -2528,12 +2510,12 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
skip = TRUE;
else if (outrel.r_offset == (bfd_vma) -2)
skip = TRUE, relocate = TRUE;
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
if (skip)
if (skip)
memset (&outrel, 0, sizeof outrel);
else if (h != NULL
else if (h != NULL
&& h->dynindx != -1
&& (r_type == R_390_PC16
|| r_type == R_390_PC16DBL
@ -2543,17 +2525,17 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
|| !info->symbolic
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0))
{
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
{
outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
outrel.r_addend = rel->r_addend;
}
else
{
}
else
{
/* This symbol is local, or marked to become local. */
relocate = TRUE;
outrel.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
outrel.r_addend = relocation + rel->r_addend;
}
}
sreloc = elf_section_data (input_section)->sreloc;
if (sreloc == NULL)
@ -2563,13 +2545,13 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
/* If this reloc is against an external symbol, we do
not want to fiddle with the addend. Otherwise, we
need to include the symbol value so that it becomes
an addend for the dynamic reloc. */
if (! relocate)
continue;
}
/* If this reloc is against an external symbol, we do
not want to fiddle with the addend. Otherwise, we
need to include the symbol value so that it becomes
an addend for the dynamic reloc. */
if (! relocate)
continue;
}
break;
/* Relocations for tls literal pool entries. */
@ -2635,7 +2617,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
if ((off & 1) != 0)
off &= ~1;
else
else
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
@ -2666,7 +2648,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
{
if (indx == 0)
{
BFD_ASSERT (! unresolved_reloc);
BFD_ASSERT (! unresolved_reloc);
bfd_put_32 (output_bfd,
relocation - dtpoff_base (info),
htab->sgot->contents + off + GOT_ENTRY_SIZE);
@ -2770,7 +2752,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
htab->tls_ldm_got.offset |= 1;
}
relocation = htab->sgot->output_offset + off;
unresolved_reloc = FALSE;
unresolved_reloc = FALSE;
break;
case R_390_TLS_LE32:
@ -2980,7 +2962,7 @@ elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
bfd_vma relative_offset;
/* This symbol has an entry in the procedure linkage table. Set
it up. */
it up. */
if (h->dynindx == -1
|| htab->splt == NULL
|| htab->sgotplt == NULL
@ -2988,26 +2970,26 @@ elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
abort ();
/* Calc. index no.
Current offset - size first entry / entry size. */
Current offset - size first entry / entry size. */
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) / PLT_ENTRY_SIZE;
/* Offset in GOT is PLT index plus GOT headers(3) times 4,
addr & GOT addr. */
addr & GOT addr. */
got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
/* S390 uses halfwords for relative branch calc! */
relative_offset = - ((PLT_FIRST_ENTRY_SIZE +
(PLT_ENTRY_SIZE * plt_index) + 18) / 2);
(PLT_ENTRY_SIZE * plt_index) + 18) / 2);
/* If offset is > 32768, branch to a previous branch
390 can only handle +-64 K jumps. */
390 can only handle +-64 K jumps. */
if ( -32768 > (int) relative_offset )
relative_offset =
-(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
relative_offset
= -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
/* Fill in the entry in the procedure linkage table. */
if (!info->shared)
{
bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0,
bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD0,
htab->splt->contents + h->plt.offset);
bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD1,
htab->splt->contents + h->plt.offset + 4);
@ -3078,10 +3060,10 @@ elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
}
/* Insert offset into reloc. table here. */
bfd_put_32 (output_bfd, plt_index * sizeof (Elf32_External_Rela),
htab->splt->contents + h->plt.offset + 28);
htab->splt->contents + h->plt.offset + 28);
/* Fill in the entry in the global offset table.
Points to instruction after GOT offset. */
Points to instruction after GOT offset. */
bfd_put_32 (output_bfd,
(htab->splt->output_section->vma
+ htab->splt->output_offset
@ -3118,7 +3100,7 @@ elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
bfd_byte *loc;
/* This symbol has an entry in the global offset table. Set it
up. */
up. */
if (htab->sgot == NULL || htab->srelgot == NULL)
abort ();
@ -3141,16 +3123,16 @@ elf_s390_finish_dynamic_symbol (output_bfd, info, h, sym)
BFD_ASSERT((h->got.offset & 1) != 0);
rela.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
rela.r_addend = (h->root.u.def.value
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
}
+ h->root.u.def.section->output_section->vma
+ h->root.u.def.section->output_offset);
}
else
{
BFD_ASSERT((h->got.offset & 1) == 0);
bfd_put_32 (output_bfd, (bfd_vma) 0, htab->sgot->contents + h->got.offset);
rela.r_info = ELF32_R_INFO (h->dynindx, R_390_GLOB_DAT);
rela.r_addend = 0;
}
rela.r_addend = 0;
}
loc = htab->srelgot->contents;
loc += htab->srelgot->reloc_count++ * sizeof (Elf32_External_Rela);
@ -3268,39 +3250,39 @@ elf_s390_finish_dynamic_sections (output_bfd, info)
/* Fill in the special first entry in the procedure linkage table. */
if (htab->splt && htab->splt->_raw_size > 0)
{
memset (htab->splt->contents, 0, PLT_FIRST_ENTRY_SIZE);
if (info->shared)
memset (htab->splt->contents, 0, PLT_FIRST_ENTRY_SIZE);
if (info->shared)
{
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD0,
htab->splt->contents );
htab->splt->contents );
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD1,
htab->splt->contents +4 );
htab->splt->contents +4 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD2,
htab->splt->contents +8 );
htab->splt->contents +8 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD3,
htab->splt->contents +12 );
htab->splt->contents +12 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_PIC_FIRST_ENTRY_WORD4,
htab->splt->contents +16 );
}
else
{
bfd_put_32 (output_bfd, (bfd_vma)PLT_FIRST_ENTRY_WORD0,
htab->splt->contents );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1,
htab->splt->contents +4 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD2,
htab->splt->contents +8 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3,
htab->splt->contents +12 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4,
htab->splt->contents +16 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5,
htab->splt->contents +20 );
bfd_put_32 (output_bfd,
htab->sgotplt->output_section->vma
htab->splt->contents +16 );
}
else
{
bfd_put_32 (output_bfd, (bfd_vma)PLT_FIRST_ENTRY_WORD0,
htab->splt->contents );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD1,
htab->splt->contents +4 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD2,
htab->splt->contents +8 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD3,
htab->splt->contents +12 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD4,
htab->splt->contents +16 );
bfd_put_32 (output_bfd, (bfd_vma) PLT_FIRST_ENTRY_WORD5,
htab->splt->contents +20 );
bfd_put_32 (output_bfd,
htab->sgotplt->output_section->vma
+ htab->sgotplt->output_offset,
htab->splt->contents + 24);
}
htab->splt->contents + 24);
}
elf_section_data (htab->splt->output_section)
->this_hdr.sh_entsize = 4;
}
@ -3375,27 +3357,27 @@ elf_s390_grok_prstatus (abfd, note)
#define elf_backend_plt_header_size PLT_ENTRY_SIZE
#define elf_backend_rela_normal 1
#define elf_info_to_howto elf_s390_info_to_howto
#define elf_info_to_howto elf_s390_info_to_howto
#define bfd_elf32_bfd_is_local_label_name elf_s390_is_local_label_name
#define bfd_elf32_bfd_link_hash_table_create elf_s390_link_hash_table_create
#define bfd_elf32_bfd_reloc_type_lookup elf_s390_reloc_type_lookup
#define elf_backend_adjust_dynamic_symbol elf_s390_adjust_dynamic_symbol
#define elf_backend_check_relocs elf_s390_check_relocs
#define elf_backend_check_relocs elf_s390_check_relocs
#define elf_backend_copy_indirect_symbol elf_s390_copy_indirect_symbol
#define elf_backend_create_dynamic_sections elf_s390_create_dynamic_sections
#define elf_backend_finish_dynamic_sections elf_s390_finish_dynamic_sections
#define elf_backend_finish_dynamic_symbol elf_s390_finish_dynamic_symbol
#define elf_backend_gc_mark_hook elf_s390_gc_mark_hook
#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook
#define elf_backend_gc_mark_hook elf_s390_gc_mark_hook
#define elf_backend_gc_sweep_hook elf_s390_gc_sweep_hook
#define elf_backend_reloc_type_class elf_s390_reloc_type_class
#define elf_backend_relocate_section elf_s390_relocate_section
#define elf_backend_relocate_section elf_s390_relocate_section
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
#define elf_backend_reloc_type_class elf_s390_reloc_type_class
#define elf_backend_grok_prstatus elf_s390_grok_prstatus
#define bfd_elf32_mkobject elf_s390_mkobject
#define elf_backend_object_p elf_s390_object_p
#define elf_backend_object_p elf_s390_object_p
#include "elf32-target.h"

View File

@ -4052,7 +4052,7 @@ allocate_dynrelocs (h, inf)
&& eh->gotplt_refcount > 0)
{
/* The symbol has been forced local, or we have some direct got refs,
so treat all the gotplt refs as got refs. */
so treat all the gotplt refs as got refs. */
h->got.refcount += eh->gotplt_refcount;
if (h->plt.refcount >= eh->gotplt_refcount)
h->plt.refcount -= eh->gotplt_refcount;
@ -5413,7 +5413,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
if ((off & 1) != 0)
off &= ~1;
else
else
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
@ -5919,9 +5919,6 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs)
struct elf_link_hash_entry **sym_hashes;
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
struct elf_link_hash_entry *h;
struct elf_sh_link_hash_entry *eh;
elf_section_data (sec)->local_dynrel = NULL;
@ -5932,15 +5929,20 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs)
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)
h = NULL;
else
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];
#ifdef INCLUDE_SHMEDIA
while (h->root.type == bfd_link_hash_indirect
@ -5950,12 +5952,18 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
}
#endif
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;
}
}
eh = (struct elf_sh_link_hash_entry *) h;
switch (sh_elf_optimized_tls_reloc (info, ELF32_R_TYPE (rel->r_info),
ELF32_R_SYM (rel->r_info)
>= symtab_hdr->sh_info))
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)
@ -5988,6 +5996,8 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs)
#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;
}
@ -6013,27 +6023,9 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs)
case R_SH_DIR32:
case R_SH_REL32:
if (h != NULL)
{
struct elf_sh_dyn_relocs **pp;
struct elf_sh_dyn_relocs *p;
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
if (ELF32_R_TYPE (rel->r_info) == R_SH_REL32)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
if (info->shared)
break;
/* Fall thru */
case R_SH_PLT32:
#ifdef INCLUDE_SHMEDIA
@ -6060,6 +6052,8 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs)
#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;

View File

@ -63,8 +63,8 @@ static struct bfd_hash_entry *link_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
static struct bfd_link_hash_table *elf32_sparc_link_hash_table_create
PARAMS ((bfd *));
static bfd_boolean create_got_section PARAMS ((bfd *,
struct bfd_link_info *));
static bfd_boolean create_got_section
PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean elf32_sparc_create_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
static void elf32_sparc_copy_indirect_symbol
@ -291,11 +291,14 @@ elf32_sparc_reloc_type_lookup (abfd, code)
return &elf32_sparc_rev32_howto;
default:
for (i = 0; i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map); i++)
{
if (sparc_reloc_map[i].bfd_reloc_val == code)
return &_bfd_sparc_elf_howto_table[(int) sparc_reloc_map[i].elf_reloc_val];
}
for (i = 0;
i < sizeof (sparc_reloc_map) / sizeof (struct elf_reloc_map);
i++)
{
if (sparc_reloc_map[i].bfd_reloc_val == code)
return (_bfd_sparc_elf_howto_table
+ (int) sparc_reloc_map[i].elf_reloc_val);
}
}
bfd_set_error (bfd_error_bad_value);
return NULL;
@ -633,9 +636,9 @@ link_hash_newfunc (entry, table, string)
if (entry == NULL)
{
entry = bfd_hash_allocate (table,
sizeof (struct elf32_sparc_link_hash_entry));
sizeof (struct elf32_sparc_link_hash_entry));
if (entry == NULL)
return entry;
return entry;
}
/* Call the allocation method of the superclass. */
@ -758,32 +761,32 @@ elf32_sparc_copy_indirect_symbol (bed, dir, ind)
if (eind->dyn_relocs != NULL)
{
if (edir->dyn_relocs != NULL)
{
struct elf32_sparc_dyn_relocs **pp;
struct elf32_sparc_dyn_relocs *p;
{
struct elf32_sparc_dyn_relocs **pp;
struct elf32_sparc_dyn_relocs *p;
if (ind->root.type == bfd_link_hash_indirect)
abort ();
if (ind->root.type == bfd_link_hash_indirect)
abort ();
/* Add reloc counts against the weak sym to the strong sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
struct elf32_sparc_dyn_relocs *q;
/* Add reloc counts against the weak sym to the strong sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
struct elf32_sparc_dyn_relocs *q;
for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec)
{
q->pc_count += p->pc_count;
q->count += p->count;
*pp = p->next;
break;
}
if (q == NULL)
pp = &p->next;
}
*pp = edir->dyn_relocs;
}
for (q = edir->dyn_relocs; q != NULL; q = q->next)
if (q->sec == p->sec)
{
q->pc_count += p->pc_count;
q->count += p->count;
*pp = p->next;
break;
}
if (q == NULL)
pp = &p->next;
}
*pp = edir->dyn_relocs;
}
edir->dyn_relocs = eind->dyn_relocs;
eind->dyn_relocs = NULL;
@ -820,15 +823,15 @@ elf32_sparc_tls_transition (info, abfd, r_type, is_local)
return R_SPARC_TLS_IE_HI22;
case R_SPARC_TLS_GD_LO10:
if (is_local)
return R_SPARC_TLS_LE_LOX10;
return R_SPARC_TLS_LE_LOX10;
return R_SPARC_TLS_IE_LO10;
case R_SPARC_TLS_IE_HI22:
if (is_local)
return R_SPARC_TLS_LE_HIX22;
return R_SPARC_TLS_LE_HIX22;
return r_type;
case R_SPARC_TLS_IE_LO10:
if (is_local)
return R_SPARC_TLS_LE_LOX10;
return R_SPARC_TLS_LE_LOX10;
return r_type;
case R_SPARC_TLS_LDM_HI22:
return R_SPARC_TLS_LE_HIX22;
@ -880,12 +883,12 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
r_type = ELF32_R_TYPE (rel->r_info);
if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
{
(*_bfd_error_handler) (_("%s: bad symbol index: %d"),
bfd_archive_filename (abfd),
r_symndx);
return FALSE;
}
{
(*_bfd_error_handler) (_("%s: bad symbol index: %d"),
bfd_archive_filename (abfd),
r_symndx);
return FALSE;
}
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
@ -1049,17 +1052,17 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
case R_SPARC_PLT32:
case R_SPARC_WPLT30:
/* This symbol requires a procedure linkage table entry. We
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code without
linking in any dynamic objects, in which case we don't
need to generate a procedure linkage table after all. */
actually build the entry in adjust_dynamic_symbol,
because this might be a case of linking PIC code without
linking in any dynamic objects, in which case we don't
need to generate a procedure linkage table after all. */
if (h == NULL)
{
/* The Solaris native assembler will generate a WPLT30
reloc for a local symbol if you assemble a call from
one section to another when using -K pic. We treat
it as WDISP30. */
reloc for a local symbol if you assemble a call from
one section to another when using -K pic. We treat
it as WDISP30. */
if (ELF32_R_TYPE (rel->r_info) == R_SPARC_PLT32)
goto r_sparc_plt32;
break;
@ -1149,8 +1152,8 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
struct elf32_sparc_dyn_relocs **head;
/* When creating a shared object, we must copy these
relocs into the output file. We create a reloc
section in dynobj and make room for the reloc. */
relocs into the output file. We create a reloc
section in dynobj and make room for the reloc. */
if (sreloc == NULL)
{
const char *name;
@ -1231,15 +1234,15 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs)
break;
case R_SPARC_GNU_VTINHERIT:
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return FALSE;
break;
case R_SPARC_GNU_VTINHERIT:
if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return FALSE;
break;
case R_SPARC_GNU_VTENTRY:
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
case R_SPARC_GNU_VTENTRY:
if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
default:
break;
@ -1263,21 +1266,21 @@ elf32_sparc_gc_mark_hook (sec, info, rel, h, sym)
{
case R_SPARC_GNU_VTINHERIT:
case R_SPARC_GNU_VTENTRY:
break;
break;
default:
switch (h->root.type)
{
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
return h->root.u.def.section;
switch (h->root.type)
{
case bfd_link_hash_defined:
case bfd_link_hash_defweak:
return h->root.u.def.section;
case bfd_link_hash_common:
return h->root.u.c.p->section;
case bfd_link_hash_common:
return h->root.u.c.p->section;
default:
break;
}
}
}
}
else
@ -1294,14 +1297,12 @@ elf32_sparc_gc_sweep_hook (abfd, info, sec, relocs)
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;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
int r_type;
struct elf_link_hash_entry *h;
elf_section_data (sec)->local_dynrel = NULL;
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
@ -1309,116 +1310,98 @@ elf32_sparc_gc_sweep_hook (abfd, info, sec, relocs)
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
switch ((r_type = elf32_sparc_tls_transition (info, abfd,
ELF32_R_TYPE (rel->r_info),
ELF32_R_SYM (rel->r_info)
>= symtab_hdr->sh_info)))
{
case R_SPARC_TLS_LDM_HI22:
case R_SPARC_TLS_LDM_LO10:
if (elf32_sparc_hash_table (info)->tls_ldm_got.refcount > 0)
elf32_sparc_hash_table (info)->tls_ldm_got.refcount -= 1;
break;
{
unsigned long r_symndx;
unsigned int r_type;
struct elf_link_hash_entry *h = NULL;
case R_SPARC_TLS_LE_HIX22:
case R_SPARC_TLS_LE_LOX10:
if (info->shared)
goto r_sparc_plt32;
break;
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf32_sparc_link_hash_entry *eh;
struct elf32_sparc_dyn_relocs **pp;
struct elf32_sparc_dyn_relocs *p;
case R_SPARC_PC10:
case R_SPARC_PC22:
if ((r_symndx = ELF32_R_SYM (rel->r_info)) >= symtab_hdr->sh_info
&& strcmp (sym_hashes[r_symndx
- symtab_hdr->sh_info]->root.root.string,
"_GLOBAL_OFFSET_TABLE_") == 0)
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
eh = (struct elf32_sparc_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);
r_type = elf32_sparc_tls_transition (info, abfd, r_type, h != NULL);
switch (r_type)
{
case R_SPARC_TLS_LDM_HI22:
case R_SPARC_TLS_LDM_LO10:
if (elf32_sparc_hash_table (info)->tls_ldm_got.refcount > 0)
elf32_sparc_hash_table (info)->tls_ldm_got.refcount -= 1;
break;
case R_SPARC_TLS_GD_HI22:
case R_SPARC_TLS_GD_LO10:
case R_SPARC_TLS_IE_HI22:
case R_SPARC_TLS_IE_LO10:
case R_SPARC_GOT10:
case R_SPARC_GOT13:
case R_SPARC_GOT22:
if (h != NULL)
{
if (h->got.refcount > 0)
h->got.refcount--;
}
else
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx]--;
}
break;
case R_SPARC_PC10:
case R_SPARC_PC22:
if (h != NULL
&& strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
break;
/* Fall through. */
case R_SPARC_DISP8:
case R_SPARC_DISP16:
case R_SPARC_DISP32:
case R_SPARC_WDISP30:
case R_SPARC_WDISP22:
case R_SPARC_WDISP19:
case R_SPARC_WDISP16:
case R_SPARC_8:
case R_SPARC_16:
case R_SPARC_32:
case R_SPARC_HI22:
case R_SPARC_22:
case R_SPARC_13:
case R_SPARC_LO10:
case R_SPARC_UA16:
case R_SPARC_UA32:
r_sparc_plt32:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf32_sparc_link_hash_entry *eh;
struct elf32_sparc_dyn_relocs **pp;
struct elf32_sparc_dyn_relocs *p;
case R_SPARC_DISP8:
case R_SPARC_DISP16:
case R_SPARC_DISP32:
case R_SPARC_WDISP30:
case R_SPARC_WDISP22:
case R_SPARC_WDISP19:
case R_SPARC_WDISP16:
case R_SPARC_8:
case R_SPARC_16:
case R_SPARC_32:
case R_SPARC_HI22:
case R_SPARC_22:
case R_SPARC_13:
case R_SPARC_LO10:
case R_SPARC_UA16:
case R_SPARC_UA32:
case R_SPARC_PLT32:
if (info->shared)
break;
/* Fall through. */
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
case R_SPARC_WPLT30:
if (h != NULL)
{
if (h->plt.refcount > 0)
h->plt.refcount--;
}
break;
if (! info->shared)
--h->plt.refcount;
eh = (struct elf32_sparc_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
if (_bfd_sparc_elf_howto_table[r_type].pc_relative)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
case R_SPARC_TLS_GD_HI22:
case R_SPARC_TLS_GD_LO10:
case R_SPARC_TLS_IE_HI22:
case R_SPARC_TLS_IE_LO10:
case R_SPARC_GOT10:
case R_SPARC_GOT13:
case R_SPARC_GOT22:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->got.refcount > 0)
h->got.refcount--;
}
else
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx]--;
}
break;
case R_SPARC_PLT32:
case R_SPARC_HIPLT22:
case R_SPARC_LOPLT10:
case R_SPARC_PCPLT32:
case R_SPARC_PCPLT10:
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->plt.refcount > 0)
h->plt.refcount--;
}
if (r_type == R_SPARC_PLT32)
goto r_sparc_plt32;
break;
default:
break;
}
default:
break;
}
}
return TRUE;
}
@ -1632,7 +1615,7 @@ allocate_dynrelocs (h, inf)
/* The first four entries in .plt are reserved. */
if (s->_raw_size == 0)
s->_raw_size = 4 * PLT_ENTRY_SIZE;
/* The procedure linkage table has a maximum size. */
if (s->_raw_size >= 0x400000)
{
@ -2176,8 +2159,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
r_type = ELF32_R_TYPE (rel->r_info);
if (r_type == R_SPARC_GNU_VTINHERIT
|| r_type == R_SPARC_GNU_VTENTRY)
continue;
|| r_type == R_SPARC_GNU_VTENTRY)
continue;
if (r_type < 0 || r_type >= (int) R_SPARC_max_std)
{
@ -2244,7 +2227,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
case R_SPARC_GOT13:
case R_SPARC_GOT22:
/* Relocation is to the entry for this symbol in the global
offset table. */
offset table. */
if (htab->sgot == NULL)
abort ();
@ -2264,13 +2247,13 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
{
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
because of a version file. We must initialize
this entry in the global offset table. Since the
offset must always be a multiple of 4, we use the
least significant bit to record whether we have
initialized it already.
-Bsymbolic link and the symbol is defined
locally, or the symbol was forced to be local
because of a version file. We must initialize
this entry in the global offset table. Since the
offset must always be a multiple of 4, we use the
least significant bit to record whether we have
initialized it already.
When doing a dynamic link, we create a .rela.got
relocation entry to initialize the value. This
@ -2342,7 +2325,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
case R_SPARC_WPLT30:
r_sparc_wplt30:
/* Relocation is to the entry for this symbol in the
procedure linkage table. */
procedure linkage table. */
/* The Solaris native assembler will generate a WPLT30 reloc
for a local symbol if you assemble a call from one
@ -2354,8 +2337,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
if (h->plt.offset == (bfd_vma) -1)
{
/* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when
using -Bsymbolic. */
happens when statically linking PIC code, or when
using -Bsymbolic. */
break;
}
@ -2427,8 +2410,8 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean skip, relocate = FALSE;
/* When generating a shared object, these relocations
are copied into the output file to be resolved at run
time. */
are copied into the output file to be resolved at run
time. */
BFD_ASSERT (sreloc != NULL);
@ -2480,7 +2463,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
if (skip)
memset (&outrel, 0, sizeof outrel);
/* h->dynindx may be -1 if the symbol was marked to
become local. */
become local. */
else if (h != NULL && ! is_plt
&& ((! info->symbolic && h->dynindx != -1)
|| (h->elf_link_hash_flags
@ -2549,7 +2532,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
/* This reloc will be computed at runtime, so there's no
need to do anything now. */
need to do anything now. */
if (! relocate)
continue;
}
@ -2614,7 +2597,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
break;
}
if (h != NULL)
if (h != NULL)
{
off = h->got.offset;
h->got.offset |= 1;
@ -2625,14 +2608,14 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
off = local_got_offsets[r_symndx];
local_got_offsets[r_symndx] |= 1;
}
r_sparc_tlsldm:
if (htab->sgot == NULL)
abort ();
if ((off & 1) != 0)
off &= ~1;
else
else
{
Elf_Internal_Rela outrel;
Elf32_External_Rela *loc;
@ -3098,7 +3081,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
{
bfd *dynobj;
struct elf32_sparc_link_hash_table *htab;
htab = elf32_sparc_hash_table (info);
dynobj = htab->elf.dynobj;
@ -3110,7 +3093,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
bfd_byte *loc;
/* This symbol has an entry in the procedure linkage table. Set
it up. */
it up. */
BFD_ASSERT (h->dynindx != -1);
@ -3164,7 +3147,7 @@ elf32_sparc_finish_dynamic_symbol (output_bfd, info, h, sym)
bfd_byte *loc;
/* This symbol has an entry in the global offset table. Set it
up. */
up. */
sgot = htab->sgot;
srela = htab->srelgot;
@ -3244,7 +3227,7 @@ elf32_sparc_finish_dynamic_sections (output_bfd, info)
bfd *dynobj;
asection *sdyn;
struct elf32_sparc_link_hash_table *htab;
htab = elf32_sparc_hash_table (info);
dynobj = htab->elf.dynobj;
@ -3512,7 +3495,7 @@ elf32_sparc_reloc_type_class (rela)
#define elf_backend_object_p elf32_sparc_object_p
#define elf_backend_final_write_processing \
elf32_sparc_final_write_processing
#define elf_backend_gc_mark_hook elf32_sparc_gc_mark_hook
#define elf_backend_gc_mark_hook elf32_sparc_gc_mark_hook
#define elf_backend_gc_sweep_hook elf32_sparc_gc_sweep_hook
#define elf_backend_reloc_type_class elf32_sparc_reloc_type_class

View File

@ -373,7 +373,7 @@ elf_s390_info_to_howto (abfd, cache_ptr, dst)
/* A relocation function which doesn't do anything. */
static bfd_reloc_status_type
s390_tls_reloc (abfd, reloc_entry, symbol, data, input_section,
output_bfd, error_message)
output_bfd, error_message)
bfd *abfd ATTRIBUTE_UNUSED;
arelent *reloc_entry;
asymbol *symbol ATTRIBUTE_UNUSED;
@ -986,7 +986,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
/* Fall through */
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT16:
case R_390_GOT32:
case R_390_GOT64:
case R_390_GOTENT:
@ -1292,9 +1292,6 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
struct elf_link_hash_entry **sym_hashes;
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
int r_type;
struct elf_link_hash_entry *h;
elf_section_data (sec)->local_dynrel = NULL;
@ -1305,16 +1302,31 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
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;
r_symndx = ELF64_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf_s390_link_hash_entry *eh;
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
if (r_symndx < symtab_hdr->sh_info)
h = NULL;
else
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
eh = (struct elf_s390_link_hash_entry *) h;
r_type = elf_s390_tls_transition (info,
ELF64_R_TYPE (rel->r_info),
r_symndx >= symtab_hdr->sh_info);
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 = ELF64_R_TYPE (rel->r_info);
r_type = elf_s390_tls_transition (info, r_type, h != NULL);
switch (r_type)
{
case R_390_TLS_LDM64:
@ -1347,14 +1359,7 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
if (r_type != R_390_TLS_IE64)
break;
/* Fall through */
case R_390_TLS_LE64:
if (!info->shared)
break;
/* Fall through */
break;
case R_390_8:
case R_390_12:
@ -1366,33 +1371,9 @@ elf_s390_gc_sweep_hook (abfd, info, sec, relocs)
case R_390_PC32:
case R_390_PC32DBL:
case R_390_PC64:
if (h != NULL)
{
struct elf_s390_link_hash_entry *eh;
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
eh = (struct elf_s390_link_hash_entry *) h;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
if (ELF64_R_TYPE (rel->r_info) == R_390_PC16
|| ELF64_R_TYPE (rel->r_info) == R_390_PC16DBL
|| ELF64_R_TYPE (rel->r_info) == R_390_PC32
|| ELF64_R_TYPE (rel->r_info) == R_390_PC32DBL
|| ELF64_R_TYPE (rel->r_info) == R_390_PC64)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
if (info->shared)
break;
/* Fall through */
case R_390_PLT16DBL:
case R_390_PLT32:
@ -2265,14 +2246,14 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
Current offset - size first entry / entry size. */
plt_index = (h->plt.offset - PLT_FIRST_ENTRY_SIZE) /
PLT_ENTRY_SIZE;
/* Offset in GOT is PLT index plus GOT headers(3) times 4,
addr & GOT addr. */
relocation = (plt_index + 3) * GOT_ENTRY_SIZE;
unresolved_reloc = FALSE;
if (r_type == R_390_GOTPLTENT)
relocation += htab->sgot->output_section->vma;
relocation += htab->sgot->output_section->vma;
break;
}
/* Fall through. */
@ -2426,17 +2407,17 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
+ htab->splt->output_offset
+ h->plt.offset);
unresolved_reloc = FALSE;
break;
break;
case R_390_PLTOFF16:
case R_390_PLTOFF32:
case R_390_PLTOFF64:
/* Relocation is to the entry for this symbol in the
procedure linkage table relative to the start of the GOT. */
/* Relocation is to the entry for this symbol in the
procedure linkage table relative to the start of the GOT. */
/* For local symbols or if we didn't make a PLT entry for
this symbol resolve the symbol directly. */
if ( h == NULL
if ( h == NULL
|| h->plt.offset == (bfd_vma) -1
|| htab->splt == NULL)
{
@ -2444,9 +2425,9 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
break;
}
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset
- htab->sgot->output_section->vma);
unresolved_reloc = FALSE;
break;
@ -2617,7 +2598,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
if ((off & 1) != 0)
off &= ~1;
else
else
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
@ -2752,7 +2733,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
htab->tls_ldm_got.offset |= 1;
}
relocation = htab->sgot->output_offset + off;
unresolved_reloc = FALSE;
unresolved_reloc = FALSE;
break;
case R_390_TLS_LE64:

View File

@ -1091,9 +1091,6 @@ elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs)
struct elf_link_hash_entry **sym_hashes;
bfd_signed_vma *local_got_refcounts;
const Elf_Internal_Rela *rel, *relend;
unsigned long r_symndx;
int r_type;
struct elf_link_hash_entry *h;
elf_section_data (sec)->local_dynrel = NULL;
@ -1103,85 +1100,79 @@ elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs)
relend = relocs + sec->reloc_count;
for (rel = relocs; rel < relend; rel++)
switch ((r_type = elf64_x86_64_tls_transition (info,
ELF64_R_TYPE (rel->r_info),
ELF64_R_SYM (rel->r_info)
>= symtab_hdr->sh_info)))
{
case R_X86_64_TLSLD:
if (elf64_x86_64_hash_table (info)->tls_ld_got.refcount > 0)
elf64_x86_64_hash_table (info)->tls_ld_got.refcount -= 1;
break;
{
unsigned long r_symndx;
unsigned int r_type;
struct elf_link_hash_entry *h = NULL;
case R_X86_64_TLSGD:
case R_X86_64_GOTTPOFF:
case R_X86_64_GOT32:
case R_X86_64_GOTPCREL:
r_symndx = ELF64_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
r_symndx = ELF64_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf64_x86_64_link_hash_entry *eh;
struct elf64_x86_64_dyn_relocs **pp;
struct elf64_x86_64_dyn_relocs *p;
case R_X86_64_8:
case R_X86_64_16:
case R_X86_64_32:
case R_X86_64_64:
case R_X86_64_32S:
case R_X86_64_PC8:
case R_X86_64_PC16:
case R_X86_64_PC32:
r_symndx = ELF64_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
struct elf64_x86_64_link_hash_entry *eh;
struct elf64_x86_64_dyn_relocs **pp;
struct elf64_x86_64_dyn_relocs *p;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
eh = (struct elf64_x86_64_link_hash_entry *) h;
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
/* Everything must go for SEC. */
*pp = p->next;
break;
}
}
if (!info->shared && h->plt.refcount > 0)
h->plt.refcount -= 1;
r_type = ELF64_R_TYPE (rel->r_info);
r_type = elf64_x86_64_tls_transition (info, r_type, h != NULL);
switch (r_type)
{
case R_X86_64_TLSLD:
if (elf64_x86_64_hash_table (info)->tls_ld_got.refcount > 0)
elf64_x86_64_hash_table (info)->tls_ld_got.refcount -= 1;
break;
eh = (struct elf64_x86_64_link_hash_entry *) h;
case R_X86_64_TLSGD:
case R_X86_64_GOTTPOFF:
case R_X86_64_GOT32:
case R_X86_64_GOTPCREL:
if (h != NULL)
{
if (h->got.refcount > 0)
h->got.refcount -= 1;
}
else if (local_got_refcounts != NULL)
{
if (local_got_refcounts[r_symndx] > 0)
local_got_refcounts[r_symndx] -= 1;
}
break;
for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
if (p->sec == sec)
{
if (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8
|| ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16
|| ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32)
p->pc_count -= 1;
p->count -= 1;
if (p->count == 0)
*pp = p->next;
break;
}
}
break;
case R_X86_64_8:
case R_X86_64_16:
case R_X86_64_32:
case R_X86_64_64:
case R_X86_64_32S:
case R_X86_64_PC8:
case R_X86_64_PC16:
case R_X86_64_PC32:
if (info->shared)
break;
/* Fall thru */
case R_X86_64_PLT32:
if (h != NULL)
{
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
case R_X86_64_PLT32:
r_symndx = ELF64_R_SYM (rel->r_info);
if (r_symndx >= symtab_hdr->sh_info)
{
h = sym_hashes[r_symndx - symtab_hdr->sh_info];
if (h->plt.refcount > 0)
h->plt.refcount -= 1;
}
break;
default:
break;
}
default:
break;
}
}
return TRUE;
}
@ -2328,7 +2319,7 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
if ((off & 1) != 0)
off &= ~1;
else
else
{
Elf_Internal_Rela outrel;
bfd_byte *loc;
@ -2406,12 +2397,12 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
addq foo@gottpoff(%rip), %rax */
BFD_ASSERT (rel->r_offset >= 4);
for (i = 0; i < 4; i++)
BFD_ASSERT (bfd_get_8 (input_bfd,
BFD_ASSERT (bfd_get_8 (input_bfd,
contents + rel->r_offset - 4 + i)
== tlsgd[i]);
BFD_ASSERT (rel->r_offset + 12 <= input_section->_raw_size);
for (i = 0; i < 4; i++)
BFD_ASSERT (bfd_get_8 (input_bfd,
BFD_ASSERT (bfd_get_8 (input_bfd,
contents + rel->r_offset + 4 + i)
== tlsgd[i+4]);
BFD_ASSERT (rel + 1 < relend);