| //===-- Unittests for remap_file_pages ------------------------------------===// |
| // |
| // 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/fcntl/open.h" |
| #include "src/sys/mman/mmap.h" |
| #include "src/sys/mman/munmap.h" |
| #include "src/sys/mman/remap_file_pages.h" |
| #include "src/unistd/close.h" |
| #include "src/unistd/sysconf.h" |
| #include "test/UnitTest/ErrnoSetterMatcher.h" |
| #include "test/UnitTest/Test.h" |
| |
| #include <sys/mman.h> |
| #include <sys/stat.h> // For S_IRWXU |
| |
| using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; |
| using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; |
| |
| TEST(LlvmLibcRemapFilePagesTest, NoError) { |
| size_t page_size = sysconf(_SC_PAGE_SIZE); |
| ASSERT_GT(page_size, size_t(0)); |
| |
| // Create a file-backed mapping |
| constexpr const char *file_name = "remap_file_pages.test.noerror"; |
| auto test_file = libc_make_test_file_path(file_name); |
| int fd = LIBC_NAMESPACE::open(test_file, O_RDWR | O_CREAT, S_IRWXU); |
| ASSERT_GT(fd, 0); |
| |
| // First, allocate some memory using mmap |
| size_t alloc_size = 2 * page_size; |
| LIBC_NAMESPACE::libc_errno = 0; |
| void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE, |
| MAP_SHARED, fd, 0); |
| ASSERT_ERRNO_SUCCESS(); |
| EXPECT_NE(addr, MAP_FAILED); |
| |
| // Now try to remap the pages |
| EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, 0, 1, 0), |
| Succeeds()); |
| |
| // Reset error number for the new function |
| LIBC_NAMESPACE::libc_errno = 0; |
| |
| // Clean up |
| EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, alloc_size), Succeeds()); |
| EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); |
| } |
| |
| TEST(LlvmLibcRemapFilePagesTest, ErrorInvalidFlags) { |
| size_t page_size = sysconf(_SC_PAGE_SIZE); |
| ASSERT_GT(page_size, size_t(0)); |
| |
| // Create a file-backed mapping |
| constexpr const char *file_name = "remap_file_pages.test.error"; |
| auto test_file = libc_make_test_file_path(file_name); |
| int fd = LIBC_NAMESPACE::open(test_file, O_RDWR | O_CREAT, S_IRWXU); |
| ASSERT_GT(fd, 0); |
| |
| // First, allocate some memory using mmap |
| size_t alloc_size = 2 * page_size; |
| LIBC_NAMESPACE::libc_errno = 0; |
| void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE, |
| MAP_SHARED, fd, 0); |
| ASSERT_ERRNO_SUCCESS(); |
| EXPECT_NE(addr, MAP_FAILED); |
| |
| // Try to remap pages with an invalid flag MAP_PRIVATE |
| EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, PROT_READ, 0, |
| MAP_PRIVATE), |
| Fails(EINVAL)); |
| |
| // Clean up |
| EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds()); |
| EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds()); |
| } |
| |
| TEST(LlvmLibcRemapFilePagesTest, ErrorInvalidAddress) { |
| size_t page_size = sysconf(_SC_PAGESIZE); |
| ASSERT_GT(page_size, size_t(0)); |
| |
| // Use an address that we haven't mapped |
| void *invalid_addr = reinterpret_cast<void *>(0x12345000); |
| |
| EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(invalid_addr, page_size, |
| PROT_READ, 0, 0), |
| Fails(EINVAL)); |
| } |