aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog22
-rw-r--r--bfd/elf64-ppc.c57
2 files changed, 60 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 487f23c..26efd2f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index bc47809..31b52e2 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -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;