614-mips64_fix_setjmp_longjmp.patch 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. commit 70a04a287a2875c82e6822c36e071afba5b63a62
  2. Author: Waldemar Brodkorb <wbx@openadk.org>
  3. Date: Wed Jan 29 18:58:56 2014 +0100
  4. libc: mips: Fix setjmp/longjmp for MIPS64 N64 ABI
  5. When booting a Linux system with qemu-system-mips64 the execution
  6. of $(pwd) in the ash shell triggers a segmentation fault. Ash uses
  7. setjmp/longjmp for exception handling.
  8. After looking at the glibc implementation,
  9. I found some differences, with this patch tries to resolve.
  10. Now the system boots up fine and no segmentation faults occur.
  11. The global pointer should be restored and the types for the
  12. register values should be wide enough.
  13. See:
  14. http://www.cygwin.com/ml/libc-alpha/2003-03/msg00363.html
  15. Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
  16. Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
  17. --- a/libc/sysdeps/linux/mips/bits/setjmp.h
  18. +++ b/libc/sysdeps/linux/mips/bits/setjmp.h
  19. @@ -26,13 +26,19 @@
  20. #include <sgidefs.h>
  21. +#if _MIPS_SIM == _MIPS_SIM_ABI32
  22. +#define ptrsize void *
  23. +#else
  24. +#define ptrsize long long
  25. +#endif
  26. +
  27. typedef struct
  28. {
  29. /* Program counter. */
  30. - void * __pc;
  31. + ptrsize __pc;
  32. /* Stack pointer. */
  33. - void * __sp;
  34. + ptrsize __sp;
  35. /* Callee-saved registers s0 through s7. */
  36. #if _MIPS_SIM == _MIPS_SIM_ABI32
  37. @@ -42,10 +48,10 @@ typedef struct
  38. #endif
  39. /* The frame pointer. */
  40. - void * __fp;
  41. + ptrsize __fp;
  42. /* The global pointer. */
  43. - void * __gp;
  44. + ptrsize __gp;
  45. /* Floating point status register. */
  46. int __fpc_csr;
  47. --- a/libc/sysdeps/linux/mips/setjmp.S
  48. +++ b/libc/sysdeps/linux/mips/setjmp.S
  49. @@ -53,6 +53,7 @@ __sigsetjmp:
  50. PTR_LA t9, __sigsetjmp_aux
  51. #if _MIPS_SIM != _MIPS_SIM_ABI32
  52. .cpreturn
  53. + move a4, gp
  54. #endif
  55. jr t9
  56. #else
  57. --- a/libc/sysdeps/linux/mips/setjmp_aux.c
  58. +++ b/libc/sysdeps/linux/mips/setjmp_aux.c
  59. @@ -31,7 +31,7 @@ extern int __sigjmp_save (sigjmp_buf, in
  60. int
  61. #if _MIPS_SIM == _MIPS_SIM_ABI64
  62. -__sigsetjmp_aux (jmp_buf env, int savemask, long sp, long fp)
  63. +__sigsetjmp_aux (jmp_buf env, int savemask, long long sp, long long fp, long long gp)
  64. #else /* O32 || N32 */
  65. __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
  66. #endif /* O32 || N32 */
  67. @@ -65,14 +65,14 @@ __sigsetjmp_aux (jmp_buf env, int savema
  68. #endif
  69. /* .. and the stack pointer; */
  70. - env[0].__jmpbuf[0].__sp = (void *) sp;
  71. + env[0].__jmpbuf[0].__sp = (ptrsize) sp;
  72. /* .. and the FP; it'll be in s8. */
  73. - env[0].__jmpbuf[0].__fp = (void *) fp;
  74. + env[0].__jmpbuf[0].__fp = (ptrsize) fp;
  75. /* .. and the GP; */
  76. #if _MIPS_SIM == _MIPS_SIM_ABI64
  77. - __asm__ __volatile__ ("sd $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
  78. + env[0].__jmpbuf[0].__gp = (ptrsize) gp;
  79. #else
  80. __asm__ __volatile__ ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
  81. #endif