Skip to content

Commit 50bf5e9

Browse files
committed
- Create remap_file_pages wrapper for the linux sys call.
- Add UnitTest for remap_file_pages - Add function to libc/spec/linux.td - Add Function spec to mman.yaml
1 parent a285ba7 commit 50bf5e9

File tree

8 files changed

+197
-0
lines changed

8 files changed

+197
-0
lines changed

libc/newhdrgen/yaml/sys/mman.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ functions:
9898
- type: void *
9999
- type: size_t
100100
- type: int
101+
- name: remap_file_pages
102+
standards:
103+
- LINUX
104+
return_type: int
105+
arguments:
106+
- type: void *
107+
- type: size_t
108+
- type: int
109+
- type: size_t
110+
- type: int
101111
- name: shm_open
102112
standards:
103113
- POSIX

libc/spec/linux.td

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ def Linux : StandardSpec<"Linux"> {
103103
ArgSpec<UnsignedIntType>,
104104
]
105105
>,
106+
FunctionSpec<
107+
"remap_file_pages",
108+
RetValSpec<IntType>,
109+
[
110+
ArgSpec<VoidPtr>,
111+
ArgSpec<SizeTType>,
112+
ArgSpec<IntType>,
113+
ArgSpec<SizeTType>,
114+
ArgSpec<IntType>,
115+
]
116+
>,
106117
] // Functions
107118
>;
108119

libc/src/sys/mman/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ add_entrypoint_object(
8686
.${LIBC_TARGET_OS}.msync
8787
)
8888

89+
add_entrypoint_object(
90+
remap_file_pages
91+
ALIAS
92+
DEPENDS
93+
.${LIBC_TARGET_OS}.remap_file_pages
94+
)
95+
8996
add_entrypoint_object(
9097
shm_open
9198
ALIAS

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,19 @@ add_entrypoint_object(
153153
libc.src.errno.errno
154154
)
155155

156+
add_entrypoint_object(
157+
remap_file_pages
158+
SRCS
159+
remap_file_pages.cpp.cpp
160+
HDRS
161+
../remap_file_pages.h.h
162+
DEPENDS
163+
libc.include.sys_mman
164+
libc.include.sys_syscall
165+
libc.src.__support.OSUtil.osutil
166+
libc.src.errno.errno
167+
)
168+
156169
add_header_library(
157170
shm_common
158171
HDRS
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//===----- Linux implementation of the POSIX remap_file_pages function ----===//
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/sys/mman/remap_file_pages.h>
10+
11+
#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
12+
#include "src/__support/common.h"
13+
#include "src/__support/macros/config.h"
14+
#include "src/errno/libc_errno.h"
15+
#include <sys/syscall.h> // For syscall numbers.
16+
17+
namespace LIBC_NAMESPACE_DECL {
18+
19+
// This function is currently linux only. It has to be refactored suitably if
20+
// remap_file_pages is to be supported on non-linux operating systems also.
21+
LLVM_LIBC_FUNCTION(int, remap_file_pages,
22+
(void *addr, size_t size, int prot, size_t pgoff, int flags))
23+
{
24+
#ifdef SYS_remap_file_pages
25+
long syscall_number = SYS_remap_file_pages;
26+
#else
27+
#error "remap_file_pages syscall is not available."
28+
#endif
29+
30+
31+
int ret = LIBC_NAMESPACE::syscall_impl<int>(
32+
syscall_number, reinterpret_cast<long>(addr), size, prot, pgoff, flags);
33+
34+
// A negative return value indicates an error with the magnitude of the
35+
// value being the error code.
36+
if (ret < 0) {
37+
libc_errno = ret;
38+
return -1;
39+
}
40+
41+
return 0;
42+
}
43+
44+
} // namespace LIBC_NAMESPACE_DECL
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Implementation header for remap_file_pages function -----*- C++ -*-===//
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+
#ifndef LLVM_LIBC_SRC_SYS_MMAN_REMAP_FILE_PAGES_H
10+
#define LLVM_LIBC_SRC_SYS_MMAN_REMAP_FILE_PAGES_H
11+
12+
#include "src/__support/macros/config.h"
13+
#include <sys/mman.h>
14+
15+
namespace LIBC_NAMESPACE_DECL {
16+
17+
int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags);
18+
19+
} // namespace LIBC_NAMESPACE_DECL
20+
21+
#endif //LLVM_LIBC_SRC_SYS_MMAN_REMAP_FILE_PAGES_H

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,23 @@ add_libc_unittest(
128128
libc.test.UnitTest.ErrnoSetterMatcher
129129
)
130130

131+
add_libc_unittest(
132+
remap_file_pages_test
133+
SUITE
134+
libc_sys_mman_unittests
135+
SRCS
136+
remap_file_pages_test.cpp
137+
DEPENDS
138+
libc.include.sys_mman
139+
libc.src.unistd.sysconf
140+
libc.test.UnitTest.Test
141+
libc.test.UnitTest.ErrnoSetterMatcher
142+
libc.src.sys.mman.remap_file_pages
143+
libc.src.errno.errno
144+
libc.src.sys.mman.mmap
145+
libc.src.sys.mman.munmap
146+
)
147+
131148
add_libc_unittest(
132149
shm_test
133150
SUITE
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===-- Unittests for remap_file_pages ------------------------------------===//
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 "src/sys/mman/remap_file_pages.h"
13+
#include "test/UnitTest/ErrnoSetterMatcher.h"
14+
#include "test/UnitTest/Test.h"
15+
#include "src/unistd/sysconf.h"
16+
17+
#include <sys/mman.h>
18+
19+
20+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
21+
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
22+
23+
TEST(LlvmLibcRemapFilePagesTest, NoError) {
24+
size_t page_size = sysconf(_SC_PAGE_SIZE);
25+
ASSERT_GT(page_size, size_t(0));
26+
27+
// First, allocate some memory using mmap
28+
size_t alloc_size = 2 * page_size;
29+
LIBC_NAMESPACE::libc_errno = 0;
30+
void *addr = LIBC_NAMESPACE::mmap(nullptr, alloc_size, PROT_READ | PROT_WRITE,
31+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
32+
ASSERT_ERRNO_SUCCESS();
33+
EXPECT_NE(addr, MAP_FAILED);
34+
35+
// Reset error number for the new function
36+
LIBC_NAMESPACE::libc_errno = 0;
37+
38+
// Now try to remap the pages
39+
EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, PROT_READ, page_size, 0),
40+
Succeeds());
41+
42+
// Reset error number for the new function
43+
LIBC_NAMESPACE::libc_errno = 0;
44+
45+
// Clean up
46+
EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, alloc_size), Succeeds());
47+
}
48+
49+
TEST(LlvmLibcRemapFilePagesTest, ErrorInvalidFlags) {
50+
size_t page_size = sysconf(_SC_PAGESIZE);
51+
ASSERT_GT(page_size, size_t(0));
52+
53+
void *addr = LIBC_NAMESPACE::mmap(nullptr, page_size, PROT_READ | PROT_WRITE,
54+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
55+
ASSERT_NE(addr, MAP_FAILED);
56+
57+
// Try to remap pages with an invalid flag MAP_PRIVATE
58+
EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(addr, page_size, PROT_READ, 0, MAP_PRIVATE),
59+
Fails(EINVAL));
60+
61+
// Clean up
62+
EXPECT_THAT(LIBC_NAMESPACE::munmap(addr, page_size), Succeeds());
63+
}
64+
65+
TEST(LlvmLibcRemapFilePagesTest, ErrorInvalidAddress) {
66+
size_t page_size = sysconf(_SC_PAGESIZE);
67+
ASSERT_GT(page_size, size_t(0));
68+
69+
// Use an address that we haven't mapped
70+
void *invalid_addr = reinterpret_cast<void*>(0x12345000);
71+
72+
EXPECT_THAT(LIBC_NAMESPACE::remap_file_pages(invalid_addr, page_size, PROT_READ, 0, 0),
73+
Fails(EINVAL));
74+
}

0 commit comments

Comments
 (0)