[libc-commits] [libc] [libc] Implement mlock family of functions (PR #80016)

Sirui Mu via libc-commits libc-commits at lists.llvm.org
Tue Jan 30 06:59:01 PST 2024


https://github.com/Lancern created https://github.com/llvm/llvm-project/pull/80016

This PR implements the following libc entrypoints: `mlock`, `mlock2`, `munlock`, `mlockall`, and `munlockall`.

These entrypoints are simply syscall wrappers.

>From a0d258cbee592bfd001af25a57b49bd201492153 Mon Sep 17 00:00:00 2001
From: Sirui Mu <msrlancern at gmail.com>
Date: Tue, 30 Jan 2024 21:56:12 +0800
Subject: [PATCH] [libc] Implement mlock family of functions

This PR implements the following libc entrypoints: mlock, mlock2, munlock,
mlockall, and munlockall.
---
 libc/config/linux/aarch64/entrypoints.txt   |  5 ++
 libc/config/linux/riscv/entrypoints.txt     |  5 ++
 libc/config/linux/x86_64/entrypoints.txt    |  5 ++
 libc/src/sys/mman/CMakeLists.txt            | 35 ++++++++++
 libc/src/sys/mman/linux/CMakeLists.txt      | 65 ++++++++++++++++++
 libc/src/sys/mman/linux/mlock.cpp           | 28 ++++++++
 libc/src/sys/mman/linux/mlock2.cpp          | 29 ++++++++
 libc/src/sys/mman/linux/mlockall.cpp        | 28 ++++++++
 libc/src/sys/mman/linux/munlock.cpp         | 28 ++++++++
 libc/src/sys/mman/linux/munlockall.cpp      | 27 ++++++++
 libc/src/sys/mman/mlock.h                   | 20 ++++++
 libc/src/sys/mman/mlock2.h                  | 20 ++++++
 libc/src/sys/mman/mlockall.h                | 18 +++++
 libc/src/sys/mman/munlock.h                 | 20 ++++++
 libc/src/sys/mman/munlockall.h              | 18 +++++
 libc/test/src/sys/mman/linux/CMakeLists.txt | 19 ++++++
 libc/test/src/sys/mman/linux/mlock_test.cpp | 76 +++++++++++++++++++++
 17 files changed, 446 insertions(+)
 create mode 100644 libc/src/sys/mman/linux/mlock.cpp
 create mode 100644 libc/src/sys/mman/linux/mlock2.cpp
 create mode 100644 libc/src/sys/mman/linux/mlockall.cpp
 create mode 100644 libc/src/sys/mman/linux/munlock.cpp
 create mode 100644 libc/src/sys/mman/linux/munlockall.cpp
 create mode 100644 libc/src/sys/mman/mlock.h
 create mode 100644 libc/src/sys/mman/mlock2.h
 create mode 100644 libc/src/sys/mman/mlockall.h
 create mode 100644 libc/src/sys/mman/munlock.h
 create mode 100644 libc/src/sys/mman/munlockall.h
 create mode 100644 libc/test/src/sys/mman/linux/mlock_test.cpp

diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index 52f1d2bce34f4..ffb79aa4a252e 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -137,6 +137,11 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.mman.munmap
     libc.src.sys.mman.posix_madvise
     libc.src.sys.mman.mincore
+    libc.src.sys.mman.mlock
+    libc.src.sys.mman.mlock2
+    libc.src.sys.mman.munlock
+    libc.src.sys.mman.mlockall
+    libc.src.sys.mman.munlockall
 
     # sys/random.h entrypoints
     libc.src.sys.random.getrandom
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index a257f3f8d64ab..c9adc8852cb92 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -143,6 +143,11 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.mman.munmap
     libc.src.sys.mman.posix_madvise
     libc.src.sys.mman.mincore
+    libc.src.sys.mman.mlock
+    libc.src.sys.mman.mlock2
+    libc.src.sys.mman.munlock
+    libc.src.sys.mman.mlockall
+    libc.src.sys.mman.munlockall
 
     # sys/random.h entrypoints
     libc.src.sys.random.getrandom
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 3812d9586121e..9b3b134ef00ef 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -143,6 +143,11 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.mman.munmap
     libc.src.sys.mman.posix_madvise
     libc.src.sys.mman.mincore
+    libc.src.sys.mman.mlock
+    libc.src.sys.mman.mlock2
+    libc.src.sys.mman.munlock
+    libc.src.sys.mman.mlockall
+    libc.src.sys.mman.munlockall
 
     # sys/random.h entrypoints
     libc.src.sys.random.getrandom
diff --git a/libc/src/sys/mman/CMakeLists.txt b/libc/src/sys/mman/CMakeLists.txt
index 2d17429a26b45..f11f5ac9df9f2 100644
--- a/libc/src/sys/mman/CMakeLists.txt
+++ b/libc/src/sys/mman/CMakeLists.txt
@@ -43,3 +43,38 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.mincore
 )
+
+add_entrypoint_object(
+  mlock
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.mlock
+)
+
+add_entrypoint_object(
+  mlock2
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.mlock2
+)
+
+add_entrypoint_object(
+  munlock
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.munlock
+)
+
+add_entrypoint_object(
+  mlockall
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.mlockall
+)
+
+add_entrypoint_object(
+  munlockall
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.munlockall
+)
diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt
index ce0cda7f22277..a6feff1f0bec1 100644
--- a/libc/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/src/sys/mman/linux/CMakeLists.txt
@@ -74,3 +74,68 @@ add_entrypoint_object(
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
 )
+
+add_entrypoint_object(
+  mlock
+  SRCS
+    mlock.cpp
+  HDRS
+    ../mlock.h
+  DEPENDS
+    libc.include.sys_mman
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  mlock2
+  SRCS
+    mlock2.cpp
+  HDRS
+    ../mlock2.h
+  DEPENDS
+    libc.include.sys_mman
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  munlock
+  SRCS
+    munlock.cpp
+  HDRS
+    ../munlock.h
+  DEPENDS
+    libc.include.sys_mman
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  mlockall
+  SRCS
+    mlockall.cpp
+  HDRS
+    ../mlockall.h
+  DEPENDS
+    libc.include.sys_mman
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
+add_entrypoint_object(
+  munlockall
+  SRCS
+    munlockall.cpp
+  HDRS
+    ../munlockall.h
+  DEPENDS
+    libc.include.sys_mman
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
diff --git a/libc/src/sys/mman/linux/mlock.cpp b/libc/src/sys/mman/linux/mlock.cpp
new file mode 100644
index 0000000000000..61ceedfcdd16d
--- /dev/null
+++ b/libc/src/sys/mman/linux/mlock.cpp
@@ -0,0 +1,28 @@
+//===------------- Linux implementation of the mlock function -------------===//
+//
+// 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/sys/mman/mlock.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, mlock, (const void *addr, size_t len)) {
+  long ret = LIBC_NAMESPACE::syscall_impl(SYS_mlock,
+                                          reinterpret_cast<long>(addr), len);
+  if (ret < 0) {
+    libc_errno = static_cast<int>(-ret);
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/linux/mlock2.cpp b/libc/src/sys/mman/linux/mlock2.cpp
new file mode 100644
index 0000000000000..1aa29970c2076
--- /dev/null
+++ b/libc/src/sys/mman/linux/mlock2.cpp
@@ -0,0 +1,29 @@
+//===------------- Linux implementation of the mlock2 function ------------===//
+//
+// 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/sys/mman/mlock2.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, mlock2,
+                   (const void *addr, size_t len, unsigned int flags)) {
+  long ret = LIBC_NAMESPACE::syscall_impl(
+      SYS_mlock2, reinterpret_cast<long>(addr), len, static_cast<long>(flags));
+  if (ret < 0) {
+    libc_errno = static_cast<int>(-ret);
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/linux/mlockall.cpp b/libc/src/sys/mman/linux/mlockall.cpp
new file mode 100644
index 0000000000000..0de7896986c7b
--- /dev/null
+++ b/libc/src/sys/mman/linux/mlockall.cpp
@@ -0,0 +1,28 @@
+//===------------ Linux implementation of the mlockall function -----------===//
+//
+// 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/sys/mman/mlockall.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, mlockall, (int flags)) {
+  long ret =
+      LIBC_NAMESPACE::syscall_impl(SYS_mlockall, static_cast<long>(flags));
+  if (ret < 0) {
+    libc_errno = static_cast<int>(-ret);
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/linux/munlock.cpp b/libc/src/sys/mman/linux/munlock.cpp
new file mode 100644
index 0000000000000..e6845d37d4e53
--- /dev/null
+++ b/libc/src/sys/mman/linux/munlock.cpp
@@ -0,0 +1,28 @@
+//===------------ Linux implementation of the munlock function ------------===//
+//
+// 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/sys/mman/munlock.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, munlock, (const void *addr, size_t len)) {
+  long ret = LIBC_NAMESPACE::syscall_impl(SYS_munlock,
+                                          reinterpret_cast<long>(addr), len);
+  if (ret < 0) {
+    libc_errno = static_cast<int>(-ret);
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/linux/munlockall.cpp b/libc/src/sys/mman/linux/munlockall.cpp
new file mode 100644
index 0000000000000..e34a3e9eeb1e3
--- /dev/null
+++ b/libc/src/sys/mman/linux/munlockall.cpp
@@ -0,0 +1,27 @@
+//===----------- Linux implementation of the munlockall function ----------===//
+//
+// 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/sys/mman/munlockall.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/errno/libc_errno.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE {
+
+LLVM_LIBC_FUNCTION(int, munlockall, ()) {
+  long ret = LIBC_NAMESPACE::syscall_impl(SYS_munlockall);
+  if (ret < 0) {
+    libc_errno = static_cast<int>(-ret);
+    return -1;
+  }
+  return 0;
+}
+
+} // namespace LIBC_NAMESPACE
diff --git a/libc/src/sys/mman/mlock.h b/libc/src/sys/mman/mlock.h
new file mode 100644
index 0000000000000..d57c013778743
--- /dev/null
+++ b/libc/src/sys/mman/mlock.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for mlock function ----------------*- 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_SYS_MMAN_MLOCK_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
+
+#include <sys/mman.h> // For size_t
+
+namespace LIBC_NAMESPACE {
+
+int mlock(const void *addr, size_t len);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCK_H
diff --git a/libc/src/sys/mman/mlock2.h b/libc/src/sys/mman/mlock2.h
new file mode 100644
index 0000000000000..2069a8f694d77
--- /dev/null
+++ b/libc/src/sys/mman/mlock2.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for mlock2 function ---------------*- 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_SYS_MMAN_MLOCK2_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCK2_H
+
+#include <sys/mman.h> // For size_t
+
+namespace LIBC_NAMESPACE {
+
+int mlock2(const void *addr, size_t len, unsigned int flags);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCK2_H
diff --git a/libc/src/sys/mman/mlockall.h b/libc/src/sys/mman/mlockall.h
new file mode 100644
index 0000000000000..2154658d83d86
--- /dev/null
+++ b/libc/src/sys/mman/mlockall.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for mlockall function -------------*- 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_SYS_MMAN_MLOCKALL_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MLOCKALL_H
+
+namespace LIBC_NAMESPACE {
+
+int mlockall(int flags);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MLOCKALL_H
diff --git a/libc/src/sys/mman/munlock.h b/libc/src/sys/mman/munlock.h
new file mode 100644
index 0000000000000..2fe01a94af586
--- /dev/null
+++ b/libc/src/sys/mman/munlock.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for munlock function --------------*- 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_SYS_MMAN_MUNLOCK_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MUNLOCK_H
+
+#include <sys/mman.h> // For size_t
+
+namespace LIBC_NAMESPACE {
+
+int munlock(const void *addr, size_t len);
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MUNLOCK_H
diff --git a/libc/src/sys/mman/munlockall.h b/libc/src/sys/mman/munlockall.h
new file mode 100644
index 0000000000000..4b64ac628456e
--- /dev/null
+++ b/libc/src/sys/mman/munlockall.h
@@ -0,0 +1,18 @@
+//===-- Implementation header for munlockall function -----------*- 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_SYS_MMAN_MUNLOCKALL_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MUNLOCKALL_H
+
+namespace LIBC_NAMESPACE {
+
+int munlockall();
+
+} // namespace LIBC_NAMESPACE
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MUNLOCKALL_H
diff --git a/libc/test/src/sys/mman/linux/CMakeLists.txt b/libc/test/src/sys/mman/linux/CMakeLists.txt
index 36557695e503c..abab03625ad5b 100644
--- a/libc/test/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/test/src/sys/mman/linux/CMakeLists.txt
@@ -80,3 +80,22 @@ add_libc_unittest(
     libc.src.unistd.sysconf
     libc.test.UnitTest.ErrnoSetterMatcher
 )
+
+add_libc_unittest(
+  mlock_test
+  SUITE
+    libc_sys_mman_unittests
+  SRCS
+    mlock_test.cpp
+  DEPENDS
+    libc.include.sys_mman
+    libc.src.errno.errno
+    libc.src.sys.mman.mmap
+    libc.src.sys.mman.munmap
+    libc.src.sys.mman.mlock
+    libc.src.sys.mman.mlock2
+    libc.src.sys.mman.munlock
+    libc.src.sys.mman.mlockall
+    libc.src.sys.mman.munlockall
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
diff --git a/libc/test/src/sys/mman/linux/mlock_test.cpp b/libc/test/src/sys/mman/linux/mlock_test.cpp
new file mode 100644
index 0000000000000..76d0a0be418af
--- /dev/null
+++ b/libc/test/src/sys/mman/linux/mlock_test.cpp
@@ -0,0 +1,76 @@
+//===-- Unittests for mlock -----------------------------------------------===//
+//
+// 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/errno/libc_errno.h"
+#include "src/sys/mman/mlock.h"
+#include "src/sys/mman/mlock2.h"
+#include "src/sys/mman/mlockall.h"
+#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munlock.h"
+#include "src/sys/mman/munlockall.h"
+#include "src/sys/mman/munmap.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include "test/UnitTest/Test.h"
+
+#include <sys/mman.h>
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+
+TEST(LlvmLibcMlockTest, NoError) {
+  size_t alloc_size = 128;
+  libc_errno = 0;
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
+                                    MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  EXPECT_EQ(0, libc_errno);
+  EXPECT_NE(addr, MAP_FAILED);
+
+  EXPECT_THAT(LIBC_NAMESPACE::mlock(addr, alloc_size), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munlock(addr, alloc_size), Succeeds());
+
+  EXPECT_THAT(LIBC_NAMESPACE::mlock2(addr, alloc_size, MLOCK_ONFAULT),
+              Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munlock(addr, alloc_size), Succeeds());
+
+  EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_CURRENT), Succeeds());
+  EXPECT_THAT(LIBC_NAMESPACE::munlockall(), Succeeds());
+
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, alloc_size), Succeeds());
+}
+
+TEST(LlvmLibcMlockTest, NoMem) {
+  size_t alloc_size = 4096; // page size
+  libc_errno = 0;
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
+                                    MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  EXPECT_EQ(0, libc_errno);
+  EXPECT_NE(addr, MAP_FAILED);
+  LIBC_NAMESPACE::munmap(addr, alloc_size);
+
+  // addr holds the address of an unmapped page. Calling mlock with such an
+  // address should get EINVAL.
+  EXPECT_THAT(LIBC_NAMESPACE::mlock(addr, alloc_size), Fails(ENOMEM));
+}
+
+TEST(LlvmLibcMlockTest, InvalidFlag) {
+  size_t alloc_size = 128; // page size
+  libc_errno = 0;
+  void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ,
+                                    MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  EXPECT_EQ(0, libc_errno);
+  EXPECT_NE(addr, MAP_FAILED);
+
+  // Invalid mlock2 flags.
+  EXPECT_THAT(LIBC_NAMESPACE::mlock2(addr, alloc_size, 1234), Fails(EINVAL));
+
+  // Invalid mlockall flags.
+  EXPECT_THAT(LIBC_NAMESPACE::mlockall(1234), Fails(EINVAL));
+  EXPECT_THAT(LIBC_NAMESPACE::mlockall(MCL_ONFAULT), Fails(EINVAL));
+
+  LIBC_NAMESPACE::munmap(addr, alloc_size);
+}



More information about the libc-commits mailing list