Ticket #15804: mem.cpp

File mem.cpp, 3.0 KB (added by KapiX, 4 years ago)

Reproducer

Line 
1// build cmd: g++ -I "/boot/system/develop/headers/private/system" -I "/boot/system/develop/headers/private/system/arch/x86_64" mem.cpp -o mem
2
3#include <errno.h>
4#include <sys/mman.h>
5#include <stdio.h>
6#include <string.h>
7
8#include <OS.h>
9#include <syscalls.h>
10
11#define CRASH() debugger("crash")
12#define UNUSED_PARAM(x) x;
13
14void* reserveUncommitted(size_t bytes, bool writable, bool executable, bool includesGuardPages)
15{
16 UNUSED_PARAM(writable);
17 UNUSED_PARAM(executable);
18
19 addr_t result = 0;
20 if (_kern_reserve_address_range(&result, B_ANY_ADDRESS, bytes) != B_OK) {
21 fprintf(stderr, "reserveUncommitted: %p, %zu bytes, %s\n", (void*)result, bytes, strerror(errno));
22 return NULL;
23 }
24 fprintf(stderr, "reserveUncommitted: %p, %zu bytes, %s\n", (void*)result, bytes, strerror(errno));
25 return (void*)result;
26}
27
28void* reserveAndCommit(size_t bytes, bool writable, bool executable, bool includesGuardPages)
29{
30 // All POSIX reservations start out logically committed.
31 int protection = PROT_READ;
32 if (writable)
33 protection |= PROT_WRITE;
34 if (executable)
35 protection |= PROT_EXEC;
36
37 int flags = MAP_PRIVATE | MAP_ANON;
38 int fd = -1;
39
40 void* result = 0;
41
42 result = mmap(result, bytes, protection, flags, fd, 0);
43 if (result == MAP_FAILED) {
44 if (executable)
45 result = 0;
46 else
47 CRASH();
48 }
49 return result;
50}
51
52void commit(void* address, size_t bytes, bool writable, bool executable)
53{
54 int protection = PROT_READ;
55 if (writable)
56 protection |= PROT_WRITE;
57 if (executable)
58 protection |= PROT_EXEC;
59
60 int flags = MAP_PRIVATE | MAP_ANON | MAP_FIXED;
61
62 void* effective = mmap(address, bytes, protection, flags, -1, 0);
63 fprintf(stderr, "commit: %zu bytes %p %p: %s\n", bytes, address, effective, strerror(errno));
64 if (effective != address) {
65 if(errno == EINVAL) {
66 int result = munmap(address, bytes);
67 fprintf(stderr, "commit unmap %d\n", result);
68 effective = mmap(address, bytes, protection, flags, -1, 0);
69 fprintf(stderr, "commit again: %zu bytes %p %p: %s\n", bytes, address, effective, strerror(errno));
70 if(effective == address) {
71 return;
72 }
73 }
74 CRASH();
75 }
76}
77
78void decommit(void* address, size_t bytes)
79{
80 int result = munmap(address, bytes);
81 fprintf(stderr, "decommit: %zu bytes %p %d: %s\n", bytes, address, result, strerror(errno));
82 if (result == -1)
83 CRASH();
84}
85
86void releaseDecommitted(void* address, size_t bytes)
87{
88 int result = _kern_unreserve_address_range((addr_t)address, bytes);
89 fprintf(stderr, "releaseDecommitted: %zu bytes %p %d: %s\n", bytes, address, result, strerror(errno));
90 if (result != B_OK)
91 CRASH();
92}
93
94int main(int argc, char** argv)
95{
96 void* address = reserveUncommitted(4096*4, false, false, false);
97 commit(address, 4096*2, false, false);
98 //decommit(address, 4096*2);
99 commit(address, 4096*3, false, false);
100 return 0;
101}