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/fcntl/open.h"
10#include "src/sys/mman/mmap.h"
11#include "src/sys/mman/munmap.h"
12#include "src/sys/mman/remap_file_pages.h"
13#include "src/unistd/close.h"
14#include "src/unistd/sysconf.h"
15#include "test/UnitTest/ErrnoCheckingTest.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
22using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
23using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
24using LlvmLibcRemapFilePagesTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
25
26TEST_F(LlvmLibcRemapFilePagesTest, NoError) {
27 size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGE_SIZE);
28 ASSERT_GT(page_size, size_t(0));
29
30 // Create a file-backed mapping
31 constexpr const char *file_name = "remap_file_pages.test.noerror";
32 auto test_file = libc_make_test_file_path(file_name);
33 int fd = LIBC_NAMESPACE::open(test_file, O_RDWR | O_CREAT, S_IRWXU);
34 ASSERT_GT(fd, 0);
35
36 // First, allocate some memory using mmap
37 size_t alloc_size = 2 * page_size;
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 // Clean up
48 EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, alloc_size), Succeeds());
49 EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
50}
51
52TEST_F(LlvmLibcRemapFilePagesTest, ErrorInvalidFlags) {
53 size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGE_SIZE);
54 ASSERT_GT(page_size, size_t(0));
55
56 // Create a file-backed mapping
57 constexpr const char *file_name = "remap_file_pages.test.error";
58 auto test_file = libc_make_test_file_path(file_name);
59 int fd = LIBC_NAMESPACE::open(test_file, O_RDWR | O_CREAT, S_IRWXU);
60 ASSERT_GT(fd, 0);
61
62 // First, allocate some memory using mmap
63 size_t alloc_size = 2 * page_size;
64 void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE,
65 MAP_SHARED, fd, 0);
66 ASSERT_ERRNO_SUCCESS();
67 EXPECT_NE(addr, MAP_FAILED);
68
69 // Try to remap pages with an invalid flag MAP_PRIVATE
70 EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, PROT_READ, 0,
71 MAP_PRIVATE),
72 Fails(EINVAL));
73
74 // Clean up
75 EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
76 EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
77}
78
79TEST_F(LlvmLibcRemapFilePagesTest, ErrorInvalidAddress) {
80 size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGESIZE);
81 ASSERT_GT(page_size, size_t(0));
82
83 // Use an address that we haven't mapped
84 void *invalid_addr = reinterpret_cast<void *>(0x12345000);
85
86 EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(invalid_addr, page_size,
87 PROT_READ, 0, 0),
88 Fails(EINVAL));
89}
90

source code of libc/test/src/sys/mman/linux/remap_file_pages_test.cpp