Yesterday's comments about setjmp caused me to dig more deeply into the function today. Here are several fixes. There is still one possibly outstanding issue with fpsr. When reading thru the calling convention it seemed to indicate that the rounding mode was not to be assumed. (Document is http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055b/IHI0055B_aapcs64.pdf)
These fields [in FPSR] are not preserved across a public interface and may have any value on entry to a subroutine. This would seem to indicate that none of those fields need to be preserved, however should fpcr (rounding modes) be saved and restored? The text doesn't seem to give any indication about saving that state across routines. setjmp.h had never been updated for arm64, the defines were all from arm32. It was necessary to move the signal mask because after saving the full floating point context, the old save location was used by the fp context. Also the context is quite a bit larger than necessary 64 * 8 bytes, where the structure is only around 31 * 8 bytes in context. setjmp.S and _setjmp.S were modified to save the full 128 bit floating point registers instead of only the 64 bit portion of the registers. _setjmp.S was modified to have _longjmp always return non-zero, effectively the same diff as was applied to setjmp.S recently. Finally, the regress/lib/libc/setjmp-signal test was wrong, it was attempting to write to a null pointer, however the compiler was optimizing away the NULL deref and replacing it with a breakpoint instruction. Adding a volatile defeats the compiler optimization, this may not be the best fix for this issue. Is there better suggestions? Unfortunately, these fixes do not explain the sh coredumps that were being seen, in fact this test is not readily producing them on the RPI3 board. However other sporatic errors were still being seen while running other code and working on these changes. Index: sys/arch/arm64/include/setjmp.h =================================================================== RCS file: /cvs/src/sys/arch/arm64/include/setjmp.h,v retrieving revision 1.1 diff -u -p -r1.1 setjmp.h --- sys/arch/arm64/include/setjmp.h 17 Dec 2016 23:38:33 -0000 1.1 +++ sys/arch/arm64/include/setjmp.h 10 Mar 2017 06:41:15 -0000 @@ -16,27 +16,32 @@ * Description of the setjmp buffer * * word 0 magic number (dependant on creator) - * 1 - 3 f4 fp register 4 - * 4 - 6 f5 fp register 5 - * 7 - 9 f6 fp register 6 - * 10 - 12 f7 fp register 7 - * 13 fpsr fp status register - * 14 r4 register 4 - * 15 r5 register 5 - * 16 r6 register 6 - * 17 r7 register 7 - * 18 r8 register 8 - * 19 r9 register 9 - * 20 r10 register 10 (sl) - * 21 r11 register 11 (fp) - * 22 r12 register 12 (ip) - * 23 r13 register 13 (sp) - * 24 r14 register 14 (lr) - * 25 signal mask (dependant on magic) - * 26 (con't) - * 27 (con't) - * 28 (con't) - * + * 1 sp stack + * 2 x19 register 19 + * 3 x20 register 20 + * 4 x21 register 21 + * 5 x22 register 22 + * 6 x23 register 23 + * 7 x24 register 24 + * 8 x25 register 25 + * 9 x26 register 26 + * 10 x27 register 27 + * 11 x28 register 28 + * 12 x29 register 29 + * 13 x30 register 30 + * 14 q8 fp register 8 + * 16 q9 fp register 9 + * 18 q10 fp register 10 + * 20 q11 fp register 11 + * 22 q12 fp register 12 + * 24 q13 fp register 13 + * 26 q14 fp register 14 + * 28 v15 fp register 15 + * 30 signal mask (dependant on magic) + * 31 (con't) + * 32 (con't) + * 33 (con't) + * * The magic number number identifies the jmp_buf and * how the buffer was created as well as providing * a sanity check. @@ -61,23 +66,28 @@ /* Valid for all jmp_buf's */ #define _JB_MAGIC 0 -#define _JB_REG_F4 1 -#define _JB_REG_F5 4 -#define _JB_REG_F6 7 -#define _JB_REG_F7 10 -#define _JB_REG_FPSR 13 -#define _JB_REG_R4 14 -#define _JB_REG_R5 15 -#define _JB_REG_R6 16 -#define _JB_REG_R7 17 -#define _JB_REG_R8 18 -#define _JB_REG_R9 19 -#define _JB_REG_R10 20 -#define _JB_REG_R11 21 -#define _JB_REG_R12 22 -#define _JB_REG_R13 23 -#define _JB_REG_R14 24 +#define _JB_REG_SP 1 +#define _JB_REG_X19 2 +#define _JB_REG_X20 3 +#define _JB_REG_X21 4 +#define _JB_REG_X22 5 +#define _JB_REG_X23 6 +#define _JB_REG_X24 7 +#define _JB_REG_X25 8 +#define _JB_REG_X26 9 +#define _JB_REG_X27 10 +#define _JB_REG_X28 11 +#define _JB_REG_X29 12 +#define _JB_REG_X30 13 +#define _JB_REG_v8 14 +#define _JB_REG_v9 16 +#define _JB_REG_v10 18 +#define _JB_REG_v11 20 +#define _JB_REG_v12 22 +#define _JB_REG_v13 24 +#define _JB_REG_v14 26 +#define _JB_REG_v15 28 /* Only valid with the _JB_MAGIC_SETJMP magic */ -#define _JB_SIGMASK 25 +#define _JB_SIGMASK 30 Index: lib/libc/arch/aarch64/gen/_setjmp.S =================================================================== RCS file: /cvs/src/lib/libc/arch/aarch64/gen/_setjmp.S,v retrieving revision 1.1 diff -u -p -r1.1 _setjmp.S --- lib/libc/arch/aarch64/gen/_setjmp.S 11 Jan 2017 18:09:24 -0000 1.1 +++ lib/libc/arch/aarch64/gen/_setjmp.S 10 Mar 2017 06:41:15 -0000 @@ -49,10 +49,10 @@ ENTRY(_setjmp) #ifndef _STANDALONE /* Store the vfp registers */ - stp d8, d9, [x0], #16 - stp d10, d11, [x0], #16 - stp d12, d13, [x0], #16 - stp d14, d15, [x0] + stp q8, q9, [x0], #32 + stp q10, q11, [x0], #32 + stp q12, q13, [x0], #32 + stp q14, q15, [x0] #endif /* Return value */ @@ -84,14 +84,15 @@ ENTRY(_longjmp) #ifndef _STANDALONE /* Restore the vfp registers */ - ldp d8, d9, [x0], #16 - ldp d10, d11, [x0], #16 - ldp d12, d13, [x0], #16 - ldp d14, d15, [x0] + ldp q8, q9, [x0], #32 + ldp q10, q11, [x0], #32 + ldp q12, q13, [x0], #32 + ldp q14, q15, [x0] #endif /* Load the return value */ - mov x0, x1 + cmp w1, #0 + csinc w0, w1, wzr, ne ret botch: Index: lib/libc/arch/aarch64/gen/setjmp.S =================================================================== RCS file: /cvs/src/lib/libc/arch/aarch64/gen/setjmp.S,v retrieving revision 1.2 diff -u -p -r1.2 setjmp.S --- lib/libc/arch/aarch64/gen/setjmp.S 8 Mar 2017 06:28:12 -0000 1.2 +++ lib/libc/arch/aarch64/gen/setjmp.S 10 Mar 2017 06:41:15 -0000 @@ -34,7 +34,6 @@ #include <machine/setjmp.h> ENTRY(setjmp) - mov x2, x0 /* save jmpbuf in x2 */ /* Store the signal mask */ mov w1, #0 /* set */ @@ -57,10 +56,10 @@ ENTRY(setjmp) stp x29, x30, [x0], #16 /* Store the vfp registers */ - stp d8, d9, [x0], #16 - stp d10, d11, [x0], #16 - stp d12, d13, [x0], #16 - stp d14, d15, [x0] + stp q8, q9, [x0], #32 + stp q10, q11, [x0], #32 + stp q12, q13, [x0], #32 + stp q14, q15, [x0] /* Return value */ mov x0, #0 @@ -100,10 +99,10 @@ ENTRY(longjmp) ldp x29, x30, [x0], #16 /* Restore the vfp registers */ - ldp d8, d9, [x0], #16 - ldp d10, d11, [x0], #16 - ldp d12, d13, [x0], #16 - ldp d14, d15, [x0] + ldp q8, q9, [x0], #32 + ldp q10, q11, [x0], #32 + ldp q12, q13, [x0], #32 + ldp q14, q15, [x0] /* Load the return value */ cmp w3, #0 Index: regress/lib/libc/setjmp-signal/setjmp-signal.c =================================================================== RCS file: /cvs/src/regress/lib/libc/setjmp-signal/setjmp-signal.c,v retrieving revision 1.3 diff -u -p -r1.3 setjmp-signal.c --- regress/lib/libc/setjmp-signal/setjmp-signal.c 3 Jan 2003 20:46:05 -0000 1.3 +++ regress/lib/libc/setjmp-signal/setjmp-signal.c 10 Mar 2017 06:41:15 -0000 @@ -19,7 +19,7 @@ main() { signal(SIGSEGV, segv_handler); if (setjmp(jb) == 0) { - *((int *)0L) = 0; + *((volatile int *)0L) = 0; return (1); } return (0); Dale Rahn dr...@dalerahn.com