| author | |
| committer | |
| log | e3cc0c25718e8ff580eabce35ba845e968c74e1a |
| tree | 2eb23012fd738a6b88a68f61557985f0a907c0d4 |
| parent | d1ac1abd34318273b746763a1ce5f3055bba541c |
| parent | 401a3361ea13e7b8e063cbad29d3c0d7cc0f86a9 |
simple malloc and free using mmap4 files changed, 77 insertions(+), 0 deletions(-)
CMakeLists.txt+1| ... | @@ -123,6 +123,7 @@ set(ZIG_STD_SRC | ... | @@ -123,6 +123,7 @@ set(ZIG_STD_SRC |
| 123 | "${CMAKE_SOURCE_DIR}/std/syscall.zig" | 123 | "${CMAKE_SOURCE_DIR}/std/syscall.zig" |
| 124 | "${CMAKE_SOURCE_DIR}/std/errno.zig" | 124 | "${CMAKE_SOURCE_DIR}/std/errno.zig" |
| 125 | "${CMAKE_SOURCE_DIR}/std/rand.zig" | 125 | "${CMAKE_SOURCE_DIR}/std/rand.zig" |
| 126 | "${CMAKE_SOURCE_DIR}/std/mem.zig" | ||
| 126 | ) | 127 | ) |
| 127 | 128 | ||
| 128 | set(C_HEADERS_DEST "lib/zig/include") | 129 | set(C_HEADERS_DEST "lib/zig/include") |
std/mem.zig created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | import "syscall.zig"; | ||
| 2 | import "std.zig"; | ||
| 3 | import "errno.zig"; | ||
| 4 | |||
| 5 | pub fn malloc(bytes: isize) -> ?&u8 { | ||
| 6 | if (bytes > 4096) { | ||
| 7 | %%stderr.printf("TODO alloc sizes > 4096B\n"); | ||
| 8 | return null; | ||
| 9 | } | ||
| 10 | |||
| 11 | const result = mmap(isize(0), 4096, MMAP_PROT_READ|MMAP_PROT_WRITE, MMAP_MAP_ANON|MMAP_MAP_SHARED, -1, 0); | ||
| 12 | |||
| 13 | if (-4096 < result && result <= 0) { | ||
| 14 | null | ||
| 15 | } else { | ||
| 16 | (&u8)(result) | ||
| 17 | } | ||
| 18 | } | ||
| 19 | |||
| 20 | pub fn free(ptr: &u8) { | ||
| 21 | munmap(isize(ptr), 4096); | ||
| 22 | } | ||
std/syscall.zig+36| ... | @@ -1,8 +1,22 @@ | ... | @@ -1,8 +1,22 @@ |
| 1 | const SYS_read = 0; | 1 | const SYS_read = 0; |
| 2 | const SYS_write = 1; | 2 | const SYS_write = 1; |
| 3 | const SYS_mmap = 9; | ||
| 4 | const SYS_munmap = 11; | ||
| 3 | const SYS_exit = 60; | 5 | const SYS_exit = 60; |
| 4 | const SYS_getrandom = 318; | 6 | const SYS_getrandom = 318; |
| 5 | 7 | ||
| 8 | // mmap constants | ||
| 9 | pub const MMAP_PROT_NONE = 0; | ||
| 10 | pub const MMAP_PROT_READ = 1; | ||
| 11 | pub const MMAP_PROT_WRITE = 2; | ||
| 12 | pub const MMAP_PROT_EXEC = 4; | ||
| 13 | |||
| 14 | pub const MMAP_MAP_FILE = 0; | ||
| 15 | pub const MMAP_MAP_SHARED = 1; | ||
| 16 | pub const MMAP_MAP_PRIVATE = 2; | ||
| 17 | pub const MMAP_MAP_FIXED = 16; | ||
| 18 | pub const MMAP_MAP_ANON = 32; | ||
| 19 | |||
| 6 | fn syscall1(number: isize, arg1: isize) -> isize { | 20 | fn syscall1(number: isize, arg1: isize) -> isize { |
| 7 | asm volatile ("syscall" | 21 | asm volatile ("syscall" |
| 8 | : [ret] "={rax}" (-> isize) | 22 | : [ret] "={rax}" (-> isize) |
| ... | @@ -17,6 +31,28 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize { | ... | @@ -17,6 +31,28 @@ fn syscall3(number: isize, arg1: isize, arg2: isize, arg3: isize) -> isize { |
| 17 | : "rcx", "r11") | 31 | : "rcx", "r11") |
| 18 | } | 32 | } |
| 19 | 33 | ||
| 34 | fn syscall2(number: isize, arg1: isize, arg2: isize) -> isize { | ||
| 35 | asm volatile ("syscall" | ||
| 36 | : [ret] "={rax}" (-> isize) | ||
| 37 | : [number] "{rax}" (number), [arg1] "{rdi}" (arg1), [arg2] "{rsi}" (arg2) | ||
| 38 | : "rcx", "r11") | ||
| 39 | } | ||
| 40 | |||
| 41 | fn syscall6(number: isize, arg1: isize, arg2: isize, arg3: isize, arg4: isize, arg5: isize, arg6: isize) -> isize { | ||
| 42 | asm volatile ("syscall" | ||
| 43 | : [ret] "={rax}" (-> isize) | ||
| 44 | : [number] "{rax}" (number), [arg1] "{rdi}" (arg1), [arg2] "{rsi}" (arg2), [arg3] "{rdx}" (arg3), [arg4] "{r10}" (arg4), [arg5] "{r8}" (arg5), [arg6] "{r9}" (arg6) | ||
| 45 | : "rcx", "r11") | ||
| 46 | } | ||
| 47 | |||
| 48 | pub fn mmap(address: isize, length: isize, prot: isize, flags: isize, fd: isize, offset: isize) -> isize { | ||
| 49 | syscall6(SYS_mmap, address, length, prot, flags, fd, offset) | ||
| 50 | } | ||
| 51 | |||
| 52 | pub fn munmap(address: isize, length: isize) -> isize { | ||
| 53 | syscall2(SYS_munmap, address, length) | ||
| 54 | } | ||
| 55 | |||
| 20 | pub fn read(fd: isize, buf: &u8, count: isize) -> isize { | 56 | pub fn read(fd: isize, buf: &u8, count: isize) -> isize { |
| 21 | syscall3(SYS_read, isize(fd), isize(buf), count) | 57 | syscall3(SYS_read, isize(fd), isize(buf), count) |
| 22 | } | 58 | } |
test/run_tests.cpp+18| ... | @@ -1344,6 +1344,24 @@ pub fn main(args: [][]u8) -> %void { | ... | @@ -1344,6 +1344,24 @@ pub fn main(args: [][]u8) -> %void { |
| 1344 | %%stdout.printf("BAD\n"); | 1344 | %%stdout.printf("BAD\n"); |
| 1345 | } | 1345 | } |
| 1346 | %%stdout.printf("OK\n"); | 1346 | %%stdout.printf("OK\n"); |
| 1347 | } | ||
| 1348 | )SOURCE", "OK\n"); | ||
| 1349 | |||
| 1350 | add_simple_case("malloc and free", R"SOURCE( | ||
| 1351 | import "mem.zig"; | ||
| 1352 | import "std.zig"; | ||
| 1353 | |||
| 1354 | pub fn main(args: [][]u8) -> %void { | ||
| 1355 | var ptr = malloc(1) ?? unreachable{}; | ||
| 1356 | |||
| 1357 | *ptr = 6; | ||
| 1358 | |||
| 1359 | if (*ptr != 6) { | ||
| 1360 | %%stdout.printf("BAD\n"); | ||
| 1361 | } | ||
| 1362 | %%stdout.printf("OK\n"); | ||
| 1363 | |||
| 1364 | free(ptr); | ||
| 1347 | } | 1365 | } |
| 1348 | )SOURCE", "OK\n"); | 1366 | )SOURCE", "OK\n"); |
| 1349 | } | 1367 | } |