Emulate brk

This commit is contained in:
jD91mZM2
2020-08-15 18:11:27 +02:00
parent 7b6ba2c73a
commit eaee4e6329
+41 -4
View File
@@ -10,9 +10,9 @@ use crate::{
fs::File,
header::{
dirent::dirent,
errno::{EINVAL, EIO, EPERM, ERANGE},
errno::{EINVAL, EIO, ENOMEM, EPERM, ERANGE},
fcntl,
sys_mman::MAP_ANON,
sys_mman::{PROT_READ, PROT_WRITE, MAP_ANONYMOUS},
sys_random,
sys_resource::{rlimit, RLIM_INFINITY},
sys_stat::stat,
@@ -28,6 +28,9 @@ use crate::{
use super::{errno, types::*, Pal, Read};
static mut BRK_CUR: *mut c_void = ptr::null_mut();
static mut BRK_END: *mut c_void = ptr::null_mut();
mod epoll;
mod extra;
mod ptrace;
@@ -95,7 +98,41 @@ impl Pal for Sys {
}
fn brk(addr: *mut c_void) -> *mut c_void {
unsafe { syscall::brk(addr as usize).unwrap_or(0) as *mut c_void }
unsafe {
// On first invocation, allocate a buffer for brk
if BRK_CUR.is_null() {
// 4 megabytes of RAM ought to be enough for anybody
const BRK_MAX_SIZE: usize = 4 * 1024 * 1024;
let allocated = Self::mmap(
ptr::null_mut(),
BRK_MAX_SIZE,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS,
0,
0,
);
if allocated == !0 as *mut c_void /* MAP_FAILED */ {
return !0 as *mut c_void;
}
BRK_CUR = allocated;
BRK_END = (allocated as *mut u8).add(BRK_MAX_SIZE) as *mut c_void;
}
if addr.is_null() {
// Lookup what previous brk() invocations have set the address to
BRK_CUR
} else if BRK_CUR <= addr && addr < BRK_END {
// It's inside buffer, return
BRK_CUR = addr;
addr
} else {
// It was outside of valid range
errno = ENOMEM;
ptr::null_mut()
}
}
}
fn chdir(path: &CStr) -> c_int {
@@ -674,7 +711,7 @@ impl Pal for Sys {
address: addr as usize,
};
if flags & MAP_ANON == MAP_ANON {
if flags & MAP_ANONYMOUS == MAP_ANONYMOUS {
let fd = e(syscall::open(
"memory:",
syscall::O_STAT | syscall::O_CLOEXEC,