Skip to content

Commit 7528b13

Browse files
authored
Extend wasi-emulated-mman with mprotect. (#500)
This implementation never changes actual memory protection, but it does verify that the address range and flags are valid. The direct motivation is fixing a linker error where LLVM links to `mprotect` in dead code.
1 parent 44c4b1e commit 7528b13

4 files changed

Lines changed: 36 additions & 0 deletions

File tree

expected/wasm32-wasip1-threads/defined-symbols.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ mmap
928928
modf
929929
modff
930930
modfl
931+
mprotect
931932
mrand48
932933
munmap
933934
nan

expected/wasm32-wasip1/defined-symbols.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,7 @@ mmap
861861
modf
862862
modff
863863
modfl
864+
mprotect
864865
mrand48
865866
munmap
866867
nan

expected/wasm32-wasip2/defined-symbols.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ monotonic_clock_now
980980
monotonic_clock_resolution
981981
monotonic_clock_subscribe_duration
982982
monotonic_clock_subscribe_instant
983+
mprotect
983984
mrand48
984985
munmap
985986
nan

libc-bottom-half/mman/mman.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <errno.h>
1010
#include <unistd.h>
1111
#include <string.h>
12+
#include <limits.h>
1213
#include <sys/mman.h>
1314
#include <sys/types.h>
1415

@@ -122,3 +123,35 @@ int munmap(void *addr, size_t length) {
122123
// Success!
123124
return 0;
124125
}
126+
127+
int mprotect(void *addr, size_t length, int prot) {
128+
// Address must be page-aligned.
129+
size_t begin = (size_t)addr;
130+
if ((begin & (PAGESIZE - 1)) != 0) {
131+
errno = EINVAL;
132+
return -1;
133+
}
134+
135+
// Length must not be big enough to wrap around.
136+
size_t end;
137+
if (__builtin_add_overflow(begin, length, &end)) {
138+
errno = ENOMEM;
139+
return -1;
140+
}
141+
142+
// Range must be in bounds of linear memory.
143+
size_t memory_size = __builtin_wasm_memory_size(0) * PAGESIZE;
144+
if (end > memory_size) {
145+
errno = ENOMEM;
146+
return -1;
147+
}
148+
149+
// Can only protect memory as read/write (which is a no-op).
150+
if (prot != (PROT_READ | PROT_WRITE)) {
151+
errno = ENOTSUP;
152+
return -1;
153+
}
154+
155+
// Success!
156+
return 0;
157+
}

0 commit comments

Comments
 (0)