This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 5af55c7023028494694f3ea3fd9ac8624b4a529a
Author: Marco Casaroli <[email protected]>
AuthorDate: Wed Oct 21 15:24:14 2026 +0200

    arch/arm: Tell the compiler which registers a system call changes.
    
    A system call returns from dispatch_syscall() with R1-R3 and R12 of the
    kernel: R2 holds the return value, and the stub function may change
    R1, R3 and R12.  The sys_call macros gave R1-R3 to the compiler as
    inputs only and did not clobber R12, so the compiler kept values in
    them across the SVC.  With CONFIG_LTO_FULL, posix_spawnattr_init()
    inlines two system calls and gives the second one the pid that it set
    for the first one in R1; sched_getscheduler() then gets another pid and
    fails with ESRCH, and no program starts on qemu-armv7a:knsh.
    
    The same happens without LTO when one function makes two system calls
    with the macros: on qemu-armv7a:knsh, sched_getparam(0) and then
    sched_getscheduler(0) give 0 and -1 (ESRCH).
    
    The GCC form now gives R0-R3 as in and out operands where they carry a
    parameter and clobbers the others and R12, and the GHS form clobbers
    them too.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 arch/arm/include/syscall.h | 128 +++++++++++++++++++++++----------------------
 1 file changed, 65 insertions(+), 63 deletions(-)

diff --git a/arch/arm/include/syscall.h b/arch/arm/include/syscall.h
index 8efd4935c26..3cc2ab96593 100644
--- a/arch/arm/include/syscall.h
+++ b/arch/arm/include/syscall.h
@@ -135,22 +135,27 @@
 
 #ifndef __ASSEMBLY__
 
+/* A system call returns with R1-R3 and R12 changed (dispatch_syscall() calls
+ * the stub function), so the macros give these registers to the compiler
+ * as outputs or as clobbered.
+ */
+
 /* SVC with SYS_ call number and no parameters */
 
 #ifdef __ghs__
-#  define sys_call0(nbr)                    \
-({                                          \
-  uintptr_t ret;                            \
-  __asm__ __volatile__                      \
-  (                                         \
-    "mov r0, %2\n\t"                        \
-    "svc %1\n\t"                            \
-    "mov %0, r0"                            \
-    : "=r"(ret)                             \
-    : "i"(SYS_syscall), "r"((uintptr_t)nbr) \
-    : "memory", "r0"                        \
-  );                                        \
-  ret;                                      \
+#  define sys_call0(nbr)                      \
+({                                            \
+  uintptr_t ret;                              \
+  __asm__ __volatile__                        \
+  (                                           \
+    "mov r0, %2\n\t"                          \
+    "svc %1\n\t"                              \
+    "mov %0, r0"                              \
+    : "=r"(ret)                               \
+    : "i"(SYS_syscall), "r"((uintptr_t)nbr)   \
+    : "memory", "r0", "r1", "r2", "r3", "r12" \
+  );                                          \
+  ret;                                        \
 })
 #else
 #  define sys_call0(nbr)                                    \
@@ -159,9 +164,9 @@
   __asm__ __volatile__                                      \
   (                                                         \
     "svc %1"                                                \
-    : "=r"(reg0)                                            \
-    : "i"(SYS_syscall), "r"(reg0)                           \
-    : "memory"                                              \
+    : "+r"(reg0)                                            \
+    : "i"(SYS_syscall)                                      \
+    : "memory", "r1", "r2", "r3", "r12"                     \
   );                                                        \
   reg0;                                                     \
 })
@@ -170,21 +175,21 @@
 /* SVC with SYS_ call number and one parameter */
 
 #ifdef __ghs__
-#  define sys_call1(nbr, parm1)              \
-({                                           \
-  uintptr_t ret;                             \
-  __asm__ __volatile__                       \
-  (                                          \
-    "mov r0, %2\n\t"                         \
-    "mov r1, %3\n\t"                         \
-    "svc %1\n\t"                             \
-    "mov %0, r0"                             \
-    : "=r"(ret)                              \
-    : "i"(SYS_syscall), "r"((uintptr_t)nbr), \
-      "r"((uintptr_t)parm1)                  \
-    : "memory", "r0", "r1"                   \
-  );                                         \
-  ret;                                       \
+#  define sys_call1(nbr, parm1)               \
+({                                            \
+  uintptr_t ret;                              \
+  __asm__ __volatile__                        \
+  (                                           \
+    "mov r0, %2\n\t"                          \
+    "mov r1, %3\n\t"                          \
+    "svc %1\n\t"                              \
+    "mov %0, r0"                              \
+    : "=r"(ret)                               \
+    : "i"(SYS_syscall), "r"((uintptr_t)nbr),  \
+      "r"((uintptr_t)parm1)                   \
+    : "memory", "r0", "r1", "r2", "r3", "r12" \
+  );                                          \
+  ret;                                        \
 })
 #else
 #  define sys_call1(nbr, parm1)                               \
@@ -193,10 +198,10 @@
   register uintptr_t reg0 __asm__("r0") = (uintptr_t)(nbr);   \
   __asm__ __volatile__                                        \
   (                                                           \
-    "svc %1"                                                  \
-    : "=r"(reg0)                                              \
-    : "i"(SYS_syscall), "r"(reg0), "r"(reg1)                  \
-    : "memory"                                                \
+    "svc %2"                                                  \
+    : "+r"(reg0), "+r"(reg1)                                  \
+    : "i"(SYS_syscall)                                        \
+    : "memory", "r2", "r3", "r12"                             \
   );                                                          \
   reg0;                                                       \
 })
@@ -218,7 +223,7 @@
     : "=r"(ret)                                    \
     : "i"(SYS_syscall), "r"((uintptr_t)nbr),       \
       "r"((uintptr_t)parm1), "r"((uintptr_t)parm2) \
-    : "memory", "r0", "r1", "r2"                   \
+    : "memory", "r0", "r1", "r2", "r3", "r12"      \
   );                                               \
   ret;                                             \
 })
@@ -230,10 +235,10 @@
   register uintptr_t reg0 __asm__("r0") = (uintptr_t)(nbr);   \
   __asm__ __volatile__                                        \
   (                                                           \
-    "svc %1"                                                  \
-    : "=r"(reg0)                                              \
-    : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2)       \
-    : "memory"                                                \
+    "svc %3"                                                  \
+    : "+r"(reg0), "+r"(reg1), "+r"(reg2)                      \
+    : "i"(SYS_syscall)                                        \
+    : "memory", "r3", "r12"                                   \
   );                                                          \
   reg0;                                                       \
 })
@@ -256,7 +261,7 @@
     : "=r"(ret)                                                     \
     : "i"(SYS_syscall), "r"((uintptr_t)nbr), "r"((uintptr_t)parm1), \
       "r"((uintptr_t)parm2), "r"((uintptr_t)parm3)                  \
-    : "memory", "r0", "r1", "r2", "r3"                              \
+    : "memory", "r0", "r1", "r2", "r3", "r12"                       \
   );                                                                \
   ret;                                                              \
 })
@@ -269,10 +274,10 @@
   register uintptr_t reg0 __asm__("r0") = (uintptr_t)(nbr);        \
   __asm__ __volatile__                                             \
   (                                                                \
-    "svc %1"                                                       \
-    : "=r"(reg0)                                                   \
-    : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) \
-    : "memory"                                                     \
+    "svc %4"                                                       \
+    : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)               \
+    : "i"(SYS_syscall)                                             \
+    : "memory", "r12"                                              \
   );                                                               \
   reg0;                                                            \
 })
@@ -298,7 +303,7 @@
     : "=r"(ret)                                                           \
     : "i"(SYS_syscall), "r"((uintptr_t)nbr), "r"((uintptr_t)parm1),       \
       "r"((uintptr_t)parm2), "r"((uintptr_t)parm3), "r"((uintptr_t)parm4) \
-    : "memory", "r0", "r1", "r2", "r3"                                    \
+    : "memory", "r0", "r1", "r2", "r3", "r12"                             \
   );                                                                      \
   ret;                                                                    \
 })
@@ -312,11 +317,10 @@
   register uintptr_t reg0 __asm__("r0") = (uintptr_t)(nbr);   \
   __asm__ __volatile__                                        \
   (                                                           \
-    "svc %1"                                                  \
-    : "=r"(reg0)                                              \
-    : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2),      \
-      "r"(reg3), "r"(reg4)                                    \
-    : "memory"                                                \
+    "svc %4"                                                  \
+    : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)          \
+    : "i"(SYS_syscall), "r"(reg4)                             \
+    : "memory", "r12"                                         \
   );                                                          \
   reg0;                                                       \
 })
@@ -345,7 +349,7 @@
     : "i"(SYS_syscall), "r"((uintptr_t)nbr), "r"((uintptr_t)parm1),        \
       "r"((uintptr_t)parm2), "r"((uintptr_t)parm3), "r"((uintptr_t)parm4), \
       "r"((uintptr_t)parm5)                                                \
-    : "memory", "r0", "r1", "r2"                                           \
+    : "memory", "r0", "r1", "r2", "r12"                                    \
   );                                                                       \
   ret;                                                                     \
 })
@@ -360,11 +364,10 @@
   register uintptr_t reg0 __asm__("r0") = (uintptr_t)(nbr);   \
   __asm__ __volatile__                                        \
   (                                                           \
-    "svc %1"                                                  \
-    : "=r"(reg0)                                              \
-    : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2),      \
-      "r"(reg3), "r"(reg4), "r"(reg5)                         \
-    : "memory"                                                \
+    "svc %4"                                                  \
+    : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)          \
+    : "i"(SYS_syscall), "r"(reg4), "r"(reg5)                  \
+    : "memory", "r12"                                         \
   );                                                          \
   reg0;                                                       \
 })
@@ -394,7 +397,7 @@
     : "i"(SYS_syscall), "r"((uintptr_t)nbr), "r"((uintptr_t)parm1),        \
       "r"((uintptr_t)parm2), "r"((uintptr_t)parm3), "r"((uintptr_t)parm4), \
       "r"((uintptr_t)parm5), "r"((uintptr_t)parm6)                         \
-    : "memory", "r0", "r1"                                                 \
+    : "memory", "r0", "r1", "r12"                                          \
   );                                                                       \
   ret;                                                                     \
 })
@@ -410,11 +413,10 @@
   register uintptr_t reg0 __asm__("r0") = (uintptr_t)(nbr);        \
   __asm__ __volatile__                                             \
   (                                                                \
-    "svc %1"                                                       \
-    : "=r"(reg0)                                                   \
-    : "i"(SYS_syscall), "r"(reg0), "r"(reg1), "r"(reg2),           \
-      "r"(reg3), "r"(reg4), "r"(reg5), "r"(reg6)                   \
-    : "memory"                                                     \
+    "svc %4"                                                       \
+    : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)               \
+    : "i"(SYS_syscall), "r"(reg4), "r"(reg5), "r"(reg6)            \
+    : "memory", "r12"                                              \
   );                                                               \
   reg0;                                                            \
 })

Reply via email to