diff options
author | John Bowler <jbowler@nslu2-linux.org> | 2005-09-22 19:36:38 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2005-09-22 19:36:38 +0000 |
commit | 3b98fa7d6706063736b5a910fc1228c747dabeb5 (patch) | |
tree | de4a0ab8cd6de843f21b47fdb834925435f1a27f /packages/binutils/binutils-2.16/binutils-2.16-thumb-glue.patch | |
parent | b58e9513f43d78e54c5f21938f74af0bccd75199 (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.patch | 76 |
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); |