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; \ })
