Skip to content

Commit

Permalink
Rework __linux_syscall
Browse files Browse the repository at this point in the history
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
  • Loading branch information
CuriousTommy committed Jan 22, 2024
1 parent f6e9f91 commit d786856
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 6 deletions.
38 changes: 37 additions & 1 deletion darling/src/libsystem_kernel/emulation/linux/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down
9 changes: 7 additions & 2 deletions darling/src/libsystem_kernel/emulation/linux/base.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
5 changes: 2 additions & 3 deletions libsyscall/os/tsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@

#ifdef DARLING
#include <darling/emulation/linux-syscalls.h>
#include <darling/emulation/base.h>
#endif

extern void _thread_set_tsd_base(void *tsd_base);
Expand All @@ -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?
Expand Down

0 comments on commit d786856

Please sign in to comment.