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]

Re: PowerPC64 plt call stubs


On Thu, Jul 14, 2011 at 12:58:35PM +0930, Alan Modra wrote:
> This makes plt call stubs omit the load of r11.  As far as I know,
> there isn't any reason to ever load r11 when making a call via the
> PLT, so the default is to omit.  Committed.

I forgot that relocs are emitted for the plt stubs.

	* elf64-ppc.c (build_plt_stub): Correct emitted relocs when no
	plt_static_chain.
	(ppc_build_one_stub): Adjust get_relocs call to suit..
	(ppc_size_one_stub): ..and reloc sizing.  Correct plt size corner case.

Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.357
diff -u -p -r1.357 elf64-ppc.c
--- bfd/elf64-ppc.c	26 Jul 2011 01:57:16 -0000	1.357
+++ bfd/elf64-ppc.c	2 Aug 2011 02:50:56 -0000
@@ -9291,7 +9291,7 @@ build_plt_stub (bfd *obfd, bfd_byte *p, 
 	  r[1].r_offset = r[0].r_offset + 8;
 	  r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
 	  r[1].r_addend = r[0].r_addend;
-	  if (PPC_HA (offset + 16) != PPC_HA (offset))
+	  if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
 	    {
 	      r[2].r_offset = r[1].r_offset + 4;
 	      r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO);
@@ -9302,9 +9302,12 @@ build_plt_stub (bfd *obfd, bfd_byte *p, 
 	      r[2].r_offset = r[1].r_offset + 8;
 	      r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
 	      r[2].r_addend = r[0].r_addend + 8;
-	      r[3].r_offset = r[2].r_offset + 4;
-	      r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
-	      r[3].r_addend = r[0].r_addend + 16;
+	      if (plt_static_chain)
+		{
+		  r[3].r_offset = r[2].r_offset + 4;
+		  r[3].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_LO_DS);
+		  r[3].r_addend = r[0].r_addend + 16;
+		}
 	    }
 	}
       bfd_put_32 (obfd, ADDIS_R12_R2 | PPC_HA (offset), p),	p += 4;
@@ -9327,7 +9330,7 @@ build_plt_stub (bfd *obfd, bfd_byte *p, 
 	{
 	  r[0].r_offset += 4;
 	  r[0].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
-	  if (PPC_HA (offset + 16) != PPC_HA (offset))
+	  if (PPC_HA (offset + 8 + 8 * plt_static_chain) != PPC_HA (offset))
 	    {
 	      r[1].r_offset = r[0].r_offset + 4;
 	      r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16);
@@ -9337,10 +9340,13 @@ build_plt_stub (bfd *obfd, bfd_byte *p, 
 	    {
 	      r[1].r_offset = r[0].r_offset + 8;
 	      r[1].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
-	      r[1].r_addend = r[0].r_addend + 16;
-	      r[2].r_offset = r[1].r_offset + 4;
-	      r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
-	      r[2].r_addend = r[0].r_addend + 8;
+	      r[1].r_addend = r[0].r_addend + 8 + 8 * plt_static_chain;
+	      if (plt_static_chain)
+		{
+		  r[2].r_offset = r[1].r_offset + 4;
+		  r[2].r_info = ELF64_R_INFO (0, R_PPC64_TOC16_DS);
+		  r[2].r_addend = r[0].r_addend + 8;
+		}
 	    }
 	}
       bfd_put_32 (obfd, STD_R2_40R1, p),			p += 4;
@@ -9808,8 +9814,10 @@ ppc_build_one_stub (struct bfd_hash_entr
       if (info->emitrelocations)
 	{
 	  r = get_relocs (stub_entry->stub_sec,
-			  (2 + (PPC_HA (off) != 0)
-			   + (PPC_HA (off + 16) == PPC_HA (off))));
+			  (2
+			   + (PPC_HA (off) != 0)
+			   + (htab->plt_static_chain
+			      && PPC_HA (off + 16) == PPC_HA (off))));
 	  if (r == NULL)
 	    return FALSE;
 	  r[0].r_offset = loc - stub_entry->stub_sec->contents;
@@ -9916,7 +9924,7 @@ ppc_size_one_stub (struct bfd_hash_entry
 	size -= 4;
       if (PPC_HA (off) == 0)
 	size -= 4;
-      if (PPC_HA (off + 16) != PPC_HA (off))
+      if (PPC_HA (off + 8 + 8 * htab->plt_static_chain) != PPC_HA (off))
 	size += 4;
       if (stub_entry->h != NULL
 	  && (stub_entry->h == htab->tls_get_addr_fd
@@ -9926,7 +9934,10 @@ ppc_size_one_stub (struct bfd_hash_entry
       if (info->emitrelocations)
 	{
 	  stub_entry->stub_sec->reloc_count
-	    += 2 + (PPC_HA (off) != 0) + (PPC_HA (off + 16) == PPC_HA (off));
+	    += (2
+		+ (PPC_HA (off) != 0)
+		+ (htab->plt_static_chain
+		   && PPC_HA (off + 16) == PPC_HA (off)));
 	  stub_entry->stub_sec->flags |= SEC_RELOC;
 	}
     }

-- 
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]