xref: /llvm-project/libc/test/src/sys/mman/linux/mremap_test.cpp (revision 5a6cc509215b62e94de3b798ea26944a375ce6cb)
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