libk  Check-in [37b0cfaa06]

Overview
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: 37b0cfaa06fd213a266dd24f1a6b482accb59f1be3ec0c99d7ba430c7a70afe4
User & Date: lexi on 2019-08-18 17:56:41
Other Links: manifest | tags
Context
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
Changes

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 --- p-headers-syscall=(location of syscall header))
           12  +    $(info --- p-headers-errno=(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}