diff --git a/libc/config/linux/syscall_numbers.h.inc b/libc/config/linux/syscall_numbers.h.inc --- a/libc/config/linux/syscall_numbers.h.inc +++ b/libc/config/linux/syscall_numbers.h.inc @@ -422,6 +422,10 @@ #define SYS_futex __NR_futex #endif +#ifdef __NR_futex_time64 +#define SYS_futex_time64 __NR_futex_time64 +#endif + #ifdef __NR_futimesat #define SYS_futimesat __NR_futimesat #endif diff --git a/libc/src/__support/File/linux_file.cpp b/libc/src/__support/File/linux_file.cpp --- a/libc/src/__support/File/linux_file.cpp +++ b/libc/src/__support/File/linux_file.cpp @@ -68,12 +68,16 @@ #ifdef SYS_lseek int ret = __llvm_libc::syscall_impl(SYS_lseek, lf->get_fd(), offset, whence); result = ret; +#elif defined(SYS_llseek) + long ret = + __llvm_libc::syscall_impl(SYS_llseek, lf->get_fd(), offset, whence); + result = ret; #elif defined(SYS__llseek) long result; int ret = __llvm_libc::syscall_impl(SYS__llseek, lf->get_fd(), offset >> 32, offset, &result, whence); #else -#error "lseek and _llseek syscalls not available to perform a seek operation." +#error "lseek, llseek and _llseek syscalls not available." #endif if (ret < 0) diff --git a/libc/src/__support/threads/linux/mutex.h b/libc/src/__support/threads/linux/mutex.h --- a/libc/src/__support/threads/linux/mutex.h +++ b/libc/src/__support/threads/linux/mutex.h @@ -76,9 +76,17 @@ // futex syscall will block if the futex data is still // `LockState::Waiting` (the 4th argument to the syscall function // below.) +#if SYS_futex __llvm_libc::syscall_impl(SYS_futex, &futex_word.val, FUTEX_WAIT_PRIVATE, FutexWordType(LockState::Waiting), 0, 0, 0); +#elif defined(SYS_futex_time64) + __llvm_libc::syscall_impl(SYS_futex_time64, &futex_word.val, + FUTEX_WAIT_PRIVATE, + FutexWordType(LockState::Waiting), 0, 0, 0); +#else +#error "futex and futex_time64 syscalls not available." +#endif was_waiting = true; // Once woken up/unblocked, try everything all over. continue; @@ -91,8 +99,16 @@ // we will wait for the futex to be woken up. Note again that the // following syscall will block only if the futex data is still // `LockState::Waiting`. +#if SYS_futex __llvm_libc::syscall_impl(SYS_futex, &futex_word, FUTEX_WAIT_PRIVATE, FutexWordType(LockState::Waiting), 0, 0, 0); +#elif defined(SYS_futex_time64) + __llvm_libc::syscall_impl(SYS_futex_time64, &futex_word, + FUTEX_WAIT_PRIVATE, + FutexWordType(LockState::Waiting), 0, 0, 0); +#else +#error "futex and futex_time64 syscalls not available." +#endif was_waiting = true; } continue; @@ -109,8 +125,15 @@ if (futex_word.compare_exchange_strong(mutex_status, FutexWordType(LockState::Free))) { // If any thread is waiting to be woken up, then do it. +#if SYS_futex __llvm_libc::syscall_impl(SYS_futex, &futex_word, FUTEX_WAKE_PRIVATE, 1, 0, 0, 0); +#elif defined(SYS_futex_time64) + __llvm_libc::syscall_impl(SYS_futex_time64, &futex_word, + FUTEX_WAKE_PRIVATE, 1, 0, 0, 0); +#else +#error "futex and futex_time64 syscalls not available." +#endif return MutexError::NONE; } diff --git a/libc/src/sys/sendfile/linux/sendfile.cpp b/libc/src/sys/sendfile/linux/sendfile.cpp --- a/libc/src/sys/sendfile/linux/sendfile.cpp +++ b/libc/src/sys/sendfile/linux/sendfile.cpp @@ -19,8 +19,15 @@ LLVM_LIBC_FUNCTION(ssize_t, sendfile, (int out_fd, int in_fd, off_t *offset, size_t count)) { +#ifdef SYS_sendfile long ret = __llvm_libc::syscall_impl(SYS_sendfile, in_fd, out_fd, offset, count); +#elif defined(SYS_sendfile64) + long ret = + __llvm_libc::syscall_impl(SYS_sendfile64, in_fd, out_fd, offset, count); +#else +#error "sendfile and sendfile64 syscalls not available." +#endif if (ret < 0) { libc_errno = -ret; return -1; diff --git a/libc/src/sys/wait/linux/wait.cpp b/libc/src/sys/wait/linux/wait.cpp --- a/libc/src/sys/wait/linux/wait.cpp +++ b/libc/src/sys/wait/linux/wait.cpp @@ -10,6 +10,7 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/__support/libc_assert.h" #include "src/errno/libc_errno.h" #include // For syscall numbers. @@ -21,7 +22,21 @@ // functionality and standard compliance in future. LLVM_LIBC_FUNCTION(pid_t, wait, (int *wait_status)) { +#if SYS_wait4 pid_t pid = __llvm_libc::syscall_impl(SYS_wait4, -1, wait_status, 0, 0); +#elif defined(SYS_waitpid) + pid_t pid = __llvm_libc::syscall_impl(SYS_waitpid, -1, wait_status, 0); +#elif defined(SYS_waitid) + siginfo_t info; + if (__llvm_libc::syscall_impl(SYS_waitid, P_ALL, 0, &info, WEXITED, 0) == -1) + // TODO: what's the libc_errno here? + return -1; + LIBC_ASSERT(wait_status != nullptr); + *wait_status = info.si_status; + pid_t pid = info.si_pid; +#else +#error "waitpid, wait4 and waitid syscalls not available." +#endif if (pid < 0) { // Error case, a child process was not created. libc_errno = -pid; diff --git a/libc/src/sys/wait/linux/wait4.cpp b/libc/src/sys/wait/linux/wait4.cpp --- a/libc/src/sys/wait/linux/wait4.cpp +++ b/libc/src/sys/wait/linux/wait4.cpp @@ -10,6 +10,7 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/__support/libc_assert.h" #include "src/errno/libc_errno.h" #include // For syscall numbers. @@ -20,7 +21,27 @@ LLVM_LIBC_FUNCTION(pid_t, wait4, (pid_t pid, int *wait_status, int options, struct rusage *usage)) { +#if SYS_wait4 pid = __llvm_libc::syscall_impl(SYS_wait4, pid, wait_status, options, usage); +#elif defined(SYS_waitpid) + pid_t pid = __llvm_libc::syscall_impl(SYS_waitpid, pid, wait_status, options); + if (pid > 0) { + if (usage != nullptr && (getrusage(info.si_pid, usage) == -1)) + // TODO: what's the libc_errno here? + return -1; + } +#elif defined(SYS_waitid) + siginfo_t info; + if (__llvm_libc::syscall_impl(SYS_waitid, P_PID, pid, &info, + options | WEXITED | WSTOPPED | WCONTINUED, + usage) == -1) + return -1; + LIBC_ASSERT(wait_status != nullptr); + *wait_status = info.si_status; + pid = info.si_pid; +#else +#error "waitpid, wait4 and waitid syscalls not available." +#endif if (pid < 0) { libc_errno = -pid; return -1; diff --git a/libc/src/sys/wait/linux/waitpid.cpp b/libc/src/sys/wait/linux/waitpid.cpp --- a/libc/src/sys/wait/linux/waitpid.cpp +++ b/libc/src/sys/wait/linux/waitpid.cpp @@ -10,6 +10,7 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/__support/libc_assert.h" #include "src/errno/libc_errno.h" #include // For syscall numbers. @@ -18,7 +19,22 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(pid_t, waitpid, (pid_t pid, int *wait_status, int options)) { +#if SYS_waitpid + pid = __llvm_libc::syscall_impl(SYS_waitpid, pid, wait_status, options); +#elif defined(SYS_wait4) pid = __llvm_libc::syscall_impl(SYS_wait4, pid, wait_status, options, 0); +#elif defined(SYS_waitid) + siginfo_t info; + if (__llvm_libc::syscall_impl(SYS_waitid, P_PID, pid, &info, options, 0) == + -1) + // TODO: what's the libc_errno here? + return -1; + LIBC_ASSERT(wait_status != nullptr); + *wait_status = info.si_status; + pid = info.si_pid; +#else +#error "waitpid, wait4 and waitid syscalls not available." +#endif if (pid < 0) { libc_errno = -pid; return -1; diff --git a/libc/src/unistd/linux/dup2.cpp b/libc/src/unistd/linux/dup2.cpp --- a/libc/src/unistd/linux/dup2.cpp +++ b/libc/src/unistd/linux/dup2.cpp @@ -27,7 +27,13 @@ // separately before making the dup3 syscall. if (oldfd == newfd) { // Check if oldfd is actually a valid file descriptor. +#if SYS_fcntl long ret = __llvm_libc::syscall_impl(SYS_fcntl, oldfd, F_GETFD); +#elif defined(SYS_fcntl64) + long ret = __llvm_libc::syscall_impl(SYS_fcntl64, oldfd, F_GETFD); +#else +#error "SYS_fcntl and SYS_fcntl64 syscalls not available." +#endif if (ret >= 0) return oldfd; libc_errno = -ret; diff --git a/libc/src/unistd/linux/ftruncate.cpp b/libc/src/unistd/linux/ftruncate.cpp --- a/libc/src/unistd/linux/ftruncate.cpp +++ b/libc/src/unistd/linux/ftruncate.cpp @@ -18,7 +18,14 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(int, ftruncate, (int fd, off_t len)) { +#ifdef SYS_ftruncate int ret = __llvm_libc::syscall_impl(SYS_ftruncate, fd, len); +#elif defined(SYS_ftruncate64) + int ret = __llvm_libc::syscall_impl(SYS_ftruncate64, fd, len); +#else +#error "ftruncate and ftruncate64 syscalls not available." +#endif + if (ret < 0) { libc_errno = -ret; return -1; diff --git a/libc/src/unistd/linux/lseek.cpp b/libc/src/unistd/linux/lseek.cpp --- a/libc/src/unistd/linux/lseek.cpp +++ b/libc/src/unistd/linux/lseek.cpp @@ -22,11 +22,14 @@ #ifdef SYS_lseek long ret = __llvm_libc::syscall_impl(SYS_lseek, fd, offset, whence); result = ret; +#elif defined(SYS_llseek) + long ret = __llvm_libc::syscall_impl(SYS_llseek, fd, offset, whence); + result = ret; #elif defined(SYS__llseek) - long ret = __llvm_libc::syscall_impl(SYS__llseek, fd, offset >> 32, offset, - &result, whence); + int ret = __llvm_libc::syscall_impl(SYS__llseek, fd, offset >> 32, offset, + &result, whence); #else -#error "lseek and _llseek syscalls not available." +#error "lseek, llseek and _llseek syscalls not available." #endif if (ret < 0) { diff --git a/libc/src/unistd/linux/truncate.cpp b/libc/src/unistd/linux/truncate.cpp --- a/libc/src/unistd/linux/truncate.cpp +++ b/libc/src/unistd/linux/truncate.cpp @@ -18,7 +18,13 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(int, truncate, (const char *path, off_t len)) { +#ifdef SYS_truncate int ret = __llvm_libc::syscall_impl(SYS_truncate, path, len); +#elif defined(SYS_truncate64) + int ret = __llvm_libc::syscall_impl(SYS_truncate64, path, len); +#else +#error "truncate and truncate64 syscalls not available." +#endif if (ret < 0) { libc_errno = -ret; return -1;