summaryrefslogtreecommitdiff
path: root/packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch')
-rw-r--r--packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch207
1 files changed, 207 insertions, 0 deletions
diff --git a/packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch b/packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch
new file mode 100644
index 0000000000..eae54f37e5
--- /dev/null
+++ b/packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch
@@ -0,0 +1,207 @@
+# Put the call_via_rx code into each executable - call_via_ip cannot
+# possibly work if called through the PLT! ldso requires this code
+# too as it is not linked with the crt stuff and thumb ldso does
+# make calls via a register.
+#
+# The patch puts the code into crti.S so that it is linked into
+# every normally built application (if thumb or interworking is
+# selected). This is only 30 extra bytes and it works - the previous
+# code did not because nothing both implemented and exported the
+# APIs (they were in libgcc, but not in the version script).
+#
+# crti.S and crtn.S is also brought up to date with GCC 3.4.4 - this
+# is essential for thumb support because the .init and .fini sections
+# must use arm or thumb code to match the compilation of the libraries.
+#
+# Note that code which pushes stuff into .init or .fini must be
+# compiled with or without -mthumb to match the uclibc compilation -
+# and gcc itself (which does do this) must therefore be compiled to
+# match.
+#
+--- uClibc-0.9.28/.pc/thumb-call-via-rx.patch/libc/sysdeps/linux/arm/crti.S 2005-08-17 15:49:41.000000000 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/crti.S 2005-09-21 19:15:19.996721584 -0700
+@@ -1,26 +1,86 @@
+ .file "initfini.c"
+
+ .section .init
+- .align 2
+ .global _init
+ .type _init, %function
++#if defined __thumb__
++ .align 1
++ .thumb
++ .thumb_func
+ _init:
+- @ args = 0, pretend = 0, frame = 0
+- @ frame_needed = 0, uses_anonymous_args = 0
+- str lr, [sp, #-4]!
+-
+- .align 2
+-
+-
+- .section .fini
++ push {r4-r7, lr}
++#else
+ .align 2
++ .arm
++_init:
++ @ gcc 3.3.2 didn't create a stack frame, gcc 3.4.4 does -
++ @ presumably 3.4.4 can put stuff into .init which requires
++ @ the arguments to be saved. This code is copied from 3.4.4
++ mov ip, sp
++ stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
++ sub fp, ip, #4
++#endif
++
++
++ .section .fini
+ .global _fini
+ .type _fini, %function
++#if defined __thumb__
++ .align 1
++ .thumb
++ .thumb_func
+ _fini:
+- @ args = 0, pretend = 0, frame = 0
+- @ frame_needed = 0, uses_anonymous_args = 0
+- str lr, [sp, #-4]!
+- .align 2
+-
+-
++ push {r4-r7, lr}
++#else
++ .align 2
++ .arm
++_fini:
++ mov ip, sp
++ stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
++ sub fp, ip, #4
++#endif
++
++
++#if (defined __thumb__ || defined __THUMB_INTERWORK__) && (defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__)
++ @ To support thumb code it is currently necessary to have the _call_via_rX
++ @ functions exposed to the linker for any program or shared library. PLT
++ @ references are inadequate - the PLT zaps ip and therefore breaks _call_via_ip
++ @ (and the compiler does generate this). It is simpler to put all the
++ @ required code in here - it only amounts to 60 bytes overhead.
++ @NOTE: it would be better to have the compiler generate this stuff as
++ @ required...
++ .section ".text"
++ .align 0
++ .force_thumb
++
++.macro call_via register
++ .global _call_via_\register
++ .type _call_via_\register, %function
++ .weak _call_via_\register
++ .hidden _call_via_\register
++ .thumb_func
++_call_via_\register:
++ bx \register
++ nop
++ .size _call_via_\register, . - _call_via_\register
++.endm
++
++ @ and calls for the 15 general purpose registers (2 bytes each).
++ call_via r0
++ call_via r1
++ call_via r2
++ call_via r3
++ call_via r4
++ call_via r5
++ call_via r6
++ call_via r7
++ call_via r8
++ call_via r9
++ call_via sl
++ call_via fp
++ call_via ip
++ call_via sp
++ call_via lr
++#endif
++
+ .ident "GCC: (GNU) 3.3.2 20031005 (Debian prerelease)"
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/crtn.S.orig 2005-09-20 16:39:20.010925582 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/crtn.S 2005-09-20 17:00:51.700206464 -0700
+@@ -1,17 +1,34 @@
+ .file "initfini.c"
+
+ .section .init
+- .align 2
+ .global _init
+ .type _init, %function
+- ldr pc, [sp], #4
++#if defined __thumb__
++ .align 1
++ .thumb
++ @ this will not work on ARMv4T, but lots of stuff
++ @ in here won't work there anyway...
++ pop {r4-r7, pc}
++#else
++ .align 2
++ .arm
++ ldmdb fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
++#endif
+ .size _init, .-_init
+
+ .section .fini
+- .align 2
+ .global _fini
+ .type _fini, %function
+- ldr pc, [sp], #4
++#if defined __thumb__
++ .align 1
++ .thumb
++ pop {r4-r7, pc}
++#else
++ .align 2
++ .arm
++ ldmdb fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
++#endif
+ .size _fini, .-_fini
+
++ @ In fact this is modified to 3.4.4
+ .ident "GCC: (GNU) 3.3.2 20031005 (Debian prerelease)"
+--- uClibc-0.9.28/.pc/thumb-call-via-rx.patch/ldso/ldso/arm/dl-syscalls.h 2005-08-17 15:49:41.000000000 -0700
++++ uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h 2005-09-21 19:17:01.143086323 -0700
+@@ -4,3 +4,39 @@
+ #define __set_errno(X) {(_dl_errno) = (X);}
+ #include "sys/syscall.h"
+
++/* _call_via_rX calls are used in thumb ldso because of calls via
++ * function pointers, but ldso is not linked with anything which
++ * provides them, so define them here (only required for thumb).
++ */
++#if defined(__thumb__)
++asm(
++ ".macro call_via register\n"
++ " .global _call_via_\\register\n"
++ " .hidden _call_via_\\register\n"
++ " .type _call_via_\\register, %function\n"
++ " .thumb_func\n"
++ "_call_via_\\register:\n"
++ " bx \\register\n"
++ " .size _call_via_\\register, . - _call_via_\\register\n"
++ ".endm\n"
++
++ ".text\n"
++ ".thumb\n"
++ ".align 1\n"
++ " call_via r0\n"
++ " call_via r1\n"
++ " call_via r2\n"
++ " call_via r3\n"
++ " call_via r4\n"
++ " call_via r5\n"
++ " call_via r6\n"
++ " call_via r7\n"
++ " call_via r8\n"
++ " call_via r9\n"
++ " call_via r10\n"
++ " call_via r11\n"
++ " call_via r12\n"
++ " call_via r13\n"
++ " call_via r14\n"
++);
++#endif