[PATCH] moxie: Save $r11 in setjmp() and longjmp()

Sebastian Huber sebastian.huber@embedded-brains.de
Fri Aug 21 08:11:58 GMT 2026


The ABI of the architecture makes $r6 to $r11 call-saved.  The routines
saved and restored $r6 to $r10 only, and _JBLEN left no room for
another register.  A value which the compiler holds in $r11 across a
setjmp() and longjmp() pair was lost.  A caller which returns through
longjmp() and then makes an indirect call through $r11 jumps to
whatever the intervening code left there.

Add $r11 to the jump buffer and raise _JBLEN to 11.  Correct the layout
comment, which swapped $sp and $fp and gave the last stack frame slot
as 0x25.

The size of jmp_buf changes, so the C library and every application
must be built together.

Found with the RTEMS test suite on the moxie GDB simulator.  The test
spmutex01 calls longjmp() from a fatal error extension and returns into
an indirect call through $r11.

Assisted-by: Claude:claude-opus-5 claude-code
Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
---
 newlib/libc/include/machine/setjmp.h | 2 +-
 newlib/libc/machine/moxie/setjmp.S   | 9 ++++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/newlib/libc/include/machine/setjmp.h b/newlib/libc/include/machine/setjmp.h
index 4e74bdb0f..568adef91 100644
--- a/newlib/libc/include/machine/setjmp.h
+++ b/newlib/libc/include/machine/setjmp.h
@@ -259,7 +259,7 @@ _BEGIN_STD_C
 #endif
 
 #ifdef __moxie__
-#define _JBLEN 10
+#define _JBLEN 11
 #endif
 
 #ifdef __CRX__
diff --git a/newlib/libc/machine/moxie/setjmp.S b/newlib/libc/machine/moxie/setjmp.S
index 014368d64..0bf36afc2 100644
--- a/newlib/libc/machine/moxie/setjmp.S
+++ b/newlib/libc/machine/moxie/setjmp.S
@@ -19,11 +19,12 @@
 #   $r8             0x08
 #   $r9             0x0c
 #   $r10            0x10
-#   $fp             0x14
-#   $sp             0x18
+#   $sp             0x14
+#   $fp             0x18
 #   stack frame fp  0x1c
 #   stack frame ra  0x20
-#   stack frame sc  0x25
+#   stack frame sc  0x24
+#   $r11            0x28
        
         .text
         .global setjmp
@@ -36,6 +37,7 @@ setjmp:
 	sto.l	0x10($r0), $r10
 	sto.l	0x14($r0), $sp
 	sto.l	0x18($r0), $fp
+	sto.l	0x28($r0), $r11
 	ldo.l   $r1,       0x00($fp)
 	sto.l   0x1c($r0), $r1
 	ldo.l   $r1,       0x04($fp)
@@ -57,6 +59,7 @@ longjmp:
 	ldo.l	$r10, 0x10($r0)
 	ldo.l	$sp, 0x14($r0)
 	ldo.l	$fp, 0x18($r0)
+	ldo.l	$r11, 0x28($r0)
 	ldo.l   $r2, 0x1c($r0)
 	sto.l   0x0($fp), $r2
 	ldo.l   $r2, 0x20($r0)
-- 
2.51.0



More information about the Newlib mailing list