* 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:
parent
f4656909e9
commit
26e415943a
|
@ -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.
|
||||
|
|
165
bfd/elf32-hppa.c
165
bfd/elf32-hppa.c
|
@ -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;
|
||||
}
|
||||
|
|
154
bfd/elf32-i386.c
154
bfd/elf32-i386.c
|
@ -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;
|
||||
|
|
502
bfd/elf32-s390.c
502
bfd/elf32-s390.c
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue