Comment: | revamp arch/ makefile, add generic syscall fn on posix, rewrite kiosend() to use k_platform_syscall instead of k_platform_write |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
37b0cfaa06fd213a266dd24f1a6b482a |
User & Date: | lexi on 2019-08-18 17:56:41 |
Other Links: | manifest | tags |
2019-08-18
| ||
18:29 | add error reporting to kiosend() check-in: b2f129d7b9 user: lexi tags: trunk | |
17:56 | revamp arch/ makefile, add generic syscall fn on posix, rewrite kiosend() to use k_platform_syscall instead of k_platform_write check-in: 37b0cfaa06 user: lexi tags: trunk | |
13:42 | add functions, generate C syscall table check-in: a8d93823f1 user: lexi tags: trunk | |
Modified arch/makefile from [21471ec514] to [ce87fe2fb7].
1 +ifeq (${OS},lin) 2 + p-headers-syscall ?= /usr/include/asm/unistd_${BITS}.h 3 + p-headers-errno ?= /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h 4 +else ifeq (${OS},fbsd) 5 + p-headers-syscall ?= /usr/include/sys/syscall.h 6 + p-headers-errno ?= /usr/include/errno.h 7 +else 8 + $(info we don’t know where to find your magic number headers.) 9 + $(info to compile libk, please provide the following variables \ 10 +to the make command line:) 11 + $(info --- [1mp-headers-syscall[m=(location of syscall header)) 12 + $(info --- [1mp-headers-errno[m=(location of your errno values header)) 13 + $(info note that /usr/include/errno.h or your system’s equivalent \ 14 +may not be sufficient. make sure the file you pass actually contains \ 15 +individual #define statements for each possible value of errno!) 16 + $(error table generation failed due to missing primaries) 17 +endif 18 + 1 19 ${TMP}: 2 20 mkdir -p ${TMP} 3 21 4 -${TMP}/calls.x86.lin.32.tbl: ${lin-headers}/unistd_32.h ${TMP} 5 - grep "#define __NR_" $< | sed 's;^#define __NR_;;' > $@ 6 -${TMP}/calls.x86.lin.64.tbl: ${lin-headers}/unistd_64.h ${TMP} 7 - grep "#define __NR_" $< | sed 's;^#define __NR_;;' > $@ 8 -${TMP}/calls.x86.fbsd.%.tbl: ${fbsd-headers}/syscall.h ${TMP} 9 - grep "#define SYS_" $< | sed 's;^#define SYS_;;' | sed 's;[\t ]\+; ;' > $@ 22 +${TMP}/calls.lin@x86.%.tbl: $(p-headers-syscall) 23 + mkdir -p ${TMP} 24 + grep -h "#define __NR_" $^ | sed 's;^#define __NR_;;' > $@ 25 +${TMP}/calls.fbsd@%.tbl: $(p-headers-syscall) 26 + mkdir -p ${TMP} 27 + grep -h "#define SYS_" $^ | sed 's;^#define SYS_;;' | sed 's;[\t ]\+; ;' > $@ 28 + 29 +${TMP}/system_calls.%: ${TMP}/calls.${OS}@${ARCH}.${BITS}.tbl ${TMP} 30 + awk -f syscall.awk -v out=$* <$< >$@ 31 + 32 +${TMP}/error_names.tbl: $(p-headers-errno) 33 + mkdir -p ${TMP} 34 + grep -h "#[ ]*define[ ]\+E" $^ | sed 's;^#[\t ]*define[\t ]\+\(E[A-Z0-9]\+\).*$$;k_platform_error_\1 \1;' > $@ 35 +${TMP}/error_numbers.tbl: $(p-headers-errno) ${TMP}/error_names.tbl 36 + cat $^ | cpp -P >$@ 10 37 11 -${TMP}/calls.s: ${TMP}/calls.${TARGET}.tbl 12 - awk -f syscall.awk -v out=asm <$< >$@ 13 -${TMP}/calls.h: ${TMP}/calls.${TARGET}.tbl 14 - awk -f syscall.awk -v out=header <$< >$@ 38 +${TMP}/error_table.h: ${TMP}/error_numbers.tbl ${TMP} 39 + awk -f errtbl.awk <$< >$@ 15 40 16 -${TMP}/typesize: typesize.c 41 +${TMP}/typesize: typesize.c ${TMP} 17 42 $(CC) -std=c11 $< -o $@ 18 -${TMP}/typesize.def: ${TMP}/typesize 43 +${TMP}/typesize.def: ${TMP}/typesize ${TMP} 19 44 $< > $@
Modified arch/posix.h from [7d3483dee1] to [b77089e7ab].
1 1 /* arch/posix.h - posix constants 2 2 * ? this file defines posix magic numbers 3 3 * needed in syscalls, both cross-platform 4 4 * ones and os-dependent ones. note that 5 5 * the values may change depending on the 6 6 * OS specified! */ 7 7 8 +#ifndef KIplatform_posix 9 +#define KIplatform_posix 8 10 #include <k/def.h> 9 11 #include <k/type.h> 10 12 11 13 enum posix_prot { 12 14 posix_prot_none = 0, 13 15 posix_prot_read = 1 << 0, 14 16 posix_prot_write = 1 << 1, ................................................................................ 28 30 posix_flag_anonymous = 0x1000, 29 31 #endif 30 32 31 33 /* platform flags */ 32 34 posix_flag_linux_hugetlb = 0x40000 33 35 }; 34 36 35 -struct kposix_syscall_result { long ret, error; } 37 +/* platform types */ 38 + 39 +typedef s64 k_platform_syscall_return; 40 +typedef u64 k_platform_syscall_error; 41 + 42 +#if KVos == KA_os_lin 43 + typedef long k_platform_syscall_arg; 44 +#elif KVos == KA_os_fbsd 45 + typedef u64 k_platform_syscall_arg; 46 +#else 47 + /* we're going to just pick a sane 48 + * fallback that's reasonably likely 49 + * to work with most systems one way 50 + * or another */ 51 + typedef unsigned long long k_platform_syscall_arg; 52 +#endif 53 + 54 +struct k_platform_syscall_answer { 55 + k_platform_syscall_return ret; 56 + k_platform_syscall_error error; 57 +}; 58 + 59 +#include <system_calls.h> 60 + 61 +extern struct k_platform_syscall_answer 62 +k_platform_syscall(enum k_platform_syscall call, u8 valency, 63 + k_platform_syscall_arg args[]); 36 64 37 -kposix_syscall(enum kposix_syscall syscall, sz argct, long args[]); 65 +#endif
Modified arch/syscall.awk from [5422b4d7e5] to [23075063af].
1 1 BEGIN { 2 - if (out == "header") { 2 + if (out == "h") { 3 3 print "#ifndef KIplatform_syscalls" 4 4 print "#define KIplatform_syscalls" 5 - print "enum /* syscall numbers */ {" 5 + print "enum k_platform_syscall {" 6 6 } 7 7 } 8 8 9 -out == "header" { print "\tk_platform_syscall_"$1" = "$2"," } 10 -out == "asm" { print "%define sys."$1" "$2 } 9 +out == "h" { print "\tk_platform_syscall_"$1" = "$2"," } # c header 10 +out == "s" { print "%define sys."$1" "$2 } # assembly 11 11 12 12 END { 13 - if (out == "header") { 14 - print "}" 13 + if (out == "h") { 14 + print "};" 15 15 print "#endif" 16 16 } 17 17 }
Modified arch/x86.fbsd.32.s from [c5f65471b5] to [fb0cced6da].
1 1 ;; abi definition file for x86 linux 64-bit 2 2 ; vim: ft=nasm 3 3 4 4 ; syscall numbers - syscall table must be created first! 5 -%include "calls.s" 5 +%include "system_calls.s" 6 6 7 7 ; extremely stupid freebsd-ism: expects the syscall to 8 8 ; come from a function 9 9 _syscall: int 0x80 10 10 ret 11 11 12 12 %define sys.call call _syscall
Modified arch/x86.fbsd.64.s from [ef3e7f83e4] to [8f1b903740].
1 1 ;; abi definition file for x86 linux 64-bit 2 2 ; vim: ft=nasm 3 3 4 4 ; syscall numbers - syscall table must be created first! 5 -%include "calls.x86.fbsd.64.s" 5 +%include "system_calls.s" 6 6 7 7 ; freebsd uses the common x86-64 ABI 8 8 %include "x86.syscall.64.s"
Modified arch/x86.lin.32.s from [cef64f4a20] to [d3081be9ee].
1 1 ;; abi definition file for x86 linux 32-bit 2 2 ; vim: ft=nasm 3 3 4 4 ; syscall32 numbers - syscall table must be created first! 5 -%include "calls.s" 5 +%include "system_calls.s" 6 6 7 7 ; syscall32 registers 8 8 %define sys.reg.n 6 9 9 %define sys.reg.0 eax 10 10 %define sys.reg.1 ebx 11 11 %define sys.reg.2 ecx 12 12 %define sys.reg.3 edx
Modified arch/x86.lin.64.s from [2072c8d435] to [a477b8d971].
1 1 ;; abi definition file for x86 linux 64-bit 2 2 ; vim: ft=nasm 3 3 4 4 ; syscall64 numbers - syscall table must be created first! 5 -%include "calls.s" 5 +%include "system_calls.s" 6 6 7 7 ; linux uses the common x86-64 ABI 8 8 %include "x86.syscall.64.s" 9 9
Modified arch/x86.syscall.64.s from [43eb022a86] to [b26026b9a4].
25 25 26 26 ; syscall ops 27 27 %define sys.call syscall 28 28 29 29 ; register order for syscall convention 30 30 %define sys.reg.n 7 31 31 %define sys.reg.ret rax 32 +%define sys.reg.err rbx 32 33 %define sys.reg.0 rax 33 34 %define sys.reg.1 rdi 34 35 %define sys.reg.2 rsi 35 36 %define sys.reg.3 rdx 36 37 %define sys.reg.4 r10 37 38 %define sys.reg.5 r8 38 39 %define sys.reg.6 r9 39 40
Modified kcore/exit.fn.x86.lin.64.s from [4c49f79d26] to [c7202f2e83].
1 1 bits 64 2 2 %include "../arch/x86.lin.64.s" 3 3 %include "../arch/x86.cdecl.64.s" 4 4 ; vim: ft=nasm 5 5 6 -global kio_posix_exit 6 +global kio_posix_exit:function 7 7 kio_posix_exit: 8 8 mov sys.reg.1, ccall.reg.0 ;nop - rdi → rdi 9 9 mov sys.reg.0, sys.exit 10 10 sys.call 11 11 ; no return
Added kcore/platform.syscall.fn.c version [4315e80d93].
1 +/* platform.syscall.fn.c 2 + * ~ lexi hale <lexi@hale.su> 3 + * this file provides a unified interface 4 + * to the host operating system's syscalls. 5 + * its function signature may vary across 6 + * OSes, as the details of each's syscall 7 + * implementation may vary drastically. 8 + */ 9 + 10 +#include <k/def.h> 11 +#include <k/type.h> 12 + 13 +#ifdef KFenv_posix 14 +# include <posix.h> 15 +#else 16 + Knoimpl(k_platform_syscall) 17 +#endif 18 + 19 +extern void k_platform_syscall_raw ( 20 + k_platform_syscall_return* return_slot, 21 + k_platform_syscall_error* error_no_slot, 22 + enum k_platform_syscall syscall_no, 23 + u8 valency, 24 + s64* args); 25 + 26 +struct k_platform_syscall_answer 27 +k_platform_syscall(enum k_platform_syscall call, u8 valency, s64 args[]) { 28 + struct k_platform_syscall_answer answer; 29 + 30 + k_platform_syscall_raw 31 + (&answer.ret, 32 + &answer.error, 33 + call, valency, args); 34 + 35 + return answer; 36 +}
Added kcore/syscall.fn.x86.lin.64.s version [f9a360108d].
1 +; kcore/syscall.fn.x86.lin.64.s 2 +; ~ lexi hale <lexi@hale.su> 3 +; 4 +; this function performs a syscall and stores its 5 +; results in the variables provided. this makes it 6 +; possible to bypass the hideous errno mechanism 7 +; altogether and access the error value of a 8 +; syscall directly. invoke as: 9 +; 10 +; void k_platform_syscall_raw(s64* result, u64* errno, 11 +; syscall, u8 valency, s64[] args) 12 + 13 +bits 64 14 +%include "../arch/x86.lin.64.s" 15 +%include "../arch/x86.cdecl.64.s" 16 +; vim: ft=nasm 17 + 18 +%macro handle_arg 1 19 + %assign v %1+1 20 + mov sys.reg. %+ v, [ccall.reg.4 + 8 * %1] 21 + dec ccall.reg.3 22 + jz .perform_call 23 +%endmacro 24 + 25 +global k_platform_syscall_raw:function 26 +k_platform_syscall_raw: 27 + ; locals: rbx = s64* result 28 + ; r12 = u64* errno 29 + ; arg 0 = s64* result 30 + ; arg 1 = errno ptr 31 + ; arg 2 = syscall num 32 + ; arg 3 = valency 33 + ; arg 4 = args ptr 34 + 35 + ; store the locals in registers that 36 + ; are guaranteed not to be clobbered, 37 + ; saving us some cycles pushing to 38 + ; and popping back from the stack 39 + mov rbx, ccall.reg.0 40 + mov r12, ccall.reg.1 41 + 42 + ; this needs to go before the loop 43 + ; or it'll get clobbered 44 + mov sys.reg.0, ccall.reg.2 45 + 46 + ; automatically generate the code 47 + ; needed to move the arguments into 48 + ; their correct registers. see above 49 + %assign i 0 50 + %rep 6 51 + handle_arg i 52 + %assign i i+1 53 + %endrep 54 + 55 + ; valency >= 7. this is not valid, so 56 + ; we set our return value to 0 and the 57 + ; error number to its maximum value in 58 + ; order to indicate that the syscall 59 + ; was invalid 60 + mov qword [rbx], 0 61 + mov qword [r12], -1 62 + ret 63 + 64 + ; we have a valency match - perform the 65 + ; requested syscall already store in rax 66 + .perform_call: sys.call 67 + 68 + ; move our return values into place and 69 + ; return to the caller (which should 70 + ; always be k_platform_syscall, btw) 71 + mov [rbx], sys.reg.ret 72 + mov [r12], sys.reg.err 73 + ret
Modified kio/send.fn.c from [5cc5cc2649] to [0bd4793a38].
6 6 * kiosend() writes to a channel with an open out stream 7 7 */ 8 8 9 9 /* we define all platform functions here, 10 10 * whether or not they're for the correct 11 11 * platform - only the ones actually called 12 12 * by the generated code will be linked */ 13 -extern sz kio_posix_fd_write(int fd, const char* buf, sz len); 13 +#include <posix.h> 14 14 15 15 kiocond kiosend(kiochan target, ksraw string, sz* len) { 16 16 if (target.out.kind == kiostream_closed) return kiocond_fail_closed_stream; 17 17 18 18 # ifdef KFenv_posix 19 - sz size = kio_posix_fd_write(target.out.platform_fd, string.ptr, string.size); 19 + /* issue the write syscall here and now so we can 20 + * retrieve errno and report it if necessary */ 21 + 22 + k_platform_syscall_arg args[] = { 23 + target.out.platform_fd, (k_platform_syscall_arg)string.ptr, string.size }; 24 + 25 + struct k_platform_syscall_answer a = k_platform_syscall 26 + (k_platform_syscall_write,3,args); 27 + 28 + sz size = a.ret; 20 29 if (size == -1) return kiocond_fail; //TODO: retrieve errno and offer more specific errors 21 30 # else 22 31 # if KVos == win 23 32 # error windows IO send function not yet defined 24 33 # else 25 34 Knoimpl(kiosend,KVos); 26 35 # error missing implementation // boring error for plebs 27 36 # endif 28 37 # endif 29 38 30 39 if (len != null) *len = size; 31 40 return kiocond_ok; 32 41 }
Modified makefile from [47b194b965] to [5163613e5d].
10 10 ifneq ($(BITS),) 11 11 export TARGET = $(ARCH).$(OS).$(BITS) 12 12 else 13 13 export TARGET = $(ARCH).$(OS) 14 14 endif 15 15 16 16 export m4 = m4 17 -export lin-headers = /usr/include/asm 18 -export fbsd-headers = /usr/include/sys 19 17 20 18 moddirs = $(wildcard k*) 21 19 binaries = $(wildcard k*/*.exe.c) 22 20 functions = $(wildcard k*/*.fn.c) 23 21 assemblies = $(wildcard k*/*.fn.$(TARGET).s) 24 22 binmods = $(sort $(dir $(binaries))) 25 23 ................................................................................ 92 90 uninstall: $(header-dir)/k $(lib-dir)/k 93 91 rm -rf $^ 94 92 95 93 lists = moddirs functions assemblies fnobjects rtobjects binaries binmods POSIX 96 94 dbg: 97 95 @echo -e lists: $(foreach var, $(lists), "\\n - \\e[1m$(var)\\e[m = $($(var))") 98 96 99 -%.obj: %/makefile $(TMP)/calls.h $(TMP)/calls.s $(OUT) 97 +%.obj: %/makefile $(TMP)/system_calls.h $(TMP)/system_calls.s $(OUT) 100 98 cd $* && $(MAKE) obj 101 99 102 100 %.tool: %/makefile $(OUT) 103 101 cd $* && $(MAKE) tool 104 102 105 103 %.dbg: %/makefile $(OUT) 106 104 cd $* && $(MAKE) dbg 107 105 108 106 %.def: %/makefile $(TMP)/typesize.def $(OUT) $(OUT)/k 109 107 cd $* && $(MAKE) def 110 108 111 -.PRECIOUS: $(TMP)/calls.% 112 -$(TMP)/calls.%: arch/makefile 109 +.PRECIOUS: $(TMP)/system_calls.% 110 +$(TMP)/system_calls.%: arch/makefile 113 111 $(MAKE) -C arch $@ 114 112 115 113 $(TMP)/typesize.def: arch/makefile $(TMP) 116 114 $(MAKE) -C arch $@ 117 115 118 116 $(OUT)/libk.so: $(fnobjects) 119 117 ld -shared $(COMPLIB) -o $@ $^
Modified modmake from [5ed7cc8a39] to [0390aebc43].
9 9 headers = $(wildcard *.h) $(gen-headers) $(patsubst %.m,%,$(wildcard *.h.m)) 10 10 11 11 tools = $(filter %.exe.c, $(src)) 12 12 nontools = $(filter-out %.exe.c, $(src)) 13 13 cobjects = $(filter %.c, $(nontools)) 14 14 sobjects = $(filter %.${TARGET}.s, $(nontools)) 15 15 16 -cflags = -std=c11 -isystem ${OUT} -isystem ${ROOT}/arch -fPIC -nostdlib ${COMPLIB} -L${OUT} 16 +cflags = -std=c11 -isystem ${OUT} -isystem ${TMP} -isystem ${ROOT}/arch -fPIC -nostdlib ${COMPLIB} -L${OUT} 17 17 18 18 m-env = atom_target_arch=${ARCH} 19 19 m-env += atom_target_os=${OS} 20 20 ifneq (${BITS},) #!!! ifdef does NOT work with environment variables 21 21 m-env += atom_target_bits=${BITS} 22 22 endif 23 23 m-env += target_posix=${POSIX}