* elf64-ppc.c (ppc64_elf_relocate_section): When optimizing toctprel

tls, check that a TOC16_DS or TOC16_LO_DS reloc isn't pointing to a
	dtprel entry.  Ensure TLS_LD DTPMOD reloc has a zero addend.  Write
	got section for RELATIVE relocs.  Fix wrong comment.  Change condition
	under which dynamic relocs update the section contents.
This commit is contained in:
Alan Modra 2003-06-16 10:50:22 +00:00
parent 72fab6974b
commit 81407a69a5
2 changed files with 60 additions and 19 deletions

View File

@ -1,3 +1,11 @@
2003-06-16 Alan Modra <amodra@bigpond.net.au>
* elf64-ppc.c (ppc64_elf_relocate_section): When optimizing toctprel
tls, check that a TOC16_DS or TOC16_LO_DS reloc isn't pointing to a
dtprel entry. Ensure TLS_LD DTPMOD reloc has a zero addend. Write
got section for RELATIVE relocs. Fix wrong comment. Change condition
under which dynamic relocs update the section contents.
2003-06-13 Robert Millan <zeratul2@wanadoo.es>
* config.bfd: Add i386-netbsd-gnu target.
@ -6,18 +14,18 @@
* opncls.c (calc_crc32): Rename to
bfd_calc_gnu_debuglink_crc32 and export.
(GNU_DEBUGLINK): Define and use to replace occurrences of
(GNU_DEBUGLINK): Define and use to replace occurrences of
hard-coded ".gnu_debuglink" in the code.
(get_debug_link_info): Prevent aborts by replacing call to
(get_debug_link_info): Prevent aborts by replacing call to
xmalloc with a call to malloc.
(find_separate_debug_file): Prevent aborts by replacing calls
(find_separate_debug_file): Prevent aborts by replacing calls
to xmalloc and xstrdup with calls to malloc and strdup.
(bfd_add_gnu_debuglink): New function. Add a .gnu_debuglink
(bfd_add_gnu_debuglink): New function. Add a .gnu_debuglink
section to a bfd.
* bfd-in2.h: Regenerate.
2003-06-12 Federico G. Schwindt <fgsch@lodoss.net>
* config.bfd (i[3-7]86-*-openbsd[0-2].* | i[3-7]86-*-openbsd3.[0-3]):
New target (was i[3-7]86-*-openbsd* before).
(i[3-7]86-*-openbsd*): Change to use bfd_elf32_i386_vec.
@ -81,11 +89,11 @@
(_bfd_mips_elf_sign_extend): New prototype.
2003-06-11 Federico G. Schwindt <fgsch@lodoss.net>
* config.bfd (sparc-*-openbsd[0-2].* | sparc-*-openbsd3.[0-1]):
New target (was sparc-*-openbsd* before).
(sparc-*-openbsd*): Change to use bfd_elf32_sparc_vec.
* configure.in (vax-*-openbsd*): Set COREFILE to netbsd-core.lo.
* configure: Regenerate.

View File

@ -7445,7 +7445,11 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
tls_mask = *toc_tls;
if (r_type == R_PPC64_TOC16_DS
|| r_type == R_PPC64_TOC16_LO_DS)
goto toctprel;
{
if (tls_mask != 0
&& (tls_mask & (TLS_DTPREL | TLS_TPREL)) == 0)
goto toctprel;
}
else
{
/* If we found a GD reloc pair, then we might be
@ -7468,11 +7472,11 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
case R_PPC64_GOT_TPREL16_DS:
case R_PPC64_GOT_TPREL16_LO_DS:
toctprel:
if (tls_mask != 0
&& (tls_mask & TLS_TPREL) == 0)
{
bfd_vma insn;
toctprel:
insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2);
insn &= 31 << 21;
insn |= 0x3c0d0000; /* addis 0,13,0 */
@ -7985,6 +7989,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
outrel.r_offset = (htab->sgot->output_section->vma
+ htab->sgot->output_offset
+ off);
outrel.r_addend = rel->r_addend;
if (tls_type & (TLS_LD | TLS_GD))
{
outrel.r_addend = 0;
@ -7997,6 +8002,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_elf64_swap_reloca_out (output_bfd,
&outrel, loc);
outrel.r_offset += 8;
outrel.r_addend = rel->r_addend;
outrel.r_info
= ELF64_R_INFO (indx, R_PPC64_DTPREL64);
}
@ -8006,11 +8012,18 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
else if (tls_type == (TLS_TLS | TLS_TPREL))
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_TPREL64);
else if (indx == 0)
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_RELATIVE);
{
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_RELATIVE);
/* Write the .got section contents for the sake
of prelink. */
loc = htab->sgot->contents + off;
bfd_put_64 (output_bfd, outrel.r_addend, loc);
}
else
outrel.r_info = ELF64_R_INFO (indx, R_PPC64_GLOB_DAT);
outrel.r_addend = rel->r_addend;
if (indx == 0)
if (indx == 0 && tls_type != (TLS_TLS | TLS_LD))
{
outrel.r_addend += relocation;
if (tls_type & (TLS_GD | TLS_DTPREL | TLS_TPREL))
@ -8023,8 +8036,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
/* Init the .got section contents here if we're not
emitting a reloc. A reloc will also init the
section contents via _bfd_final_link_relocate. */
emitting a reloc. */
else
{
relocation += rel->r_addend;
@ -8254,9 +8266,6 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
or this is an opd section reloc which must point
at a local function. */
outrel.r_addend += relocation;
/* We need to relocate .opd contents for ld.so, and
it doesn't hurt to relocate in other cases. */
relocate = TRUE;
if (r_type == R_PPC64_ADDR64 || r_type == R_PPC64_TOC)
{
if (is_opd && h != NULL)
@ -8274,6 +8283,12 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
unresolved_reloc = FALSE;
}
outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE);
/* We need to relocate .opd contents for ld.so.
Prelink also wants simple and consistent rules
for relocs. This make all RELATIVE relocs have
*r_offset equal to r_addend. */
relocate = TRUE;
}
else
{
@ -8315,9 +8330,27 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
/* If this reloc is against an external symbol, it will
be computed at runtime, so there's no need to do
anything now. */
anything now. However, for the sake of prelink ensure
that the section contents are a known value. */
if (! relocate)
continue;
{
unresolved_reloc = FALSE;
/* The value chosen here is quite arbitrary as ld.so
ignores section contents except for the special
case of .opd where the contents might be accessed
before relocation. Choose zero, as that won't
cause reloc overflow. */
relocation = 0;
addend = 0;
/* Use *r_offset == r_addend for R_PPC64_ADDR64 relocs
to improve backward compatibility with older
versions of ld. */
if (r_type == R_PPC64_ADDR64)
addend = outrel.r_addend;
/* Adjust pc_relative relocs to have zero in *r_offset. */
else if (ppc64_elf_howto_table[(int) r_type]->pc_relative)
addend = outrel.r_offset;
}
}
break;