1*5a6cc509SJingyu Qiu //===-- Unittests for mremap ----------------------------------------------===// 2*5a6cc509SJingyu Qiu // 3*5a6cc509SJingyu Qiu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*5a6cc509SJingyu Qiu // See https://llvm.org/LICENSE.txt for license information. 5*5a6cc509SJingyu Qiu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*5a6cc509SJingyu Qiu // 7*5a6cc509SJingyu Qiu //===----------------------------------------------------------------------===// 8*5a6cc509SJingyu Qiu 9*5a6cc509SJingyu Qiu #include "src/errno/libc_errno.h" 10*5a6cc509SJingyu Qiu #include "src/sys/mman/mmap.h" 11*5a6cc509SJingyu Qiu #include "src/sys/mman/mremap.h" 12*5a6cc509SJingyu Qiu #include "src/sys/mman/munmap.h" 13*5a6cc509SJingyu Qiu #include "test/UnitTest/ErrnoSetterMatcher.h" 14*5a6cc509SJingyu Qiu #include "test/UnitTest/Test.h" 15*5a6cc509SJingyu Qiu 16*5a6cc509SJingyu Qiu #include <sys/mman.h> 17*5a6cc509SJingyu Qiu 18*5a6cc509SJingyu Qiu using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; 19*5a6cc509SJingyu Qiu using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; 20*5a6cc509SJingyu Qiu 21*5a6cc509SJingyu Qiu TEST(LlvmLibcMremapTest, NoError) { 22*5a6cc509SJingyu Qiu size_t initial_size = 128; 23*5a6cc509SJingyu Qiu size_t new_size = 256; 24*5a6cc509SJingyu Qiu LIBC_NAMESPACE::libc_errno = 0; 25*5a6cc509SJingyu Qiu 26*5a6cc509SJingyu Qiu // Allocate memory using mmap. 27*5a6cc509SJingyu Qiu void *addr = 28*5a6cc509SJingyu Qiu LIBC_NAMESPACE::mmap(nullptr, initial_size, PROT_READ | PROT_WRITE, 29*5a6cc509SJingyu Qiu MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 30*5a6cc509SJingyu Qiu ASSERT_ERRNO_SUCCESS(); 31*5a6cc509SJingyu Qiu EXPECT_NE(addr, MAP_FAILED); 32*5a6cc509SJingyu Qiu 33*5a6cc509SJingyu Qiu int *array = reinterpret_cast<int *>(addr); 34*5a6cc509SJingyu Qiu // Writing to the memory should not crash the test. 35*5a6cc509SJingyu Qiu array[0] = 123; 36*5a6cc509SJingyu Qiu EXPECT_EQ(array[0], 123); 37*5a6cc509SJingyu Qiu 38*5a6cc509SJingyu Qiu // Re-map the memory using mremap with an increased size. 39*5a6cc509SJingyu Qiu void *new_addr = 40*5a6cc509SJingyu Qiu LIBC_NAMESPACE::mremap(addr, initial_size, new_size, MREMAP_MAYMOVE); 41*5a6cc509SJingyu Qiu ASSERT_ERRNO_SUCCESS(); 42*5a6cc509SJingyu Qiu EXPECT_NE(new_addr, MAP_FAILED); 43*5a6cc509SJingyu Qiu EXPECT_EQ(reinterpret_cast<int *>(new_addr)[0], 44*5a6cc509SJingyu Qiu 123); // Verify data is preserved. 45*5a6cc509SJingyu Qiu 46*5a6cc509SJingyu Qiu // Clean up memory by unmapping it. 47*5a6cc509SJingyu Qiu EXPECT_THAT(LIBC_NAMESPACE::munmap(new_addr, new_size), Succeeds()); 48*5a6cc509SJingyu Qiu } 49*5a6cc509SJingyu Qiu 50*5a6cc509SJingyu Qiu TEST(LlvmLibcMremapTest, Error_InvalidSize) { 51*5a6cc509SJingyu Qiu size_t initial_size = 128; 52*5a6cc509SJingyu Qiu LIBC_NAMESPACE::libc_errno = 0; 53*5a6cc509SJingyu Qiu 54*5a6cc509SJingyu Qiu // Allocate memory using mmap. 55*5a6cc509SJingyu Qiu void *addr = 56*5a6cc509SJingyu Qiu LIBC_NAMESPACE::mmap(nullptr, initial_size, PROT_READ | PROT_WRITE, 57*5a6cc509SJingyu Qiu MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); 58*5a6cc509SJingyu Qiu ASSERT_ERRNO_SUCCESS(); 59*5a6cc509SJingyu Qiu EXPECT_NE(addr, MAP_FAILED); 60*5a6cc509SJingyu Qiu 61*5a6cc509SJingyu Qiu // Attempt to re-map the memory with an invalid new size (0). 62*5a6cc509SJingyu Qiu void *new_addr = 63*5a6cc509SJingyu Qiu LIBC_NAMESPACE::mremap(addr, initial_size, 0, MREMAP_MAYMOVE); 64*5a6cc509SJingyu Qiu EXPECT_THAT(new_addr, Fails(EINVAL, MAP_FAILED)); 65*5a6cc509SJingyu Qiu 66*5a6cc509SJingyu Qiu // Clean up the original mapping. 67*5a6cc509SJingyu Qiu EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, initial_size), Succeeds()); 68*5a6cc509SJingyu Qiu } 69