Index: arch/posix/errnos ================================================================== --- arch/posix/errnos +++ arch/posix/errnos @@ -7,5 +7,11 @@ EIO EAGAIN EFBIG EINTR EDESTADDRREQ +EACCES +EMFILE +ENODEV +ENOMEM +ENXIO +EOVERFLOW Index: build.sh ================================================================== --- build.sh +++ build.sh @@ -148,11 +148,11 @@ fi fi if test "$debug" = yes; then local dflag="-g dwarf2" fi - report $asm $flags $dflag "-f$bin_fmt" -i "$gen" "$src" -o "$output"; + report $asm $flags $dflag "-f$bin_fmt" -i "$gen" -i "$PWD" "$src" -o "$output"; } comp_co() { comp_c $1 $2 "-c -fPIC"; } comp_c(){ local src=$1 local output=$2 Index: global/common.sh ================================================================== --- global/common.sh +++ global/common.sh @@ -59,6 +59,14 @@ # the following function is called to report a command invocation # the person compiling the library. the first argument should be # an ansi format string; this is used to color-code the tool being # launched and thus should be different for each one. -report() { announce $@; $@; } +report() { + announce $@; $@; + status=$? + if test $status -ne 0; then + args=($@) + say "process ${args[0]} failed with status code $status" + exit $status + fi +} Index: mod/kcore/syscall.fn.x86.lin.64.s ================================================================== --- mod/kcore/syscall.fn.x86.lin.64.s +++ mod/kcore/syscall.fn.x86.lin.64.s @@ -9,17 +9,17 @@ ; ; void k_platform_syscall_raw(s64* result, u64* errno, ; syscall, u8 valency, s64[] args) bits 64 -%include "../arch/posix/x86.lin.64.s" -%include "../arch/x86.cdecl.64.s" +%include "arch/posix/x86.lin.64.s" +%include "arch/x86.cdecl.64.s" ; vim: ft=nasm %macro handle_arg 1 %assign v %1+1 - mov sys.reg. %+ v, [ccall.reg.4 + 8 * %1] + mov sys.reg. %+ v, [r15 + 8 * %1] dec ccall.reg.3 jz .perform_call %endmacro global k_platform_syscall_raw:function @@ -40,10 +40,17 @@ mov r12, ccall.reg.1 ; this needs to go before the loop ; or it'll get clobbered mov sys.reg.0, ccall.reg.2 + + ; the fourth argument is in %r8, which + ; is also a syscall register, so we + ; need to move it to a safe register + ; to keep it from getting clobbered + ; before we begin the "loop" + mov r15, ccall.reg.4 ; automatically generate the code ; needed to move the arguments into ; their correct registers. see above %assign i 0 Index: mod/kcore/testbin.exe.c ================================================================== --- mod/kcore/testbin.exe.c +++ mod/kcore/testbin.exe.c @@ -20,14 +20,15 @@ /* great, continue */ } else { return kbad_io; } - void* region = kmheapa(2048); - if (region == null) return kbad_mem; + void* region; + kmcond alloc = kmheapa(®ion, 2048); + if (alloc != kmcond_ok) return kbad_mem; kmzero(region,2048); if (kmheapf(region) >= kmcond_fail) return kbad_mem; return kbad_ok; } Index: mod/kmem/heapa.fn.c ================================================================== --- mod/kmem/heapa.fn.c +++ mod/kmem/heapa.fn.c @@ -10,20 +10,22 @@ /* arch specific headers */ #ifdef KFenv_posix # include #endif + +#include /* we define all our platform functions here, whether or not * they're for the correct platform - only the ones that are * called by the preprocessed form of the code will actually * be linked, linker errors are our friend here! */ extern void* kmem_platform_mmap(void* addr, unsigned long sz, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off); -void* kmheapa(sz len) { +kmcond kmheapa(void** where, sz len) { /* allocate an object on the heap and return * a pointer, or NULL if the allocation failed. */ union { void* raw; ubyte* byte; @@ -51,20 +53,38 @@ * that information in the region that we are mapping. * the user will receive an adjusted pointer that can * be adjusted to point a field of type size_t that * contains the size of the allocated space.*/ - region.byte = kmem_platform_mmap(null, region_size, - posix_prot_read | posix_prot_write, - posix_flag_anonymous | posix_map_shared, -1, 0); + k_platform_syscall_arg args[] = { + null, region_size, + posix_prot_read | posix_prot_write, + posix_flag_anonymous | posix_map_shared, + -1, 0 + }; + + struct k_platform_syscall_answer r = k_platform_syscall + (k_platform_syscall_mmap, Kmsz(args), args); + + if (r.error == 0) region.byte = (ubyte*)r.ret; else { + switch (r.error) { + case k_platform_error_EAGAIN: return kmcond_bad_lock; + case k_platform_error_EINVAL: return kmcond_bad_size; + case k_platform_error_EMFILE: return kmcond_too_many; + case k_platform_error_ENOMEM: return kmcond_no_room; + default: return kmcond_fail_assert; + } + } + + /* region.byte = kmem_platform_mmap(null, region_size, */ + /* posix_prot_read | posix_prot_write, */ + /* posix_flag_anonymous | posix_map_shared, -1, 0); */ + /* impl note: while per manpage fd is "ignored" * for MAP_ANONYMOUS, "some implementations" require * a value of -1 */ - if (region.raw == (void*) -1) return null; - /* worth retrieving errno? discuss */ - # else Knoimpl(kmheapa,KVos); # error missing implementation # endif @@ -71,7 +91,8 @@ void* const object = (region.byte + sizeof (kmbox)); region.header -> kind = kmkind_heap; region.header -> size = len; - return object; + *where = object; + return kmcond_ok; } Index: mod/kmem/heapao.fn.c ================================================================== --- mod/kmem/heapao.fn.c +++ mod/kmem/heapao.fn.c @@ -5,13 +5,17 @@ * kmheapao() allocates a region in heap memory * and returns a kmptr struct referencing that * newly allocated region. */ -kmptr kmheapao(sz size) { - void* ptr = kmheapa(size); +kmcond kmheapao(kmptr* where, sz size) { + void* ptr; + kmcond e = kmheapa(&ptr, size); + if (e != kmcond_ok) return e; kmptr p = { .kind = (ptr != null ? kmkind_heap : kmkind_fail), .ref = ptr, .shred = false, - }; return p; + }; + *where = p; + return kmcond_ok; } Index: mod/kmem/mem.h ================================================================== --- mod/kmem/mem.h +++ mod/kmem/mem.h @@ -1,8 +1,9 @@ #ifndef KImem #define KImem #include +#include #ifndef KFclean # define Kmsz(e) ( sizeof (e) / sizeof (e) [0] ) #endif @@ -9,17 +10,25 @@ #ifdef __cplusplus extern "C" { #endif typedef enum kmcond { - kmcond_ok, + kmcond_ok = kmcond_id, kmcond_unnecessary, kmcond_fail, kmcond_unhandled, kmcond_mismatch, kmcond_bad_address, + kmcond_bad_lock, + kmcond_bad_size, + kmcond_no_room, + kmcond_too_many, + + /* when something truly should + * never happen: */ + kmcond_fail_assert, } kmcond; typedef enum kmkind { kmkind_none, kmkind_fail, @@ -61,13 +70,13 @@ void* ref; } kmptr; /* heap functions */ -void* kmheapa(sz); -kmptr kmheapao(sz); -kmcond kmheapf(void*); +kmcond kmheapa (void**, sz); +kmcond kmheapao(kmptr*, sz); +kmcond kmheapf (void*); /* generic functions */ kmcond kmfree(kmptr); kmkind kmtell(void*);