Add mmap, munmap, mremap and brk syscalls

This commit is contained in:
Tate, Hongliang Tian 2018-12-15 23:44:00 +08:00
parent 852903de20
commit ea00690e68
8 changed files with 176 additions and 5 deletions

@ -17,12 +17,19 @@ extern ssize_t occlum_write(int fd, const void* buf, size_t size);
extern ssize_t occlum_readv(int fd, struct iovec* iov, int count);
extern ssize_t occlum_writev(int fd, const struct iovec* iov, int count);
extern off_t occlum_lseek(int fd, off_t offset, int whence);
extern int occlum_spawn(int* child_pid, const char* path,
const char** argv,
const char** envp);
extern int occlum_wait4(int child_pid, int* status, int options/*, struct rusage* rusage*/);
extern unsigned int occlum_getpid(void);
extern void occlum_exit(int status);
extern void *occlum_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
extern int occlum_munmap(void *addr, size_t length);
extern void *occlum_mremap(void *old_address, size_t old_size, size_t new_size, int flags, void *new_address);
extern void* occlum_brk(void* addr);
extern int occlum_unknown(int num);
#ifdef __cplusplus

@ -1,6 +1,8 @@
use prelude::*;
use {std, file, file_table, fs, process};
use {std, file, file_table, fs, process, vm};
use std::ffi::{CStr, CString};
use fs::{off_t};
use vm::{VMAreaFlags, VMResizeOptions};
// Use the internal syscall wrappers from sgx_tstd
//use std::libc_fs as fs;
//use std::libc_io as io;
@ -158,6 +160,80 @@ pub fn do_lseek(fd: c_int, offset: off_t, whence: c_int) -> Result<off_t, Error>
fs::do_lseek(fd, seek_from)
}
fn do_mmap(addr: *const c_void, size: size_t, prot: c_int,
flags: c_int, fd: c_int, offset: off_t)
-> Result<*const c_void, Error>
{
let addr = addr as usize;
let size = size as usize;
let flags = VMAreaFlags(prot as u32);
vm::do_mmap(addr, size, flags).map(|ret_addr| ret_addr as *const c_void)
}
fn do_munmap(addr: *const c_void, size: size_t) -> Result<(), Error> {
let addr = addr as usize;
let size = size as usize;
vm::do_munmap(addr, size)
}
fn do_mremap(old_addr: *const c_void, old_size: size_t,
new_size: size_t, flags: c_int, new_addr: *const c_void)
-> Result<*const c_void, Error>
{
let old_addr = old_addr as usize;
let old_size = old_size as usize;
let mut options = VMResizeOptions::new(new_size)?;
// TODO: handle flags and new_addr
vm::do_mremap(old_addr, old_size, &options)
.map(|ret_addr| ret_addr as *const c_void)
}
fn do_brk(new_brk_addr: *const c_void) -> Result<*const c_void, Error> {
let new_brk_addr = new_brk_addr as usize;
vm::do_brk(new_brk_addr).map(|ret_brk_addr| ret_brk_addr as *const c_void)
}
const MAP_FAILED : *const c_void = ((-1) as i64) as *const c_void;
#[no_mangle]
pub extern "C" fn occlum_mmap(addr: *const c_void, length: size_t, prot: c_int,
flags: c_int, fd: c_int, offset: off_t)
-> *const c_void
{
match do_mmap(addr, length, prot, flags, fd, offset) {
Ok(ret_addr) => { ret_addr },
Err(e) => { MAP_FAILED }
}
}
#[no_mangle]
pub extern "C" fn occlum_munmap(addr: *const c_void, length: size_t) -> c_int {
match do_munmap(addr, length) {
Ok(()) => { 0 },
Err(e) => { -1 }
}
}
#[no_mangle]
pub extern "C" fn occlum_mremap(old_addr: *const c_void, old_size: size_t,
new_size: size_t, flags: c_int,
new_addr: *const c_void)
-> *const c_void
{
match do_mremap(old_addr, old_size, new_size, flags, new_addr) {
Ok(ret_addr) => { ret_addr },
Err(e) => { MAP_FAILED }
}
}
#[no_mangle]
pub extern "C" fn occlum_brk(addr: *const c_void) -> *const c_void {
match do_brk(addr) {
Ok(ret_addr) => { ret_addr },
Err(e) => { MAP_FAILED }
}
}
#[no_mangle]
pub extern "C" fn occlum_open(path_buf: * const c_char, flags: c_int, mode: c_int) -> c_int {

@ -4,7 +4,7 @@
#define DECL_SYSCALL_ARG(_type, _name, _arg) \
_type _name = (_type) (_arg)
long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4) {
long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5) {
long ret = 0;
switch (num) {
@ -81,10 +81,39 @@ long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long
ret = occlum_getpid();
break;
}
case SYS_mmap: {
DECL_SYSCALL_ARG(void*, addr, arg0);
DECL_SYSCALL_ARG(size_t, length, arg1);
DECL_SYSCALL_ARG(int, prot, arg2);
DECL_SYSCALL_ARG(int, flags, arg3);
DECL_SYSCALL_ARG(int, fd, arg4);
DECL_SYSCALL_ARG(off_t, offset, arg5);
ret = (long) occlum_mmap(addr, length, prot, flags, fd, offset);
break;
}
case SYS_munmap: {
DECL_SYSCALL_ARG(void*, addr, arg0);
DECL_SYSCALL_ARG(size_t, length, arg1);
ret = occlum_munmap(addr, length);
break;
}
case SYS_mremap: {
DECL_SYSCALL_ARG(void*, old_addr, arg0);
DECL_SYSCALL_ARG(size_t, old_size, arg1);
DECL_SYSCALL_ARG(size_t, new_size, arg2);
DECL_SYSCALL_ARG(int, flags, arg3);
DECL_SYSCALL_ARG(void*, new_addr, arg4);
ret = (long) occlum_mremap(old_addr, old_size, new_size, flags, new_addr);
break;
}
case SYS_brk: {
DECL_SYSCALL_ARG(void*, addr, arg0);
ret = (long) occlum_brk(addr);
break;
}
default:
ret = occlum_unknown(num);
break;
}
return ret;
}

@ -1,5 +1,8 @@
use prelude::*;
use std::{fmt};
use file_table::{FileDesc};
use fs::{off_t};
use process::{Process, ProcessRef, get_current};
// TODO: Rename VMSpace to VMUniverse
@ -13,8 +16,43 @@ mod process_vm;
pub use self::vm_range::{VMRange, VMRangeTrait};
pub use self::process_vm::{ProcessVM};
pub const PAGE_SIZE : usize = 4096;
// TODO: separate proc and flags
// TODO: accept fd and offset
pub fn do_mmap(addr: usize, size: usize, flags: VMAreaFlags)
-> Result<usize, Error>
{
let current_ref = get_current();
let mut current_process = current_ref.lock().unwrap();
let current_vm = current_process.get_vm_mut();
current_vm.mmap(addr, size, flags)
}
pub fn do_munmap(addr: usize, size: usize) -> Result<(), Error> {
let current_ref = get_current();
let mut current_process = current_ref.lock().unwrap();
let current_vm = current_process.get_vm_mut();
current_vm.munmap(addr, size)
}
// TODO: accept flags
pub fn do_mremap(old_addr: usize, old_size: usize, options: &VMResizeOptions)
-> Result<usize, Error>
{
let current_ref = get_current();
let mut current_process = current_ref.lock().unwrap();
let current_vm = current_process.get_vm_mut();
current_vm.mremap(old_addr, old_size, options)
}
pub fn do_brk(addr: usize) -> Result<usize, Error> {
let current_ref = get_current();
let mut current_process = current_ref.lock().unwrap();
let current_vm = current_process.get_vm_mut();
current_vm.brk(addr)
}
pub const PAGE_SIZE : usize = 4096;
#[derive(Debug)]
pub struct VMSpace {

@ -145,6 +145,7 @@ impl ProcessVM {
self.get_stack_vma().get_end()
}
// TODO: override the mmaping of already mmaped range
pub fn mmap(&mut self, addr: usize, size: usize, flags: VMAreaFlags)
-> Result<usize, Error>
{

@ -1,7 +1,7 @@
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PROJECT_DIR := $(realpath $(CUR_DIR)/../)
TEST_SUITES := empty hello_world
TEST_SUITES := empty hello_world malloc
BUILD_TEST_SUITES := $(TEST_SUITES:%=%)
RUN_TEST_SUITES := $(TEST_SUITES:%=run-%)
CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%)

4
test/malloc/Makefile Normal file

@ -0,0 +1,4 @@
include ../test_common.mk
EXTRA_C_FLAGS :=
EXTRA_LINK_FLAGS :=

16
test/malloc/main.c Normal file

@ -0,0 +1,16 @@
#include <stdlib.h>
#include <stdio.h>
#define MAX_SIZE (1*1024*1024)
#define MIN_SIZE 8
int main(void) {
printf("Testing malloc and free...\n");
for (size_t buf_size = MIN_SIZE; buf_size <= MAX_SIZE; buf_size *= 4) {
printf("buf_size = %lu\n", buf_size);
void* buf = malloc(buf_size);
free(buf);
}
printf("Done.\n");
return 0;
}