Skip to content

Commit 525ae42

Browse files
SoftJing1jingyuqiu
authored andcommitted
add mremap
1 parent e9eec14 commit 525ae42

File tree

8 files changed

+201
-1
lines changed

8 files changed

+201
-1
lines changed

libc/newhdrgen/yaml/sys/mman.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,17 @@ functions:
5555
- type: int
5656
- type: int
5757
- type: off_t
58+
- name: mremap
59+
standards:
60+
- POSIX
61+
return_type: void *
62+
arguments:
63+
- type: void *
64+
- type: size_t
65+
- type: size_t
66+
- type: int
67+
- type: void *
68+
description: "This argument is optional."
5869
- name: mprotect
5970
standards:
6071
- POSIX

libc/spec/linux.td

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def Linux : StandardSpec<"Linux"> {
103103
ArgSpec<UnsignedIntType>,
104104
]
105105
>,
106-
FunctionSpec<
106+
FunctionSpec<
107107
"remap_file_pages",
108108
RetValSpec<IntType>,
109109
[
@@ -114,6 +114,17 @@ def Linux : StandardSpec<"Linux"> {
114114
ArgSpec<IntType>,
115115
]
116116
>,
117+
FunctionSpec<
118+
"mremap",
119+
RetValSpec<VoidPtr>,
120+
[
121+
ArgSpec<VoidPtr>,
122+
ArgSpec<SizeTType>,
123+
ArgSpec<SizeTType>,
124+
ArgSpec<IntType>,
125+
ArgSpec<VoidPtr>,
126+
]
127+
>,
117128
] // Functions
118129
>;
119130

libc/src/sys/mman/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,10 @@ add_entrypoint_object(
106106
DEPENDS
107107
.${LIBC_TARGET_OS}.shm_unlink
108108
)
109+
110+
add_entrypoint_object(
111+
mremap,
112+
ALIAS,
113+
DEPENDS
114+
.${LIBC_TARGET_OS}.mremap
115+
)

libc/src/sys/mman/linux/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ add_entrypoint_object(
2424
libc.src.errno.errno
2525
)
2626

27+
add_entrypoint_object(
28+
mremap
29+
SRCS
30+
mremap.cpp
31+
HDRS
32+
../mremap.h
33+
DEPENDS
34+
libc.include.sys_mman
35+
libc.include.sys_syscall
36+
libc.src.__support.OSUtil.osutil
37+
libc.src.errno.errno
38+
)
39+
2740
add_entrypoint_object(
2841
munmap
2942
SRCS

libc/src/sys/mman/linux/mremap.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//===---------- Linux implementation of the POSIX mremap function
2+
//-----------===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "src/sys/mman/mremap.h"
11+
12+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
13+
#include "src/__support/common.h"
14+
15+
#include "src/__support/macros/config.h"
16+
#include "src/errno/libc_errno.h"
17+
#include <linux/param.h> // For EXEC_PAGESIZE.
18+
#include <stdarg.h>
19+
#include <sys/syscall.h> // For syscall numbers.
20+
21+
namespace LIBC_NAMESPACE_DECL {
22+
23+
LLVM_LIBC_FUNCTION(void *, mremap,
24+
(void *old_address, size_t old_size, size_t new_size,
25+
int flags, ... /* void *new_address */)) {
26+
27+
#ifdef SYS_mremap
28+
long syscall_number = SYS_mremap;
29+
#else
30+
#error "mremap syscalls not available."
31+
#endif
32+
long ret = 0;
33+
if (flags & MREMAP_FIXED) {
34+
void *arg;
35+
va_list varargs;
36+
va_start(varargs, flags);
37+
arg = va_arg(varargs, void *);
38+
va_end(varargs);
39+
ret = LIBC_NAMESPACE::syscall_impl(syscall_number, old_address, old_size,
40+
new_size, flags, arg);
41+
} else {
42+
ret = LIBC_NAMESPACE::syscall_impl(syscall_number, old_address, old_size,
43+
new_size, flags);
44+
}
45+
if (ret < 0 && ret > -EXEC_PAGESIZE) {
46+
libc_errno = static_cast<int>(-ret);
47+
return MAP_FAILED;
48+
}
49+
50+
return reinterpret_cast<void *>(ret);
51+
}
52+
53+
} // namespace LIBC_NAMESPACE_DECL

libc/src/sys/mman/mremap.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- Implementation header for mremap function -----------------*- C++
2+
//-*-===//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_LIBC_SRC_SYS_MMAN_MREMAP_H
11+
#define LLVM_LIBC_SRC_SYS_MMAN_MREMAP_H
12+
13+
#include "src/__support/macros/config.h"
14+
#include <sys/mman.h> // For size_t and off_t
15+
16+
namespace LIBC_NAMESPACE_DECL {
17+
18+
void *mremap(void *old_address, size_t old_size, size_t new_size, int flags,
19+
... /* void *new_address */);
20+
21+
} // namespace LIBC_NAMESPACE_DECL
22+
23+
#endif // LLVM_LIBC_SRC_SYS_MMAN_MREMAP_H

libc/test/src/sys/mman/linux/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ add_libc_unittest(
1414
libc.test.UnitTest.ErrnoSetterMatcher
1515
)
1616

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

0 commit comments

Comments
 (0)