xref: /llvm-project/libc/test/src/sys/mman/linux/remap_file_pages_test.cpp (revision 7477b61b2416ca130bd3ed9bbc96988e5de17623)
176173b1bSAly ElAshram //===-- Unittests for remap_file_pages ------------------------------------===//
276173b1bSAly ElAshram //
376173b1bSAly ElAshram // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
476173b1bSAly ElAshram // See https://llvm.org/LICENSE.txt for license information.
576173b1bSAly ElAshram // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
676173b1bSAly ElAshram //
776173b1bSAly ElAshram //===----------------------------------------------------------------------===//
876173b1bSAly ElAshram 
976173b1bSAly ElAshram #include "src/errno/libc_errno.h"
1076173b1bSAly ElAshram #include "src/fcntl/open.h"
1176173b1bSAly ElAshram #include "src/sys/mman/mmap.h"
1276173b1bSAly ElAshram #include "src/sys/mman/munmap.h"
1376173b1bSAly ElAshram #include "src/sys/mman/remap_file_pages.h"
1476173b1bSAly ElAshram #include "src/unistd/close.h"
1576173b1bSAly ElAshram #include "src/unistd/sysconf.h"
1676173b1bSAly ElAshram #include "test/UnitTest/ErrnoSetterMatcher.h"
1776173b1bSAly ElAshram #include "test/UnitTest/Test.h"
1876173b1bSAly ElAshram 
1976173b1bSAly ElAshram #include <sys/mman.h>
2076173b1bSAly ElAshram #include <sys/stat.h> // For S_IRWXU
2176173b1bSAly ElAshram 
2276173b1bSAly ElAshram using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
2376173b1bSAly ElAshram using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
2476173b1bSAly ElAshram 
2576173b1bSAly ElAshram TEST(LlvmLibcRemapFilePagesTest, NoError) {
26*7477b61bSTristan Ross   size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGE_SIZE);
2776173b1bSAly ElAshram   ASSERT_GT(page_size, size_t(0));
2876173b1bSAly ElAshram 
2976173b1bSAly ElAshram   // Create a file-backed mapping
3076173b1bSAly ElAshram   constexpr const char *file_name = "remap_file_pages.test.noerror";
3176173b1bSAly ElAshram   auto test_file = libc_make_test_file_path(file_name);
3276173b1bSAly ElAshram   int fd = LIBC_NAMESPACE::open(test_file, O_RDWR | O_CREAT, S_IRWXU);
3376173b1bSAly ElAshram   ASSERT_GT(fd, 0);
3476173b1bSAly ElAshram 
3576173b1bSAly ElAshram   // First, allocate some memory using mmap
3676173b1bSAly ElAshram   size_t alloc_size = 2 * page_size;
3776173b1bSAly ElAshram   LIBC_NAMESPACE::libc_errno = 0;
3876173b1bSAly ElAshram   void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE,
3976173b1bSAly ElAshram                                     MAP_SHARED, fd, 0);
4076173b1bSAly ElAshram   ASSERT_ERRNO_SUCCESS();
4176173b1bSAly ElAshram   EXPECT_NE(addr, MAP_FAILED);
4276173b1bSAly ElAshram 
4376173b1bSAly ElAshram   // Now try to remap the pages
4476173b1bSAly ElAshram   EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, 0, 1, 0),
4576173b1bSAly ElAshram               Succeeds());
4676173b1bSAly ElAshram 
4776173b1bSAly ElAshram   // Reset error number for the new function
4876173b1bSAly ElAshram   LIBC_NAMESPACE::libc_errno = 0;
4976173b1bSAly ElAshram 
5076173b1bSAly ElAshram   // Clean up
5176173b1bSAly ElAshram   EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, alloc_size), Succeeds());
5276173b1bSAly ElAshram   EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
5376173b1bSAly ElAshram }
5476173b1bSAly ElAshram 
5576173b1bSAly ElAshram TEST(LlvmLibcRemapFilePagesTest, ErrorInvalidFlags) {
56*7477b61bSTristan Ross   size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGE_SIZE);
5776173b1bSAly ElAshram   ASSERT_GT(page_size, size_t(0));
5876173b1bSAly ElAshram 
5976173b1bSAly ElAshram   // Create a file-backed mapping
6076173b1bSAly ElAshram   constexpr const char *file_name = "remap_file_pages.test.error";
6176173b1bSAly ElAshram   auto test_file = libc_make_test_file_path(file_name);
6276173b1bSAly ElAshram   int fd = LIBC_NAMESPACE::open(test_file, O_RDWR | O_CREAT, S_IRWXU);
6376173b1bSAly ElAshram   ASSERT_GT(fd, 0);
6476173b1bSAly ElAshram 
6576173b1bSAly ElAshram   // First, allocate some memory using mmap
6676173b1bSAly ElAshram   size_t alloc_size = 2 * page_size;
6776173b1bSAly ElAshram   LIBC_NAMESPACE::libc_errno = 0;
6876173b1bSAly ElAshram   void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE,
6976173b1bSAly ElAshram                                     MAP_SHARED, fd, 0);
7076173b1bSAly ElAshram   ASSERT_ERRNO_SUCCESS();
7176173b1bSAly ElAshram   EXPECT_NE(addr, MAP_FAILED);
7276173b1bSAly ElAshram 
7376173b1bSAly ElAshram   // Try to remap pages with an invalid flag MAP_PRIVATE
7476173b1bSAly ElAshram   EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, PROT_READ, 0,
7576173b1bSAly ElAshram                                                MAP_PRIVATE),
7676173b1bSAly ElAshram               Fails(EINVAL));
7776173b1bSAly ElAshram 
7876173b1bSAly ElAshram   // Clean up
7976173b1bSAly ElAshram   EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
8076173b1bSAly ElAshram   EXPECT_THAT(LIBC_NAMESPACE::close(fd), Succeeds());
8176173b1bSAly ElAshram }
8276173b1bSAly ElAshram 
8376173b1bSAly ElAshram TEST(LlvmLibcRemapFilePagesTest, ErrorInvalidAddress) {
84*7477b61bSTristan Ross   size_t page_size = LIBC_NAMESPACE::sysconf(_SC_PAGESIZE);
8576173b1bSAly ElAshram   ASSERT_GT(page_size, size_t(0));
8676173b1bSAly ElAshram 
8776173b1bSAly ElAshram   // Use an address that we haven't mapped
8876173b1bSAly ElAshram   void *invalid_addr = reinterpret_cast<void *>(0x12345000);
8976173b1bSAly ElAshram 
9076173b1bSAly ElAshram   EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(invalid_addr, page_size,
9176173b1bSAly ElAshram                                                PROT_READ, 0, 0),
9276173b1bSAly ElAshram               Fails(EINVAL));
9376173b1bSAly ElAshram }
94