[PATCH] slightly improve ARM PLT generation
Adam Goode
adam@spicenitz.org
Sun May 24 01:25:00 GMT 2009
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. */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 260 bytes
Desc: OpenPGP digital signature
URL: <https://sourceware.org/pipermail/binutils/attachments/20090524/6b17216f/attachment.sig>
More information about the Binutils
mailing list