[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.
This commit is contained in:
@@ -185,6 +185,15 @@ add_proxy_header_library(
|
|||||||
libc.include.llvm-libc-macros.sys_stat_macros
|
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_header_library(unistd_overlay HDRS unistd_overlay.h)
|
||||||
add_proxy_header_library(
|
add_proxy_header_library(
|
||||||
unistd_macros
|
unistd_macros
|
||||||
|
|||||||
22
libc/hdr/sys_mman_macros.h
Normal file
22
libc/hdr/sys_mman_macros.h
Normal file
@@ -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 <sys/mman.h>
|
||||||
|
|
||||||
|
#endif // LLVM_LIBC_FULL_BUILD
|
||||||
|
|
||||||
|
#endif // LLVM_LIBC_HDR_SYS_MMAN_MACROS_H
|
||||||
@@ -185,3 +185,53 @@ add_header_library(
|
|||||||
libc.hdr.types.struct_timespec
|
libc.hdr.types.struct_timespec
|
||||||
libc.include.sys_syscall
|
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
|
||||||
|
)
|
||||||
|
|||||||
59
libc/src/__support/OSUtil/linux/syscall_wrappers/mmap.h
Normal file
59
libc/src/__support/OSUtil/linux/syscall_wrappers/mmap.h
Normal file
@@ -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 <linux/param.h> // For EXEC_PAGESIZE
|
||||||
|
#include <sys/syscall.h> // For syscall numbers
|
||||||
|
|
||||||
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
|
namespace linux_syscalls {
|
||||||
|
|
||||||
|
LIBC_INLINE ErrorOr<void *> 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<long>(syscall_number, reinterpret_cast<long>(addr), size,
|
||||||
|
prot, flags, fd, static_cast<long>(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<int>(ret));
|
||||||
|
return reinterpret_cast<void *>(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace linux_syscalls
|
||||||
|
} // namespace LIBC_NAMESPACE_DECL
|
||||||
|
|
||||||
|
#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_MMAP_H
|
||||||
32
libc/src/__support/OSUtil/linux/syscall_wrappers/mprotect.h
Normal file
32
libc/src/__support/OSUtil/linux/syscall_wrappers/mprotect.h
Normal file
@@ -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 <sys/syscall.h> // For syscall numbers
|
||||||
|
|
||||||
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
|
namespace linux_syscalls {
|
||||||
|
|
||||||
|
LIBC_INLINE ErrorOr<int> mprotect(void *addr, size_t size, int prot) {
|
||||||
|
int ret =
|
||||||
|
syscall_impl<int>(SYS_mprotect, reinterpret_cast<long>(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
|
||||||
31
libc/src/__support/OSUtil/linux/syscall_wrappers/munmap.h
Normal file
31
libc/src/__support/OSUtil/linux/syscall_wrappers/munmap.h
Normal file
@@ -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 <sys/syscall.h> // For syscall numbers
|
||||||
|
|
||||||
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
|
namespace linux_syscalls {
|
||||||
|
|
||||||
|
LIBC_INLINE ErrorOr<int> munmap(void *addr, size_t size) {
|
||||||
|
int ret = syscall_impl<int>(SYS_munmap, reinterpret_cast<long>(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
|
||||||
@@ -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 <sys/syscall.h> // For syscall numbers
|
||||||
|
|
||||||
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
|
namespace linux_syscalls {
|
||||||
|
|
||||||
|
LIBC_INLINE ErrorOr<int> pkey_mprotect(void *addr, size_t len, int prot,
|
||||||
|
int pkey) {
|
||||||
|
#if !defined(SYS_pkey_mprotect)
|
||||||
|
return Error(ENOSYS);
|
||||||
|
#else
|
||||||
|
int ret = syscall_impl<int>(SYS_pkey_mprotect, reinterpret_cast<long>(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
|
||||||
@@ -25,9 +25,10 @@ add_entrypoint_object(
|
|||||||
HDRS
|
HDRS
|
||||||
../mmap.h
|
../mmap.h
|
||||||
DEPENDS
|
DEPENDS
|
||||||
libc.include.sys_mman
|
libc.hdr.sys_mman_macros
|
||||||
libc.include.sys_syscall
|
libc.hdr.types.size_t
|
||||||
libc.src.__support.OSUtil.osutil
|
libc.hdr.types.off_t
|
||||||
|
libc.src.__support.OSUtil.linux.syscall_wrappers.mmap
|
||||||
libc.src.errno.errno
|
libc.src.errno.errno
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,23 +52,11 @@ add_entrypoint_object(
|
|||||||
HDRS
|
HDRS
|
||||||
../munmap.h
|
../munmap.h
|
||||||
DEPENDS
|
DEPENDS
|
||||||
libc.include.sys_mman
|
libc.hdr.types.size_t
|
||||||
libc.include.sys_syscall
|
libc.src.__support.OSUtil.linux.syscall_wrappers.munmap
|
||||||
libc.src.__support.OSUtil.osutil
|
|
||||||
libc.src.errno.errno
|
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(
|
add_entrypoint_object(
|
||||||
mprotect
|
mprotect
|
||||||
SRCS
|
SRCS
|
||||||
@@ -75,11 +64,9 @@ add_entrypoint_object(
|
|||||||
HDRS
|
HDRS
|
||||||
../mprotect.h
|
../mprotect.h
|
||||||
DEPENDS
|
DEPENDS
|
||||||
libc.include.sys_mman
|
libc.hdr.types.size_t
|
||||||
libc.include.sys_syscall
|
libc.src.__support.OSUtil.linux.syscall_wrappers.mprotect
|
||||||
libc.src.__support.OSUtil.osutil
|
|
||||||
libc.src.errno.errno
|
libc.src.errno.errno
|
||||||
.mprotect_common
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_entrypoint_object(
|
add_entrypoint_object(
|
||||||
@@ -240,11 +227,10 @@ add_entrypoint_object(
|
|||||||
HDRS
|
HDRS
|
||||||
../pkey_mprotect.h
|
../pkey_mprotect.h
|
||||||
DEPENDS
|
DEPENDS
|
||||||
libc.include.sys_mman
|
libc.hdr.types.size_t
|
||||||
libc.include.sys_syscall
|
libc.src.__support.OSUtil.linux.syscall_wrappers.mprotect
|
||||||
libc.src.__support.OSUtil.osutil
|
libc.src.__support.OSUtil.linux.syscall_wrappers.pkey_mprotect
|
||||||
libc.src.errno.errno
|
libc.src.errno.errno
|
||||||
.mprotect_common
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_entrypoint_object(
|
add_entrypoint_object(
|
||||||
|
|||||||
@@ -7,61 +7,24 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "src/sys/mman/mmap.h"
|
#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/common.h"
|
||||||
|
|
||||||
#include "src/__support/libc_errno.h"
|
#include "src/__support/libc_errno.h"
|
||||||
#include "src/__support/macros/config.h"
|
#include "src/__support/macros/config.h"
|
||||||
#include <linux/param.h> // For EXEC_PAGESIZE.
|
|
||||||
#include <sys/syscall.h> // For syscall numbers.
|
|
||||||
|
|
||||||
namespace LIBC_NAMESPACE_DECL {
|
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,
|
LLVM_LIBC_FUNCTION(void *, mmap,
|
||||||
(void *addr, size_t size, int prot, int flags, int fd,
|
(void *addr, size_t size, int prot, int flags, int fd,
|
||||||
off_t offset)) {
|
off_t offset)) {
|
||||||
// A lot of POSIX standard prescribed validation of the parameters is not
|
auto result = linux_syscalls::mmap(addr, size, prot, flags, fd, offset);
|
||||||
// done in this function as modern linux versions do it in the syscall.
|
if (!result) {
|
||||||
// TODO: Perform argument validation not done by the linux syscall.
|
libc_errno = result.error();
|
||||||
|
|
||||||
// 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<long>(offset);
|
|
||||||
long ret =
|
|
||||||
LIBC_NAMESPACE::syscall_impl(syscall_number, reinterpret_cast<long>(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<int>(-ret);
|
|
||||||
return MAP_FAILED;
|
return MAP_FAILED;
|
||||||
}
|
}
|
||||||
|
return result.value();
|
||||||
return reinterpret_cast<void *>(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LIBC_NAMESPACE_DECL
|
} // namespace LIBC_NAMESPACE_DECL
|
||||||
|
|||||||
@@ -8,25 +8,20 @@
|
|||||||
|
|
||||||
#include "src/sys/mman/mprotect.h"
|
#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/common.h"
|
||||||
|
|
||||||
#include "src/__support/error_or.h"
|
|
||||||
#include "src/__support/libc_errno.h"
|
#include "src/__support/libc_errno.h"
|
||||||
#include "src/__support/macros/config.h"
|
#include "src/__support/macros/config.h"
|
||||||
#include "src/sys/mman/linux/mprotect_common.h"
|
|
||||||
#include <sys/syscall.h> // For syscall numbers.
|
|
||||||
|
|
||||||
namespace LIBC_NAMESPACE_DECL {
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
|
|
||||||
LLVM_LIBC_FUNCTION(int, mprotect, (void *addr, size_t size, int prot)) {
|
LLVM_LIBC_FUNCTION(int, mprotect, (void *addr, size_t size, int prot)) {
|
||||||
ErrorOr<int> result =
|
auto result = linux_syscalls::mprotect(addr, size, prot);
|
||||||
LIBC_NAMESPACE::mprotect_common::mprotect_impl(addr, size, prot);
|
if (!result) {
|
||||||
if (!result.has_value()) {
|
|
||||||
libc_errno = result.error();
|
libc_errno = result.error();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return result.value();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LIBC_NAMESPACE_DECL
|
} // namespace LIBC_NAMESPACE_DECL
|
||||||
|
|||||||
@@ -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 <sys/syscall.h> // 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<int> mprotect_impl(void *addr, size_t size, int prot) {
|
|
||||||
int ret = LIBC_NAMESPACE::syscall_impl<int>(
|
|
||||||
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.
|
|
||||||
if (ret < 0) {
|
|
||||||
return Error(-ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace mprotect_common
|
|
||||||
|
|
||||||
} // namespace LIBC_NAMESPACE_DECL
|
|
||||||
@@ -8,28 +8,19 @@
|
|||||||
|
|
||||||
#include "src/sys/mman/munmap.h"
|
#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/common.h"
|
||||||
|
|
||||||
#include "src/__support/libc_errno.h"
|
#include "src/__support/libc_errno.h"
|
||||||
#include "src/__support/macros/config.h"
|
#include "src/__support/macros/config.h"
|
||||||
#include <sys/syscall.h> // For syscall numbers.
|
|
||||||
|
|
||||||
namespace LIBC_NAMESPACE_DECL {
|
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)) {
|
LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) {
|
||||||
int ret = LIBC_NAMESPACE::syscall_impl<int>(
|
auto result = linux_syscalls::munmap(addr, size);
|
||||||
SYS_munmap, reinterpret_cast<long>(addr), size);
|
if (!result) {
|
||||||
|
libc_errno = result.error();
|
||||||
// A negative return value indicates an error with the magnitude of the
|
|
||||||
// value being the error code.
|
|
||||||
if (ret < 0) {
|
|
||||||
libc_errno = -ret;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,51 +8,28 @@
|
|||||||
|
|
||||||
#include "src/sys/mman/pkey_mprotect.h"
|
#include "src/sys/mman/pkey_mprotect.h"
|
||||||
|
|
||||||
#include "hdr/errno_macros.h" // For ENOSYS
|
#include "src/__support/OSUtil/linux/syscall_wrappers/mprotect.h"
|
||||||
#include "hdr/types/size_t.h"
|
#include "src/__support/OSUtil/linux/syscall_wrappers/pkey_mprotect.h"
|
||||||
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
|
|
||||||
#include "src/__support/common.h"
|
#include "src/__support/common.h"
|
||||||
#include "src/__support/error_or.h"
|
|
||||||
#include "src/__support/libc_errno.h"
|
#include "src/__support/libc_errno.h"
|
||||||
#include "src/__support/macros/config.h"
|
#include "src/__support/macros/config.h"
|
||||||
#include "src/sys/mman/linux/mprotect_common.h"
|
|
||||||
|
|
||||||
#include <sys/syscall.h> // For syscall numbers.
|
|
||||||
|
|
||||||
namespace LIBC_NAMESPACE_DECL {
|
namespace LIBC_NAMESPACE_DECL {
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
LIBC_INLINE ErrorOr<int> 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<int>(SYS_pkey_mprotect, addr, len,
|
|
||||||
prot, pkey);
|
|
||||||
if (ret < 0) {
|
|
||||||
return Error(-ret);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
LLVM_LIBC_FUNCTION(int, pkey_mprotect,
|
LLVM_LIBC_FUNCTION(int, pkey_mprotect,
|
||||||
(void *addr, size_t len, int prot, int pkey)) {
|
(void *addr, size_t len, int prot, int pkey)) {
|
||||||
ErrorOr<int> ret =
|
ErrorOr<int> ret(0);
|
||||||
LIBC_NAMESPACE::internal::pkey_mprotect_impl(addr, len, prot, pkey);
|
if (pkey == -1) {
|
||||||
if (!ret.has_value()) {
|
ret = linux_syscalls::mprotect(addr, len, prot);
|
||||||
|
} else {
|
||||||
|
ret = linux_syscalls::pkey_mprotect(addr, len, prot, pkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
libc_errno = ret.error();
|
libc_errno = ret.error();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return ret.value();
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LIBC_NAMESPACE_DECL
|
} // namespace LIBC_NAMESPACE_DECL
|
||||||
|
|||||||
Reference in New Issue
Block a user