]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tools/nolibc: handle 64-bit system call arguments on x32
authorThomas Weißschuh <linux@weissschuh.net>
Sat, 18 Apr 2026 10:19:59 +0000 (12:19 +0200)
committerThomas Weißschuh <linux@weissschuh.net>
Mon, 27 Apr 2026 18:09:00 +0000 (20:09 +0200)
The x32 system call ABI expects 64-bit values directly in registers.
This does not work on nolibc currently, as a 'long' is only 32 bits
wide. Switch the system call wrappers to use 'long long' instead which
can handle 64-bit values on x32. As on x86_64 'long' and 'long long' are
the same, this does not change the behavior there.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Link: https://patch.msgid.link/20260418-nolibc-largefile-v1-4-b91f0775bac3@weissschuh.net
tools/include/nolibc/arch-x86.h

index db5ccba772d086aa22aab7740d5cebf04f8e5e9f..fe152ac2650ba1d4af36f3454d289d4f9eeead6e 100644 (file)
@@ -202,8 +202,8 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote
 
 #define __nolibc_syscall0(num)                                                \
 ({                                                                            \
-       long _ret;                                                            \
-       register long _num  __asm__ ("rax") = (num);                          \
+       long long _ret;                                                       \
+       register long long _num  __asm__ ("rax") = (num);                     \
                                                                              \
        __asm__ volatile (                                                    \
                "syscall\n"                                                   \
@@ -216,9 +216,9 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote
 
 #define __nolibc_syscall1(num, arg1)                                          \
 ({                                                                            \
-       long _ret;                                                            \
-       register long _num  __asm__ ("rax") = (num);                          \
-       register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
+       long long _ret;                                                       \
+       register long long _num  __asm__ ("rax") = (num);                     \
+       register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
                                                                              \
        __asm__ volatile (                                                    \
                "syscall\n"                                                   \
@@ -232,10 +232,10 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote
 
 #define __nolibc_syscall2(num, arg1, arg2)                                    \
 ({                                                                            \
-       long _ret;                                                            \
-       register long _num  __asm__ ("rax") = (num);                          \
-       register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-       register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
+       long long _ret;                                                       \
+       register long long _num  __asm__ ("rax") = (num);                     \
+       register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+       register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
                                                                              \
        __asm__ volatile (                                                    \
                "syscall\n"                                                   \
@@ -249,11 +249,11 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote
 
 #define __nolibc_syscall3(num, arg1, arg2, arg3)                              \
 ({                                                                            \
-       long _ret;                                                            \
-       register long _num  __asm__ ("rax") = (num);                          \
-       register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-       register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-       register long _arg3 __asm__ ("rdx") = (long)(arg3);                   \
+       long long _ret;                                                       \
+       register long long _num  __asm__ ("rax") = (num);                     \
+       register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+       register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
+       register long long _arg3 __asm__ ("rdx") = __nolibc_arg_to_reg(arg3); \
                                                                              \
        __asm__ volatile (                                                    \
                "syscall\n"                                                   \
@@ -267,12 +267,12 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote
 
 #define __nolibc_syscall4(num, arg1, arg2, arg3, arg4)                        \
 ({                                                                            \
-       long _ret;                                                            \
-       register long _num  __asm__ ("rax") = (num);                          \
-       register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-       register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-       register long _arg3 __asm__ ("rdx") = (long)(arg3);                   \
-       register long _arg4 __asm__ ("r10") = (long)(arg4);                   \
+       long long _ret;                                                       \
+       register long long _num  __asm__ ("rax") = (num);                     \
+       register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+       register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
+       register long long _arg3 __asm__ ("rdx") = __nolibc_arg_to_reg(arg3); \
+       register long long _arg4 __asm__ ("r10") = __nolibc_arg_to_reg(arg4); \
                                                                              \
        __asm__ volatile (                                                    \
                "syscall\n"                                                   \
@@ -286,13 +286,13 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote
 
 #define __nolibc_syscall5(num, arg1, arg2, arg3, arg4, arg5)                  \
 ({                                                                            \
-       long _ret;                                                            \
-       register long _num  __asm__ ("rax") = (num);                          \
-       register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-       register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-       register long _arg3 __asm__ ("rdx") = (long)(arg3);                   \
-       register long _arg4 __asm__ ("r10") = (long)(arg4);                   \
-       register long _arg5 __asm__ ("r8")  = (long)(arg5);                   \
+       long long _ret;                                                       \
+       register long long _num  __asm__ ("rax") = (num);                     \
+       register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+       register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
+       register long long _arg3 __asm__ ("rdx") = __nolibc_arg_to_reg(arg3); \
+       register long long _arg4 __asm__ ("r10") = __nolibc_arg_to_reg(arg4); \
+       register long long _arg5 __asm__ ("r8")  = __nolibc_arg_to_reg(arg5); \
                                                                              \
        __asm__ volatile (                                                    \
                "syscall\n"                                                   \
@@ -306,14 +306,14 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __nolibc_no_stack_prote
 
 #define __nolibc_syscall6(num, arg1, arg2, arg3, arg4, arg5, arg6)            \
 ({                                                                            \
-       long _ret;                                                            \
-       register long _num  __asm__ ("rax") = (num);                          \
-       register long _arg1 __asm__ ("rdi") = (long)(arg1);                   \
-       register long _arg2 __asm__ ("rsi") = (long)(arg2);                   \
-       register long _arg3 __asm__ ("rdx") = (long)(arg3);                   \
-       register long _arg4 __asm__ ("r10") = (long)(arg4);                   \
-       register long _arg5 __asm__ ("r8")  = (long)(arg5);                   \
-       register long _arg6 __asm__ ("r9")  = (long)(arg6);                   \
+       long long _ret;                                                       \
+       register long long _num  __asm__ ("rax") = (num);                     \
+       register long long _arg1 __asm__ ("rdi") = __nolibc_arg_to_reg(arg1); \
+       register long long _arg2 __asm__ ("rsi") = __nolibc_arg_to_reg(arg2); \
+       register long long _arg3 __asm__ ("rdx") = __nolibc_arg_to_reg(arg3); \
+       register long long _arg4 __asm__ ("r10") = __nolibc_arg_to_reg(arg4); \
+       register long long _arg5 __asm__ ("r8")  = __nolibc_arg_to_reg(arg5); \
+       register long long _arg6 __asm__ ("r9")  = __nolibc_arg_to_reg(arg6); \
                                                                              \
        __asm__ volatile (                                                    \
                "syscall\n"                                                   \