* elf32-ppc.c (ppc_elf_relocate_section): Remove unnecessary test.
* elf64-ppc.c (ppc64_elf_tls_optimize): Decrement tlsld_got.refcount on invalid LD relocs. (allocate_dynrelocs): Invalid LD relocs don't use tlsld_got entry. (ppc64_elf_relocate_section): Unify new handling of LD relocs and tlsld_got entry. Use IS_PPC64_TLS_RELOC.
This commit is contained in:
parent
89c3607e7b
commit
d881513ac9
3 changed files with 74 additions and 74 deletions
|
@ -1,5 +1,12 @@
|
||||||
2003-02-18 Alan Modra <amodra@bigpond.net.au>
|
2003-02-18 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf32-ppc.c (ppc_elf_relocate_section): Remove unnecessary test.
|
||||||
|
* elf64-ppc.c (ppc64_elf_tls_optimize): Decrement tlsld_got.refcount
|
||||||
|
on invalid LD relocs.
|
||||||
|
(allocate_dynrelocs): Invalid LD relocs don't use tlsld_got entry.
|
||||||
|
(ppc64_elf_relocate_section): Unify new handling of LD relocs and
|
||||||
|
tlsld_got entry. Use IS_PPC64_TLS_RELOC.
|
||||||
|
|
||||||
* elf32-ppc.h: New file.
|
* elf32-ppc.h: New file.
|
||||||
* elf32-ppc.c: Include elf32-ppc.h.
|
* elf32-ppc.c: Include elf32-ppc.h.
|
||||||
(NOP, CROR_151515, CROR_313131, TP_OFFSET, DTP_OFFSET): Define.
|
(NOP, CROR_151515, CROR_313131, TP_OFFSET, DTP_OFFSET): Define.
|
||||||
|
|
|
@ -4554,8 +4554,7 @@ ppc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
|
|
||||||
indx = 0;
|
indx = 0;
|
||||||
if (tls_type == (TLS_TLS | TLS_LD)
|
if (tls_type == (TLS_TLS | TLS_LD)
|
||||||
&& ((tls_mask & TLS_LD) == 0
|
&& (h == NULL
|
||||||
|| h == NULL
|
|
||||||
|| !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)))
|
|| !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)))
|
||||||
offp = &htab->tlsld_got.offset;
|
offp = &htab->tlsld_got.offset;
|
||||||
else if (h != NULL)
|
else if (h != NULL)
|
||||||
|
|
138
bfd/elf64-ppc.c
138
bfd/elf64-ppc.c
|
@ -5238,10 +5238,10 @@ ppc64_elf_tls_optimize (obfd, info)
|
||||||
/* These relocs should never be against a symbol
|
/* These relocs should never be against a symbol
|
||||||
defined in a shared lib. Leave them alone if
|
defined in a shared lib. Leave them alone if
|
||||||
that turns out to be the case. */
|
that turns out to be the case. */
|
||||||
|
htab->tlsld_got.refcount -= 1;
|
||||||
if (!is_local)
|
if (!is_local)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
htab->tlsld_got.refcount -= 1;
|
|
||||||
/* LD -> LE */
|
/* LD -> LE */
|
||||||
tls_set = 0;
|
tls_set = 0;
|
||||||
tls_clear = TLS_LD;
|
tls_clear = TLS_LD;
|
||||||
|
@ -5559,7 +5559,8 @@ allocate_dynrelocs (h, inf)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gent->tls_type & TLS_LD) != 0)
|
if ((gent->tls_type & TLS_LD) != 0
|
||||||
|
&& !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC))
|
||||||
{
|
{
|
||||||
gent->got.offset = htab->tlsld_got.offset;
|
gent->got.offset = htab->tlsld_got.offset;
|
||||||
continue;
|
continue;
|
||||||
|
@ -5567,7 +5568,8 @@ allocate_dynrelocs (h, inf)
|
||||||
|
|
||||||
s = htab->sgot;
|
s = htab->sgot;
|
||||||
gent->got.offset = s->_raw_size;
|
gent->got.offset = s->_raw_size;
|
||||||
s->_raw_size += (gent->tls_type & eh->tls_mask & TLS_GD) ? 16 : 8;
|
s->_raw_size
|
||||||
|
+= (gent->tls_type & eh->tls_mask & (TLS_GD | TLS_LD)) ? 16 : 8;
|
||||||
dyn = htab->elf.dynamic_sections_created;
|
dyn = htab->elf.dynamic_sections_created;
|
||||||
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
|
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))
|
||||||
htab->srelgot->_raw_size
|
htab->srelgot->_raw_size
|
||||||
|
@ -6961,26 +6963,6 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
ppc_howto_init ();
|
ppc_howto_init ();
|
||||||
|
|
||||||
htab = ppc_hash_table (info);
|
htab = ppc_hash_table (info);
|
||||||
if ((htab->tlsld_got.offset & 1) == 0)
|
|
||||||
{
|
|
||||||
if (info->shared)
|
|
||||||
{
|
|
||||||
outrel.r_offset = (htab->sgot->output_section->vma
|
|
||||||
+ htab->sgot->output_offset
|
|
||||||
+ htab->tlsld_got.offset);
|
|
||||||
outrel.r_info = ELF64_R_INFO (0, R_PPC64_DTPMOD64);
|
|
||||||
outrel.r_addend = 0;
|
|
||||||
|
|
||||||
loc = htab->srelgot->contents;
|
|
||||||
loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
|
|
||||||
bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
bfd_put_64 (output_bfd, (bfd_vma) 1,
|
|
||||||
htab->sgot->contents + htab->tlsld_got.offset);
|
|
||||||
|
|
||||||
htab->tlsld_got.offset |= 1;
|
|
||||||
}
|
|
||||||
local_got_ents = elf_local_got_ents (input_bfd);
|
local_got_ents = elf_local_got_ents (input_bfd);
|
||||||
TOCstart = elf_gp (output_bfd);
|
TOCstart = elf_gp (output_bfd);
|
||||||
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
|
||||||
|
@ -7087,7 +7069,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
for the final instruction stream. */
|
for the final instruction stream. */
|
||||||
tls_mask = 0;
|
tls_mask = 0;
|
||||||
tls_gd = 0;
|
tls_gd = 0;
|
||||||
if (IS_TLS_RELOC (r_type))
|
if (IS_PPC64_TLS_RELOC (r_type))
|
||||||
{
|
{
|
||||||
if (h != NULL)
|
if (h != NULL)
|
||||||
tls_mask = ((struct ppc_link_hash_entry *) h)->tls_mask;
|
tls_mask = ((struct ppc_link_hash_entry *) h)->tls_mask;
|
||||||
|
@ -7565,57 +7547,64 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
{
|
{
|
||||||
/* Relocation is to the entry for this symbol in the global
|
/* Relocation is to the entry for this symbol in the global
|
||||||
offset table. */
|
offset table. */
|
||||||
struct got_entry *ent;
|
bfd_vma *offp;
|
||||||
bfd_vma off;
|
bfd_vma off;
|
||||||
unsigned long indx;
|
unsigned long indx = 0;
|
||||||
|
|
||||||
if (htab->sgot == NULL)
|
if (htab->sgot == NULL)
|
||||||
abort ();
|
abort ();
|
||||||
|
|
||||||
if (h != NULL)
|
if (tls_type == (TLS_TLS | TLS_LD)
|
||||||
ent = h->got.glist;
|
&& (h == NULL
|
||||||
|
|| !(h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)))
|
||||||
|
offp = &htab->tlsld_got.offset;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (local_got_ents == NULL)
|
struct got_entry *ent;
|
||||||
abort ();
|
|
||||||
ent = local_got_ents[r_symndx];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; ent != NULL; ent = ent->next)
|
if (h != NULL)
|
||||||
if (ent->addend == rel->r_addend
|
{
|
||||||
&& ent->tls_type == tls_type)
|
bfd_boolean dyn = htab->elf.dynamic_sections_created;
|
||||||
break;
|
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
|
||||||
if (ent == NULL)
|
|| (info->shared
|
||||||
abort ();
|
&& (info->symbolic
|
||||||
|
|| h->dynindx == -1
|
||||||
off = ent->got.offset;
|
|| (h->elf_link_hash_flags
|
||||||
indx = 0;
|
& ELF_LINK_FORCED_LOCAL))
|
||||||
if (h != NULL)
|
&& (h->elf_link_hash_flags
|
||||||
{
|
& ELF_LINK_HASH_DEF_REGULAR)))
|
||||||
bfd_boolean dyn = htab->elf.dynamic_sections_created;
|
/* This is actually a static link, or it is a
|
||||||
if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)
|
-Bsymbolic link and the symbol is defined
|
||||||
|| (info->shared
|
locally, or the symbol was forced to be local
|
||||||
&& (info->symbolic
|
because of a version file. */
|
||||||
|| h->dynindx == -1
|
;
|
||||||
|| (h->elf_link_hash_flags
|
else
|
||||||
& ELF_LINK_FORCED_LOCAL))
|
{
|
||||||
&& (h->elf_link_hash_flags
|
indx = h->dynindx;
|
||||||
& ELF_LINK_HASH_DEF_REGULAR)))
|
unresolved_reloc = FALSE;
|
||||||
/* This is actually a static link, or it is a
|
}
|
||||||
-Bsymbolic link and the symbol is defined
|
ent = h->got.glist;
|
||||||
locally, or the symbol was forced to be local
|
}
|
||||||
because of a version file. */
|
|
||||||
;
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
indx = h->dynindx;
|
if (local_got_ents == NULL)
|
||||||
unresolved_reloc = FALSE;
|
abort ();
|
||||||
|
ent = local_got_ents[r_symndx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (; ent != NULL; ent = ent->next)
|
||||||
|
if (ent->addend == rel->r_addend
|
||||||
|
&& ent->tls_type == tls_type)
|
||||||
|
break;
|
||||||
|
if (ent == NULL)
|
||||||
|
abort ();
|
||||||
|
offp = &ent->got.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The offset must always be a multiple of 8. We use the
|
/* The offset must always be a multiple of 8. We use the
|
||||||
least significant bit to record whether we have already
|
least significant bit to record whether we have already
|
||||||
processed this entry. */
|
processed this entry. */
|
||||||
|
off = *offp;
|
||||||
if ((off & 1) != 0)
|
if ((off & 1) != 0)
|
||||||
off &= ~1;
|
off &= ~1;
|
||||||
else
|
else
|
||||||
|
@ -7623,22 +7612,27 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
/* Generate relocs for the dynamic linker, except in
|
/* Generate relocs for the dynamic linker, except in
|
||||||
the case of TLSLD where we'll use one entry per
|
the case of TLSLD where we'll use one entry per
|
||||||
module. */
|
module. */
|
||||||
if ((info->shared || indx != 0)
|
*offp = off | 1;
|
||||||
&& tls_type != (TLS_TLS | TLS_LD))
|
if (info->shared || indx != 0)
|
||||||
{
|
{
|
||||||
outrel.r_offset = (htab->sgot->output_section->vma
|
outrel.r_offset = (htab->sgot->output_section->vma
|
||||||
+ htab->sgot->output_offset
|
+ htab->sgot->output_offset
|
||||||
+ off);
|
+ off);
|
||||||
if (tls_type == (TLS_TLS | TLS_GD))
|
if (tls_type & (TLS_LD | TLS_GD))
|
||||||
{
|
{
|
||||||
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPMOD64);
|
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPMOD64);
|
||||||
outrel.r_addend = 0;
|
outrel.r_addend = 0;
|
||||||
loc = htab->srelgot->contents;
|
if (tls_type == (TLS_TLS | TLS_GD))
|
||||||
loc += (htab->srelgot->reloc_count++
|
{
|
||||||
* sizeof (Elf64_External_Rela));
|
loc = htab->srelgot->contents;
|
||||||
bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
|
loc += (htab->srelgot->reloc_count++
|
||||||
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
|
* sizeof (Elf64_External_Rela));
|
||||||
outrel.r_offset += 8;
|
bfd_elf64_swap_reloca_out (output_bfd,
|
||||||
|
&outrel, loc);
|
||||||
|
outrel.r_info
|
||||||
|
= ELF64_R_INFO (indx, R_PPC64_DTPREL64);
|
||||||
|
outrel.r_offset += 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (tls_type == (TLS_TLS | TLS_DTPREL))
|
else if (tls_type == (TLS_TLS | TLS_DTPREL))
|
||||||
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
|
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_DTPREL64);
|
||||||
|
@ -7659,10 +7653,9 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
|
|
||||||
/* Init the .got section contents if we're not
|
/* Init the .got section contents if we're not
|
||||||
emitting a reloc. */
|
emitting a reloc. */
|
||||||
if (!(info->shared || indx != 0)
|
else
|
||||||
&& tls_type != (TLS_TLS | TLS_LD))
|
|
||||||
{
|
{
|
||||||
relocation += ent->addend;
|
relocation += rel->r_addend;
|
||||||
if (tls_type != 0)
|
if (tls_type != 0)
|
||||||
{
|
{
|
||||||
relocation -= htab->tls_sec->vma + DTP_OFFSET;
|
relocation -= htab->tls_sec->vma + DTP_OFFSET;
|
||||||
|
@ -7676,10 +7669,11 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
|
||||||
htab->sgot->contents + off + 8);
|
htab->sgot->contents + off + 8);
|
||||||
relocation = 1;
|
relocation = 1;
|
||||||
}
|
}
|
||||||
|
else if (tls_type == (TLS_TLS | TLS_LD))
|
||||||
|
relocation = 1;
|
||||||
bfd_put_64 (output_bfd, relocation,
|
bfd_put_64 (output_bfd, relocation,
|
||||||
htab->sgot->contents + off);
|
htab->sgot->contents + off);
|
||||||
}
|
}
|
||||||
ent->got.offset |= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (off >= (bfd_vma) -2)
|
if (off >= (bfd_vma) -2)
|
||||||
|
|
Loading…
Reference in a new issue