xref: /llvm-project/libc/test/src/sys/mman/linux/remap_file_pages_test.cpp (revision 7477b61b2416ca130bd3ed9bbc96988e5de17623)
1 //===-- Unittests for remap_file_pages ------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "src/errno/libc_errno.h"
10 #include "src/fcntl/open.h"
11 #include "src/sys/mman/mmap.h"
12 #include "src/sys/mman/munmap.h"
13 #include "src/sys/mman/remap_file_pages.h"
14 #include "src/unistd/close.h"
15 #include "src/unistd/sysconf.h"
16 #include "test/UnitTest/ErrnoSetterMatcher.h"
17 #include "test/UnitTest/Test.h"
18 
19 #include <sys/mman.h>
20 #include <sys/stat.h> // For S_IRWXU
21 
22 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
23 using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
24 
25 TEST(LlvmLibcRemapFilePagesTest, NoError) {
26   size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGE_SIZE);
27   ASSERT_GT(page_size, size_t(0));
28 
29   // Create a file-backed mapping
30   constexpr const char *file_name = "remap_file_pages.test.noerror";
31   auto test_file = libc_make_test_file_path(file_name);
32   int fd = LIBC_NAMESPACE::open(test_file, O_RDWR | O_CREAT, S_IRWXU);
33   ASSERT_GT(fd, 0);
34 
35   // First, allocate some memory using mmap
36   size_t alloc_size = 2 * page_size;
37   LIBC_NAMESPACE::libc_errno = 0;
38   void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE,
39                                     MAP_SHARED, fd, 0);
40   ASSERT_ERRNO_SUCCESS();
41   EXPECT_NE(addr, MAP_FAILED);
42 
43   // Now try to remap the pages
44   EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, 0, 1, 0),
45               Succeeds());
46 
47   // Reset error number for the new function
48   LIBC_NAMESPACE::libc_errno = 0;
49 
50   // Clean up
51   EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, alloc_size), Succeeds());
52   EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
53 }
54 
55 TEST(LlvmLibcRemapFilePagesTest, ErrorInvalidFlags) {
56   size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGE_SIZE);
57   ASSERT_GT(page_size, size_t(0));
58 
59   // Create a file-backed mapping
60   constexpr const char *file_name = "remap_file_pages.test.error";
61   auto test_file = libc_make_test_file_path(file_name);
62   int fd = LIBC_NAMESPACE::open(test_file, O_RDWR | O_CREAT, S_IRWXU);
63   ASSERT_GT(fd, 0);
64 
65   // First, allocate some memory using mmap
66   size_t alloc_size = 2 * page_size;
67   LIBC_NAMESPACE::libc_errno = 0;
68   void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE,
69                                     MAP_SHARED, fd, 0);
70   ASSERT_ERRNO_SUCCESS();
71   EXPECT_NE(addr, MAP_FAILED);
72 
73   // Try to remap pages with an invalid flag MAP_PRIVATE
74   EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, PROT_READ, 0,
75                                                MAP_PRIVATE),
76               Fails(EINVAL));
77 
78   // Clean up
79   EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
80   EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
81 }
82 
83 TEST(LlvmLibcRemapFilePagesTest, ErrorInvalidAddress) {
84   size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGESIZE);
85   ASSERT_GT(page_size, size_t(0));
86 
87   // Use an address that we haven't mapped
88   void *invalid_addr = reinterpret_cast<void *>(0x12345000);
89 
90   EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(invalid_addr, page_size,
91                                                PROT_READ, 0, 0),
92               Fails(EINVAL));
93 }
94