From 699d3bfdbaca78bf9beeaf9a6221ea7b3aef22bd Mon Sep 17 00:00:00 2001 From: Jeff Bailey Date: Thu, 30 Apr 2026 18:09:10 +0100 Subject: [PATCH] [libc] Add sys/mman syscall wrappers (#195103) Added ErrorOr-returning syscall wrappers for mmap, munmap, mprotect, and pkey_mprotect in src/__support/OSUtil/linux/syscall_wrappers/. Migrated the sys/mman Linux entrypoint implementations to use them, following the design in libc/docs/dev/syscall_wrapper_refactor.rst. Removed the shared mprotect_common.h in favour of per-syscall wrapper headers. Added hdr/sys_mman_macros.h proxy header. --- libc/hdr/CMakeLists.txt | 9 +++ libc/hdr/sys_mman_macros.h | 22 +++++++ .../linux/syscall_wrappers/CMakeLists.txt | 50 ++++++++++++++++ .../OSUtil/linux/syscall_wrappers/mmap.h | 59 +++++++++++++++++++ .../OSUtil/linux/syscall_wrappers/mprotect.h | 32 ++++++++++ .../OSUtil/linux/syscall_wrappers/munmap.h | 31 ++++++++++ .../linux/syscall_wrappers/pkey_mprotect.h | 38 ++++++++++++ libc/src/sys/mman/linux/CMakeLists.txt | 36 ++++------- libc/src/sys/mman/linux/mmap.cpp | 49 ++------------- libc/src/sys/mman/linux/mprotect.cpp | 13 ++-- libc/src/sys/mman/linux/mprotect_common.h | 38 ------------ libc/src/sys/mman/linux/munmap.cpp | 17 ++---- libc/src/sys/mman/linux/pkey_mprotect.cpp | 45 ++++---------- 13 files changed, 277 insertions(+), 162 deletions(-) create mode 100644 libc/hdr/sys_mman_macros.h create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/mmap.h create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/mprotect.h create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/munmap.h create mode 100644 libc/src/__support/OSUtil/linux/syscall_wrappers/pkey_mprotect.h delete mode 100644 libc/src/sys/mman/linux/mprotect_common.h diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt index 0a496206f490..a941d63f7d21 100644 --- a/libc/hdr/CMakeLists.txt +++ b/libc/hdr/CMakeLists.txt @@ -185,6 +185,15 @@ add_proxy_header_library( libc.include.llvm-libc-macros.sys_stat_macros ) +add_proxy_header_library( + sys_mman_macros + HDRS + sys_mman_macros.h + FULL_BUILD_DEPENDS + libc.include.sys_mman + libc.include.llvm-libc-macros.sys_mman_macros +) + add_header_library(unistd_overlay HDRS unistd_overlay.h) add_proxy_header_library( unistd_macros diff --git a/libc/hdr/sys_mman_macros.h b/libc/hdr/sys_mman_macros.h new file mode 100644 index 000000000000..baf1a7bae5df --- /dev/null +++ b/libc/hdr/sys_mman_macros.h @@ -0,0 +1,22 @@ +//===-- Definition of macros from sys/mman.h ------------------------------===// +// +// 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_HDR_SYS_MMAN_MACROS_H +#define LLVM_LIBC_HDR_SYS_MMAN_MACROS_H + +#ifdef LIBC_FULL_BUILD + +#include "include/llvm-libc-macros/sys-mman-macros.h" + +#else // Overlay mode + +#include + +#endif // LLVM_LIBC_FULL_BUILD + +#endif // LLVM_LIBC_HDR_SYS_MMAN_MACROS_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt index ddabd0c39b85..2215d2cab285 100644 --- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt @@ -185,3 +185,53 @@ add_header_library( libc.hdr.types.struct_timespec libc.include.sys_syscall ) + +add_header_library( + mmap + HDRS + mmap.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + libc.hdr.types.off_t + libc.include.sys_syscall +) + +add_header_library( + munmap + HDRS + munmap.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + libc.include.sys_syscall +) + +add_header_library( + mprotect + HDRS + mprotect.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + libc.include.sys_syscall +) + +add_header_library( + pkey_mprotect + HDRS + pkey_mprotect.h + DEPENDS + libc.src.__support.OSUtil.osutil + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.macros.config + libc.hdr.errno_macros + libc.include.sys_syscall +) diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/mmap.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/mmap.h new file mode 100644 index 000000000000..983973e70e20 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/mmap.h @@ -0,0 +1,59 @@ +//===-- Syscall wrapper for mmap --------------------------------*- 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___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MMAP_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MMAP_H + +#include "hdr/types/off_t.h" +#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl, linux_utils::is_valid_mmap +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For EXEC_PAGESIZE +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr mmap(void *addr, size_t size, int prot, int flags, + int fd, off_t offset) { + // TODO: Perform POSIX-prescribed argument validation not done by the + // linux syscall. + + // EXEC_PAGESIZE is used for the page size. While this is OK for x86_64, + // it might not be correct in general. + // TODO: Use pagesize read from the ELF aux vector instead of + // EXEC_PAGESIZE. +#ifdef SYS_mmap2 + offset /= EXEC_PAGESIZE; + long syscall_number = SYS_mmap2; +#elif defined(SYS_mmap) + long syscall_number = SYS_mmap; +#else +#error "mmap or mmap2 syscalls not available." +#endif + + // Explicit cast to silence "implicit conversion loses integer precision" + // warnings when compiling for 32-bit systems. + long ret = + syscall_impl(syscall_number, reinterpret_cast(addr), size, + prot, flags, fd, static_cast(offset)); + + // A negative return value from the syscall can also be an error-free + // value returned by the syscall. However, since a valid return address + // cannot be within the last page, a return value corresponding to a + // location in the last page is an error value. + if (!linux_utils::is_valid_mmap(ret)) + return Error(-static_cast(ret)); + return reinterpret_cast(ret); +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MMAP_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/mprotect.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/mprotect.h new file mode 100644 index 000000000000..a85032ddcc54 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/mprotect.h @@ -0,0 +1,32 @@ +//===-- Syscall wrapper for mprotect ----------------------------*- 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___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MPROTECT_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MPROTECT_H + +#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr mprotect(void *addr, size_t size, int prot) { + int ret = + syscall_impl(SYS_mprotect, reinterpret_cast(addr), size, prot); + if (ret < 0) + return Error(-ret); + return ret; +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MPROTECT_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/munmap.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/munmap.h new file mode 100644 index 000000000000..1cd35e54f450 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/munmap.h @@ -0,0 +1,31 @@ +//===-- Syscall wrapper for munmap ------------------------------*- 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___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MUNMAP_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MUNMAP_H + +#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr munmap(void *addr, size_t size) { + int ret = syscall_impl(SYS_munmap, reinterpret_cast(addr), size); + if (ret < 0) + return Error(-ret); + return ret; +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MUNMAP_H diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/pkey_mprotect.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/pkey_mprotect.h new file mode 100644 index 000000000000..1fa759ae3cd2 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/pkey_mprotect.h @@ -0,0 +1,38 @@ +//===-- Syscall wrapper for pkey_mprotect -----------------------*- 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___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_PKEY_MPROTECT_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_PKEY_MPROTECT_H + +#include "hdr/errno_macros.h" +#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl +#include "src/__support/common.h" +#include "src/__support/error_or.h" +#include "src/__support/macros/config.h" +#include // For syscall numbers + +namespace LIBC_NAMESPACE_DECL { +namespace linux_syscalls { + +LIBC_INLINE ErrorOr pkey_mprotect(void *addr, size_t len, int prot, + int pkey) { +#if !defined(SYS_pkey_mprotect) + return Error(ENOSYS); +#else + int ret = syscall_impl(SYS_pkey_mprotect, reinterpret_cast(addr), + len, prot, pkey); + if (ret < 0) + return Error(-ret); + return ret; +#endif +} + +} // namespace linux_syscalls +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_PKEY_MPROTECT_H diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt index 4c90ca0f0154..36485d57dafc 100644 --- a/libc/src/sys/mman/linux/CMakeLists.txt +++ b/libc/src/sys/mman/linux/CMakeLists.txt @@ -25,9 +25,10 @@ add_entrypoint_object( HDRS ../mmap.h DEPENDS - libc.include.sys_mman - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil + libc.hdr.sys_mman_macros + libc.hdr.types.size_t + libc.hdr.types.off_t + libc.src.__support.OSUtil.linux.syscall_wrappers.mmap libc.src.errno.errno ) @@ -51,23 +52,11 @@ add_entrypoint_object( HDRS ../munmap.h DEPENDS - libc.include.sys_mman - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil + libc.hdr.types.size_t + libc.src.__support.OSUtil.linux.syscall_wrappers.munmap libc.src.errno.errno ) -add_header_library( - mprotect_common - HDRS - mprotect_common.h - DEPENDS - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil - libc.src.errno.errno - libc.src.__support.error_or -) - add_entrypoint_object( mprotect SRCS @@ -75,11 +64,9 @@ add_entrypoint_object( HDRS ../mprotect.h DEPENDS - libc.include.sys_mman - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil + libc.hdr.types.size_t + libc.src.__support.OSUtil.linux.syscall_wrappers.mprotect libc.src.errno.errno - .mprotect_common ) add_entrypoint_object( @@ -240,11 +227,10 @@ add_entrypoint_object( HDRS ../pkey_mprotect.h DEPENDS - libc.include.sys_mman - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil + libc.hdr.types.size_t + libc.src.__support.OSUtil.linux.syscall_wrappers.mprotect + libc.src.__support.OSUtil.linux.syscall_wrappers.pkey_mprotect libc.src.errno.errno - .mprotect_common ) add_entrypoint_object( diff --git a/libc/src/sys/mman/linux/mmap.cpp b/libc/src/sys/mman/linux/mmap.cpp index 76a6611e2b32..41d63c27d6c0 100644 --- a/libc/src/sys/mman/linux/mmap.cpp +++ b/libc/src/sys/mman/linux/mmap.cpp @@ -7,61 +7,24 @@ //===----------------------------------------------------------------------===// #include "src/sys/mman/mmap.h" +#include "hdr/sys_mman_macros.h" -#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/OSUtil/linux/syscall_wrappers/mmap.h" #include "src/__support/common.h" - #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include // For EXEC_PAGESIZE. -#include // For syscall numbers. namespace LIBC_NAMESPACE_DECL { -// This function is currently linux only. It has to be refactored suitably if -// mmap is to be supported on non-linux operating systems also. LLVM_LIBC_FUNCTION(void *, mmap, (void *addr, size_t size, int prot, int flags, int fd, off_t offset)) { - // A lot of POSIX standard prescribed validation of the parameters is not - // done in this function as modern linux versions do it in the syscall. - // TODO: Perform argument validation not done by the linux syscall. - - // EXEC_PAGESIZE is used for the page size. While this is OK for x86_64, it - // might not be correct in general. - // TODO: Use pagesize read from the ELF aux vector instead of EXEC_PAGESIZE. - -#ifdef SYS_mmap2 - offset /= EXEC_PAGESIZE; - long syscall_number = SYS_mmap2; -#elif defined(SYS_mmap) - long syscall_number = SYS_mmap; -#else -#error "mmap or mmap2 syscalls not available." -#endif - - // We add an explicit cast to silence a "implicit conversion loses integer - // precision" warning when compiling for 32-bit systems. - long mmap_offset = static_cast(offset); - long ret = - LIBC_NAMESPACE::syscall_impl(syscall_number, reinterpret_cast(addr), - size, prot, flags, fd, mmap_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 - // up in case an error code is detected. - // - // A point to keep in mind for the fix up is that a negative return value - // from the syscall can also be an error-free value returned by the syscall. - // However, since a valid return address cannot be within the last page, a - // return value corresponding to a location in the last page is an error - // value. - if (!linux_utils::is_valid_mmap(ret)) { - libc_errno = static_cast(-ret); + auto result = linux_syscalls::mmap(addr, size, prot, flags, fd, offset); + if (!result) { + libc_errno = result.error(); return MAP_FAILED; } - - return reinterpret_cast(ret); + return result.value(); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/mprotect.cpp b/libc/src/sys/mman/linux/mprotect.cpp index c891f03a4713..44ae328af6b9 100644 --- a/libc/src/sys/mman/linux/mprotect.cpp +++ b/libc/src/sys/mman/linux/mprotect.cpp @@ -8,25 +8,20 @@ #include "src/sys/mman/mprotect.h" -#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/OSUtil/linux/syscall_wrappers/mprotect.h" #include "src/__support/common.h" - -#include "src/__support/error_or.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include "src/sys/mman/linux/mprotect_common.h" -#include // For syscall numbers. namespace LIBC_NAMESPACE_DECL { LLVM_LIBC_FUNCTION(int, mprotect, (void *addr, size_t size, int prot)) { - ErrorOr result = - LIBC_NAMESPACE::mprotect_common::mprotect_impl(addr, size, prot); - if (!result.has_value()) { + auto result = linux_syscalls::mprotect(addr, size, prot); + if (!result) { libc_errno = result.error(); return -1; } - return result.value(); + return 0; } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/mprotect_common.h b/libc/src/sys/mman/linux/mprotect_common.h deleted file mode 100644 index 5cd354f9919d..000000000000 --- a/libc/src/sys/mman/linux/mprotect_common.h +++ /dev/null @@ -1,38 +0,0 @@ -//===---------- Shared Linux implementation of POSIX mprotect. ------------===// -// -// 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/__support/OSUtil/syscall.h" // For internal syscall function. -#include "src/__support/common.h" -#include "src/__support/error_or.h" -#include "src/__support/libc_errno.h" -#include "src/__support/macros/attributes.h" -#include "src/__support/macros/config.h" -#include // For syscall numbers. - -namespace LIBC_NAMESPACE_DECL { - -namespace mprotect_common { - -// This function is currently linux only. It has to be refactored suitably if -// mprotect is to be supported on non-linux operating systems also. -LIBC_INLINE ErrorOr mprotect_impl(void *addr, size_t size, int prot) { - int ret = LIBC_NAMESPACE::syscall_impl( - SYS_mprotect, reinterpret_cast(addr), size, prot); - - // A negative return value indicates an error with the magnitude of the - // value being the error code. - if (ret < 0) { - return Error(-ret); - } - - return 0; -} - -} // namespace mprotect_common - -} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/sys/mman/linux/munmap.cpp b/libc/src/sys/mman/linux/munmap.cpp index 61b1f1549dd1..ac02e13bab89 100644 --- a/libc/src/sys/mman/linux/munmap.cpp +++ b/libc/src/sys/mman/linux/munmap.cpp @@ -8,28 +8,19 @@ #include "src/sys/mman/munmap.h" -#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/OSUtil/linux/syscall_wrappers/munmap.h" #include "src/__support/common.h" - #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include // For syscall numbers. namespace LIBC_NAMESPACE_DECL { -// This function is currently linux only. It has to be refactored suitably if -// mmap is to be supported on non-linux operating systems also. LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) { - int ret = LIBC_NAMESPACE::syscall_impl( - SYS_munmap, reinterpret_cast(addr), size); - - // A negative return value indicates an error with the magnitude of the - // value being the error code. - if (ret < 0) { - libc_errno = -ret; + auto result = linux_syscalls::munmap(addr, size); + if (!result) { + libc_errno = result.error(); return -1; } - return 0; } diff --git a/libc/src/sys/mman/linux/pkey_mprotect.cpp b/libc/src/sys/mman/linux/pkey_mprotect.cpp index daa12fa927f8..ac34a2de0804 100644 --- a/libc/src/sys/mman/linux/pkey_mprotect.cpp +++ b/libc/src/sys/mman/linux/pkey_mprotect.cpp @@ -8,51 +8,28 @@ #include "src/sys/mman/pkey_mprotect.h" -#include "hdr/errno_macros.h" // For ENOSYS -#include "hdr/types/size_t.h" -#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/OSUtil/linux/syscall_wrappers/mprotect.h" +#include "src/__support/OSUtil/linux/syscall_wrappers/pkey_mprotect.h" #include "src/__support/common.h" -#include "src/__support/error_or.h" #include "src/__support/libc_errno.h" #include "src/__support/macros/config.h" -#include "src/sys/mman/linux/mprotect_common.h" - -#include // For syscall numbers. namespace LIBC_NAMESPACE_DECL { -namespace internal { - -LIBC_INLINE ErrorOr pkey_mprotect_impl(void *addr, size_t len, int prot, - int pkey) { - // Fall back to mprotect if pkey is -1 - // to maintain compatibility with kernel versions that don't support pkey. - if (pkey == -1) { - return LIBC_NAMESPACE::mprotect_common::mprotect_impl(addr, len, prot); - } - -#if !defined(SYS_pkey_mprotect) - return Error(ENOSYS); -#else - int ret = LIBC_NAMESPACE::syscall_impl(SYS_pkey_mprotect, addr, len, - prot, pkey); - if (ret < 0) { - return Error(-ret); - } - return 0; -#endif -} - -} // namespace internal LLVM_LIBC_FUNCTION(int, pkey_mprotect, (void *addr, size_t len, int prot, int pkey)) { - ErrorOr ret = - LIBC_NAMESPACE::internal::pkey_mprotect_impl(addr, len, prot, pkey); - if (!ret.has_value()) { + ErrorOr ret(0); + if (pkey == -1) { + ret = linux_syscalls::mprotect(addr, len, prot); + } else { + ret = linux_syscalls::pkey_mprotect(addr, len, prot, pkey); + } + + if (!ret) { libc_errno = ret.error(); return -1; } - return ret.value(); + return 0; } } // namespace LIBC_NAMESPACE_DECL