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

Reply via email to