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