From 1a913f6bf2ac33426f889900b75afa471cc4cee5 Mon Sep 17 00:00:00 2001 From: MovingtoMars Date: Thu, 28 Jan 2016 12:39:02 +1300 Subject: [PATCH] simple malloc and free using mmap --- CMakeLists.txt | 1 + std/mem.zig | 21 +++++++++++++++++++++ std/syscall.zig | 36 ++++++++++++++++++++++++++++++++++++ test/run_tests.cpp | 18 ++++++++++++++++++ 4 files changed, 76 insertions(+) create mode 100644 std/mem.zig diff --git a/CMakeLists.txt b/CMakeLists.txt index a745cf1fa..5e06248ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,7 @@ set(ZIG_STD_SRC "${CMAKE_SOURCE_DIR}/std/syscall.zig" "${CMAKE_SOURCE_DIR}/std/errno.zig" "${CMAKE_SOURCE_DIR}/std/rand.zig" + "${CMAKE_SOURCE_DIR}/std/mem.zig" ) set(C_HEADERS_DEST "lib/zig/include") diff --git a/std/mem.zig b/std/mem.zig new file mode 100644 index 000000000..d19dad9f9 --- /dev/null +++ b/std/mem.zig @@ -0,0 +1,21 @@ +import "syscall.zig"; +import "std.zig"; + +pub fn malloc(bytes: isize) -> ?&u8 { + if (bytes > 4096) { + %%stderr.printf("TODO alloc sizes > 4096B\n"); + return null; + } + + const result = mmap(0, 4096, MMAP_PROT_READ|MMAP_PROT_WRITE, MMAP_MAP_ANON|MMAP_MAP_SHARED, -1, 0); + + if (result == -1) { + return null; + } + + (&u8)(result) +} + +pub fn free(ptr: &u8) { + munmap(isize(ptr), 4096); +} diff --git a/std/syscall.zig b/std/syscall.zig index eeabd2a51..504f785fe 100644 --- a/std/syscall.zig +++ b/std/syscall.zig @@ -1,8 +1,22 @@ const SYS_read = 0; const SYS_write = 1; +const SYS_mmap = 9; +const SYS_munmap = 11; const SYS_exit = 60; const SYS_getrandom = 318; +// mmap constants +pub const MMAP_PROT_NONE = 0; +pub const MMAP_PROT_READ = 1; +pub const MMAP_PROT_WRITE = 2; +pub const MMAP_PROT_EXEC = 4; + +pub const MMAP_MAP_FILE = 0; +pub const MMAP_MAP_SHARED = 1; +pub const MMAP_MAP_PRIVATE = 2; +pub const MMAP_MAP_FIXED = 16; +pub const MMAP_MAP_ANON = 32; + fn syscall1(number: isize, arg1: isize) -> isize { asm volatile ("syscall" : [ret] "={rax}" (-> isize) @@ -17,6 +31,28 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize { : "rcx", "r11") } +fn syscall2(number: isize, arg1: isize, arg2: isize) -> isize { + asm volatile ("syscall" + : [ret] "={rax}" (-> isize) + : [number] "{rax}" (number), [arg1] "{rdi}" (arg1), [arg2] "{rsi}" (arg2) + : "rcx", "r11") +} + +fn syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize { + asm volatile ("syscall" + : [ret] "={rax}" (-> isize) + : [number] "{rax}" (number), [arg1] "{rdi}" (arg1), [arg2] "{rsi}" (arg2), [arg3] "{rdx}" (arg3), [arg4] "{r10}" (arg4), [arg5] "{r8}" (arg5), [arg6] "{r9}" (arg6) + : "rcx", "r11") +} + +pub fn mmap(address: isize, length: isize, prot: isize, flags: isize, fd: isize, offset: isize) -> isize { + syscall6(SYS_mmap, address, length, prot, flags, fd, offset) +} + +pub fn munmap(address: isize, length: isize) -> isize { + syscall2(SYS_munmap, address, length) +} + pub fn read(fd: isize, buf: &u8, count: isize) -> isize { syscall3(SYS_read, isize(fd), isize(buf), count) } diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 2b80832e8..73478c6b5 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -1344,6 +1344,24 @@ pub fn main(args: [][]u8) -> %void { %%stdout.printf("BAD\n"); } %%stdout.printf("OK\n"); +} + )SOURCE", "OK\n"); + + add_simple_case("malloc and free", R"SOURCE( +import "mem.zig"; +import "std.zig"; + +pub fn main(args: [][]u8) -> %void { + var ptr = malloc(1) ?? unreachable{}; + + *ptr = 6; + + if (*ptr != 6) { + %%stdout.printf("BAD\n"); + } + %%stdout.printf("OK\n"); + + free(ptr); } )SOURCE", "OK\n"); }