From 4fe5ca5b131cea35f0b3265d18a86f12bfc149e7 Mon Sep 17 00:00:00 2001 From: Greg McGary Date: Wed, 22 Nov 2006 00:12:30 +0000 Subject: [PATCH] * elf32-ppc.c (ppc_elf_relocate_section): Fixup D field at proper offset in little-endian mode. * elf64-ppc.c (ppc_elf_relocate_section): Likewise. --- bfd/ChangeLog | 6 ++++++ bfd/elf32-ppc.c | 18 ++++++++++-------- bfd/elf64-ppc.c | 17 +++++++++-------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c703067cad..6cf89cccbd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2006-11-21 Greg McGary + + * elf32-ppc.c (ppc_elf_relocate_section): Fixup D field + at proper offset in little-endian mode. + * elf64-ppc.c (ppc_elf_relocate_section): Likewise. + 2006-11-21 Jakub Jelinek * elf-eh-frame.c (struct cie): New type. diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 281fab0155..3561d8be2d 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -5504,6 +5504,7 @@ ppc_elf_relocate_section (bfd *output_bfd, asection *got2, *sreloc = NULL; bfd_vma *local_got_offsets; bfd_boolean ret = TRUE; + bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0); #ifdef DEBUG _bfd_error_handler ("ppc_elf_relocate_section called for %B section %A, " @@ -5630,10 +5631,10 @@ ppc_elf_relocate_section (bfd *output_bfd, && (tls_mask & TLS_TPREL) == 0) { bfd_vma insn; - insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2); + insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset); insn &= 31 << 21; insn |= 0x3c020000; /* addis 0,2,0 */ - bfd_put_32 (output_bfd, insn, contents + rel->r_offset - 2); + bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset); r_type = R_PPC_TPREL16_HA; rel->r_info = ELF32_R_INFO (r_symndx, r_type); } @@ -5677,9 +5678,10 @@ ppc_elf_relocate_section (bfd *output_bfd, bfd_put_32 (output_bfd, insn, contents + rel->r_offset); r_type = R_PPC_TPREL16_LO; rel->r_info = ELF32_R_INFO (r_symndx, r_type); + /* Was PPC_TLS which sits on insn boundary, now - PPC_TPREL16_LO which is at insn+2. */ - rel->r_offset += 2; + PPC_TPREL16_LO which is at low-order half-word. */ + rel->r_offset += d_offset; } break; @@ -5701,7 +5703,7 @@ ppc_elf_relocate_section (bfd *output_bfd, else { bfd_put_32 (output_bfd, NOP, contents + rel->r_offset); - rel->r_offset -= 2; + rel->r_offset -= d_offset; r_type = R_PPC_NONE; } rel->r_info = ELF32_R_INFO (r_symndx, r_type); @@ -5750,7 +5752,7 @@ ppc_elf_relocate_section (bfd *output_bfd, /* OK, it checks out. Replace the call. */ offset = rel[1].r_offset; insn1 = bfd_get_32 (output_bfd, - contents + rel->r_offset - 2); + contents + rel->r_offset - d_offset); if ((tls_mask & tls_gd) != 0) { /* IE */ @@ -5778,10 +5780,10 @@ ppc_elf_relocate_section (bfd *output_bfd, rel->r_info = ELF32_R_INFO (r_symndx, r_type); rel[1].r_info = ELF32_R_INFO (r_symndx, R_PPC_TPREL16_LO); - rel[1].r_offset += 2; + rel[1].r_offset += d_offset; rel[1].r_addend = rel->r_addend; } - bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - 2); + bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - d_offset); bfd_put_32 (output_bfd, insn2, contents + offset); if (tls_gd == 0) { diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 0c81e5e31c..6658b5b4b3 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -9731,6 +9731,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, bfd_boolean is_opd; /* Disabled until we sort out how ld should choose 'y' vs 'at'. */ bfd_boolean is_power4 = FALSE; + bfd_vma d_offset = (bfd_big_endian (output_bfd) ? 2 : 0); /* Initialize howto table if needed. */ if (!ppc64_elf_howto_table[R_PPC64_ADDR32]) @@ -9960,10 +9961,10 @@ ppc64_elf_relocate_section (bfd *output_bfd, && (tls_mask & TLS_TPREL) == 0) { toctprel: - insn = bfd_get_32 (output_bfd, contents + rel->r_offset - 2); + insn = bfd_get_32 (output_bfd, contents + rel->r_offset - d_offset); insn &= 31 << 21; insn |= 0x3c0d0000; /* addis 0,13,0 */ - bfd_put_32 (output_bfd, insn, contents + rel->r_offset - 2); + bfd_put_32 (output_bfd, insn, contents + rel->r_offset - d_offset); r_type = R_PPC64_TPREL16_HA; if (toc_symndx != 0) { @@ -10015,8 +10016,8 @@ ppc64_elf_relocate_section (bfd *output_bfd, insn |= rtra; bfd_put_32 (output_bfd, insn, contents + rel->r_offset); /* Was PPC64_TLS which sits on insn boundary, now - PPC64_TPREL16_LO which is at insn+2. */ - rel->r_offset += 2; + PPC64_TPREL16_LO which is at low-order half-word. */ + rel->r_offset += d_offset; r_type = R_PPC64_TPREL16_LO; if (toc_symndx != 0) { @@ -10049,7 +10050,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, else { bfd_put_32 (output_bfd, NOP, contents + rel->r_offset); - rel->r_offset -= 2; + rel->r_offset -= d_offset; r_type = R_PPC64_NONE; } rel->r_info = ELF64_R_INFO (r_symndx, r_type); @@ -10098,7 +10099,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, /* OK, it checks out. Replace the call. */ offset = rel[1].r_offset; insn1 = bfd_get_32 (output_bfd, - contents + rel->r_offset - 2); + contents + rel->r_offset - d_offset); insn3 = bfd_get_32 (output_bfd, contents + offset + 4); if ((tls_mask & tls_gd) != 0) @@ -10133,7 +10134,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, rel->r_info = ELF64_R_INFO (r_symndx, r_type); rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_TPREL16_LO); - rel[1].r_offset += 2; + rel[1].r_offset += d_offset; } if (insn3 == NOP || insn3 == CROR_151515 || insn3 == CROR_313131) @@ -10142,7 +10143,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, insn2 = NOP; rel[1].r_offset += 4; } - bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - 2); + bfd_put_32 (output_bfd, insn1, contents + rel->r_offset - d_offset); bfd_put_32 (output_bfd, insn2, contents + offset); bfd_put_32 (output_bfd, insn3, contents + offset + 4); if (tls_gd == 0 || toc_symndx != 0) -- 2.34.1