This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Edit ELFv2 global entry prologue to non-PIC


Changing addis r2,r12,..; addi r2,r2,.. to lis r2,..; addi r2,r2..
in non-PIC executables has the benefit of removing a dependency on r12.
I should really do the same for plt call stubs..

bfd/
	* elf64-ppc.c (ppc64_elf_relocate_section): Edit global entry
	prologue to non-PIC in non-PIC executables.
ld/testsuite/
	* ld-powerpc/elfv2exe.d: Adjust for non-PIC global entry.

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index f0ec690..c364d34 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -13503,6 +13503,39 @@ ppc64_elf_relocate_section (bfd *output_bfd,
 	      rel->r_info = ELF64_R_INFO (r_symndx, r_type);
 	    }
 	  break;
+
+	case R_PPC64_REL16_HA:
+	  /* If we are generating a non-PIC executable, edit
+	     .	0:	addis 2,12,.TOC.-0b@ha
+	     .		addi 2,2,.TOC.-0b@l
+	     used by ELFv2 global entry points to set up r2, to
+	     .		lis 2,.TOC.@ha
+	     .		addi 2,2,.TOC.@l
+	     if .TOC. is in range.  */
+	  if (!info->shared
+	      && h != NULL && &h->elf == htab->elf.hgot
+	      && rel + 1 < relend
+	      && rel[1].r_info == ELF64_R_INFO (r_symndx, R_PPC64_REL16_LO)
+	      && rel[1].r_offset == rel->r_offset + 4
+	      && rel[1].r_addend == rel->r_addend + 4
+	      && relocation + 0x80008000 <= 0xffffffff)
+	    {
+	      unsigned int insn1, insn2;
+	      bfd_vma offset = rel->r_offset - d_offset;
+	      insn1 = bfd_get_32 (output_bfd, contents + offset);
+	      insn2 = bfd_get_32 (output_bfd, contents + offset + 4);
+	      if ((insn1 & 0xffff0000) == 0x3c4c0000 /* addis 2,12 */
+		  && (insn2 & 0xffff0000) == 0x38420000 /* addi 2,2 */)
+		{
+		  r_type = R_PPC64_ADDR16_HA;
+		  rel->r_info = ELF64_R_INFO (r_symndx, r_type);
+		  rel->r_addend -= d_offset;
+		  rel[1].r_info = ELF64_R_INFO (r_symndx, R_PPC64_ADDR16_LO);
+		  rel[1].r_addend -= d_offset + 4;
+		  bfd_put_32 (output_bfd, 0x3c400000, contents + offset);
+		}
+	    }
+	  break;
 	}
 
       /* Handle other relocations that tweak non-addend part of insn.  */
diff --git a/ld/testsuite/ld-powerpc/elfv2exe.d b/ld/testsuite/ld-powerpc/elfv2exe.d
index 50d4685..7ff9d38 100644
--- a/ld/testsuite/ld-powerpc/elfv2exe.d
+++ b/ld/testsuite/ld-powerpc/elfv2exe.d
@@ -20,8 +20,8 @@ Disassembly of section \.text:
 .*:	(20 04 80 4e|4e 80 04 20) 	bctr
 
 0+100000e0 <_start>:
-.*:	(02 00 4c 3c|3c 4c 00 02) 	addis   r2,r12,2
-.*:	(60 80 42 38|38 42 80 60) 	addi    r2,r2,-32672
+.*:	(02 10 40 3c|3c 40 10 02) 	lis     r2,4098
+.*:	(40 81 42 38|38 42 81 40) 	addi    r2,r2,-32448
 .*:	(a6 02 08 7c|7c 08 02 a6) 	mflr    r0
 .*:	(e1 ff 21 f8|f8 21 ff e1) 	stdu    r1,-32\(r1\)
 .*:	(30 00 01 f8|f8 01 00 30) 	std     r0,48\(r1\)
-- 
1.7.9.5


-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]