aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain/uClibc/patches-0.9.33.2/614-mips64_fix_setjmp_longjmp.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain/uClibc/patches-0.9.33.2/614-mips64_fix_setjmp_longjmp.patch')
-rw-r--r--toolchain/uClibc/patches-0.9.33.2/614-mips64_fix_setjmp_longjmp.patch99
1 files changed, 99 insertions, 0 deletions
diff --git a/toolchain/uClibc/patches-0.9.33.2/614-mips64_fix_setjmp_longjmp.patch b/toolchain/uClibc/patches-0.9.33.2/614-mips64_fix_setjmp_longjmp.patch
new file mode 100644
index 0000000..1706130
--- /dev/null
+++ b/toolchain/uClibc/patches-0.9.33.2/614-mips64_fix_setjmp_longjmp.patch
@@ -0,0 +1,99 @@
+commit 70a04a287a2875c82e6822c36e071afba5b63a62
+Author: Waldemar Brodkorb <wbx@openadk.org>
+Date: Wed Jan 29 18:58:56 2014 +0100
+
+ libc: mips: Fix setjmp/longjmp for MIPS64 N64 ABI
+
+ When booting a Linux system with qemu-system-mips64 the execution
+ of $(pwd) in the ash shell triggers a segmentation fault. Ash uses
+ setjmp/longjmp for exception handling.
+
+ After looking at the glibc implementation,
+ I found some differences, with this patch tries to resolve.
+ Now the system boots up fine and no segmentation faults occur.
+
+ The global pointer should be restored and the types for the
+ register values should be wide enough.
+
+ See:
+ http://www.cygwin.com/ml/libc-alpha/2003-03/msg00363.html
+
+ Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
+ Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
+
+--- a/libc/sysdeps/linux/mips/bits/setjmp.h
++++ b/libc/sysdeps/linux/mips/bits/setjmp.h
+@@ -26,13 +26,19 @@
+
+ #include <sgidefs.h>
+
++#if _MIPS_SIM == _MIPS_SIM_ABI32
++#define ptrsize void *
++#else
++#define ptrsize long long
++#endif
++
+ typedef struct
+ {
+ /* Program counter. */
+- void * __pc;
++ ptrsize __pc;
+
+ /* Stack pointer. */
+- void * __sp;
++ ptrsize __sp;
+
+ /* Callee-saved registers s0 through s7. */
+ #if _MIPS_SIM == _MIPS_SIM_ABI32
+@@ -42,10 +48,10 @@ typedef struct
+ #endif
+
+ /* The frame pointer. */
+- void * __fp;
++ ptrsize __fp;
+
+ /* The global pointer. */
+- void * __gp;
++ ptrsize __gp;
+
+ /* Floating point status register. */
+ int __fpc_csr;
+--- a/libc/sysdeps/linux/mips/setjmp.S
++++ b/libc/sysdeps/linux/mips/setjmp.S
+@@ -53,6 +53,7 @@ __sigsetjmp:
+ PTR_LA t9, __sigsetjmp_aux
+ #if _MIPS_SIM != _MIPS_SIM_ABI32
+ .cpreturn
++ move a4, gp
+ #endif
+ jr t9
+ #else
+--- a/libc/sysdeps/linux/mips/setjmp_aux.c
++++ b/libc/sysdeps/linux/mips/setjmp_aux.c
+@@ -31,7 +31,7 @@ extern int __sigjmp_save (sigjmp_buf, in
+
+ int
+ #if _MIPS_SIM == _MIPS_SIM_ABI64
+-__sigsetjmp_aux (jmp_buf env, int savemask, long sp, long fp)
++__sigsetjmp_aux (jmp_buf env, int savemask, long long sp, long long fp, long long gp)
+ #else /* O32 || N32 */
+ __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
+ #endif /* O32 || N32 */
+@@ -65,14 +65,14 @@ __sigsetjmp_aux (jmp_buf env, int savema
+ #endif
+
+ /* .. and the stack pointer; */
+- env[0].__jmpbuf[0].__sp = (void *) sp;
++ env[0].__jmpbuf[0].__sp = (ptrsize) sp;
+
+ /* .. and the FP; it'll be in s8. */
+- env[0].__jmpbuf[0].__fp = (void *) fp;
++ env[0].__jmpbuf[0].__fp = (ptrsize) fp;
+
+ /* .. and the GP; */
+ #if _MIPS_SIM == _MIPS_SIM_ABI64
+- __asm__ __volatile__ ("sd $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
++ env[0].__jmpbuf[0].__gp = (ptrsize) gp;
+ #else
+ __asm__ __volatile__ ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
+ #endif