From 73c03b5efdeb7449112b73b72ec10ece5b123efd Mon Sep 17 00:00:00 2001 From: Schrodinger ZHU Yifan Date: Thu, 21 Nov 2024 15:04:30 -0500 Subject: [PATCH] [libc] provide binary compatibility with syscall symbol --- libc/config/linux/aarch64/entrypoints.txt | 1 + libc/config/linux/riscv/entrypoints.txt | 1 + libc/config/linux/x86_64/entrypoints.txt | 1 + libc/src/unistd/CMakeLists.txt | 7 +++++ libc/src/unistd/linux/CMakeLists.txt | 10 +++++++ libc/src/unistd/linux/syscall_compat.cpp | 32 +++++++++++++++++++++++ libc/src/unistd/syscall_compat.h | 21 +++++++++++++++ libc/test/src/unistd/CMakeLists.txt | 1 + libc/test/src/unistd/syscall_test.cpp | 10 +++++++ 9 files changed, 84 insertions(+) create mode 100644 libc/src/unistd/linux/syscall_compat.cpp create mode 100644 libc/src/unistd/syscall_compat.h diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index 74ca3742977a5..9a34029ab7823 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -1002,6 +1002,7 @@ if(LLVM_LIBC_FULL_BUILD) # unistd.h entrypoints libc.src.unistd.__llvm_libc_syscall + libc.src.unistd.syscall_compat libc.src.unistd._exit libc.src.unistd.environ libc.src.unistd.execv diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index 5419462d4f5b3..d7bdc6daa1b01 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -940,6 +940,7 @@ if(LLVM_LIBC_FULL_BUILD) # unistd.h entrypoints libc.src.unistd.__llvm_libc_syscall + libc.src.unistd.syscall_compat libc.src.unistd._exit libc.src.unistd.environ libc.src.unistd.execv diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 957e28bd66cc4..5b6aa83712c99 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -1094,6 +1094,7 @@ if(LLVM_LIBC_FULL_BUILD) # unistd.h entrypoints libc.src.unistd.__llvm_libc_syscall + libc.src.unistd.syscall_compat libc.src.unistd._exit libc.src.unistd.environ libc.src.unistd.execv diff --git a/libc/src/unistd/CMakeLists.txt b/libc/src/unistd/CMakeLists.txt index 1a0b2e3293d03..29f71ceca6475 100644 --- a/libc/src/unistd/CMakeLists.txt +++ b/libc/src/unistd/CMakeLists.txt @@ -252,6 +252,13 @@ add_entrypoint_object( .${LIBC_TARGET_OS}.__llvm_libc_syscall ) +add_entrypoint_object( + syscall_compat + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.syscall_compat +) + add_entrypoint_object( sysconf ALIAS diff --git a/libc/src/unistd/linux/CMakeLists.txt b/libc/src/unistd/linux/CMakeLists.txt index 8a44873141414..106477cec2b07 100644 --- a/libc/src/unistd/linux/CMakeLists.txt +++ b/libc/src/unistd/linux/CMakeLists.txt @@ -465,6 +465,16 @@ add_entrypoint_object( libc.src.errno.errno ) +add_entrypoint_object( + syscall_compat + SRCS + syscall_compat.cpp + HDRS + ../syscall_compat.h + DEPENDS + .__llvm_libc_syscall +) + add_entrypoint_object( sysconf SRCS diff --git a/libc/src/unistd/linux/syscall_compat.cpp b/libc/src/unistd/linux/syscall_compat.cpp new file mode 100644 index 0000000000000..fc0039e15552f --- /dev/null +++ b/libc/src/unistd/linux/syscall_compat.cpp @@ -0,0 +1,32 @@ +//===-- Linux implementation of syscall (va compat) -----------------------===// +// +// 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_compat.h" +#include "src/__support/common.h" +#include "src/unistd/syscall.h" + +#include "src/__support/macros/config.h" +#include + +namespace LIBC_NAMESPACE_DECL { + +#undef syscall +LLVM_LIBC_FUNCTION(long, syscall, (long n, ...)) { + va_list args; + va_start(args, n); + long arg1 = va_arg(args, long); + long arg2 = va_arg(args, long); + long arg3 = va_arg(args, long); + long arg4 = va_arg(args, long); + long arg5 = va_arg(args, long); + long arg6 = va_arg(args, long); + va_end(args); + return __llvm_libc_syscall(n, arg1, arg2, arg3, arg4, arg5, arg6); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/unistd/syscall_compat.h b/libc/src/unistd/syscall_compat.h new file mode 100644 index 0000000000000..4f2271ce52d13 --- /dev/null +++ b/libc/src/unistd/syscall_compat.h @@ -0,0 +1,21 @@ +//===-- Implementation header for syscall (va compat) -----------*- 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_COMPAT_H +#define LLVM_LIBC_SRC_UNISTD_SYSCALL_COMPAT_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { +#pragma push_macro("syscall") +#undef syscall +long syscall(long number, ...); +#pragma pop_macro("syscall") +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_UNISTD_SYSCALL_COMPAT_H diff --git a/libc/test/src/unistd/CMakeLists.txt b/libc/test/src/unistd/CMakeLists.txt index e036e09cde702..43491202626a1 100644 --- a/libc/test/src/unistd/CMakeLists.txt +++ b/libc/test/src/unistd/CMakeLists.txt @@ -429,6 +429,7 @@ add_libc_unittest( libc.include.sys_syscall libc.src.errno.errno libc.src.unistd.__llvm_libc_syscall + libc.src.unistd.syscall_compat libc.test.UnitTest.ErrnoSetterMatcher ) diff --git a/libc/test/src/unistd/syscall_test.cpp b/libc/test/src/unistd/syscall_test.cpp index f6cc3eab9aabe..9ac842267b404 100644 --- a/libc/test/src/unistd/syscall_test.cpp +++ b/libc/test/src/unistd/syscall_test.cpp @@ -8,6 +8,7 @@ #include "src/errno/libc_errno.h" #include "src/unistd/syscall.h" +#include "src/unistd/syscall_compat.h" #include "test/UnitTest/ErrnoSetterMatcher.h" #include "test/UnitTest/Test.h" @@ -177,3 +178,12 @@ TEST(LlvmLibcSyscallTest, FileLinkCreateDestroy) { ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_close, dir_fd), 0l); ASSERT_ERRNO_SUCCESS(); } + +TEST(LlvmLibcSyscallTest, TrivialCallCompat) { + LIBC_NAMESPACE::libc_errno = 0; +#pragma push_macro("syscall") +#undef syscall + ASSERT_GE(LIBC_NAMESPACE::syscall(SYS_gettid), 0l); +#pragma pop_macro("syscall") + ASSERT_ERRNO_SUCCESS(); +}