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