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]

[PATCH] slightly improve ARM PLT generation


According to ARM's AAELF document, section A.3, we can just use an add/ldr
combination if we only need to go <2^20 bytes away from PLT to
PLTGOT (the common case).

This patch does that. Comments welcome, this is my first binutils patch.

It adds these failures:
FAIL: Simple non-PIC shared library
FAIL: Simple PIC shared library
FAIL: Simple dynamic application
FAIL: Non-pcrel function reference
FAIL: Thumb shared library with ARM entry points
FAIL: Mixed ARM/Thumb shared library
FAIL: Mixed ARM/Thumb dynamic application
FAIL: Mixed ARM/Thumb arch5 dynamic application

The tests need to be updated to match the new PLT. New tests should be written
to test for a GOT entry being >=2^20 bytes from its PLT entry.


Adam

--

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.196
diff -u -3 -p -r1.196 elf32-arm.c
--- bfd/elf32-arm.c	22 May 2009 11:58:44 -0000	1.196
+++ bfd/elf32-arm.c	23 May 2009 14:10:28 -0000
@@ -1937,6 +1937,15 @@ static const bfd_vma elf32_arm_plt_entry
     0x00000000,		/* unused		*/
   };
 
+/* Or sometimes like this.  */
+static const bfd_vma elf32_arm_near_plt_entry [] =
+  {
+    0xe28fca00,		/* add	 ip, pc, #NN	*/
+    0xe5bcf000,		/* ldr	 pc, [ip, #NN]! */
+    0x00000000,		/* unused		*/
+    0x00000000,		/* unused		*/
+  };
+
 #else
 
 /* The first entry in a procedure linkage table looks like
@@ -1961,6 +1970,14 @@ static const bfd_vma elf32_arm_plt_entry
     0xe5bcf000,		/* ldr	 pc, [ip, #0xNNN]!  */
   };
 
+/* Or sometimes like this.  */
+static const bfd_vma elf32_arm_near_plt_entry [] =
+  {
+    0xe28fca00,		/* add	 ip, pc, #0xNN000  */
+    0xe5bcf000,		/* ldr	 pc, [ip, #0xNNN]! */
+    0x00000000,		/* unused                  */
+  };
+
 #endif
 
 /* The format of the first entry in the procedure linkage table
@@ -12022,21 +12039,39 @@ elf32_arm_finish_dynamic_symbol (bfd * o
 				  elf32_arm_plt_thumb_stub[1], ptr - 2);
 		}
 
-	      put_arm_insn (htab, output_bfd,
-			    elf32_arm_plt_entry[0]
-			    | ((got_displacement & 0x0ff00000) >> 20),
-			    ptr + 0);
-	      put_arm_insn (htab, output_bfd,
-			    elf32_arm_plt_entry[1]
-			    | ((got_displacement & 0x000ff000) >> 12),
-			    ptr+ 4);
-	      put_arm_insn (htab, output_bfd,
-			    elf32_arm_plt_entry[2]
-			    | (got_displacement & 0x00000fff),
-			    ptr + 8);
+	      if (got_displacement >= 0x100000)
+		{
+		  put_arm_insn (htab, output_bfd,
+				elf32_arm_plt_entry[0]
+				| ((got_displacement & 0x0ff00000) >> 20),
+				ptr + 0);
+		  put_arm_insn (htab, output_bfd,
+				elf32_arm_plt_entry[1]
+				| ((got_displacement & 0x000ff000) >> 12),
+				ptr + 4);
+		  put_arm_insn (htab, output_bfd,
+				elf32_arm_plt_entry[2]
+				| (got_displacement & 0x00000fff),
+				ptr + 8);
 #ifdef FOUR_WORD_PLT
-	      bfd_put_32 (output_bfd, elf32_arm_plt_entry[3], ptr + 12);
+		  bfd_put_32 (output_bfd, elf32_arm_plt_entry[3], ptr + 12);
 #endif
+		}
+	      else
+		{
+		  put_arm_insn (htab, output_bfd,
+				elf32_arm_near_plt_entry[0]
+				| ((got_displacement & 0x000ff000) >> 12),
+				ptr + 0);
+		  put_arm_insn (htab, output_bfd,
+				elf32_arm_near_plt_entry[1]
+				| (got_displacement & 0x00000fff),
+				ptr + 4);
+		  bfd_put_32 (output_bfd, elf32_arm_near_plt_entry[2], ptr + 8);
+#ifdef FOUR_WORD_PLT
+		  bfd_put_32 (output_bfd, elf32_arm_near_plt_entry[3], ptr + 12);
+#endif
+		}
 	    }
 
 	  /* Fill in the entry in the global offset table.  */

Attachment: signature.asc
Description: OpenPGP digital signature


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