summaryrefslogtreecommitdiff
path: root/packages/binutils/binutils-2.16/binutils-2.16-thumb-glue.patch
diff options
context:
space:
mode:
authorJohn Bowler <jbowler@nslu2-linux.org>2005-09-22 19:36:38 +0000
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>2005-09-22 19:36:38 +0000
commit3b98fa7d6706063736b5a910fc1228c747dabeb5 (patch)
treede4a0ab8cd6de843f21b47fdb834925435f1a27f /packages/binutils/binutils-2.16/binutils-2.16-thumb-glue.patch
parentb58e9513f43d78e54c5f21938f74af0bccd75199 (diff)
binutils_2.16: patch thumb trampoline and glue code generation
This patch fixes problems with the ARM thumb specific code generation. It also adds debugging to bfd/elf32-arm.c to detect ref counting problems - one error message can fire in theory in the absence of thumb support if a union refcount field is used to refcount when it is set to something else. The error should be ignorable, in that the code should not have changed in effect.
Diffstat (limited to 'packages/binutils/binutils-2.16/binutils-2.16-thumb-glue.patch')
-rw-r--r--packages/binutils/binutils-2.16/binutils-2.16-thumb-glue.patch76
1 files changed, 76 insertions, 0 deletions
diff --git a/packages/binutils/binutils-2.16/binutils-2.16-thumb-glue.patch b/packages/binutils/binutils-2.16/binutils-2.16-thumb-glue.patch
new file mode 100644
index 0000000000..59d8035f7d
--- /dev/null
+++ b/packages/binutils/binutils-2.16/binutils-2.16-thumb-glue.patch
@@ -0,0 +1,76 @@
+# The ARM->Thumb glue uses an ldr of the target function address, this
+# simply doesn't work for PIC code, changed to use 4 word PIC glue
+#
+--- binutils-2.16/.pc/binutils-2.16-thumb-glue.patch/bfd/elf32-arm.c 2005-09-18 03:52:15.465165051 -0700
++++ binutils-2.16/bfd/elf32-arm.c 2005-09-18 03:52:33.546302825 -0700
+@@ -1493,19 +1493,20 @@
+ return myh;
+ }
+
+-/* ARM->Thumb glue:
++/* ARM->Thumb glue (PIC version):
+
+ .arm
+ __func_from_arm:
+ ldr r12, __func_addr
++ add r12, r12, pc @ pc is __func_addr, so r12 is func
+ bx r12
+ __func_addr:
+- .word func @ behave as if you saw a ARM_32 reloc. */
++ .word func-.+1 @ offset to actual function, low bit set */
+
+-#define ARM2THUMB_GLUE_SIZE 12
+-static const insn32 a2t1_ldr_insn = 0xe59fc000;
+-static const insn32 a2t2_bx_r12_insn = 0xe12fff1c;
+-static const insn32 a2t3_func_addr_insn = 0x00000001;
++#define ARM2THUMB_GLUE_SIZE 16
++static const insn32 a2t1_ldr_insn = 0xe59fc004;
++static const insn32 a2t2_add_r12_insn = 0xe08fc00c;
++static const insn32 a2t3_bx_r12_insn = 0xe12fff1c;
+
+ /* Thumb->ARM: Thumb->(non-interworking aware) ARM
+
+@@ -2187,6 +2188,8 @@
+
+ if ((my_offset & 0x01) == 0x01)
+ {
++ long int ret_offset;
++
+ if (sym_sec != NULL
+ && sym_sec->owner != NULL
+ && !INTERWORK_FLAG (sym_sec->owner))
+@@ -2203,12 +2206,31 @@
+ bfd_put_32 (output_bfd, (bfd_vma) a2t1_ldr_insn,
+ s->contents + my_offset);
+
+- bfd_put_32 (output_bfd, (bfd_vma) a2t2_bx_r12_insn,
++ bfd_put_32 (output_bfd, (bfd_vma) a2t2_add_r12_insn,
+ s->contents + my_offset + 4);
+
+- /* It's a thumb address. Add the low order bit. */
+- bfd_put_32 (output_bfd, val | a2t3_func_addr_insn,
++ bfd_put_32 (output_bfd, (bfd_vma) a2t3_bx_r12_insn,
+ s->contents + my_offset + 8);
++
++ /* Calculate the offset to the actual function. */
++ ret_offset =
++ /* Address of destination of the stub. */
++ ((bfd_signed_vma) val)
++ - ((bfd_signed_vma)
++ /* Offset from the start of the current section
++ to the start of the stubs. */
++ (s->output_offset
++ /* Offset of the start of this stub from the start of the stubs. */
++ + my_offset
++ /* Address of the start of the current section. */
++ + s->output_section->vma)
++ /* The word is 12 bytes into the stub. */
++ + 12
++ /* The destination is a thumb function so the bottom bit must be set. */
++ - 1);
++
++ bfd_put_32 (output_bfd, (bfd_vma) ret_offset,
++ s->contents + my_offset + 12);
+ }
+
+ BFD_ASSERT (my_offset <= globals->arm_glue_size);