11
11
#include " src/sys/mman/mincore.h"
12
12
#include " src/sys/mman/mmap.h"
13
13
#include " src/sys/mman/munmap.h"
14
+ #include " src/unistd/sysconf.h"
14
15
#include " test/UnitTest/ErrnoSetterMatcher.h"
15
16
#include " test/UnitTest/LibcTest.h"
16
17
#include " test/UnitTest/Test.h"
17
18
18
- #include < linux/param.h> // For EXEC_PAGESIZE
19
19
#include < sys/mman.h>
20
+ #include < unistd.h> // For sysconf.
20
21
21
22
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
22
23
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
@@ -28,88 +29,105 @@ TEST(LlvmLibcMincoreTest, UnMappedMemory) {
28
29
EXPECT_THAT (res, Fails (ENOMEM, -1 ));
29
30
}
30
31
32
+ // It is always possible to find an aligned boundary if we allocate page sized
33
+ // memory.
34
+ static char *aligned_addr (void *addr, size_t alignment) {
35
+ char *byte_addr = static_cast <char *>(addr);
36
+ uintptr_t addr_val = reinterpret_cast <uintptr_t >(addr);
37
+ uintptr_t offset =
38
+ addr_val % alignment == 0 ? 0 : alignment - (addr_val % alignment);
39
+ return byte_addr + offset;
40
+ }
41
+
31
42
TEST (LlvmLibcMincoreTest, InvalidVec) {
32
- void *addr = LIBC_NAMESPACE::mmap (nullptr , 4 * EXEC_PAGESIZE, PROT_READ,
43
+ size_t page_size = static_cast <size_t >(LIBC_NAMESPACE::sysconf (_SC_PAGESIZE));
44
+ void *addr = LIBC_NAMESPACE::mmap (nullptr , 5 * page_size, PROT_READ,
33
45
MAP_ANONYMOUS | MAP_PRIVATE, -1 , 0 );
34
46
EXPECT_NE (addr, MAP_FAILED);
35
- EXPECT_EQ (reinterpret_cast <unsigned long >(addr) % EXEC_PAGESIZE, 0ul );
47
+ // Since we allocated 5 pages, we can find an aligned boundary after which
48
+ // there are at least 4 pages
49
+ char *aligned = aligned_addr (addr, page_size);
36
50
libc_errno = 0 ;
37
- int res = LIBC_NAMESPACE::mincore (addr , 1 , nullptr );
51
+ int res = LIBC_NAMESPACE::mincore (aligned , 1 , nullptr );
38
52
EXPECT_THAT (res, Fails (EFAULT, -1 ));
39
- void *area =
40
- LIBC_NAMESPACE::mmap (nullptr , EXEC_PAGESIZE, PROT_READ | PROT_WRITE,
41
- MAP_ANONYMOUS | MAP_PRIVATE, -1 , 0 );
53
+ void *area = LIBC_NAMESPACE::mmap (nullptr , page_size, PROT_READ | PROT_WRITE,
54
+ MAP_ANONYMOUS | MAP_PRIVATE, -1 , 0 );
42
55
EXPECT_NE (area, MAP_FAILED);
43
- unsigned char *ptr = static_cast <unsigned char *>(area) + EXEC_PAGESIZE - 3 ;
44
- res = LIBC_NAMESPACE::mincore (addr , 4 * EXEC_PAGESIZE , ptr);
56
+ unsigned char *ptr = static_cast <unsigned char *>(area) + page_size - 3 ;
57
+ res = LIBC_NAMESPACE::mincore (aligned , 4 * page_size , ptr);
45
58
EXPECT_THAT (res, Fails (EFAULT, -1 ));
46
- EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, EXEC_PAGESIZE ), Succeeds ());
47
- EXPECT_THAT (LIBC_NAMESPACE::munmap (area, 2 ), Succeeds ());
59
+ EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, 5 * page_size ), Succeeds ());
60
+ EXPECT_THAT (LIBC_NAMESPACE::munmap (area, page_size ), Succeeds ());
48
61
}
49
62
50
63
TEST (LlvmLibcMincoreTest, UnalignedAddr) {
51
- void *addr = LIBC_NAMESPACE::mmap (nullptr , EXEC_PAGESIZE, PROT_READ,
64
+ size_t page_size = static_cast <size_t >(LIBC_NAMESPACE::sysconf (_SC_PAGESIZE));
65
+ void *addr = LIBC_NAMESPACE::mmap (nullptr , page_size, PROT_READ,
52
66
MAP_ANONYMOUS | MAP_PRIVATE, -1 , 0 );
53
67
EXPECT_NE (addr, MAP_FAILED);
54
- EXPECT_EQ ( reinterpret_cast < unsigned long >(addr) % EXEC_PAGESIZE, 0ul );
68
+ char *aligned = aligned_addr (addr, page_size );
55
69
libc_errno = 0 ;
56
- int res = LIBC_NAMESPACE::mincore (static_cast < char *>(addr) + 1 , 1 , nullptr );
70
+ int res = LIBC_NAMESPACE::mincore (aligned + 1 , 1 , nullptr );
57
71
EXPECT_THAT (res, Fails (EINVAL, -1 ));
58
- EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, EXEC_PAGESIZE ), Succeeds ());
72
+ EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, page_size ), Succeeds ());
59
73
}
60
74
61
75
TEST (LlvmLibcMincoreTest, NoError) {
62
- void *addr = LIBC_NAMESPACE::mmap (nullptr , EXEC_PAGESIZE, PROT_READ,
76
+ size_t page_size = static_cast <size_t >(LIBC_NAMESPACE::sysconf (_SC_PAGESIZE));
77
+ void *addr = LIBC_NAMESPACE::mmap (nullptr , page_size, PROT_READ,
63
78
MAP_ANONYMOUS | MAP_PRIVATE, -1 , 0 );
64
79
EXPECT_NE (addr, MAP_FAILED);
65
- EXPECT_EQ ( reinterpret_cast < unsigned long >(addr) % EXEC_PAGESIZE, 0ul );
80
+ char *aligned = aligned_addr (addr, page_size );
66
81
unsigned char vec;
67
82
libc_errno = 0 ;
68
- int res = LIBC_NAMESPACE::mincore (addr , 1 , &vec);
83
+ int res = LIBC_NAMESPACE::mincore (aligned , 1 , &vec);
69
84
EXPECT_THAT (res, Succeeds ());
70
- EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, EXEC_PAGESIZE ), Succeeds ());
85
+ EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, page_size ), Succeeds ());
71
86
}
72
87
73
88
TEST (LlvmLibcMincoreTest, NegativeLength) {
74
- void *addr = LIBC_NAMESPACE::mmap (nullptr , EXEC_PAGESIZE, PROT_READ,
89
+ size_t page_size = static_cast <size_t >(LIBC_NAMESPACE::sysconf (_SC_PAGESIZE));
90
+ void *addr = LIBC_NAMESPACE::mmap (nullptr , page_size, PROT_READ,
75
91
MAP_ANONYMOUS | MAP_PRIVATE, -1 , 0 );
76
92
EXPECT_NE (addr, MAP_FAILED);
77
- EXPECT_EQ ( reinterpret_cast < unsigned long >(addr) % EXEC_PAGESIZE, 0ul );
93
+ char *aligned = aligned_addr (addr, page_size );
78
94
unsigned char vec;
79
95
libc_errno = 0 ;
80
- int res = LIBC_NAMESPACE::mincore (addr , -1 , &vec);
96
+ int res = LIBC_NAMESPACE::mincore (aligned , -1 , &vec);
81
97
EXPECT_THAT (res, Fails (ENOMEM, -1 ));
82
- EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, EXEC_PAGESIZE ), Succeeds ());
98
+ EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, page_size ), Succeeds ());
83
99
}
84
100
85
101
TEST (LlvmLibcMincoreTest, PageOut) {
86
102
unsigned char vec;
103
+ size_t page_size = static_cast <size_t >(LIBC_NAMESPACE::sysconf (_SC_PAGESIZE));
104
+ // allocate 2 pages since we need to page out page_size bytes
87
105
void *addr =
88
- LIBC_NAMESPACE::mmap (nullptr , EXEC_PAGESIZE , PROT_READ | PROT_WRITE,
106
+ LIBC_NAMESPACE::mmap (nullptr , 2 * page_size , PROT_READ | PROT_WRITE,
89
107
MAP_ANONYMOUS | MAP_PRIVATE, -1 , 0 );
90
108
EXPECT_NE (addr, MAP_FAILED);
91
- EXPECT_EQ ( reinterpret_cast < unsigned long >(addr) % EXEC_PAGESIZE, 0ul );
109
+ char *aligned = aligned_addr (addr, page_size );
92
110
93
111
// touch the page
94
112
{
95
- static_cast < char *>(addr) [0 ] = 0 ;
113
+ aligned [0 ] = 0 ;
96
114
libc_errno = 0 ;
97
- int res = LIBC_NAMESPACE::mincore (addr , 1 , &vec);
115
+ int res = LIBC_NAMESPACE::mincore (aligned , 1 , &vec);
98
116
EXPECT_EQ (vec & 1u , 1u );
99
117
EXPECT_THAT (res, Succeeds ());
100
118
}
101
119
102
120
// page out the memory
103
121
{
104
122
libc_errno = 0 ;
105
- EXPECT_THAT (LIBC_NAMESPACE::madvise (addr, EXEC_PAGESIZE , MADV_DONTNEED),
123
+ EXPECT_THAT (LIBC_NAMESPACE::madvise (aligned, page_size , MADV_DONTNEED),
106
124
Succeeds ());
107
125
108
126
libc_errno = 0 ;
109
- int res = LIBC_NAMESPACE::mincore (addr, EXEC_PAGESIZE , &vec);
127
+ int res = LIBC_NAMESPACE::mincore (aligned, 1 , &vec);
110
128
EXPECT_EQ (vec & 1u , 0u );
111
129
EXPECT_THAT (res, Succeeds ());
112
130
}
113
131
114
- EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, EXEC_PAGESIZE ), Succeeds ());
132
+ EXPECT_THAT (LIBC_NAMESPACE::munmap (addr, 2 * page_size ), Succeeds ());
115
133
}
0 commit comments