riscv-pk
riscv-pk copied to clipboard
mmap affects sbrk
Hi there,
I was reading mmap code here, and I found that mmap actually uses __vm_alloc
when MAP_FIXED
is not used. However __vm_alloc
would search for pages starting at current.brk, the result of this, is that mmap calls would affect brk_max
, which then limits the size of memory brk
can change.
So the following program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <malloc.h>
#include <machine/syscall.h>
#define PAGE_SIZE (1 << 12)
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#define MAP_PRIVATE 0x2
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_POPULATE 0x8000
uintptr_t mmap(uintptr_t addr, size_t length, int prot, int flags, int fd, off_t offset)
{
return syscall_errno(222, addr, length, prot, flags, fd, offset);
}
size_t brk(size_t pos)
{
return syscall_errno(214, pos, 0, 0, 0, 0, 0);
}
int main(int argc, char *argv[]) {
size_t initial_brk = brk(0);
printf("Initial brk: 0x%08X\n", initial_brk);
void *buf = malloc(1000);
printf("Malloc result: 0x%08X\n", (uintptr_t) buf);
void *ptr = (void *) mmap(0, 1000, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
printf("mmap result: 0x%08X\n", ptr);
buf = malloc(1000);
printf("Malloc result: 0x%08X\n", (uintptr_t) buf);
buf = malloc(1000);
printf("Malloc result: 0x%08X\n", (uintptr_t) buf);
buf = malloc(1000);
printf("Malloc result: 0x%08X\n", (uintptr_t) buf);
buf = malloc(1000);
printf("Malloc result: 0x%08X\n", (uintptr_t) buf);
return 0;
}
Would generate the following result:
Initial brk: 0x0001DFF8
Malloc result: 0x0001E408
mmap result: 0x0001F000
Malloc result: 0x0001E7F8
Malloc result: 0x0001EBE8
Malloc result: 0x00000000
Malloc result: 0x00000000
I'm testing this on rv32imac target but I think the result is the similar across all targets. My question is: is this expected behavior? Does this mean we have to be extra cautious when using mmap?