* elf64-ppc.c (ppc64_elf_tls_optimize): Only optimize
R_PPC64_TPREL64 and R_PPC64_DTPMOD64 relocs when they are in the .toc and referenced by a TLS code sequence. (ppc64_elf_edit_toc): Cater for the unlikely situation that .toc is the first section in a file.
This commit is contained in:
parent
2a60a7a82c
commit
30038c5930
|
@ -1,3 +1,11 @@
|
||||||
|
2006-05-05 Alan Modra <amodra@bigpond.net.au>
|
||||||
|
|
||||||
|
* elf64-ppc.c (ppc64_elf_tls_optimize): Only optimize
|
||||||
|
R_PPC64_TPREL64 and R_PPC64_DTPMOD64 relocs when they are in
|
||||||
|
the .toc and referenced by a TLS code sequence.
|
||||||
|
(ppc64_elf_edit_toc): Cater for the unlikely situation that
|
||||||
|
.toc is the first section in a file.
|
||||||
|
|
||||||
2006-05-04 Andreas Schwab <schwab@suse.de>
|
2006-05-04 Andreas Schwab <schwab@suse.de>
|
||||||
|
|
||||||
* aoutf1.h (struct external_sparc_core): Declare c_regs as struct
|
* aoutf1.h (struct external_sparc_core): Declare c_regs as struct
|
||||||
|
|
|
@ -6699,12 +6699,22 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
||||||
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
|
||||||
{
|
{
|
||||||
Elf_Internal_Sym *locsyms = NULL;
|
Elf_Internal_Sym *locsyms = NULL;
|
||||||
|
asection *toc = bfd_get_section_by_name (ibfd, ".toc");
|
||||||
|
unsigned char *toc_ref = NULL;
|
||||||
|
|
||||||
for (sec = ibfd->sections; sec != NULL; sec = sec->next)
|
/* Look at all the sections for this file, with TOC last. */
|
||||||
|
for (sec = (ibfd->sections == toc && toc && toc->next ? toc->next
|
||||||
|
: ibfd->sections);
|
||||||
|
sec != NULL;
|
||||||
|
sec = (sec == toc ? NULL
|
||||||
|
: sec->next == NULL ? toc
|
||||||
|
: sec->next == toc && toc->next ? toc->next
|
||||||
|
: sec->next))
|
||||||
if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
|
if (sec->has_tls_reloc && !bfd_is_abs_section (sec->output_section))
|
||||||
{
|
{
|
||||||
Elf_Internal_Rela *relstart, *rel, *relend;
|
Elf_Internal_Rela *relstart, *rel, *relend;
|
||||||
int expecting_tls_get_addr;
|
int expecting_tls_get_addr;
|
||||||
|
long toc_ref_index = 0;
|
||||||
|
|
||||||
/* Read the relocations. */
|
/* Read the relocations. */
|
||||||
relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
|
relstart = _bfd_elf_link_read_relocs (ibfd, sec, NULL, NULL,
|
||||||
|
@ -6733,6 +6743,8 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
||||||
err_free_rel:
|
err_free_rel:
|
||||||
if (elf_section_data (sec)->relocs != relstart)
|
if (elf_section_data (sec)->relocs != relstart)
|
||||||
free (relstart);
|
free (relstart);
|
||||||
|
if (toc_ref != NULL)
|
||||||
|
free (toc_ref);
|
||||||
if (locsyms != NULL
|
if (locsyms != NULL
|
||||||
&& (elf_tdata (ibfd)->symtab_hdr.contents
|
&& (elf_tdata (ibfd)->symtab_hdr.contents
|
||||||
!= (unsigned char *) locsyms))
|
!= (unsigned char *) locsyms))
|
||||||
|
@ -6840,8 +6852,12 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
||||||
rel - 1, ibfd);
|
rel - 1, ibfd);
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
goto err_free_rel;
|
goto err_free_rel;
|
||||||
if (toc_tls != NULL)
|
if (retval > 1 && toc_tls != NULL)
|
||||||
expecting_tls_get_addr = retval > 1;
|
{
|
||||||
|
expecting_tls_get_addr = 1;
|
||||||
|
if (toc_ref != NULL)
|
||||||
|
toc_ref[toc_ref_index] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expecting_tls_get_addr)
|
if (expecting_tls_get_addr)
|
||||||
|
@ -6859,8 +6875,40 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
||||||
expecting_tls_get_addr = 0;
|
expecting_tls_get_addr = 0;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case R_PPC64_TOC16:
|
||||||
|
case R_PPC64_TOC16_LO:
|
||||||
|
case R_PPC64_TLS:
|
||||||
|
expecting_tls_get_addr = 0;
|
||||||
|
if (sym_sec == toc && toc != NULL)
|
||||||
|
{
|
||||||
|
/* Mark this toc entry as referenced by a TLS
|
||||||
|
code sequence. We can do that now in the
|
||||||
|
case of R_PPC64_TLS, and after checking for
|
||||||
|
tls_get_addr for the TOC16 relocs. */
|
||||||
|
if (toc_ref == NULL)
|
||||||
|
{
|
||||||
|
toc_ref = bfd_zmalloc (toc->size / 8);
|
||||||
|
if (toc_ref == NULL)
|
||||||
|
goto err_free_rel;
|
||||||
|
}
|
||||||
|
if (h != NULL)
|
||||||
|
value = h->root.u.def.value;
|
||||||
|
else
|
||||||
|
value = sym->st_value;
|
||||||
|
value += rel->r_addend;
|
||||||
|
BFD_ASSERT (value < toc->size && value % 8 == 0);
|
||||||
|
toc_ref_index = value / 8;
|
||||||
|
if (r_type == R_PPC64_TLS)
|
||||||
|
toc_ref[toc_ref_index] = 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
case R_PPC64_TPREL64:
|
case R_PPC64_TPREL64:
|
||||||
expecting_tls_get_addr = 0;
|
expecting_tls_get_addr = 0;
|
||||||
|
if (sec != toc
|
||||||
|
|| toc_ref == NULL
|
||||||
|
|| !toc_ref[rel->r_offset / 8])
|
||||||
|
continue;
|
||||||
if (ok_tprel)
|
if (ok_tprel)
|
||||||
{
|
{
|
||||||
/* IE -> LE */
|
/* IE -> LE */
|
||||||
|
@ -6873,6 +6921,10 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
||||||
|
|
||||||
case R_PPC64_DTPMOD64:
|
case R_PPC64_DTPMOD64:
|
||||||
expecting_tls_get_addr = 0;
|
expecting_tls_get_addr = 0;
|
||||||
|
if (sec != toc
|
||||||
|
|| toc_ref == NULL
|
||||||
|
|| !toc_ref[rel->r_offset / 8])
|
||||||
|
continue;
|
||||||
if (rel + 1 < relend
|
if (rel + 1 < relend
|
||||||
&& (rel[1].r_info
|
&& (rel[1].r_info
|
||||||
== ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64))
|
== ELF64_R_INFO (r_symndx, R_PPC64_DTPREL64))
|
||||||
|
@ -6951,6 +7003,9 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
||||||
free (relstart);
|
free (relstart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (toc_ref != NULL)
|
||||||
|
free (toc_ref);
|
||||||
|
|
||||||
if (locsyms != NULL
|
if (locsyms != NULL
|
||||||
&& (elf_tdata (ibfd)->symtab_hdr.contents
|
&& (elf_tdata (ibfd)->symtab_hdr.contents
|
||||||
!= (unsigned char *) locsyms))
|
!= (unsigned char *) locsyms))
|
||||||
|
@ -7146,13 +7201,14 @@ ppc64_elf_edit_toc (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now check all kept sections that might reference the toc. */
|
/* Now check all kept sections that might reference the toc.
|
||||||
for (sec = ibfd->sections;
|
Check the toc itself last. */
|
||||||
|
for (sec = (ibfd->sections == toc && toc->next ? toc->next
|
||||||
|
: ibfd->sections);
|
||||||
sec != NULL;
|
sec != NULL;
|
||||||
/* Check the toc itself last. */
|
|
||||||
sec = (sec == toc ? NULL
|
sec = (sec == toc ? NULL
|
||||||
: sec->next == toc && sec->next->next ? sec->next->next
|
|
||||||
: sec->next == NULL ? toc
|
: sec->next == NULL ? toc
|
||||||
|
: sec->next == toc && toc->next ? toc->next
|
||||||
: sec->next))
|
: sec->next))
|
||||||
{
|
{
|
||||||
int repeat;
|
int repeat;
|
||||||
|
|
Loading…
Reference in New Issue