[libc-commits] [libc] 1801c35 - [libc] add syscall function
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Fri Sep 30 15:46:37 PDT 2022
Author: Michael Jones
Date: 2022-09-30T15:46:28-07:00
New Revision: 1801c356f61f0caef367138e889ad60b116b5760
URL: https://github.com/llvm/llvm-project/commit/1801c356f61f0caef367138e889ad60b116b5760
DIFF: https://github.com/llvm/llvm-project/commit/1801c356f61f0caef367138e889ad60b116b5760.diff
LOG: [libc] add syscall function
Add the syscall wrapper function and tests. It's implemented using a
macro to guarantee the minimum number of arguments.
Reviewed By: sivachandra, lntue
Differential Revision: https://reviews.llvm.org/D134919
Added:
libc/src/unistd/linux/syscall.cpp
libc/src/unistd/syscall.h
libc/test/src/unistd/syscall_test.cpp
Modified:
libc/config/linux/x86_64/entrypoints.txt
libc/include/llvm-libc-macros/linux/unistd-macros.h
libc/loader/linux/aarch64/start.cpp
libc/loader/linux/x86_64/start.cpp
libc/spec/posix.td
libc/src/__support/File/linux_dir.cpp
libc/src/__support/File/linux_file.cpp
libc/src/__support/OSUtil/linux/aarch64/syscall.h
libc/src/__support/OSUtil/linux/arm/syscall.h
libc/src/__support/OSUtil/linux/io.h
libc/src/__support/OSUtil/linux/quick_exit.h
libc/src/__support/OSUtil/linux/syscall.h
libc/src/__support/OSUtil/linux/x86_64/syscall.h
libc/src/__support/threads/linux/callonce.cpp
libc/src/__support/threads/linux/mutex.h
libc/src/__support/threads/linux/thread.cpp
libc/src/fcntl/linux/creat.cpp
libc/src/fcntl/linux/open.cpp
libc/src/fcntl/linux/openat.cpp
libc/src/sched/linux/sched_getaffinity.cpp
libc/src/sched/linux/sched_setaffinity.cpp
libc/src/signal/linux/__restore.cpp
libc/src/signal/linux/raise.cpp
libc/src/signal/linux/sigaction.cpp
libc/src/signal/linux/signal_utils.h
libc/src/signal/linux/sigprocmask.cpp
libc/src/stdio/linux/remove.cpp
libc/src/stdlib/linux/_Exit.cpp
libc/src/sys/mman/linux/madvise.cpp
libc/src/sys/mman/linux/mmap.cpp
libc/src/sys/mman/linux/mprotect.cpp
libc/src/sys/mman/linux/munmap.cpp
libc/src/sys/mman/linux/posix_madvise.cpp
libc/src/sys/resource/linux/getrlimit.cpp
libc/src/sys/resource/linux/setrlimit.cpp
libc/src/sys/sendfile/linux/sendfile.cpp
libc/src/sys/stat/linux/chmod.cpp
libc/src/sys/stat/linux/fchmod.cpp
libc/src/sys/stat/linux/fchmodat.cpp
libc/src/sys/stat/linux/kernel_statx.h
libc/src/sys/stat/linux/mkdir.cpp
libc/src/sys/stat/linux/mkdirat.cpp
libc/src/sys/utsname/linux/uname.cpp
libc/src/threads/linux/CndVar.h
libc/src/threads/linux/call_once.cpp
libc/src/time/clock_gettime.cpp
libc/src/time/nanosleep.cpp
libc/src/unistd/CMakeLists.txt
libc/src/unistd/linux/CMakeLists.txt
libc/src/unistd/linux/access.cpp
libc/src/unistd/linux/chdir.cpp
libc/src/unistd/linux/close.cpp
libc/src/unistd/linux/dup.cpp
libc/src/unistd/linux/dup2.cpp
libc/src/unistd/linux/dup3.cpp
libc/src/unistd/linux/fchdir.cpp
libc/src/unistd/linux/fsync.cpp
libc/src/unistd/linux/ftruncate.cpp
libc/src/unistd/linux/geteuid.cpp
libc/src/unistd/linux/getpid.cpp
libc/src/unistd/linux/getppid.cpp
libc/src/unistd/linux/getuid.cpp
libc/src/unistd/linux/link.cpp
libc/src/unistd/linux/linkat.cpp
libc/src/unistd/linux/lseek.cpp
libc/src/unistd/linux/pread.cpp
libc/src/unistd/linux/pwrite.cpp
libc/src/unistd/linux/read.cpp
libc/src/unistd/linux/readlink.cpp
libc/src/unistd/linux/readlinkat.cpp
libc/src/unistd/linux/rmdir.cpp
libc/src/unistd/linux/symlink.cpp
libc/src/unistd/linux/symlinkat.cpp
libc/src/unistd/linux/truncate.cpp
libc/src/unistd/linux/unlink.cpp
libc/src/unistd/linux/unlinkat.cpp
libc/src/unistd/linux/write.cpp
libc/test/src/__support/OSUtil/linux/x86_64/syscall_test.cpp
libc/test/src/sched/affinity_test.cpp
libc/test/src/unistd/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 6745b548b3eae..42da9adf83070 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -154,6 +154,7 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.unistd.rmdir
libc.src.unistd.symlink
libc.src.unistd.symlinkat
+ libc.src.unistd.__llvm_libc_syscall
libc.src.unistd.truncate
libc.src.unistd.unlink
libc.src.unistd.unlinkat
diff --git a/libc/include/llvm-libc-macros/linux/unistd-macros.h b/libc/include/llvm-libc-macros/linux/unistd-macros.h
index 41f8f917ced79..9fbb9ae28d4af 100644
--- a/libc/include/llvm-libc-macros/linux/unistd-macros.h
+++ b/libc/include/llvm-libc-macros/linux/unistd-macros.h
@@ -15,4 +15,13 @@
#define W_OK 2
#define R_OK 4
+// Macro to set up the call to the __llvm_libc_syscall function
+// This is to prevent the call from having fewer than 6 arguments, since six
+// arguments are always passed to the syscall. Unnecessary arguments are
+// ignored.
+#define __syscall_helper(sysno, arg1, arg2, arg3, arg4, arg5, arg6, ...) \
+ __llvm_libc_syscall((long)(sysno), (long)(arg1), (long)(arg2), (long)(arg3), \
+ (long)(arg4), (long)(arg5), (long)(arg6))
+#define syscall(...) __syscall_helper(__VA_ARGS__, 0, 1, 2, 3, 4, 5, 6)
+
#endif // __LLVM_LIBC_MACROS_LINUX_UNISTD_MACROS_H
diff --git a/libc/loader/linux/aarch64/start.cpp b/libc/loader/linux/aarch64/start.cpp
index a28f6a323a80e..7234c2a105049 100644
--- a/libc/loader/linux/aarch64/start.cpp
+++ b/libc/loader/linux/aarch64/start.cpp
@@ -68,13 +68,13 @@ void init_tls(TLSDescriptor &tls_descriptor) {
// We cannot call the mmap function here as the functions set errno on
// failure. Since errno is implemented via a thread local variable, we cannot
// use errno before TLS is setup.
- long mmap_ret_val = __llvm_libc::syscall(MMAP_SYSCALL_NUMBER, nullptr,
- alloc_size, PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ long mmap_ret_val = __llvm_libc::syscall_impl(
+ MMAP_SYSCALL_NUMBER, nullptr, alloc_size, PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
// We cannot check the return value with MAP_FAILED as that is the return
// of the mmap function and not the mmap syscall.
if (mmap_ret_val < 0 && static_cast<uintptr_t>(mmap_ret_val) > -app.pageSize)
- __llvm_libc::syscall(SYS_exit, 1);
+ __llvm_libc::syscall_impl(SYS_exit, 1);
uintptr_t thread_ptr = uintptr_t(reinterpret_cast<uintptr_t *>(mmap_ret_val));
uintptr_t tls_addr = thread_ptr + size_of_pointers + padding;
__llvm_libc::inline_memcpy(reinterpret_cast<char *>(tls_addr),
@@ -88,7 +88,7 @@ void init_tls(TLSDescriptor &tls_descriptor) {
void cleanup_tls(uintptr_t addr, uintptr_t size) {
if (size == 0)
return;
- __llvm_libc::syscall(SYS_munmap, addr, size);
+ __llvm_libc::syscall_impl(SYS_munmap, addr, size);
}
static void set_thread_ptr(uintptr_t val) { __arm_wsr64("tpidr_el0", val); }
@@ -133,9 +133,9 @@ struct AuxEntry {
};
__attribute__((noinline)) static void do_start() {
- auto tid = __llvm_libc::syscall(SYS_gettid);
+ auto tid = __llvm_libc::syscall_impl(SYS_gettid);
if (tid <= 0)
- __llvm_libc::syscall(SYS_exit, 1);
+ __llvm_libc::syscall_impl(SYS_exit, 1);
__llvm_libc::main_thread_attrib.tid = tid;
// After the argv array, is a 8-byte long NULL value before the array of env
diff --git a/libc/loader/linux/x86_64/start.cpp b/libc/loader/linux/x86_64/start.cpp
index 3353588b1256b..19670fa1a41db 100644
--- a/libc/loader/linux/x86_64/start.cpp
+++ b/libc/loader/linux/x86_64/start.cpp
@@ -58,13 +58,13 @@ void init_tls(TLSDescriptor &tls_descriptor) {
// We cannot call the mmap function here as the functions set errno on
// failure. Since errno is implemented via a thread local variable, we cannot
// use errno before TLS is setup.
- long mmapRetVal = __llvm_libc::syscall(
+ long mmapRetVal = __llvm_libc::syscall_impl(
mmapSyscallNumber, nullptr, tlsSizeWithAddr, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
// We cannot check the return value with MAP_FAILED as that is the return
// of the mmap function and not the mmap syscall.
if (mmapRetVal < 0 && static_cast<uintptr_t>(mmapRetVal) > -app.pageSize)
- __llvm_libc::syscall(SYS_exit, 1);
+ __llvm_libc::syscall_impl(SYS_exit, 1);
uintptr_t *tlsAddr = reinterpret_cast<uintptr_t *>(mmapRetVal);
// x86_64 TLS faces down from the thread pointer with the first entry
@@ -83,13 +83,14 @@ void init_tls(TLSDescriptor &tls_descriptor) {
void cleanup_tls(uintptr_t addr, uintptr_t size) {
if (size == 0)
return;
- __llvm_libc::syscall(SYS_munmap, addr, size);
+ __llvm_libc::syscall_impl(SYS_munmap, addr, size);
}
// Sets the thread pointer to |val|. Returns true on success, false on failure.
static bool set_thread_ptr(uintptr_t val) {
- return __llvm_libc::syscall(SYS_arch_prctl, ARCH_SET_FS, val) == -1 ? false
- : true;
+ return __llvm_libc::syscall_impl(SYS_arch_prctl, ARCH_SET_FS, val) == -1
+ ? false
+ : true;
}
using InitCallback = void(int, char **, char **);
@@ -152,9 +153,9 @@ extern "C" void _start() {
__asm__ __volatile__("andq $0xfffffffffffffff0, %%rsp\n\t" ::: "%rsp");
__asm__ __volatile__("andq $0xfffffffffffffff0, %%rbp\n\t" ::: "%rbp");
- auto tid = __llvm_libc::syscall(SYS_gettid);
+ auto tid = __llvm_libc::syscall_impl(SYS_gettid);
if (tid <= 0)
- __llvm_libc::syscall(SYS_exit, 1);
+ __llvm_libc::syscall_impl(SYS_exit, 1);
__llvm_libc::main_thread_attrib.tid = tid;
// After the argv array, is a 8-byte long NULL value before the array of env
@@ -202,7 +203,7 @@ extern "C" void _start() {
__llvm_libc::TLSDescriptor tls;
__llvm_libc::init_tls(tls);
if (tls.size != 0 && !__llvm_libc::set_thread_ptr(tls.tp))
- __llvm_libc::syscall(SYS_exit, 1);
+ __llvm_libc::syscall_impl(SYS_exit, 1);
__llvm_libc::self.attrib = &__llvm_libc::main_thread_attrib;
__llvm_libc::main_thread_attrib.atexit_callback_mgr =
diff --git a/libc/spec/posix.td b/libc/spec/posix.td
index d3464e7d655a5..3f31723c43d79 100644
--- a/libc/spec/posix.td
+++ b/libc/spec/posix.td
@@ -482,6 +482,11 @@ def POSIX : StandardSpec<"POSIX"> {
RetValSpec<IntType>,
[ArgSpec<IntType>, ArgSpec<ConstCharPtr>, ArgSpec<IntType>, ArgSpec<ConstCharPtr>]
>,
+ FunctionSpec<
+ "__llvm_libc_syscall",
+ RetValSpec<LongType>,
+ [ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>,ArgSpec<LongType>]
+ >,
FunctionSpec<
"truncate",
RetValSpec<IntType>,
diff --git a/libc/src/__support/File/linux_dir.cpp b/libc/src/__support/File/linux_dir.cpp
index 99d2436ecaec4..82274e1fce94c 100644
--- a/libc/src/__support/File/linux_dir.cpp
+++ b/libc/src/__support/File/linux_dir.cpp
@@ -19,9 +19,9 @@ namespace __llvm_libc {
int platform_opendir(const char *name) {
int open_flags = O_RDONLY | O_DIRECTORY | O_CLOEXEC;
#ifdef SYS_open
- int fd = __llvm_libc::syscall(SYS_open, name, open_flags);
+ int fd = __llvm_libc::syscall_impl(SYS_open, name, open_flags);
#elif defined(SYS_openat)
- int fd = __llvm_libc::syscall(SYS_openat, AT_FDCWD, name, open_flags);
+ int fd = __llvm_libc::syscall_impl(SYS_openat, AT_FDCWD, name, open_flags);
#else
#error \
"SYS_open and SYS_openat syscalls not available to perform an open operation."
@@ -36,7 +36,7 @@ int platform_opendir(const char *name) {
size_t platform_fetch_dirents(int fd, cpp::span<uint8_t> buffer) {
long size =
- __llvm_libc::syscall(SYS_getdents, fd, buffer.data(), buffer.size());
+ __llvm_libc::syscall_impl(SYS_getdents, fd, buffer.data(), buffer.size());
if (size < 0) {
errno = -size;
return 0;
@@ -45,7 +45,7 @@ size_t platform_fetch_dirents(int fd, cpp::span<uint8_t> buffer) {
}
bool platform_closedir(int fd) {
- long ret = __llvm_libc::syscall(SYS_close, fd);
+ long ret = __llvm_libc::syscall_impl(SYS_close, fd);
if (ret < 0) {
errno = -ret;
return false;
diff --git a/libc/src/__support/File/linux_file.cpp b/libc/src/__support/File/linux_file.cpp
index 98abb6e1f64a8..782cee48e4715 100644
--- a/libc/src/__support/File/linux_file.cpp
+++ b/libc/src/__support/File/linux_file.cpp
@@ -53,7 +53,7 @@ namespace {
size_t write_func(File *f, const void *data, size_t size) {
auto *lf = reinterpret_cast<LinuxFile *>(f);
- long ret = __llvm_libc::syscall(SYS_write, lf->get_fd(), data, size);
+ long ret = __llvm_libc::syscall_impl(SYS_write, lf->get_fd(), data, size);
if (ret < 0) {
errno = -ret;
return 0;
@@ -63,7 +63,7 @@ size_t write_func(File *f, const void *data, size_t size) {
size_t read_func(File *f, void *buf, size_t size) {
auto *lf = reinterpret_cast<LinuxFile *>(f);
- long ret = __llvm_libc::syscall(SYS_read, lf->get_fd(), buf, size);
+ long ret = __llvm_libc::syscall_impl(SYS_read, lf->get_fd(), buf, size);
if (ret < 0) {
errno = -ret;
return 0;
@@ -74,11 +74,11 @@ size_t read_func(File *f, void *buf, size_t size) {
int seek_func(File *f, long offset, int whence) {
auto *lf = reinterpret_cast<LinuxFile *>(f);
#ifdef SYS_lseek
- long ret = __llvm_libc::syscall(SYS_lseek, lf->get_fd(), offset, whence);
+ long ret = __llvm_libc::syscall_impl(SYS_lseek, lf->get_fd(), offset, whence);
#elif defined(SYS__llseek)
long result;
- long ret = __llvm_libc::syscall(SYS__llseek, lf->get_fd(), offset >> 32,
- offset, &result, whence);
+ long 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."
#endif
@@ -92,7 +92,7 @@ int seek_func(File *f, long offset, int whence) {
int close_func(File *f) {
auto *lf = reinterpret_cast<LinuxFile *>(f);
- long ret = __llvm_libc::syscall(SYS_close, lf->get_fd());
+ long ret = __llvm_libc::syscall_impl(SYS_close, lf->get_fd());
if (ret < 0) {
errno = -ret;
return -1;
@@ -102,7 +102,7 @@ int close_func(File *f) {
int flush_func(File *f) {
auto *lf = reinterpret_cast<LinuxFile *>(f);
- long ret = __llvm_libc::syscall(SYS_fsync, lf->get_fd());
+ long ret = __llvm_libc::syscall_impl(SYS_fsync, lf->get_fd());
if (ret < 0) {
errno = -ret;
return -1;
@@ -144,10 +144,10 @@ File *openfile(const char *path, const char *mode) {
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
#ifdef SYS_open
- int fd = __llvm_libc::syscall(SYS_open, path, open_flags, OPEN_MODE);
+ int fd = __llvm_libc::syscall_impl(SYS_open, path, open_flags, OPEN_MODE);
#elif defined(SYS_openat)
- int fd =
- __llvm_libc::syscall(SYS_openat, AT_FDCWD, path, open_flags, OPEN_MODE);
+ int fd = __llvm_libc::syscall_impl(SYS_openat, AT_FDCWD, path, open_flags,
+ OPEN_MODE);
#else
#error "SYS_open and SYS_openat syscalls not available to perform a file open."
#endif
diff --git a/libc/src/__support/OSUtil/linux/aarch64/syscall.h b/libc/src/__support/OSUtil/linux/aarch64/syscall.h
index 841f63e368453..2d1f0669e8f76 100644
--- a/libc/src/__support/OSUtil/linux/aarch64/syscall.h
+++ b/libc/src/__support/OSUtil/linux/aarch64/syscall.h
@@ -44,50 +44,52 @@
namespace __llvm_libc {
-__attribute__((always_inline)) inline long syscall(long number) {
+__attribute__((always_inline)) inline long syscall_impl(long number) {
REGISTER_DECL_0;
SYSCALL_INSTR(REGISTER_CONSTRAINT_0);
return x0;
}
-__attribute__((always_inline)) inline long syscall(long number, long arg1) {
+__attribute__((always_inline)) inline long syscall_impl(long number,
+ long arg1) {
REGISTER_DECL_1;
SYSCALL_INSTR(REGISTER_CONSTRAINT_1);
return x0;
}
-__attribute__((always_inline)) inline long syscall(long number, long arg1,
- long arg2) {
+__attribute__((always_inline)) inline long syscall_impl(long number, long arg1,
+ long arg2) {
REGISTER_DECL_2;
SYSCALL_INSTR(REGISTER_CONSTRAINT_2);
return x0;
}
-__attribute__((always_inline)) inline long syscall(long number, long arg1,
- long arg2, long arg3) {
+__attribute__((always_inline)) inline long syscall_impl(long number, long arg1,
+ long arg2, long arg3) {
REGISTER_DECL_3;
SYSCALL_INSTR(REGISTER_CONSTRAINT_3);
return x0;
}
__attribute__((always_inline)) inline long
-syscall(long number, long arg1, long arg2, long arg3, long arg4) {
+syscall_impl(long number, long arg1, long arg2, long arg3, long arg4) {
REGISTER_DECL_4;
SYSCALL_INSTR(REGISTER_CONSTRAINT_4);
return x0;
}
-__attribute__((always_inline)) inline long
-syscall(long number, long arg1, long arg2, long arg3, long arg4, long arg5) {
+__attribute__((always_inline)) inline long syscall_impl(long number, long arg1,
+ long arg2, long arg3,
+ long arg4, long arg5) {
REGISTER_DECL_5;
SYSCALL_INSTR(REGISTER_CONSTRAINT_5);
return x0;
}
-__attribute__((always_inline)) inline long syscall(long number, long arg1,
- long arg2, long arg3,
- long arg4, long arg5,
- long arg6) {
+__attribute__((always_inline)) inline long syscall_impl(long number, long arg1,
+ long arg2, long arg3,
+ long arg4, long arg5,
+ long arg6) {
REGISTER_DECL_6;
SYSCALL_INSTR(REGISTER_CONSTRAINT_6);
return x0;
diff --git a/libc/src/__support/OSUtil/linux/arm/syscall.h b/libc/src/__support/OSUtil/linux/arm/syscall.h
index 79cfff8859eee..268d4093cec2d 100644
--- a/libc/src/__support/OSUtil/linux/arm/syscall.h
+++ b/libc/src/__support/OSUtil/linux/arm/syscall.h
@@ -50,50 +50,52 @@
namespace __llvm_libc {
-__attribute__((always_inline)) inline long syscall(long number) {
+__attribute__((always_inline)) inline long syscall_impl(long number) {
REGISTER_DECL_0;
SYSCALL_INSTR(REGISTER_CONSTRAINT_0);
return r0;
}
-__attribute__((always_inline)) inline long syscall(long number, long arg1) {
+__attribute__((always_inline)) inline long syscall_impl(long number,
+ long arg1) {
REGISTER_DECL_1;
SYSCALL_INSTR(REGISTER_CONSTRAINT_1);
return r0;
}
-__attribute__((always_inline)) inline long syscall(long number, long arg1,
- long arg2) {
+__attribute__((always_inline)) inline long syscall_impl(long number, long arg1,
+ long arg2) {
REGISTER_DECL_2;
SYSCALL_INSTR(REGISTER_CONSTRAINT_2);
return r0;
}
-__attribute__((always_inline)) inline long syscall(long number, long arg1,
- long arg2, long arg3) {
+__attribute__((always_inline)) inline long syscall_impl(long number, long arg1,
+ long arg2, long arg3) {
REGISTER_DECL_3;
SYSCALL_INSTR(REGISTER_CONSTRAINT_3);
return r0;
}
__attribute__((always_inline)) inline long
-syscall(long number, long arg1, long arg2, long arg3, long arg4) {
+syscall_impl(long number, long arg1, long arg2, long arg3, long arg4) {
REGISTER_DECL_4;
SYSCALL_INSTR(REGISTER_CONSTRAINT_4);
return r0;
}
-__attribute__((always_inline)) inline long
-syscall(long number, long arg1, long arg2, long arg3, long arg4, long arg5) {
+__attribute__((always_inline)) inline long syscall_impl(long number, long arg1,
+ long arg2, long arg3,
+ long arg4, long arg5) {
REGISTER_DECL_5;
SYSCALL_INSTR(REGISTER_CONSTRAINT_5);
return r0;
}
-__attribute__((always_inline)) inline long syscall(long number, long arg1,
- long arg2, long arg3,
- long arg4, long arg5,
- long arg6) {
+__attribute__((always_inline)) inline long syscall_impl(long number, long arg1,
+ long arg2, long arg3,
+ long arg4, long arg5,
+ long arg6) {
REGISTER_DECL_6;
SYSCALL_INSTR(REGISTER_CONSTRAINT_6);
return r0;
diff --git a/libc/src/__support/OSUtil/linux/io.h b/libc/src/__support/OSUtil/linux/io.h
index fa63ecda831fb..b99f828446fc5 100644
--- a/libc/src/__support/OSUtil/linux/io.h
+++ b/libc/src/__support/OSUtil/linux/io.h
@@ -17,8 +17,8 @@
namespace __llvm_libc {
static inline void write_to_stderr(const char *msg) {
- __llvm_libc::syscall(SYS_write, 2 /* stderr */, msg,
- internal::string_length(msg));
+ __llvm_libc::syscall_impl(SYS_write, 2 /* stderr */, msg,
+ internal::string_length(msg));
}
} // namespace __llvm_libc
diff --git a/libc/src/__support/OSUtil/linux/quick_exit.h b/libc/src/__support/OSUtil/linux/quick_exit.h
index c985c630be35a..ca755de19522f 100644
--- a/libc/src/__support/OSUtil/linux/quick_exit.h
+++ b/libc/src/__support/OSUtil/linux/quick_exit.h
@@ -17,8 +17,8 @@ namespace __llvm_libc {
static inline void quick_exit(int status) {
for (;;) {
- __llvm_libc::syscall(SYS_exit_group, status);
- __llvm_libc::syscall(SYS_exit, status);
+ __llvm_libc::syscall_impl(SYS_exit_group, status);
+ __llvm_libc::syscall_impl(SYS_exit, status);
}
}
diff --git a/libc/src/__support/OSUtil/linux/syscall.h b/libc/src/__support/OSUtil/linux/syscall.h
index 1756ee65e16d3..645145a3044cf 100644
--- a/libc/src/__support/OSUtil/linux/syscall.h
+++ b/libc/src/__support/OSUtil/linux/syscall.h
@@ -22,9 +22,10 @@
namespace __llvm_libc {
template <typename... Ts>
-__attribute__((always_inline)) inline long syscall(long __number, Ts... ts) {
+__attribute__((always_inline)) inline long syscall_impl(long __number,
+ Ts... ts) {
static_assert(sizeof...(Ts) <= 6, "Too many arguments for syscall");
- return syscall(__number, (long)ts...);
+ return syscall_impl(__number, (long)ts...);
}
} // namespace __llvm_libc
diff --git a/libc/src/__support/OSUtil/linux/x86_64/syscall.h b/libc/src/__support/OSUtil/linux/x86_64/syscall.h
index c6f88a6ec853a..1bb401abd2f28 100644
--- a/libc/src/__support/OSUtil/linux/x86_64/syscall.h
+++ b/libc/src/__support/OSUtil/linux/x86_64/syscall.h
@@ -15,7 +15,7 @@
namespace __llvm_libc {
-__attribute__((always_inline)) inline long syscall(long __number) {
+__attribute__((always_inline)) inline long syscall_impl(long __number) {
long retcode;
LIBC_INLINE_ASM("syscall"
: "=a"(retcode)
@@ -24,7 +24,8 @@ __attribute__((always_inline)) inline long syscall(long __number) {
return retcode;
}
-__attribute__((always_inline)) inline long syscall(long __number, long __arg1) {
+__attribute__((always_inline)) inline long syscall_impl(long __number,
+ long __arg1) {
long retcode;
LIBC_INLINE_ASM("syscall"
: "=a"(retcode)
@@ -33,8 +34,8 @@ __attribute__((always_inline)) inline long syscall(long __number, long __arg1) {
return retcode;
}
-__attribute__((always_inline)) inline long syscall(long __number, long __arg1,
- long __arg2) {
+__attribute__((always_inline)) inline long
+syscall_impl(long __number, long __arg1, long __arg2) {
long retcode;
LIBC_INLINE_ASM("syscall"
: "=a"(retcode)
@@ -43,8 +44,8 @@ __attribute__((always_inline)) inline long syscall(long __number, long __arg1,
return retcode;
}
-__attribute__((always_inline)) inline long syscall(long __number, long __arg1,
- long __arg2, long __arg3) {
+__attribute__((always_inline)) inline long
+syscall_impl(long __number, long __arg1, long __arg2, long __arg3) {
long retcode;
LIBC_INLINE_ASM("syscall"
: "=a"(retcode)
@@ -54,7 +55,8 @@ __attribute__((always_inline)) inline long syscall(long __number, long __arg1,
}
__attribute__((always_inline)) inline long
-syscall(long __number, long __arg1, long __arg2, long __arg3, long __arg4) {
+syscall_impl(long __number, long __arg1, long __arg2, long __arg3,
+ long __arg4) {
long retcode;
register long r10 __asm__("r10") = __arg4;
LIBC_INLINE_ASM("syscall"
@@ -65,9 +67,9 @@ syscall(long __number, long __arg1, long __arg2, long __arg3, long __arg4) {
return retcode;
}
-__attribute__((always_inline)) inline long syscall(long __number, long __arg1,
- long __arg2, long __arg3,
- long __arg4, long __arg5) {
+__attribute__((always_inline)) inline long
+syscall_impl(long __number, long __arg1, long __arg2, long __arg3, long __arg4,
+ long __arg5) {
long retcode;
register long r10 __asm__("r10") = __arg4;
register long r8 __asm__("r8") = __arg5;
@@ -79,10 +81,9 @@ __attribute__((always_inline)) inline long syscall(long __number, long __arg1,
return retcode;
}
-__attribute__((always_inline)) inline long syscall(long __number, long __arg1,
- long __arg2, long __arg3,
- long __arg4, long __arg5,
- long __arg6) {
+__attribute__((always_inline)) inline long
+syscall_impl(long __number, long __arg1, long __arg2, long __arg3, long __arg4,
+ long __arg5, long __arg6) {
long retcode;
register long r10 __asm__("r10") = __arg4;
register long r8 __asm__("r8") = __arg5;
@@ -96,7 +97,6 @@ __attribute__((always_inline)) inline long syscall(long __number, long __arg1,
}
#undef SYSCALL_CLOBBER_LIST
-
} // namespace __llvm_libc
#endif // LLVM_LIBC_SRC_SUPPORT_OSUTIL_LINUX_X86_64_SYSCALL_H
diff --git a/libc/src/__support/threads/linux/callonce.cpp b/libc/src/__support/threads/linux/callonce.cpp
index 1aab6fc9c4497..7dc957f0129cd 100644
--- a/libc/src/__support/threads/linux/callonce.cpp
+++ b/libc/src/__support/threads/linux/callonce.cpp
@@ -34,9 +34,9 @@ int callonce(CallOnceFlag *flag, CallOnceCallback *func) {
func();
auto status = futex_word->exchange(FINISH);
if (status == WAITING) {
- __llvm_libc::syscall(SYS_futex, &futex_word->val, FUTEX_WAKE_PRIVATE,
- INT_MAX, // Wake all waiters.
- 0, 0, 0);
+ __llvm_libc::syscall_impl(SYS_futex, &futex_word->val, FUTEX_WAKE_PRIVATE,
+ INT_MAX, // Wake all waiters.
+ 0, 0, 0);
}
return 0;
}
@@ -44,9 +44,10 @@ int callonce(CallOnceFlag *flag, CallOnceCallback *func) {
FutexWordType status = START;
if (futex_word->compare_exchange_strong(status, WAITING) ||
status == WAITING) {
- __llvm_libc::syscall(SYS_futex, &futex_word->val, FUTEX_WAIT_PRIVATE,
- WAITING, // Block only if status is still |WAITING|.
- 0, 0, 0);
+ __llvm_libc::syscall_impl(
+ SYS_futex, &futex_word->val, FUTEX_WAIT_PRIVATE,
+ WAITING, // Block only if status is still |WAITING|.
+ 0, 0, 0);
}
return 0;
diff --git a/libc/src/__support/threads/linux/mutex.h b/libc/src/__support/threads/linux/mutex.h
index 0133b2069d845..19221c97aeffb 100644
--- a/libc/src/__support/threads/linux/mutex.h
+++ b/libc/src/__support/threads/linux/mutex.h
@@ -76,8 +76,9 @@ struct Mutex {
// futex syscall will block if the futex data is still
// `LockState::Waiting` (the 4th argument to the syscall function
// below.)
- __llvm_libc::syscall(SYS_futex, &futex_word.val, FUTEX_WAIT_PRIVATE,
- FutexWordType(LockState::Waiting), 0, 0, 0);
+ __llvm_libc::syscall_impl(SYS_futex, &futex_word.val,
+ FUTEX_WAIT_PRIVATE,
+ FutexWordType(LockState::Waiting), 0, 0, 0);
was_waiting = true;
// Once woken up/unblocked, try everything all over.
continue;
@@ -90,8 +91,8 @@ struct Mutex {
// 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`.
- __llvm_libc::syscall(SYS_futex, &futex_word, FUTEX_WAIT_PRIVATE,
- FutexWordType(LockState::Waiting), 0, 0, 0);
+ __llvm_libc::syscall_impl(SYS_futex, &futex_word, FUTEX_WAIT_PRIVATE,
+ FutexWordType(LockState::Waiting), 0, 0, 0);
was_waiting = true;
}
continue;
@@ -108,8 +109,8 @@ struct Mutex {
if (futex_word.compare_exchange_strong(mutex_status,
FutexWordType(LockState::Free))) {
// If any thread is waiting to be woken up, then do it.
- __llvm_libc::syscall(SYS_futex, &futex_word, FUTEX_WAKE_PRIVATE, 1, 0,
- 0, 0);
+ __llvm_libc::syscall_impl(SYS_futex, &futex_word, FUTEX_WAKE_PRIVATE, 1,
+ 0, 0, 0);
return MutexError::NONE;
}
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index 08661c63e75f5..15f38c0a0eba2 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -56,13 +56,13 @@ static constexpr unsigned CLONE_SYSCALL_FLAGS =
static inline cpp::ErrorOr<void *> alloc_stack(size_t size) {
long mmap_result =
- __llvm_libc::syscall(MMAP_SYSCALL_NUMBER,
- 0, // No special address
- size,
- PROT_READ | PROT_WRITE, // Read and write stack
- MAP_ANONYMOUS | MAP_PRIVATE, // Process private
- -1, // Not backed by any file
- 0 // No offset
+ __llvm_libc::syscall_impl(MMAP_SYSCALL_NUMBER,
+ 0, // No special address
+ size,
+ PROT_READ | PROT_WRITE, // Read and write stack
+ MAP_ANONYMOUS | MAP_PRIVATE, // Process private
+ -1, // Not backed by any file
+ 0 // No offset
);
if (mmap_result < 0 && (uintptr_t(mmap_result) >= UINTPTR_MAX - size))
return cpp::Error{int(-mmap_result)};
@@ -70,7 +70,7 @@ static inline cpp::ErrorOr<void *> alloc_stack(size_t size) {
}
static inline void free_stack(void *stack, size_t size) {
- __llvm_libc::syscall(SYS_munmap, stack, size);
+ __llvm_libc::syscall_impl(SYS_munmap, stack, size);
}
struct Thread;
@@ -192,7 +192,7 @@ int Thread::run(ThreadStyle style, ThreadRunner runner, void *arg, void *stack,
// variables from this function will not be availalbe to the child thread.
#ifdef LLVM_LIBC_ARCH_X86_64
long register clone_result asm("rax");
- clone_result = __llvm_libc::syscall(
+ clone_result = __llvm_libc::syscall_impl(
SYS_clone, CLONE_SYSCALL_FLAGS, adjusted_stack,
&attrib->tid, // The address where the child tid is written
&clear_tid->val, // The futex where the child thread status is signalled
@@ -200,7 +200,7 @@ int Thread::run(ThreadStyle style, ThreadRunner runner, void *arg, void *stack,
);
#elif defined(LLVM_LIBC_ARCH_AARCH64)
long register clone_result asm("x0");
- clone_result = __llvm_libc::syscall(
+ clone_result = __llvm_libc::syscall_impl(
SYS_clone, CLONE_SYSCALL_FLAGS, adjusted_stack,
&attrib->tid, // The address where the child tid is written
tls.tp, // The thread pointer value for the new thread.
@@ -264,8 +264,8 @@ void Thread::wait() {
while (clear_tid->load() != 0) {
// We cannot do a FUTEX_WAIT_PRIVATE here as the kernel does a
// FUTEX_WAKE and not a FUTEX_WAKE_PRIVATE.
- __llvm_libc::syscall(SYS_futex, &clear_tid->val, FUTEX_WAIT,
- CLEAR_TID_VALUE, nullptr);
+ __llvm_libc::syscall_impl(SYS_futex, &clear_tid->val, FUTEX_WAIT,
+ CLEAR_TID_VALUE, nullptr);
}
}
@@ -293,7 +293,7 @@ int Thread::set_name(const cpp::string_view &name) {
if (*this == self) {
// If we are setting the name of the current thread, then we can
// use the syscall to set the name.
- int retval = __llvm_libc::syscall(SYS_prctl, PR_SET_NAME, name.data());
+ int retval = __llvm_libc::syscall_impl(SYS_prctl, PR_SET_NAME, name.data());
if (retval < 0)
return -retval;
else
@@ -304,15 +304,17 @@ int Thread::set_name(const cpp::string_view &name) {
cpp::StringStream path_stream(path_name_buffer);
construct_thread_name_file_path(path_stream, attrib->tid);
#ifdef SYS_open
- int fd = __llvm_libc::syscall(SYS_open, path_name_buffer, O_RDWR);
+ int fd = __llvm_libc::syscall_impl(SYS_open, path_name_buffer, O_RDWR);
#else
- int fd = __llvm_libc::syscall(SYS_openat, AT_FDCWD, path_name_buffer, O_RDWR);
+ int fd =
+ __llvm_libc::syscall_impl(SYS_openat, AT_FDCWD, path_name_buffer, O_RDWR);
#endif
if (fd < 0)
return -fd;
- int retval = __llvm_libc::syscall(SYS_write, fd, name.data(), name.size());
- __llvm_libc::syscall(SYS_close, fd);
+ int retval =
+ __llvm_libc::syscall_impl(SYS_write, fd, name.data(), name.size());
+ __llvm_libc::syscall_impl(SYS_close, fd);
if (retval < 0)
return -retval;
@@ -331,7 +333,7 @@ int Thread::get_name(cpp::StringStream &name) const {
if (*this == self) {
// If we are getting the name of the current thread, then we can
// use the syscall to get the name.
- int retval = __llvm_libc::syscall(SYS_prctl, PR_GET_NAME, name_buffer);
+ int retval = __llvm_libc::syscall_impl(SYS_prctl, PR_GET_NAME, name_buffer);
if (retval < 0)
return -retval;
name << name_buffer;
@@ -342,16 +344,17 @@ int Thread::get_name(cpp::StringStream &name) const {
cpp::StringStream path_stream(path_name_buffer);
construct_thread_name_file_path(path_stream, attrib->tid);
#ifdef SYS_open
- int fd = __llvm_libc::syscall(SYS_open, path_name_buffer, O_RDONLY);
+ int fd = __llvm_libc::syscall_impl(SYS_open, path_name_buffer, O_RDONLY);
#else
- int fd =
- __llvm_libc::syscall(SYS_openat, AT_FDCWD, path_name_buffer, O_RDONLY);
+ int fd = __llvm_libc::syscall_impl(SYS_openat, AT_FDCWD, path_name_buffer,
+ O_RDONLY);
#endif
if (fd < 0)
return -fd;
- int retval = __llvm_libc::syscall(SYS_read, fd, name_buffer, NAME_SIZE_MAX);
- __llvm_libc::syscall(SYS_close, fd);
+ int retval =
+ __llvm_libc::syscall_impl(SYS_read, fd, name_buffer, NAME_SIZE_MAX);
+ __llvm_libc::syscall_impl(SYS_close, fd);
if (retval < 0)
return -retval;
if (retval == NAME_SIZE_MAX)
@@ -385,13 +388,13 @@ void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
// Set the CLEAR_TID address to nullptr to prevent the kernel
// from signalling at a non-existent futex location.
- __llvm_libc::syscall(SYS_set_tid_address, 0);
+ __llvm_libc::syscall_impl(SYS_set_tid_address, 0);
}
if (style == ThreadStyle::POSIX)
- __llvm_libc::syscall(SYS_exit, retval.posix_retval);
+ __llvm_libc::syscall_impl(SYS_exit, retval.posix_retval);
else
- __llvm_libc::syscall(SYS_exit, retval.stdc_retval);
+ __llvm_libc::syscall_impl(SYS_exit, retval.stdc_retval);
}
} // namespace __llvm_libc
diff --git a/libc/src/fcntl/linux/creat.cpp b/libc/src/fcntl/linux/creat.cpp
index 9bca317006699..4cf7b792b4d58 100644
--- a/libc/src/fcntl/linux/creat.cpp
+++ b/libc/src/fcntl/linux/creat.cpp
@@ -19,11 +19,11 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, creat, (const char *path, int mode_flags)) {
#ifdef SYS_open
- int fd = __llvm_libc::syscall(SYS_open, path, O_CREAT | O_WRONLY | O_TRUNC,
- mode_flags);
+ int fd = __llvm_libc::syscall_impl(SYS_open, path,
+ O_CREAT | O_WRONLY | O_TRUNC, mode_flags);
#else
- int fd = __llvm_libc::syscall(SYS_openat, AT_FDCWD, path,
- O_CREAT | O_WRONLY | O_TRUNC, mode_flags);
+ int fd = __llvm_libc::syscall_impl(SYS_openat, AT_FDCWD, path,
+ O_CREAT | O_WRONLY | O_TRUNC, mode_flags);
#endif
if (fd > 0)
diff --git a/libc/src/fcntl/linux/open.cpp b/libc/src/fcntl/linux/open.cpp
index 3b8e08a7169ab..8fe68debcdcfe 100644
--- a/libc/src/fcntl/linux/open.cpp
+++ b/libc/src/fcntl/linux/open.cpp
@@ -30,9 +30,10 @@ LLVM_LIBC_FUNCTION(int, open, (const char *path, int flags, ...)) {
}
#ifdef SYS_open
- int fd = __llvm_libc::syscall(SYS_open, path, flags, mode_flags);
+ int fd = __llvm_libc::syscall_impl(SYS_open, path, flags, mode_flags);
#else
- int fd = __llvm_libc::syscall(SYS_openat, AT_FDCWD, path, flags, mode_flags);
+ int fd =
+ __llvm_libc::syscall_impl(SYS_openat, AT_FDCWD, path, flags, mode_flags);
#endif
if (fd > 0)
return fd;
diff --git a/libc/src/fcntl/linux/openat.cpp b/libc/src/fcntl/linux/openat.cpp
index b55fa92206f51..23e2c6b89cdcb 100644
--- a/libc/src/fcntl/linux/openat.cpp
+++ b/libc/src/fcntl/linux/openat.cpp
@@ -29,7 +29,7 @@ LLVM_LIBC_FUNCTION(int, openat, (int dfd, const char *path, int flags, ...)) {
va_end(varargs);
}
- int fd = __llvm_libc::syscall(SYS_openat, dfd, path, flags, mode_flags);
+ int fd = __llvm_libc::syscall_impl(SYS_openat, dfd, path, flags, mode_flags);
if (fd > 0)
return fd;
diff --git a/libc/src/sched/linux/sched_getaffinity.cpp b/libc/src/sched/linux/sched_getaffinity.cpp
index 5d45d15e303db..a4c3de9808f0b 100644
--- a/libc/src/sched/linux/sched_getaffinity.cpp
+++ b/libc/src/sched/linux/sched_getaffinity.cpp
@@ -21,7 +21,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, sched_getaffinity,
(pid_t tid, size_t cpuset_size, cpu_set_t *mask)) {
long ret =
- __llvm_libc::syscall(SYS_sched_getaffinity, tid, cpuset_size, mask);
+ __llvm_libc::syscall_impl(SYS_sched_getaffinity, tid, cpuset_size, mask);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/sched/linux/sched_setaffinity.cpp b/libc/src/sched/linux/sched_setaffinity.cpp
index 4f22aaaa508cf..6feb9977912bb 100644
--- a/libc/src/sched/linux/sched_setaffinity.cpp
+++ b/libc/src/sched/linux/sched_setaffinity.cpp
@@ -20,7 +20,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, sched_setaffinity,
(pid_t tid, size_t cpuset_size, const cpu_set_t *mask)) {
long ret =
- __llvm_libc::syscall(SYS_sched_setaffinity, tid, cpuset_size, mask);
+ __llvm_libc::syscall_impl(SYS_sched_setaffinity, tid, cpuset_size, mask);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/signal/linux/__restore.cpp b/libc/src/signal/linux/__restore.cpp
index b76b5b858acc3..f73c1b7296ac0 100644
--- a/libc/src/signal/linux/__restore.cpp
+++ b/libc/src/signal/linux/__restore.cpp
@@ -19,6 +19,6 @@ extern "C" void __restore_rt()
__attribute__((no_sanitize("all"),
hidden));
-extern "C" void __restore_rt() { __llvm_libc::syscall(SYS_rt_sigreturn); }
+extern "C" void __restore_rt() { __llvm_libc::syscall_impl(SYS_rt_sigreturn); }
} // namespace __llvm_libc
diff --git a/libc/src/signal/linux/raise.cpp b/libc/src/signal/linux/raise.cpp
index eb880d1bd7057..6371273635d2b 100644
--- a/libc/src/signal/linux/raise.cpp
+++ b/libc/src/signal/linux/raise.cpp
@@ -16,9 +16,9 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, raise, (int sig)) {
::sigset_t sigset;
block_all_signals(sigset);
- long pid = __llvm_libc::syscall(SYS_getpid);
- long tid = __llvm_libc::syscall(SYS_gettid);
- int ret = __llvm_libc::syscall(SYS_tgkill, pid, tid, sig);
+ long pid = __llvm_libc::syscall_impl(SYS_getpid);
+ long tid = __llvm_libc::syscall_impl(SYS_gettid);
+ int ret = __llvm_libc::syscall_impl(SYS_tgkill, pid, tid, sig);
restore_signals(sigset);
return ret;
}
diff --git a/libc/src/signal/linux/sigaction.cpp b/libc/src/signal/linux/sigaction.cpp
index c6324005a6d1c..a229e142fd157 100644
--- a/libc/src/signal/linux/sigaction.cpp
+++ b/libc/src/signal/linux/sigaction.cpp
@@ -34,8 +34,9 @@ LLVM_LIBC_FUNCTION(int, sigaction,
}
KernelSigaction kernel_old;
- int ret = syscall(SYS_rt_sigaction, signal, libc_new ? &kernel_new : nullptr,
- libc_old ? &kernel_old : nullptr, sizeof(sigset_t));
+ int ret = __llvm_libc::syscall_impl(
+ SYS_rt_sigaction, signal, libc_new ? &kernel_new : nullptr,
+ libc_old ? &kernel_old : nullptr, sizeof(sigset_t));
if (ret) {
errno = -ret;
return -1;
diff --git a/libc/src/signal/linux/signal_utils.h b/libc/src/signal/linux/signal_utils.h
index 8eba593e4e610..7c45e0862d524 100644
--- a/libc/src/signal/linux/signal_utils.h
+++ b/libc/src/signal/linux/signal_utils.h
@@ -95,13 +95,13 @@ constexpr inline bool delete_signal(sigset_t &set, int signal) {
static inline int block_all_signals(sigset_t &set) {
sigset_t full = full_set();
- return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_BLOCK, &full, &set,
- sizeof(sigset_t));
+ return __llvm_libc::syscall_impl(SYS_rt_sigprocmask, SIG_BLOCK, &full, &set,
+ sizeof(sigset_t));
}
static inline int restore_signals(const sigset_t &set) {
- return __llvm_libc::syscall(SYS_rt_sigprocmask, SIG_SETMASK, &set, nullptr,
- sizeof(sigset_t));
+ return __llvm_libc::syscall_impl(SYS_rt_sigprocmask, SIG_SETMASK, &set,
+ nullptr, sizeof(sigset_t));
}
} // namespace __llvm_libc
diff --git a/libc/src/signal/linux/sigprocmask.cpp b/libc/src/signal/linux/sigprocmask.cpp
index 343fd0f41bc4b..cd205815eff57 100644
--- a/libc/src/signal/linux/sigprocmask.cpp
+++ b/libc/src/signal/linux/sigprocmask.cpp
@@ -21,8 +21,8 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, sigprocmask,
(int how, const sigset_t *__restrict set,
sigset_t *__restrict oldset)) {
- int ret = __llvm_libc::syscall(SYS_rt_sigprocmask, how, set, oldset,
- sizeof(sigset_t));
+ int ret = __llvm_libc::syscall_impl(SYS_rt_sigprocmask, how, set, oldset,
+ sizeof(sigset_t));
if (!ret)
return 0;
diff --git a/libc/src/stdio/linux/remove.cpp b/libc/src/stdio/linux/remove.cpp
index cdada40bdfa68..2a868a78abf6a 100644
--- a/libc/src/stdio/linux/remove.cpp
+++ b/libc/src/stdio/linux/remove.cpp
@@ -20,9 +20,9 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, remove, (const char *path)) {
// We first try unlinking it as a file. If it is ia file, it will succeed. If
// it fails with EISDIR, we will try unlinking it as a directory.
- int ret = __llvm_libc::syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+ int ret = __llvm_libc::syscall_impl(SYS_unlinkat, AT_FDCWD, path, 0);
if (ret == -EISDIR)
- ret = __llvm_libc::syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+ ret = __llvm_libc::syscall_impl(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
if (ret >= 0)
return 0;
errno = -ret;
diff --git a/libc/src/stdlib/linux/_Exit.cpp b/libc/src/stdlib/linux/_Exit.cpp
index 51b0a48c7521b..0300a08847cea 100644
--- a/libc/src/stdlib/linux/_Exit.cpp
+++ b/libc/src/stdlib/linux/_Exit.cpp
@@ -16,8 +16,8 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(void, _Exit, (int status)) {
for (;;) {
- __llvm_libc::syscall(SYS_exit_group, status);
- __llvm_libc::syscall(SYS_exit, status);
+ __llvm_libc::syscall_impl(SYS_exit_group, status);
+ __llvm_libc::syscall_impl(SYS_exit, status);
}
}
diff --git a/libc/src/sys/mman/linux/madvise.cpp b/libc/src/sys/mman/linux/madvise.cpp
index 6dcc19a792ebe..3e6e574d1f14e 100644
--- a/libc/src/sys/mman/linux/madvise.cpp
+++ b/libc/src/sys/mman/linux/madvise.cpp
@@ -19,8 +19,8 @@ namespace __llvm_libc {
// This function is currently linux only. It has to be refactored suitably if
// madvise is to be supported on non-linux operating systems also.
LLVM_LIBC_FUNCTION(int, madvise, (void *addr, size_t size, int advice)) {
- long ret_val = __llvm_libc::syscall(SYS_madvise, reinterpret_cast<long>(addr),
- size, advice);
+ long ret_val = __llvm_libc::syscall_impl(
+ SYS_madvise, reinterpret_cast<long>(addr), size, advice);
// A negative return value indicates an error with the magnitude of the
// value being the error code.
diff --git a/libc/src/sys/mman/linux/mmap.cpp b/libc/src/sys/mman/linux/mmap.cpp
index 6ae482a8409ad..f08877e466c15 100644
--- a/libc/src/sys/mman/linux/mmap.cpp
+++ b/libc/src/sys/mman/linux/mmap.cpp
@@ -40,8 +40,8 @@ LLVM_LIBC_FUNCTION(void *, mmap,
#endif
long ret_val =
- __llvm_libc::syscall(syscall_number, reinterpret_cast<long>(addr), size,
- prot, flags, fd, offset);
+ __llvm_libc::syscall_impl(syscall_number, reinterpret_cast<long>(addr),
+ size, prot, flags, fd, offset);
// The mmap/mmap2 syscalls return negative values on error. These negative
// values are actually the negative values of the error codes. So, fix them
diff --git a/libc/src/sys/mman/linux/mprotect.cpp b/libc/src/sys/mman/linux/mprotect.cpp
index 9a295d947ba7d..6ea35c279d54e 100644
--- a/libc/src/sys/mman/linux/mprotect.cpp
+++ b/libc/src/sys/mman/linux/mprotect.cpp
@@ -19,8 +19,8 @@ namespace __llvm_libc {
// This function is currently linux only. It has to be refactored suitably if
// mprotect is to be supported on non-linux operating systems also.
LLVM_LIBC_FUNCTION(int, mprotect, (void *addr, size_t size, int prot)) {
- long ret_val = __llvm_libc::syscall(SYS_mprotect,
- reinterpret_cast<long>(addr), size, prot);
+ long ret_val = __llvm_libc::syscall_impl(
+ SYS_mprotect, reinterpret_cast<long>(addr), size, prot);
// A negative return value indicates an error with the magnitude of the
// value being the error code.
diff --git a/libc/src/sys/mman/linux/munmap.cpp b/libc/src/sys/mman/linux/munmap.cpp
index 2abeb3134242b..3be5a8977299e 100644
--- a/libc/src/sys/mman/linux/munmap.cpp
+++ b/libc/src/sys/mman/linux/munmap.cpp
@@ -20,7 +20,7 @@ namespace __llvm_libc {
// mmap is to be supported on non-linux operating systems also.
LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) {
long ret_val =
- __llvm_libc::syscall(SYS_munmap, reinterpret_cast<long>(addr), size);
+ __llvm_libc::syscall_impl(SYS_munmap, reinterpret_cast<long>(addr), size);
// A negative return value indicates an error with the magnitude of the
// value being the error code.
diff --git a/libc/src/sys/mman/linux/posix_madvise.cpp b/libc/src/sys/mman/linux/posix_madvise.cpp
index 2d36747f76d30..51e8477d678e8 100644
--- a/libc/src/sys/mman/linux/posix_madvise.cpp
+++ b/libc/src/sys/mman/linux/posix_madvise.cpp
@@ -23,8 +23,8 @@ LLVM_LIBC_FUNCTION(int, posix_madvise, (void *addr, size_t size, int advice)) {
if (advice == POSIX_MADV_DONTNEED) {
return 0;
}
- long ret_val = __llvm_libc::syscall(SYS_madvise, reinterpret_cast<long>(addr),
- size, advice);
+ long ret_val = __llvm_libc::syscall_impl(
+ SYS_madvise, reinterpret_cast<long>(addr), size, advice);
return ret_val < 0 ? -ret_val : 0;
}
diff --git a/libc/src/sys/resource/linux/getrlimit.cpp b/libc/src/sys/resource/linux/getrlimit.cpp
index a9d1d2754a97f..613c1a78e6709 100644
--- a/libc/src/sys/resource/linux/getrlimit.cpp
+++ b/libc/src/sys/resource/linux/getrlimit.cpp
@@ -18,7 +18,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, getrlimit, (int res, struct rlimit *limits)) {
- long ret = __llvm_libc::syscall(SYS_prlimit64, 0, res, nullptr, limits);
+ long ret = __llvm_libc::syscall_impl(SYS_prlimit64, 0, res, nullptr, limits);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/sys/resource/linux/setrlimit.cpp b/libc/src/sys/resource/linux/setrlimit.cpp
index efca4c565b91b..b0c1ea52e783e 100644
--- a/libc/src/sys/resource/linux/setrlimit.cpp
+++ b/libc/src/sys/resource/linux/setrlimit.cpp
@@ -18,7 +18,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, setrlimit, (int res, const struct rlimit *limits)) {
- long ret = __llvm_libc::syscall(SYS_prlimit64, 0, res, limits, nullptr);
+ long ret = __llvm_libc::syscall_impl(SYS_prlimit64, 0, res, limits, nullptr);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/sys/sendfile/linux/sendfile.cpp b/libc/src/sys/sendfile/linux/sendfile.cpp
index 8beaae2607bab..1f8a2c4421b3c 100644
--- a/libc/src/sys/sendfile/linux/sendfile.cpp
+++ b/libc/src/sys/sendfile/linux/sendfile.cpp
@@ -19,7 +19,8 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(ssize_t, sendfile,
(int out_fd, int in_fd, off_t *offset, size_t count)) {
- long ret = __llvm_libc::syscall(SYS_sendfile, in_fd, out_fd, offset, count);
+ long ret =
+ __llvm_libc::syscall_impl(SYS_sendfile, in_fd, out_fd, offset, count);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/sys/stat/linux/chmod.cpp b/libc/src/sys/stat/linux/chmod.cpp
index 5e092f24461a3..1b8c6ee19b58a 100644
--- a/libc/src/sys/stat/linux/chmod.cpp
+++ b/libc/src/sys/stat/linux/chmod.cpp
@@ -20,9 +20,9 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, chmod, (const char *path, mode_t mode)) {
#ifdef SYS_chmod
- long ret = __llvm_libc::syscall(SYS_chmod, path, mode);
+ long ret = __llvm_libc::syscall_impl(SYS_chmod, path, mode);
#elif defined(SYS_fchmodat)
- long ret = __llvm_libc::syscall(SYS_fchmodat, AT_FDCWD, path, mode);
+ long ret = __llvm_libc::syscall_impl(SYS_fchmodat, AT_FDCWD, path, mode);
#else
#error "chmod and chmodat syscalls not available."
#endif
diff --git a/libc/src/sys/stat/linux/fchmod.cpp b/libc/src/sys/stat/linux/fchmod.cpp
index 5edf3a51aa2d7..c6ce8d9acb8fc 100644
--- a/libc/src/sys/stat/linux/fchmod.cpp
+++ b/libc/src/sys/stat/linux/fchmod.cpp
@@ -19,7 +19,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, fchmod, (int fd, mode_t mode)) {
- long ret = __llvm_libc::syscall(SYS_fchmod, fd, mode);
+ long ret = __llvm_libc::syscall_impl(SYS_fchmod, fd, mode);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/sys/stat/linux/fchmodat.cpp b/libc/src/sys/stat/linux/fchmodat.cpp
index 6c880bda6e404..82a9a831eef55 100644
--- a/libc/src/sys/stat/linux/fchmodat.cpp
+++ b/libc/src/sys/stat/linux/fchmodat.cpp
@@ -19,7 +19,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, fchmodat,
(int dirfd, const char *path, mode_t mode, int flags)) {
- long ret = __llvm_libc::syscall(SYS_fchmodat, dirfd, path, mode, flags);
+ long ret = __llvm_libc::syscall_impl(SYS_fchmodat, dirfd, path, mode, flags);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/sys/stat/linux/kernel_statx.h b/libc/src/sys/stat/linux/kernel_statx.h
index 3f14f4dca8cc6..7260f155f512b 100644
--- a/libc/src/sys/stat/linux/kernel_statx.h
+++ b/libc/src/sys/stat/linux/kernel_statx.h
@@ -73,8 +73,8 @@ inline int statx(int dirfd, const char *__restrict path, int flags,
struct stat *__restrict statbuf) {
// We make a statx syscall and copy out the result into the |statbuf|.
::statx_buf xbuf;
- long ret =
- syscall(SYS_statx, dirfd, path, flags, ::STATX_BASIC_STATS_MASK, &xbuf);
+ long ret = __llvm_libc::syscall_impl(SYS_statx, dirfd, path, flags,
+ ::STATX_BASIC_STATS_MASK, &xbuf);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/sys/stat/linux/mkdir.cpp b/libc/src/sys/stat/linux/mkdir.cpp
index aac100dae98ed..404ea0f7be41a 100644
--- a/libc/src/sys/stat/linux/mkdir.cpp
+++ b/libc/src/sys/stat/linux/mkdir.cpp
@@ -20,9 +20,9 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, mkdir, (const char *path, mode_t mode)) {
#ifdef SYS_mkdir
- long ret = __llvm_libc::syscall(SYS_mkdir, path, mode);
+ long ret = __llvm_libc::syscall_impl(SYS_mkdir, path, mode);
#elif defined(SYS_mkdirat)
- long ret = __llvm_libc::syscall(SYS_mkdirat, AT_FDCWD, path, mode);
+ long ret = __llvm_libc::syscall_impl(SYS_mkdirat, AT_FDCWD, path, mode);
#else
#error "mkdir and mkdirat syscalls not available."
#endif
diff --git a/libc/src/sys/stat/linux/mkdirat.cpp b/libc/src/sys/stat/linux/mkdirat.cpp
index 9b4197dfefae8..0ab146942f5af 100644
--- a/libc/src/sys/stat/linux/mkdirat.cpp
+++ b/libc/src/sys/stat/linux/mkdirat.cpp
@@ -19,7 +19,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, mkdirat, (int dfd, const char *path, mode_t mode)) {
#ifdef SYS_mkdirat
- long ret = __llvm_libc::syscall(SYS_mkdirat, dfd, path, mode);
+ long ret = __llvm_libc::syscall_impl(SYS_mkdirat, dfd, path, mode);
#else
#error "mkdirat syscalls not available."
#endif
diff --git a/libc/src/sys/utsname/linux/uname.cpp b/libc/src/sys/utsname/linux/uname.cpp
index 42bdf2544913b..86724b3ffcc31 100644
--- a/libc/src/sys/utsname/linux/uname.cpp
+++ b/libc/src/sys/utsname/linux/uname.cpp
@@ -18,7 +18,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, uname, (struct utsname * name)) {
- long ret = __llvm_libc::syscall(SYS_uname, name);
+ long ret = __llvm_libc::syscall_impl(SYS_uname, name);
if (ret >= 0)
return 1;
diff --git a/libc/src/threads/linux/CndVar.h b/libc/src/threads/linux/CndVar.h
index 009cb9f06c3f3..c526277d62c7d 100644
--- a/libc/src/threads/linux/CndVar.h
+++ b/libc/src/threads/linux/CndVar.h
@@ -84,8 +84,8 @@ struct CndVar {
}
}
- __llvm_libc::syscall(SYS_futex, &waiter.futex_word.val, FUTEX_WAIT,
- WS_Waiting, 0, 0, 0);
+ __llvm_libc::syscall_impl(SYS_futex, &waiter.futex_word.val, FUTEX_WAIT,
+ WS_Waiting, 0, 0, 0);
// At this point, if locking |m| fails, we can simply return as the
// queued up waiter would have been removed from the queue.
@@ -109,7 +109,7 @@ struct CndVar {
qmtx.futex_word = FutexWordType(Mutex::LockState::Free);
- __llvm_libc::syscall(
+ __llvm_libc::syscall_impl(
SYS_futex, &qmtx.futex_word.val, FUTEX_WAKE_OP, 1, 1,
&first->futex_word.val,
FUTEX_OP(FUTEX_OP_SET, WS_Signalled, FUTEX_OP_CMP_EQ, WS_Waiting));
@@ -126,7 +126,7 @@ struct CndVar {
// atomically update the waiter status to WS_Signalled before waking
// up the waiter. A dummy location is used for the other futex of
// FUTEX_WAKE_OP.
- __llvm_libc::syscall(
+ __llvm_libc::syscall_impl(
SYS_futex, &dummy_futex_word, FUTEX_WAKE_OP, 1, 1,
&waiter->futex_word.val,
FUTEX_OP(FUTEX_OP_SET, WS_Signalled, FUTEX_OP_CMP_EQ, WS_Waiting));
diff --git a/libc/src/threads/linux/call_once.cpp b/libc/src/threads/linux/call_once.cpp
index e04c4e47853b8..ac87a0d877d3b 100644
--- a/libc/src/threads/linux/call_once.cpp
+++ b/libc/src/threads/linux/call_once.cpp
@@ -46,9 +46,9 @@ LLVM_LIBC_FUNCTION(void, call_once,
func();
auto status = futex_word->exchange(FINISH);
if (status == WAITING) {
- __llvm_libc::syscall(SYS_futex, &futex_word->val, FUTEX_WAKE_PRIVATE,
- INT_MAX, // Wake all waiters.
- 0, 0, 0);
+ __llvm_libc::syscall_impl(SYS_futex, &futex_word->val, FUTEX_WAKE_PRIVATE,
+ INT_MAX, // Wake all waiters.
+ 0, 0, 0);
}
return;
}
@@ -56,9 +56,10 @@ LLVM_LIBC_FUNCTION(void, call_once,
FutexWordType status = START;
if (futex_word->compare_exchange_strong(status, WAITING) ||
status == WAITING) {
- __llvm_libc::syscall(SYS_futex, &futex_word->val, FUTEX_WAIT_PRIVATE,
- WAITING, // Block only if status is still |WAITING|.
- 0, 0, 0);
+ __llvm_libc::syscall_impl(
+ SYS_futex, &futex_word->val, FUTEX_WAIT_PRIVATE,
+ WAITING, // Block only if status is still |WAITING|.
+ 0, 0, 0);
}
}
diff --git a/libc/src/time/clock_gettime.cpp b/libc/src/time/clock_gettime.cpp
index 420dc367e571e..407135b6d3ebf 100644
--- a/libc/src/time/clock_gettime.cpp
+++ b/libc/src/time/clock_gettime.cpp
@@ -21,8 +21,8 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, clock_gettime,
(clockid_t clockid, struct timespec *tp)) {
long ret_val =
- __llvm_libc::syscall(SYS_clock_gettime, static_cast<long>(clockid),
- reinterpret_cast<long>(tp));
+ __llvm_libc::syscall_impl(SYS_clock_gettime, static_cast<long>(clockid),
+ reinterpret_cast<long>(tp));
// A negative return value indicates an error with the magnitude of the
// value being the error code.
if (ret_val < 0) {
diff --git a/libc/src/time/nanosleep.cpp b/libc/src/time/nanosleep.cpp
index 2eb5e97aff090..d586b6aee5cd3 100644
--- a/libc/src/time/nanosleep.cpp
+++ b/libc/src/time/nanosleep.cpp
@@ -18,7 +18,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, nanosleep,
(const struct timespec *req, struct timespec *rem)) {
- int ret = __llvm_libc::syscall(SYS_nanosleep, req, rem);
+ int ret = __llvm_libc::syscall_impl(SYS_nanosleep, req, rem);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt
index 437556c3a4585..1e54f4cd4d351 100644
--- a/libc/src/unistd/CMakeLists.txt
+++ b/libc/src/unistd/CMakeLists.txt
@@ -170,6 +170,13 @@ add_entrypoint_object(
.${LIBC_TARGET_OS}.symlinkat
)
+add_entrypoint_object(
+ __llvm_libc_syscall
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.__llvm_libc_syscall
+)
+
add_entrypoint_object(
truncate
ALIAS
diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt
index 6c1bf34f70392..0bbde7a102ab6 100644
--- a/libc/src/unistd/linux/CMakeLists.txt
+++ b/libc/src/unistd/linux/CMakeLists.txt
@@ -314,6 +314,18 @@ add_entrypoint_object(
libc.src.errno.errno
)
+add_entrypoint_object(
+ __llvm_libc_syscall
+ SRCS
+ syscall.cpp
+ HDRS
+ ../syscall.h
+ DEPENDS
+ libc.include.unistd
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.errno
+)
+
add_entrypoint_object(
truncate
SRCS
diff --git a/libc/src/unistd/linux/access.cpp b/libc/src/unistd/linux/access.cpp
index 41fd3793f9077..1862faaeefdd4 100644
--- a/libc/src/unistd/linux/access.cpp
+++ b/libc/src/unistd/linux/access.cpp
@@ -19,9 +19,9 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, access, (const char *path, int mode)) {
#ifdef SYS_access
- long ret = __llvm_libc::syscall(SYS_access, path, mode);
+ long ret = __llvm_libc::syscall_impl(SYS_access, path, mode);
#elif defined(SYS_faccessat)
- long ret = __llvm_libc::syscall(SYS_faccessat, AT_FDCWD, path, mode, 0);
+ long ret = __llvm_libc::syscall_impl(SYS_faccessat, AT_FDCWD, path, mode, 0);
#else
#error "access syscalls not available."
#endif
diff --git a/libc/src/unistd/linux/chdir.cpp b/libc/src/unistd/linux/chdir.cpp
index 93ae33861c98a..9a8bc1d93f08b 100644
--- a/libc/src/unistd/linux/chdir.cpp
+++ b/libc/src/unistd/linux/chdir.cpp
@@ -17,7 +17,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, chdir, (const char *path)) {
- long ret = __llvm_libc::syscall(SYS_chdir, path);
+ long ret = __llvm_libc::syscall_impl(SYS_chdir, path);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/close.cpp b/libc/src/unistd/linux/close.cpp
index 5380c078ded71..850222e8b7ec6 100644
--- a/libc/src/unistd/linux/close.cpp
+++ b/libc/src/unistd/linux/close.cpp
@@ -17,7 +17,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, close, (int fd)) {
- long ret = __llvm_libc::syscall(SYS_close, fd);
+ long ret = __llvm_libc::syscall_impl(SYS_close, fd);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/dup.cpp b/libc/src/unistd/linux/dup.cpp
index 9706b98897a80..9e537dc88bb42 100644
--- a/libc/src/unistd/linux/dup.cpp
+++ b/libc/src/unistd/linux/dup.cpp
@@ -17,7 +17,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, dup, (int fd)) {
- long ret = __llvm_libc::syscall(SYS_dup, fd);
+ long ret = __llvm_libc::syscall_impl(SYS_dup, fd);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/dup2.cpp b/libc/src/unistd/linux/dup2.cpp
index e066a7c471692..760adc6b7bb64 100644
--- a/libc/src/unistd/linux/dup2.cpp
+++ b/libc/src/unistd/linux/dup2.cpp
@@ -20,20 +20,20 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, dup2, (int oldfd, int newfd)) {
#ifdef SYS_dup2
// If dup2 syscall is available, we make use of directly.
- long ret = __llvm_libc::syscall(SYS_dup2, oldfd, newfd);
+ long ret = __llvm_libc::syscall_impl(SYS_dup2, oldfd, newfd);
#elif defined(SYS_dup3)
// If dup2 syscall is not available, we try using the dup3 syscall. However,
// dup3 fails if oldfd is the same as newfd. So, we handle that case
// separately before making the dup3 syscall.
if (oldfd == newfd) {
// Check if oldfd is actually a valid file descriptor.
- long ret = __llvm_libc::syscall(SYS_fcntl, oldfd, F_GETFD);
+ long ret = __llvm_libc::syscall_impl(SYS_fcntl, oldfd, F_GETFD);
if (ret >= 0)
return oldfd;
errno = -ret;
return -1;
}
- long ret = __llvm_libc::syscall(SYS_dup3, oldfd, newfd, 0);
+ long ret = __llvm_libc::syscall_impl(SYS_dup3, oldfd, newfd, 0);
#else
#error "SYS_dup2 and SYS_dup3 not available for the target."
#endif
diff --git a/libc/src/unistd/linux/dup3.cpp b/libc/src/unistd/linux/dup3.cpp
index 193ff3e278dd8..8f6930900f0f8 100644
--- a/libc/src/unistd/linux/dup3.cpp
+++ b/libc/src/unistd/linux/dup3.cpp
@@ -18,7 +18,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, dup3, (int oldfd, int newfd, int flags)) {
// If dup2 syscall is available, we make use of directly.
- long ret = __llvm_libc::syscall(SYS_dup3, oldfd, newfd, flags);
+ long ret = __llvm_libc::syscall_impl(SYS_dup3, oldfd, newfd, flags);
if (ret >= 0)
return ret;
errno = -ret;
diff --git a/libc/src/unistd/linux/fchdir.cpp b/libc/src/unistd/linux/fchdir.cpp
index 86af84d4ebfd6..2d5aea3efa5d3 100644
--- a/libc/src/unistd/linux/fchdir.cpp
+++ b/libc/src/unistd/linux/fchdir.cpp
@@ -17,7 +17,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, fchdir, (int fd)) {
- long ret = __llvm_libc::syscall(SYS_fchdir, fd);
+ long ret = __llvm_libc::syscall_impl(SYS_fchdir, fd);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/fsync.cpp b/libc/src/unistd/linux/fsync.cpp
index 2ee9cc945babe..1665611321bb7 100644
--- a/libc/src/unistd/linux/fsync.cpp
+++ b/libc/src/unistd/linux/fsync.cpp
@@ -17,7 +17,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, fsync, (int fd)) {
- long ret = __llvm_libc::syscall(SYS_fsync, fd);
+ long ret = __llvm_libc::syscall_impl(SYS_fsync, fd);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/ftruncate.cpp b/libc/src/unistd/linux/ftruncate.cpp
index 38de44100162a..f96d31e6c4985 100644
--- a/libc/src/unistd/linux/ftruncate.cpp
+++ b/libc/src/unistd/linux/ftruncate.cpp
@@ -18,7 +18,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, ftruncate, (int fd, off_t len)) {
- int ret = __llvm_libc::syscall(SYS_ftruncate, fd, len);
+ int ret = __llvm_libc::syscall_impl(SYS_ftruncate, fd, len);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/geteuid.cpp b/libc/src/unistd/linux/geteuid.cpp
index 734da5abd4847..213d961032876 100644
--- a/libc/src/unistd/linux/geteuid.cpp
+++ b/libc/src/unistd/linux/geteuid.cpp
@@ -16,7 +16,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(uid_t, geteuid, ()) {
- return __llvm_libc::syscall(SYS_geteuid);
+ return __llvm_libc::syscall_impl(SYS_geteuid);
}
} // namespace __llvm_libc
diff --git a/libc/src/unistd/linux/getpid.cpp b/libc/src/unistd/linux/getpid.cpp
index d00112f8b929b..f04e751bc75f3 100644
--- a/libc/src/unistd/linux/getpid.cpp
+++ b/libc/src/unistd/linux/getpid.cpp
@@ -16,7 +16,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(pid_t, getpid, ()) {
- return __llvm_libc::syscall(SYS_getpid);
+ return __llvm_libc::syscall_impl(SYS_getpid);
}
} // namespace __llvm_libc
diff --git a/libc/src/unistd/linux/getppid.cpp b/libc/src/unistd/linux/getppid.cpp
index be5ab23cfcb34..7a19d8dcc563d 100644
--- a/libc/src/unistd/linux/getppid.cpp
+++ b/libc/src/unistd/linux/getppid.cpp
@@ -16,7 +16,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(pid_t, getppid, ()) {
- return __llvm_libc::syscall(SYS_getppid);
+ return __llvm_libc::syscall_impl(SYS_getppid);
}
} // namespace __llvm_libc
diff --git a/libc/src/unistd/linux/getuid.cpp b/libc/src/unistd/linux/getuid.cpp
index 716fa61de762c..b31ee49c83a89 100644
--- a/libc/src/unistd/linux/getuid.cpp
+++ b/libc/src/unistd/linux/getuid.cpp
@@ -16,7 +16,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(uid_t, getuid, ()) {
- return __llvm_libc::syscall(SYS_getuid);
+ return __llvm_libc::syscall_impl(SYS_getuid);
}
} // namespace __llvm_libc
diff --git a/libc/src/unistd/linux/link.cpp b/libc/src/unistd/linux/link.cpp
index 9f6f915d16135..2d77c37686ed8 100644
--- a/libc/src/unistd/linux/link.cpp
+++ b/libc/src/unistd/linux/link.cpp
@@ -19,10 +19,10 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, link, (const char *path1, const char *path2)) {
#ifdef SYS_link
- long ret = __llvm_libc::syscall(SYS_link, path1, path2);
+ long ret = __llvm_libc::syscall_impl(SYS_link, path1, path2);
#elif defined(SYS_linkat)
- long ret =
- __llvm_libc::syscall(SYS_linkat, AT_FDCWD, path1, AT_FDCWD, path2, 0);
+ long ret = __llvm_libc::syscall_impl(SYS_linkat, AT_FDCWD, path1, AT_FDCWD,
+ path2, 0);
#else
#error "SYS_link or SYS_linkat not available."
#endif
diff --git a/libc/src/unistd/linux/linkat.cpp b/libc/src/unistd/linux/linkat.cpp
index ef5761173dd0a..170cd0abee34d 100644
--- a/libc/src/unistd/linux/linkat.cpp
+++ b/libc/src/unistd/linux/linkat.cpp
@@ -20,7 +20,8 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, linkat,
(int fd1, const char *path1, int fd2, const char *path2,
int flags)) {
- long ret = __llvm_libc::syscall(SYS_linkat, fd1, path1, fd2, path2, flags);
+ long ret =
+ __llvm_libc::syscall_impl(SYS_linkat, fd1, path1, fd2, path2, flags);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/lseek.cpp b/libc/src/unistd/linux/lseek.cpp
index 4afddd37c695b..07f93baa9469e 100644
--- a/libc/src/unistd/linux/lseek.cpp
+++ b/libc/src/unistd/linux/lseek.cpp
@@ -20,11 +20,11 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(off_t, lseek, (int fd, off_t offset, int whence)) {
off_t result;
#ifdef SYS_lseek
- long ret = __llvm_libc::syscall(SYS_lseek, fd, offset, whence);
+ long ret = __llvm_libc::syscall_impl(SYS_lseek, fd, offset, whence);
result = ret;
#elif defined(SYS__llseek)
- long ret = __llvm_libc::syscall(SYS__llseek, fd, offset >> 32, offset,
- &result, whence);
+ long ret = __llvm_libc::syscall_impl(SYS__llseek, fd, offset >> 32, offset,
+ &result, whence);
#else
#error "lseek and _llseek syscalls not available."
#endif
diff --git a/libc/src/unistd/linux/pread.cpp b/libc/src/unistd/linux/pread.cpp
index 24f4d472e84f7..1434f9781c2df 100644
--- a/libc/src/unistd/linux/pread.cpp
+++ b/libc/src/unistd/linux/pread.cpp
@@ -18,7 +18,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(ssize_t, pread,
(int fd, void *buf, size_t count, off_t offset)) {
- long ret = __llvm_libc::syscall(SYS_pread64, fd, buf, count, offset);
+ long ret = __llvm_libc::syscall_impl(SYS_pread64, fd, buf, count, offset);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/pwrite.cpp b/libc/src/unistd/linux/pwrite.cpp
index d26f87660de9c..597d266696b89 100644
--- a/libc/src/unistd/linux/pwrite.cpp
+++ b/libc/src/unistd/linux/pwrite.cpp
@@ -18,7 +18,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(ssize_t, pwrite,
(int fd, const void *buf, size_t count, off_t offset)) {
- long ret = __llvm_libc::syscall(SYS_pwrite64, fd, buf, count, offset);
+ long ret = __llvm_libc::syscall_impl(SYS_pwrite64, fd, buf, count, offset);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/read.cpp b/libc/src/unistd/linux/read.cpp
index 309976374b998..468409d08e6f7 100644
--- a/libc/src/unistd/linux/read.cpp
+++ b/libc/src/unistd/linux/read.cpp
@@ -17,7 +17,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(ssize_t, read, (int fd, void *buf, size_t count)) {
- long ret = __llvm_libc::syscall(SYS_read, fd, buf, count);
+ long ret = __llvm_libc::syscall_impl(SYS_read, fd, buf, count);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/readlink.cpp b/libc/src/unistd/linux/readlink.cpp
index 354cdb2dc4e70..713620e43c9aa 100644
--- a/libc/src/unistd/linux/readlink.cpp
+++ b/libc/src/unistd/linux/readlink.cpp
@@ -21,10 +21,10 @@ LLVM_LIBC_FUNCTION(ssize_t, readlink,
(const char *__restrict path, char *__restrict buf,
size_t bufsize)) {
#ifdef SYS_readlink
- ssize_t ret = __llvm_libc::syscall(SYS_readlink, path, buf, bufsize);
+ ssize_t ret = __llvm_libc::syscall_impl(SYS_readlink, path, buf, bufsize);
#elif defined(SYS_readlinkat)
ssize_t ret =
- __llvm_libc::syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
+ __llvm_libc::syscall_impl(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
#else
#error "SYS_readlink or SYS_readlinkat not available."
#endif
diff --git a/libc/src/unistd/linux/readlinkat.cpp b/libc/src/unistd/linux/readlinkat.cpp
index ceb4061a84cd2..8b0994a2622dc 100644
--- a/libc/src/unistd/linux/readlinkat.cpp
+++ b/libc/src/unistd/linux/readlinkat.cpp
@@ -20,7 +20,8 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(ssize_t, readlinkat,
(int fd, const char *__restrict path, char *__restrict buf,
size_t bufsize)) {
- ssize_t ret = __llvm_libc::syscall(SYS_readlinkat, fd, path, buf, bufsize);
+ ssize_t ret =
+ __llvm_libc::syscall_impl(SYS_readlinkat, fd, path, buf, bufsize);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/rmdir.cpp b/libc/src/unistd/linux/rmdir.cpp
index 8bc180550021b..144a0902ffaf6 100644
--- a/libc/src/unistd/linux/rmdir.cpp
+++ b/libc/src/unistd/linux/rmdir.cpp
@@ -19,9 +19,10 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, rmdir, (const char *path)) {
#ifdef SYS_rmdir
- long ret = __llvm_libc::syscall(SYS_rmdir, path);
+ long ret = __llvm_libc::syscall_impl(SYS_rmdir, path);
#elif defined(SYS_unlinkat)
- long ret = __llvm_libc::syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+ long ret =
+ __llvm_libc::syscall_impl(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
#else
#error "rmdir and unlinkat syscalls not available."
#endif
diff --git a/libc/src/unistd/linux/symlink.cpp b/libc/src/unistd/linux/symlink.cpp
index add7b95f756dc..caa07b0b4f9cb 100644
--- a/libc/src/unistd/linux/symlink.cpp
+++ b/libc/src/unistd/linux/symlink.cpp
@@ -19,9 +19,9 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, symlink, (const char *path1, const char *path2)) {
#ifdef SYS_symlink
- long ret = __llvm_libc::syscall(SYS_symlink, path1, path2);
+ long ret = __llvm_libc::syscall_impl(SYS_symlink, path1, path2);
#elif defined(SYS_symlinkat)
- long ret = __llvm_libc::syscall(SYS_symlinkat, path1, AT_FDCWD, path2);
+ long ret = __llvm_libc::syscall_impl(SYS_symlinkat, path1, AT_FDCWD, path2);
#else
#error "SYS_symlink or SYS_symlinkat not available."
#endif
diff --git a/libc/src/unistd/linux/symlinkat.cpp b/libc/src/unistd/linux/symlinkat.cpp
index e0edfc842dd68..25377b6959347 100644
--- a/libc/src/unistd/linux/symlinkat.cpp
+++ b/libc/src/unistd/linux/symlinkat.cpp
@@ -19,7 +19,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, symlinkat,
(const char *path1, int fd, const char *path2)) {
- long ret = __llvm_libc::syscall(SYS_symlinkat, path1, fd, path2);
+ long ret = __llvm_libc::syscall_impl(SYS_symlinkat, path1, fd, path2);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/syscall.cpp b/libc/src/unistd/linux/syscall.cpp
new file mode 100644
index 0000000000000..83884043484f3
--- /dev/null
+++ b/libc/src/unistd/linux/syscall.cpp
@@ -0,0 +1,33 @@
+//===-- Linux implementation of syscall -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/syscall.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <stdarg.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(long, __llvm_libc_syscall,
+ (long number, long arg1, long arg2, long arg3, long arg4,
+ long arg5, long arg6)) {
+ long ret =
+ __llvm_libc::syscall_impl(number, arg1, arg2, arg3, arg4, arg5, arg6);
+ // Syscalls may return large positive values that overflow, but will never
+ // return values between -4096 and -1
+ if (static_cast<unsigned long>(ret) > -4096UL) {
+ errno = -ret;
+ return -1;
+ }
+ return ret;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/unistd/linux/truncate.cpp b/libc/src/unistd/linux/truncate.cpp
index c24bfa8e47b70..9ab05c15b81a1 100644
--- a/libc/src/unistd/linux/truncate.cpp
+++ b/libc/src/unistd/linux/truncate.cpp
@@ -18,7 +18,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, truncate, (const char *path, off_t len)) {
- int ret = __llvm_libc::syscall(SYS_truncate, path, len);
+ int ret = __llvm_libc::syscall_impl(SYS_truncate, path, len);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/linux/unlink.cpp b/libc/src/unistd/linux/unlink.cpp
index 386a84e7679e2..019b081e280c9 100644
--- a/libc/src/unistd/linux/unlink.cpp
+++ b/libc/src/unistd/linux/unlink.cpp
@@ -19,9 +19,9 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, unlink, (const char *path)) {
#ifdef SYS_unlink
- long ret = __llvm_libc::syscall(SYS_unlink, path);
+ long ret = __llvm_libc::syscall_impl(SYS_unlink, path);
#elif defined(SYS_unlinkat)
- long ret = __llvm_libc::syscall(SYS_unlinkat, AT_FDCWD, path, 0);
+ long ret = __llvm_libc::syscall_impl(SYS_unlinkat, AT_FDCWD, path, 0);
#else
#error "Unlink syscalls not available."
#endif
diff --git a/libc/src/unistd/linux/unlinkat.cpp b/libc/src/unistd/linux/unlinkat.cpp
index dcfea888453f0..9ca6108a68973 100644
--- a/libc/src/unistd/linux/unlinkat.cpp
+++ b/libc/src/unistd/linux/unlinkat.cpp
@@ -19,7 +19,7 @@ namespace __llvm_libc {
LLVM_LIBC_FUNCTION(int, unlinkat, (int dfd, const char *path, int flags)) {
#ifdef SYS_unlinkat
- long ret = __llvm_libc::syscall(SYS_unlinkat, dfd, path, flags);
+ long ret = __llvm_libc::syscall_impl(SYS_unlinkat, dfd, path, flags);
#else
#error "unlinkat syscall not available."
#endif
diff --git a/libc/src/unistd/linux/write.cpp b/libc/src/unistd/linux/write.cpp
index 68ff1fa3d848e..599ff4b232916 100644
--- a/libc/src/unistd/linux/write.cpp
+++ b/libc/src/unistd/linux/write.cpp
@@ -17,7 +17,7 @@
namespace __llvm_libc {
LLVM_LIBC_FUNCTION(ssize_t, write, (int fd, const void *buf, size_t count)) {
- long ret = __llvm_libc::syscall(SYS_write, fd, buf, count);
+ long ret = __llvm_libc::syscall_impl(SYS_write, fd, buf, count);
if (ret < 0) {
errno = -ret;
return -1;
diff --git a/libc/src/unistd/syscall.h b/libc/src/unistd/syscall.h
new file mode 100644
index 0000000000000..81ff64ebcf5a1
--- /dev/null
+++ b/libc/src/unistd/syscall.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for syscall -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_UNISTD_SYSCALL_H
+#define LLVM_LIBC_SRC_UNISTD_SYSCALL_H
+
+#include <stdarg.h>
+#include <unistd.h>
+
+namespace __llvm_libc {
+
+long __llvm_libc_syscall(long number, long arg1, long arg2, long arg3,
+ long arg4, long arg5, long arg6);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_UNISTD_SYSCALL_H
diff --git a/libc/test/src/__support/OSUtil/linux/x86_64/syscall_test.cpp b/libc/test/src/__support/OSUtil/linux/x86_64/syscall_test.cpp
index 4869e0028df0a..18f9908738517 100644
--- a/libc/test/src/__support/OSUtil/linux/x86_64/syscall_test.cpp
+++ b/libc/test/src/__support/OSUtil/linux/x86_64/syscall_test.cpp
@@ -16,28 +16,29 @@ TEST(LlvmLibcX86_64_SyscallTest, APITest) {
using __llvm_libc::cpp::function;
- function<long(long)> f([](long n) { return __llvm_libc::syscall(n); });
+ function<long(long)> f([](long n) { return __llvm_libc::syscall_impl(n); });
function<long(long, long)> f1(
- [](long n, long a1) { return __llvm_libc::syscall(n, a1); });
- function<long(long, long, long)> f2(
- [](long n, long a1, long a2) { return __llvm_libc::syscall(n, a1, a2); });
+ [](long n, long a1) { return __llvm_libc::syscall_impl(n, a1); });
+ function<long(long, long, long)> f2([](long n, long a1, long a2) {
+ return __llvm_libc::syscall_impl(n, a1, a2);
+ });
function<long(long, long, long, long)> f3(
[](long n, long a1, long a2, long a3) {
- return __llvm_libc::syscall(n, a1, a2, a3);
+ return __llvm_libc::syscall_impl(n, a1, a2, a3);
});
function<long(long, long, long, long, long)> f4(
[](long n, long a1, long a2, long a3, long a4) {
- return __llvm_libc::syscall(n, a1, a2, a3, a4);
+ return __llvm_libc::syscall_impl(n, a1, a2, a3, a4);
});
function<long(long, long, long, long, long, long)> f5(
[](long n, long a1, long a2, long a3, long a4, long a5) {
- return __llvm_libc::syscall(n, a1, a2, a3, a4, a5);
+ return __llvm_libc::syscall_impl(n, a1, a2, a3, a4, a5);
});
function<long(long, long, long, long, long, long, long)> f6(
[](long n, long a1, long a2, long a3, long a4, long a5, long a6) {
- return __llvm_libc::syscall(n, a1, a2, a3, a4, a5, a6);
+ return __llvm_libc::syscall_impl(n, a1, a2, a3, a4, a5, a6);
});
function<long(long, void *)> not_long_type(
- [](long n, void *a1) { return __llvm_libc::syscall(n, a1); });
+ [](long n, void *a1) { return __llvm_libc::syscall_impl(n, a1); });
}
diff --git a/libc/test/src/sched/affinity_test.cpp b/libc/test/src/sched/affinity_test.cpp
index 860a479cd16a5..446e85721e91f 100644
--- a/libc/test/src/sched/affinity_test.cpp
+++ b/libc/test/src/sched/affinity_test.cpp
@@ -19,7 +19,7 @@ TEST(LlvmLibcSchedAffinityTest, SmokeTest) {
cpu_set_t mask;
errno = 0;
using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
- pid_t tid = __llvm_libc::syscall(SYS_gettid);
+ pid_t tid = __llvm_libc::syscall_impl(SYS_gettid);
ASSERT_GT(tid, pid_t(0));
// We just get and set the same mask.
ASSERT_THAT(__llvm_libc::sched_getaffinity(tid, sizeof(cpu_set_t), &mask),
@@ -30,7 +30,7 @@ TEST(LlvmLibcSchedAffinityTest, SmokeTest) {
TEST(LlvmLibcSchedAffinityTest, BadMask) {
using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
- pid_t tid = __llvm_libc::syscall(SYS_gettid);
+ pid_t tid = __llvm_libc::syscall_impl(SYS_gettid);
errno = 0;
ASSERT_THAT(__llvm_libc::sched_getaffinity(tid, sizeof(cpu_set_t), nullptr),
diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt
index 8f35efe947e55..448116e140b23 100644
--- a/libc/test/src/unistd/CMakeLists.txt
+++ b/libc/test/src/unistd/CMakeLists.txt
@@ -361,3 +361,18 @@ add_libc_unittest(
DEPENDS
libc.src.unistd.geteuid
)
+
+add_libc_unittest(
+ syscall_test
+ SUITE
+ libc_unistd_unittests
+ SRCS
+ syscall_test.cpp
+ DEPENDS
+ libc.src.unistd.__llvm_libc_syscall
+ libc.include.errno
+ libc.include.unistd
+ libc.include.fcntl
+ libc.include.sys_syscall
+ libc.test.errno_setter_matcher
+)
diff --git a/libc/test/src/unistd/syscall_test.cpp b/libc/test/src/unistd/syscall_test.cpp
new file mode 100644
index 0000000000000..e4c50545b1e37
--- /dev/null
+++ b/libc/test/src/unistd/syscall_test.cpp
@@ -0,0 +1,115 @@
+//===-- Unittests for syscalls --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/unistd/syscall.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/syscall.h> // For syscall numbers.
+#include <unistd.h>
+
+using __llvm_libc::testing::ErrnoSetterMatcher::Succeeds;
+
+// We only do a smoke test here. Actual functionality tests are
+// done by the unit tests of the syscall wrappers like mmap.
+// The goal is to test syscalls with a wide number of args.
+
+// There is no function named "syscall" in llvm-libc, we instead use a macro to
+// set up the arguments properly. We still need to specify the namespace though
+// because the macro generates a call to the actual internal function
+// (__llvm_libc_syscall) which is inside the namespace.
+TEST(LlvmLibcSyscallTest, TrivialCall) {
+ errno = 0;
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_gettid), 0l);
+ ASSERT_EQ(errno, 0);
+}
+
+TEST(LlvmLibcSyscallTest, SymlinkCreateDestroy) {
+ constexpr const char LINK_VAL[] = "syscall_readlink_test_value";
+ constexpr const char LINK[] = "testdata/syscall_readlink.test.link";
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_symlink, LINK_VAL, LINK), 0l);
+ ASSERT_EQ(errno, 0);
+
+ char buf[sizeof(LINK_VAL)];
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_readlink, LINK, buf, sizeof(buf)), 0l);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_unlink, LINK), 0l);
+ ASSERT_EQ(errno, 0);
+}
+
+TEST(LlvmLibcSyscallTest, FileReadWrite) {
+ constexpr const char HELLO[] = "hello";
+ constexpr int HELLO_SIZE = sizeof(HELLO);
+
+ constexpr const char *TEST_FILE = "testdata/syscall_pread_pwrite.test";
+
+ int fd =
+ __llvm_libc::syscall(SYS_open, TEST_FILE, O_WRONLY | O_CREAT, S_IRWXU);
+ ASSERT_GT(fd, 0);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_pwrite64, fd, HELLO, HELLO_SIZE, 0), 0l);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_fsync, fd), 0l);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_close, fd), 0l);
+ ASSERT_EQ(errno, 0);
+}
+
+TEST(LlvmLibcSyscallTest, FileLinkCreateDestroy) {
+ constexpr const char *TEST_DIR = "testdata";
+ constexpr const char *TEST_FILE = "syscall_linkat.test";
+ constexpr const char *TEST_FILE_PATH = "testdata/syscall_linkat.test";
+ constexpr const char *TEST_FILE_LINK = "syscall_linkat.test.link";
+ constexpr const char *TEST_FILE_LINK_PATH =
+ "testdata/syscall_linkat.test.link";
+
+ // The test strategy is as follows:
+ // 1. Create a normal file
+ // 2. Create a link to that file.
+ // 3. Open the link to check that the link was created.
+ // 4. Cleanup the file and its link.
+
+ int write_fd = __llvm_libc::syscall(SYS_open, TEST_FILE_PATH,
+ O_WRONLY | O_CREAT, S_IRWXU);
+ ASSERT_GT(write_fd, 0);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_close, write_fd), 0l);
+ ASSERT_EQ(errno, 0);
+
+ int dir_fd = __llvm_libc::syscall(SYS_open, TEST_DIR, O_DIRECTORY, 0);
+ ASSERT_GT(dir_fd, 0);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_linkat, dir_fd, TEST_FILE, dir_fd,
+ TEST_FILE_LINK, 0),
+ 0l);
+ ASSERT_EQ(errno, 0);
+
+ int link_fd = __llvm_libc::syscall(SYS_open, TEST_FILE_LINK_PATH, O_PATH, 0);
+ ASSERT_GT(link_fd, 0);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_unlink, TEST_FILE_PATH), 0l);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_unlink, TEST_FILE_LINK_PATH), 0l);
+ ASSERT_EQ(errno, 0);
+
+ ASSERT_GE(__llvm_libc::syscall(SYS_close, dir_fd), 0l);
+ ASSERT_EQ(errno, 0);
+}
More information about the libc-commits
mailing list