diff options
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.patch | 99 |
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 |