From f9749bf66e57f0a2c6d25ed3694623acd8b99632 Mon Sep 17 00:00:00 2001 From: "Thomas A." Date: Mon, 1 Jan 2024 18:43:14 -0800 Subject: [PATCH] Rework __linux_syscall The way variadic functions are handled on macOS differs between x86/x86-64 and ARM64. See the following for more details: https://developer.apple.com/documentation/apple-silicon/addressing-architectural-differences-in-your-macos-code#Dont-Redeclare-a-Function-to-Have-Variable-Parameters --- .../libsystem_kernel/emulation/linux/base.c | 38 ++++++++++++++++++- .../libsystem_kernel/emulation/linux/base.h | 9 ++++- libsyscall/os/tsd.h | 5 +-- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/darling/src/libsystem_kernel/emulation/linux/base.c b/darling/src/libsystem_kernel/emulation/linux/base.c index ec866f7..7ef8f0f 100644 --- a/darling/src/libsystem_kernel/emulation/linux/base.c +++ b/darling/src/libsystem_kernel/emulation/linux/base.c @@ -18,11 +18,47 @@ long __unknown_syscall_machdep(int nr, ...) } VISIBLE -int __linux_syscall(int nr, long a1, long a2, long a3, long a4, long a5, long a6) +int __linux_syscall_6args(int nr, long a1, long a2, long a3, long a4, long a5, long a6) { return linux_syscall(a1, a2, a3, a4, a5, a6, nr); } +VISIBLE +int __linux_syscall_noargs(int nr) +{ + return __linux_syscall_6args(nr, 0, 0, 0, 0, 0, 0); +} + +VISIBLE +int __linux_syscall_1arg(int nr, long a1) +{ + return __linux_syscall_6args(nr, a1, 0, 0, 0, 0, 0); +} + +VISIBLE +int __linux_syscall_2args(int nr, long a1, long a2) +{ + return __linux_syscall_6args(nr, a1, a2, 0, 0, 0, 0); +} + +VISIBLE +int __linux_syscall_3args(int nr, long a1, long a2, long a3) +{ + return __linux_syscall_6args(nr, a1, a2, a3, 0, 0, 0); +} + +VISIBLE +int __linux_syscall_4args(int nr, long a1, long a2, long a3, long a4) +{ + return __linux_syscall_6args(nr, a1, a2, a3, a4, 0, 0); +} + +VISIBLE +int __linux_syscall_5args(int nr, long a1, long a2, long a3, long a4, long a5) +{ + return __linux_syscall_6args(nr, a1, a2, a3, a4, a5, 0); +} + #ifdef __TESTING void _start() { diff --git a/darling/src/libsystem_kernel/emulation/linux/base.h b/darling/src/libsystem_kernel/emulation/linux/base.h index fbde716..f8e959d 100644 --- a/darling/src/libsystem_kernel/emulation/linux/base.h +++ b/darling/src/libsystem_kernel/emulation/linux/base.h @@ -21,8 +21,13 @@ long linux_syscall(long a1, long a2, long a3, long a4, long a5, long a6, int nr) #ifndef BUILDING_BASE_C -VISIBLE -int __linux_syscall(int nr, ...); +VISIBLE int __linux_syscall_noargs(int); +VISIBLE int __linux_syscall_1arg(int,long); +VISIBLE int __linux_syscall_2args(int,long,long); +VISIBLE int __linux_syscall_3args(int,long,long,long); +VISIBLE int __linux_syscall_4args(int,long,long,long,long); +VISIBLE int __linux_syscall_5args(int,long,long,long,long,long); +VISIBLE int __linux_syscall_6args(int,long,long,long,long,long,long); #endif /* BUILDING_BASE_C */ diff --git a/libsyscall/os/tsd.h b/libsyscall/os/tsd.h index a10648f..9e10ddd 100644 --- a/libsyscall/os/tsd.h +++ b/libsyscall/os/tsd.h @@ -54,6 +54,7 @@ #ifdef DARLING #include +#include #endif extern void _thread_set_tsd_base(void *tsd_base); @@ -63,10 +64,8 @@ static __inline__ unsigned int _os_cpu_number(void) { #ifdef DARLING - extern int __linux_syscall(int nr, ...); - unsigned int cpu_num = 0; - int status = __linux_syscall(__NR_getcpu, &cpu_num, 0, 0, 0, 0, 0); + int status = __linux_syscall_3args(__NR_getcpu, (long)&cpu_num, 0, 0); // should we even check? i don't think it's possible for it to fail with these arguments if (status < 0) { return 0; // i guess?