[libc-commits] [libc] 5a6cc50 - [libc] add mremap (#112804)

via libc-commits libc-commits at lists.llvm.org
Wed Nov 6 10:25:53 PST 2024


Author: Jingyu Qiu
Date: 2024-11-06T10:25:50-08:00
New Revision: 5a6cc509215b62e94de3b798ea26944a375ce6cb

URL: https://github.com/llvm/llvm-project/commit/5a6cc509215b62e94de3b798ea26944a375ce6cb
DIFF: https://github.com/llvm/llvm-project/commit/5a6cc509215b62e94de3b798ea26944a375ce6cb.diff

LOG: [libc] add mremap (#112804)

Added: 
    libc/src/sys/mman/linux/mremap.cpp
    libc/src/sys/mman/mremap.h
    libc/test/src/sys/mman/linux/mremap_test.cpp

Modified: 
    libc/config/linux/aarch64/entrypoints.txt
    libc/config/linux/x86_64/entrypoints.txt
    libc/newhdrgen/yaml/sys/mman.yaml
    libc/spec/linux.td
    libc/src/sys/mman/CMakeLists.txt
    libc/src/sys/mman/linux/CMakeLists.txt
    libc/test/src/sys/mman/linux/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index bf60d6f000529f..571527426de31b 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -245,6 +245,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.mman.mlock2
     libc.src.sys.mman.mlockall
     libc.src.sys.mman.mmap
+    libc.src.sys.mman.mremap
     libc.src.sys.mman.mprotect
     libc.src.sys.mman.msync
     libc.src.sys.mman.munlock

diff  --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index b8c2a82a4d5b2f..9a4a0ff9e75a40 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -244,6 +244,7 @@ set(TARGET_LIBC_ENTRYPOINTS
     libc.src.sys.mman.mlock2
     libc.src.sys.mman.mlockall
     libc.src.sys.mman.mmap
+    libc.src.sys.mman.mremap
     libc.src.sys.mman.mprotect
     libc.src.sys.mman.msync
     libc.src.sys.mman.munlock

diff  --git a/libc/newhdrgen/yaml/sys/mman.yaml b/libc/newhdrgen/yaml/sys/mman.yaml
index 7c4fb1ef09e791..962ca3591917f7 100644
--- a/libc/newhdrgen/yaml/sys/mman.yaml
+++ b/libc/newhdrgen/yaml/sys/mman.yaml
@@ -55,6 +55,16 @@ functions:
       - type: int
       - type: int
       - type: off_t
+  - name: mremap
+    standards:
+      - POSIX
+    return_type: void *
+    arguments:
+      - type: void *
+      - type: size_t
+      - type: size_t
+      - type: int
+      - type: '...'
   - name: mprotect
     standards:
       - POSIX

diff  --git a/libc/spec/linux.td b/libc/spec/linux.td
index c8604e8184f681..9b5dc8e30c95e4 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -103,7 +103,7 @@ def Linux : StandardSpec<"Linux"> {
             ArgSpec<UnsignedIntType>,
           ]
         >,
-         FunctionSpec<
+        FunctionSpec<
           "remap_file_pages",
           RetValSpec<IntType>,
           [
@@ -114,6 +114,17 @@ def Linux : StandardSpec<"Linux"> {
             ArgSpec<IntType>,
           ]
         >,
+        FunctionSpec<
+          "mremap",
+          RetValSpec<VoidPtr>,
+          [
+            ArgSpec<VoidPtr>,
+            ArgSpec<SizeTType>,
+            ArgSpec<SizeTType>,
+            ArgSpec<IntType>,
+            ArgSpec<VarArgType>,
+          ]
+        >,
       ]  // Functions
   >;
 

diff  --git a/libc/src/sys/mman/CMakeLists.txt b/libc/src/sys/mman/CMakeLists.txt
index 4ea43e14be0297..4d4c2ad376050e 100644
--- a/libc/src/sys/mman/CMakeLists.txt
+++ b/libc/src/sys/mman/CMakeLists.txt
@@ -106,3 +106,10 @@ add_entrypoint_object(
   DEPENDS
     .${LIBC_TARGET_OS}.shm_unlink
 )
+
+add_entrypoint_object(
+  mremap
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.mremap
+)

diff  --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt
index 47c16f79bc8d58..89a0ad1527a065 100644
--- a/libc/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/src/sys/mman/linux/CMakeLists.txt
@@ -24,6 +24,19 @@ add_entrypoint_object(
     libc.src.errno.errno
 )
 
+add_entrypoint_object(
+  mremap
+  SRCS
+    mremap.cpp
+  HDRS
+    ../mremap.h
+  DEPENDS
+    libc.include.sys_mman
+    libc.include.sys_syscall
+    libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
+)
+
 add_entrypoint_object(
   munmap
   SRCS

diff  --git a/libc/src/sys/mman/linux/mremap.cpp b/libc/src/sys/mman/linux/mremap.cpp
new file mode 100644
index 00000000000000..38bcfce833d3d9
--- /dev/null
+++ b/libc/src/sys/mman/linux/mremap.cpp
@@ -0,0 +1,45 @@
+//===---------- Linux implementation of the POSIX mremap 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/mremap.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include "src/__support/macros/config.h"
+#include "src/errno/libc_errno.h"
+#include <linux/param.h> // For EXEC_PAGESIZE.
+#include <stdarg.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(void *, mremap,
+                   (void *old_address, size_t old_size, size_t new_size,
+                    int flags, ... /* void *new_address */)) {
+
+  long ret = 0;
+  void *new_address = nullptr;
+  if (flags & MREMAP_FIXED) {
+    va_list varargs;
+    va_start(varargs, flags);
+    new_address = va_arg(varargs, void *);
+    va_end(varargs);
+  }
+  ret = LIBC_NAMESPACE::syscall_impl<long>(SYS_mremap, old_address, old_size,
+                                           new_size, flags, new_address);
+
+  if (ret < 0 && ret > -EXEC_PAGESIZE) {
+    libc_errno = static_cast<int>(-ret);
+    return MAP_FAILED;
+  }
+
+  return reinterpret_cast<void *>(ret);
+}
+
+} // namespace LIBC_NAMESPACE_DECL

diff  --git a/libc/src/sys/mman/mremap.h b/libc/src/sys/mman/mremap.h
new file mode 100644
index 00000000000000..208946bc58a2e3
--- /dev/null
+++ b/libc/src/sys/mman/mremap.h
@@ -0,0 +1,22 @@
+//===-- Implementation header for mremap 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_SYS_MMAN_MREMAP_H
+#define LLVM_LIBC_SRC_SYS_MMAN_MREMAP_H
+
+#include "src/__support/macros/config.h"
+#include <sys/mman.h> // For size_t and off_t
+
+namespace LIBC_NAMESPACE_DECL {
+
+void *mremap(void *old_address, size_t old_size, size_t new_size, int flags,
+             ... /* void *new_address */);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_MMAN_MREMAP_H

diff  --git a/libc/test/src/sys/mman/linux/CMakeLists.txt b/libc/test/src/sys/mman/linux/CMakeLists.txt
index 69263986cc574c..44ed11aadfe8b7 100644
--- a/libc/test/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/test/src/sys/mman/linux/CMakeLists.txt
@@ -14,6 +14,21 @@ add_libc_unittest(
     libc.test.UnitTest.ErrnoSetterMatcher
 )
 
+add_libc_unittest(
+  mremap_test
+  SUITE
+    libc_sys_mman_unittests
+  SRCS
+    mremap_test.cpp
+  DEPENDS
+    libc.include.sys_mman
+    libc.src.errno.errno
+    libc.src.sys.mman.mmap
+    libc.src.sys.mman.mremap
+    libc.src.sys.mman.munmap
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
+
 if (NOT LLVM_USE_SANITIZER)
   add_libc_unittest(
     mprotect_test

diff  --git a/libc/test/src/sys/mman/linux/mremap_test.cpp b/libc/test/src/sys/mman/linux/mremap_test.cpp
new file mode 100644
index 00000000000000..12e4485588421d
--- /dev/null
+++ b/libc/test/src/sys/mman/linux/mremap_test.cpp
@@ -0,0 +1,68 @@
+//===-- Unittests for mremap ----------------------------------------------===//
+//
+// 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/mmap.h"
+#include "src/sys/mman/mremap.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(LlvmLibcMremapTest, NoError) {
+  size_t initial_size = 128;
+  size_t new_size = 256;
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  // Allocate memory using mmap.
+  void *addr =
+      LIBC_NAMESPACE::mmap(nullptr, initial_size, PROT_READ | PROT_WRITE,
+                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  ASSERT_ERRNO_SUCCESS();
+  EXPECT_NE(addr, MAP_FAILED);
+
+  int *array = reinterpret_cast<int *>(addr);
+  // Writing to the memory should not crash the test.
+  array[0] = 123;
+  EXPECT_EQ(array[0], 123);
+
+  // Re-map the memory using mremap with an increased size.
+  void *new_addr =
+      LIBC_NAMESPACE::mremap(addr, initial_size, new_size, MREMAP_MAYMOVE);
+  ASSERT_ERRNO_SUCCESS();
+  EXPECT_NE(new_addr, MAP_FAILED);
+  EXPECT_EQ(reinterpret_cast<int *>(new_addr)[0],
+            123); // Verify data is preserved.
+
+  // Clean up memory by unmapping it.
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(new_addr, new_size), Succeeds());
+}
+
+TEST(LlvmLibcMremapTest, Error_InvalidSize) {
+  size_t initial_size = 128;
+  LIBC_NAMESPACE::libc_errno = 0;
+
+  // Allocate memory using mmap.
+  void *addr =
+      LIBC_NAMESPACE::mmap(nullptr, initial_size, PROT_READ | PROT_WRITE,
+                           MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  ASSERT_ERRNO_SUCCESS();
+  EXPECT_NE(addr, MAP_FAILED);
+
+  // Attempt to re-map the memory with an invalid new size (0).
+  void *new_addr =
+      LIBC_NAMESPACE::mremap(addr, initial_size, 0, MREMAP_MAYMOVE);
+  EXPECT_THAT(new_addr, Fails(EINVAL, MAP_FAILED));
+
+  // Clean up the original mapping.
+  EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, initial_size), Succeeds());
+}


        


More information about the libc-commits mailing list