libk  Check-in [a8d93823f1]

Overview
Comment:add functions, generate C syscall table
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a8d93823f15bad6e3941fad7053b8e0d5e078b563f9ee1c15ea8c1063e9ee027
User & Date: lexi on 2019-08-18 13:42:35
Other Links: manifest | tags
Context
2019-08-18
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
11:34
add memory functions check-in: 5393623a84 user: lexi tags: trunk
Changes

Modified arch/makefile from [3adea95421] to [21471ec514].

     1      1   ${TMP}:
     2      2   	mkdir -p ${TMP}
     3      3   
     4         -${TMP}/calls.x86.lin.32.s: ${lin-headers}/unistd_32.h ${TMP}
     5         -	grep "#define __NR_" $< | sed 's;^#define __NR_;%define sys.;' > $@
     6         -${TMP}/calls.x86.lin.64.s: ${lin-headers}/unistd_64.h ${TMP}
     7         -	grep "#define __NR_" $< | sed 's;^#define __NR_;%define sys.;' > $@
     8         -${TMP}/calls.x86.fbsd.%.s: ${fbsd-headers}/syscall.h ${TMP}
     9         -	grep "#define	SYS_" $< | sed 's;^#define	SYS_;%define sys.;' > $@
            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 ]\+; ;' > $@
           10  +
           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 <$< >$@
           15  +
    10     16   ${TMP}/typesize: typesize.c
    11     17   	$(CC) -std=c11 $< -o $@
    12     18   ${TMP}/typesize.def: ${TMP}/typesize
    13     19   	$< > $@

Added arch/posix.h version [7d3483dee1].

            1  +/* arch/posix.h - posix constants
            2  + *  ? this file defines posix magic numbers
            3  + *    needed in syscalls, both cross-platform
            4  + *    ones and os-dependent ones. note that
            5  + *    the values may change depending on the
            6  + *    OS specified! */
            7  +
            8  +#include <k/def.h>
            9  +#include <k/type.h>
           10  +
           11  +enum posix_prot {
           12  +	posix_prot_none  = 0,
           13  +	posix_prot_read  = 1 << 0,
           14  +	posix_prot_write = 1 << 1,
           15  +	posix_prot_exec  = 1 << 2
           16  +};
           17  +
           18  +enum posix_map {
           19  +	posix_map_shared  = 1,
           20  +	posix_map_private = 2
           21  +};
           22  +
           23  +enum posix_flag {
           24  +	posix_flag_fixed     = 0x10,
           25  +#if KVos == KA_os_lin
           26  +	posix_flag_anonymous = 0x20,
           27  +#elif KVos == KA_os_fbsd
           28  +	posix_flag_anonymous = 0x1000,
           29  +#endif
           30  +
           31  +	/* platform flags */
           32  +	posix_flag_linux_hugetlb = 0x40000
           33  +};
           34  +
           35  +struct kposix_syscall_result { long ret, error; }
           36  +
           37  +kposix_syscall(enum kposix_syscall syscall, sz argct, long args[]);

Added arch/syscall.awk version [5422b4d7e5].

            1  +BEGIN {
            2  +	if (out == "header") {
            3  +		print "#ifndef KIplatform_syscalls"
            4  +		print "#define KIplatform_syscalls"
            5  +		print "enum /* syscall numbers */ {"
            6  +	}
            7  +}
            8  +
            9  +out == "header" { print "\tk_platform_syscall_"$1" = "$2"," }
           10  +out == "asm"    { print "%define sys."$1" "$2 }
           11  +
           12  +END {
           13  +	if (out == "header") {
           14  +		print "}"
           15  +		print "#endif"
           16  +	}
           17  +}

Modified arch/typesize.c from [71add081ad] to [e15b370325].

    24     24   	if (!found_sz && sizeof(type) == sizeof(size_t)) \
    25     25   		found_sz = 1, sflag(type_sz, "unsigned " #type); \
    26     26   	if (!found_ofs && sizeof(type) == sizeof(ptrdiff_t)) \
    27     27   		found_ofs = 1, sflag(type_offset, "signed " #type); \
    28     28   }
    29     29   
    30     30   int main() {
           31  +	unsigned char etest[sizeof(int)] = {0xFF,0x00};
           32  +	if ((*(int*)etest) == 0xFF) sflag(prop_endian,"low");
           33  +		else sflag(prop_endian,"high");
           34  +	
    31     35   	int found_sz = 0, found_ofs = 0, found_type = 0;
    32     36   	iflag(arch_byte_bits,CHAR_BIT);
    33     37   	describe_integral(char,char);
    34     38   	describe_integral(short,short);
    35     39   	describe_integral(int,int);
    36     40   	describe_integral(long,long);
    37     41   	describe_integral(long long,llong);
    38     42   	printf("\n");
    39     43   	return 0;
    40     44   }

Modified arch/x86.fbsd.32.s from [a34cfac886] to [c5f65471b5].

     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.32.s"
            5  +%include "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.lin.32.s from [fed93e863f] to [cef64f4a20].

     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.x86.lin.32.s"
            5  +%include "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 [f2e5b4d4ec] to [2072c8d435].

     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.x86.lin.64.s"
            5  +%include "calls.s"
     6      6   
     7      7   ; linux uses the common x86-64 ABI
     8      8   %include "x86.syscall.64.s"
     9      9   

Added kbuild/kbuild.md version [a7d1456a88].

            1  +# kbuild
            2  +
            3  +**kbuild** is a small build tool designed to maximize the ease of writing portable libk applications. kbuild is included because most C compilers automatically assume their input should be linked with libc, inserting several implicit flags that need to be changed or removed for libk. while it is fully possible to build libk programs without using kbuild, it can be somewhat tedious, especially for code too small to warrant a makefile.
            4  +
            5  +kbuild is not intended to replace complex build systems like gmake, nor is it intended to be used only with libk binaries.
            6  +
            7  +unlike most build systems, kbuild does not use a makefile or project file. kbuild is invoked simply by passing it a list of C files, which it will build and link together. kbuild recursively calculates dependencies for each file, by parsing `#include` directives and kbuild-specific pragmas.
            8  +
            9  +kbuild passes a series of variables through to the preprocessor, providing information about the current system that can be useful for conditional compilation.
           10  +
           11  +these are the phases of the kbuild process:
           12  +
           13  +
           14  +# pragmas
           15  +
           16  +to support automatic linking, kbuild handles the following pragmas.
           17  +
           18  + * `#pragma k lib` adds a library name to the list of libraries to include. on linux, pkg-config will be used to locate the library and add the appropriate flags to the command line. link flags will be applied to the final binary, while all other flags will apply only to the compilation of the source unit; for this reason, library pragmas should precede `#include` directives. `#pragma k lib c` can be used to link the standard C library; if it is present, libk will not be linked unless it is explicitly named (`#pragma k lib k`).
           19  + * `#pragma k flag` indicates that a file should be compiled with a specific flag. this will be passed directly to the compiler, so it should be used within `#if` statements to detect the operating system and/or compiler being used.
           20  + * `#pragma k link` adds a flag to the final linker command line
           21  + * `#pragma k env` requests a specific environment variable be passed to the compiler with the -D flag; `#pragma k env EDITOR` will create a macro `KE_EDITOR` if `$EDITOR` is set in the user's environment. on encountering an `env` predicate for a variable it has not already passed, `kbuild` will terminate parsing and re-run cpp with the new variable set. this allows the use of environment variables to make first-pass decisions, though its effects may be somewhat unintuitive - a `#pragma k env` directive can affect the evaluation of a macro expression earlier in the same file. `#pragma k env` without an argument requests all host environment variables be passed through to the program.
           22  +
           23  +pragmas are scanned from the preprocessed file, meaning `#if` blocks can be used to control whether a library is linked or flag is passed.
           24  +
           25  +the `_Pragma` form is not currently supported, but supporting it is a long-term goal.

Added kbuild/makefile version [f0df06fe05].

            1  +include ../modmake

Added kcore/old/def.h.m version [9c53671363].

            1  +--- kcore/def.h.m → <k/def.h>
            2  +--- ~ lexi hale <lexi@hale.su>
            3  +--- this file gathers information on the environment it's
            4  +--- being compiled in, setting macros that other headers
            5  +--- need. it will be emitted as <k/def.h>.
            6  +--- vim: ft=c
            7  +#ifndef KIdef
            8  +#define KIdef
            9  +
           10  +[ifdef atom_target_bits]
           11  +	[define target: [atom_target_arch].[atom_target_os].[atom_target_bits]]
           12  +	#define KVbits [atom_target_bits]
           13  +[else]
           14  +	[define target: [atom_target_arch].[atom_target_os]]
           15  +[endif]
           16  +#define KVtarget [target]
           17  +#define KVos [atom_target_os]
           18  +#define KVarch [atom_target_arch]
           19  +[if [target_unix] == yes]
           20  +	#define KFenv_unix
           21  +	#define KFenv_posix
           22  +[else]
           23  +	[if [target_posix] == yes]
           24  +		#define KFenv_posix
           25  +	[endif]
           26  +[endif]
           27  +
           28  +#define Kpragma(p) _Pragma(#p)
           29  +#if defined(__GNUC__) || defined(__clang__)
           30  +#   define Kerror(msg) Kpragma(GCC error #msg) 
           31  +#else
           32  +#   define Kerror(msg) Kpragma(message #msg)
           33  +#endif
           34  +#define Knoimpl(fn) Kerror(no implementation of fn for platform [target])
           35  +
           36  +#endif

Added kcore/old/type.h.m version [def2d33e25].

            1  +--- kcore/type.h.m → <k/type.h>
            2  +--- ~ lexi hale <lexi@hale.su>
            3  +--- this file gathers information on the environment it's
            4  +--- being compiled in, defining types that our code
            5  +--- needs. it will be emitted as <k/type.h>.
            6  +--- vim: ft=c
            7  +#ifndef KItype
            8  +#define KItype
            9  +
           10  +/* we define 64-bit types first due to an oddity in how
           11  + * 128-bit types are handled: we want kc_?big to reference
           12  + * the absolute largest type available to the compiler,
           13  + * but in some cases, 128-bits may not be among the
           14  + * standard C types despite being supported by the
           15  + * compiler. to work around this, we first check whether
           16  + * 64-bit types are available (__int128_t only works on
           17  + * 64-bit systems) and then whether the compiler is one
           18  + * that supports the 128-bit extension - but only if a
           19  + * native 128-bit type is not available.
           20  + * 
           21  + * once this is done, we can be certain that u128 will
           22  + * reference the largest available integer type and can
           23  + * safely define kc_?big by reference to it. */
           24  +
           25  +[ifdef type_bit64]
           26  +	typedef unsigned [type_bit64] u64;
           27  +	typedef   signed [type_bit64] s64;
           28  +	[ifndef type_bit128]
           29  +	/* even if no native type is 128 bits long, clang and
           30  +	 * gcc have extensions to support 128 bit arithmetic
           31  +	 * on 64-bit hardware */
           32  +#		if defined(__GNUC__) || defined(__clang__)
           33  +			typedef unsigned __int128_t u128;
           34  +			typedef   signed __int128_t s128;
           35  +#		else
           36  +			/* if we don't have access to that extension
           37  +			 * or native 128-bit types, then we just use
           38  +			 * the largest native type specified in the
           39  +			 * C standard */
           40  +			typedef unsigned long long u128;
           41  +			typedef   signed long long s128;
           42  +#		endif
           43  +	[endif]
           44  +[else]
           45  +	typedef unsigned long long u64;
           46  +	typedef   signed long long s64;
           47  +
           48  +	typedef u64 u128;
           49  +	typedef	s64 s128;
           50  +[endif]
           51  +
           52  +[ifdef type_bit128]
           53  +	typedef unsigned [type_bit128] u128;
           54  +	typedef   signed [type_bit128] s128;
           55  +[endif]
           56  +
           57  +typedef unsigned char ubyte;
           58  +typedef   signed char sbyte;
           59  +typedef          u128 ubig;
           60  +typedef          s128 sbig;
           61  +
           62  +[ifdef type_bit8]
           63  +	typedef unsigned [type_bit8] u8;
           64  +	typedef   signed [type_bit8] s8;
           65  +[else]
           66  +	typedef ubyte u8;
           67  +	typedef	sbyte s8;
           68  +[endif]
           69  +
           70  +[ifdef type_bit16]
           71  +	typedef unsigned [type_bit16] u16;
           72  +	typedef   signed [type_bit16] s16;
           73  +[else]
           74  +	typedef ubig u16;
           75  +	typedef	sbig s16;
           76  +[endif]
           77  +
           78  +[ifdef type_bit32]
           79  +	typedef unsigned [type_bit32] u32;
           80  +	typedef   signed [type_bit32] s32;
           81  +[else]
           82  +	typedef ubig u32;
           83  +	typedef	sbig s32;
           84  +[endif]
           85  +
           86  +enum /* max-min values of each type */ {
           87  +	byte_bits = [byte_bits],
           88  +
           89  +	  u8_min = 0,   u8_max = ((u8)-1),
           90  +	 u16_min = 0,  u16_max = ((u16)-1),
           91  +	 u32_min = 0,  u32_max = ((u32)-1),
           92  +	 u64_min = 0,  u32_max = ((u64)-1),
           93  +	u128_min = 0, u128_max = ((u128)-1),
           94  +
           95  +	/* assuming two's complement. TODO: check math */
           96  +	[define merge: $1$2]
           97  +	[define [sspec type]:
           98  +		[merge [type],_min] = 0 - ((1 << sizeof([type]) * kc_byte_bits) / 2),
           99  +		[merge [type],_max] =      (1 << sizeof([type]) * kc_byte_bits) / 2 - 1]
          100  +
          101  +	[sspec s8], [sspec s16], [sspec s32],
          102  +	[sspec s64], [sspec s128],
          103  +
          104  +	kc_uchar_min  = 0, kc_uchar_max  = [type_max_u_char],
          105  +	kc_ushort_min = 0, kc_ushort_max = [type_max_u_short],
          106  +	kc_uint_min   = 0, kc_uint_max   = [type_max_u_int],
          107  +	kc_ulong_min  = 0, kc_ulong_max  = [type_max_u_long],
          108  +	kc_ullong_min = 0, kc_ullong_max = [type_max_u_llong],
          109  +
          110  +	kc_schar_min  = [type_min_s_char],  kc_schar_max  = [type_max_s_char],
          111  +	kc_sshort_min = [type_min_s_short], kc_sshort_max = [type_max_s_short],
          112  +	kc_sint_min   = [type_min_s_int],   kc_sint_max   = [type_max_s_int],
          113  +	kc_slong_min  = [type_min_s_long],  kc_slong_max  = [type_max_s_long],
          114  +	kc_sllong_min = [type_min_s_llong], kc_sllong_max = [type_max_s_llong],
          115  +
          116  +	ubig_min = u128_min, ubig_max = u128_max,
          117  +	sbig_min = s128_min, sbig_max = s128_max,
          118  +
          119  +	ubyte_min = kc_uchar_min, ubyte_max = kc_uchar_max,
          120  +	sbyte_min = kc_schar_min, sbyte_max = kc_schar_max,
          121  +};
          122  +
          123  +[ifdef type_sz]
          124  +	typedef [type_sz] sz;
          125  +[else]
          126  +#	ifdef __cplusplus
          127  + 	   /* C++ gives us a clean, standardized way to do this */
          128  + 	   typedef decltype (sizeof(char)) sz;
          129  +#	else
          130  +#		if defined(__GNUC__) || defined(__clang__)
          131  +			typedef __typeof__ (sizeof(char)) sz;
          132  +#		else
          133  +			/* we're stumped - set sz to the safest possible value under
          134  +			 * the circumstances, and warn the user. */
          135  +#			warning no authoritative sz (size_t) type definition \
          136  +			        available; defaulting to largest unsigned integer type
          137  +			typedef ubig sz;
          138  +#		endif
          139  +#	endif
          140  +[endif]
          141  +
          142  +[ifdef type_offset]
          143  +	typedef [type_offset] offset;
          144  +[else]
          145  +#	ifdef __cplusplus
          146  + 	   /* C++ gives us a clean, standardized way to do this */
          147  +		typedef decltype (((void*)-1) - 1) offset;
          148  +#	else
          149  +#		if defined(__GNUC__) || defined(__clang__)
          150  +			typedef __typeof__ (((void*)10) - ((void*)5)) offset;
          151  +#		else
          152  +			/* no dice - set offset to the safest possible value under
          153  +			 * the circumstances, and warn the user. */
          154  +#			warning no authoritative offset (ptrdiff_t) type definition \
          155  +			        available; defaulting to largest unsigned integer type
          156  +			typedef sbig offset;
          157  +#		endif
          158  +#	endif
          159  +[endif]
          160  +
          161  +// exit status integer types - pls use kbad in <k/magic.h> instead
          162  +[if [target_posix] == yes]
          163  +	/* by convention, posix return values are 8-bit,
          164  +	 * but note that many modern UNIXes do technically
          165  +	 * support higher-bit values. for this reason,
          166  +	 * longstat is defined differently under posix. */
          167  +	typedef u8 stat;
          168  +	typedef u32 stat_long;
          169  +[else]
          170  +	[if ([atom_target_os] == win) ||
          171  +		([atom_target_os] == vms)]
          172  +		typedef u32 stat;
          173  +	[else]
          174  +		typedef u8 stat;
          175  +		/* we don't know a specific exit status type
          176  +		 * for your arch so we're going with a sane
          177  +		 * default. if this is wrong, help us fix it! */
          178  +	[endif]
          179  +	typedef stat stat_long;
          180  +[endif]
          181  +
          182  +#endif

Modified kcore/testbin.exe.c from [a4a4905883] to [c4d82c1a4a].

    17     17   	maybe = no;
    18     18   
    19     19   	if (kiosend(e.std, ptr, null) == kiocond_ok) {
    20     20   		/* great, continue */
    21     21   	} else {
    22     22   		return kbad_io;
    23     23   	}
    24         -	kmptr object = kmheapao(sizeof (struct object) * 16);
    25         -	if (object.kind == kmkind_fail) return kbad_mem;
           24  +
           25  +	void* region = kmheapa(2048);
           26  +	if (region == null) return kbad_mem;
           27  +
           28  +	kmzero(region,2048);
    26     29   
    27         -	/* struct object* block = kmheapa(sizeof (struct object) * 4); */
    28         -	
    29         -	struct object* block = object.ref;
    30         -	block[5].a = 5;
    31         -
    32         -	if (kmfree(object) != kmcond_ok) return kbad_mem;
           30  +	if (kmheapf(region) >= kmcond_fail) return kbad_mem;
    33     31   
    34     32   	return kbad_ok;
    35     33   }

Modified kcore/type.h.m from [6926347ff4] to [ebd330ccf3].

    79     79   ifdef(“type_bit32”,“
    80     80   	typedef unsigned type_bit32 u32;
    81     81   	typedef   signed type_bit32 s32;
    82     82   ”,“
    83     83   	typedef ubig u32;
    84     84   	typedef	sbig s32;
    85     85   ”)dnl
           86  +
           87  +define(“cat”, “$1$2”)
           88  +typedef enum kcendian {
           89  +	kcendian_high,
           90  +	kcendian_low,
           91  +	kcendian_system = cat(kcendian_,prop_endian), 
           92  +} kcendian;
    86     93   
    87     94   enum /* max-min values of each type */ {
    88     95   	byte_bits = arch_byte_bits,
    89     96   
    90     97   	  u8_min = 0,   u8_max = ((u8)-1),
    91     98   	 u16_min = 0,  u16_max = ((u16)-1),
    92     99   	 u32_min = 0,  u32_max = ((u32)-1),

Added kdbg/dbg.h version [8bdd73759a].

            1  +#ifndef KIdbg
            2  +#define KIdbg
            3  +#ifdef __cplusplus
            4  +extern "C" {
            5  +#endif
            6  +
            7  +#include <k/type.h>
            8  +#include <k/io.h>
            9  +
           10  +void kdbg_hexdump(kiochan, void*, sz);
           11  +
           12  +#ifdef __cplusplus
           13  +}
           14  +#endif
           15  +#endif

Added kdbg/kdbg.md version [7320047f34].

            1  +# kdbg
            2  +kdbg is a module offering convenience functions, useful primarily for debugging purposes.
            3  +
            4  +## functions
            5  + * `kdbg_hexdump(kiochan,void*,sz) → void` prints a canonical hexdump of a specified region of memory to the specified `kiochan`.

Added kdbg/makefile version [f0df06fe05].

            1  +include ../modmake

Added kmem/free.fn.c version [cc32756862].

            1  +#include <k/mem.h>
            2  +#include <k/core.h>
            3  +#include <k/def.h>
            4  +#include <k/type.h>
            5  +
            6  +/* free.fn.c - kmfree() "arbitrary free"
            7  + * ~ lexi hale <lexi@hale.su>
            8  + * kmfree() frees memory allocated in any manner.
            9  + * it ignores non-dynamically allocated memory,
           10  + * returning kmcond_unnecessary. to check for
           11  + * success, compare result < kmcond_fail.
           12  + */
           13  +
           14  +kmcond kmfree(kmptr ptr) {
           15  +	if (ptr.kind <= kmkind_fail) return kmcond_unnecessary;
           16  +	switch (ptr.kind) {
           17  +		case kmkind_heap: return kmheapf(ptr.ref);
           18  +	}
           19  +
           20  +	return kmcond_unhandled;
           21  +}
           22  +

Added kmem/heapao.fn.c version [930b5d7379].

            1  +#include <k/core.h>
            2  +#include <k/mem.h>
            3  +/* heapao.fn.c - kmheapao() "allocate heap object"
            4  + * ~ lexi hale <lexi@hale.su>
            5  + * kmheapao() allocates a region in heap memory
            6  + * and returns a kmptr struct referencing that
            7  + * newly allocated region.
            8  + */
            9  +
           10  +kmptr kmheapao(sz size) {
           11  +	void* ptr = kmheapa(size);
           12  +	kmptr p = {
           13  +		.kind = (ptr != null ? kmkind_heap : kmkind_fail),
           14  +		.ref = ptr,
           15  +		.shred = false,
           16  +	}; return p;
           17  +}

Added kmem/heapf.fn.c version [6a14dc9781].

            1  +#include <k/mem.h>
            2  +#include <k/core.h>
            3  +#include <k/def.h>
            4  +#include <k/type.h>
            5  +#include <posix.h>
            6  +/* heapf.c - kmheapf() "heap free"
            7  + * ~ lexi hale <lexi@hale.su>
            8  + * kmheapf() frees a region on the heap à la libc free()
            9  + * see also: kmheapa() "heap alloc"
           10  + */
           11  +
           12  +/* we define all platform functions here,
           13  + * whether or not they're for the correct
           14  + * platform - only the ones actually called
           15  + * by the generated code will be linked,
           16  + * linker errors are our friend here! */
           17  +extern int kmem_platform_munmap(void* addr, unsigned long sz);
           18  +
           19  +kmcond kmheapf(void* ptr) {
           20  +	/* take an object allocated on the heap and free it,
           21  +	 * returning kmcond_ok on success or an appropriate
           22  +	 * value on failure. */
           23  +	struct kmbox* header = (kmbox*)
           24  +		(((ubyte*)ptr) - sizeof (kmbox));
           25  +	sz const total = header -> size + sizeof (kmbox);
           26  +
           27  +	if (header -> kind != kmkind_heap) return kmcond_mismatch;
           28  +#	ifdef KFenv_posix
           29  +		/* currently allocation is handled on posix by naive use
           30  +		 * of MAP_ANONYMOUS. munmap needs to be told the size of
           31  +		 * the region to unmap (free), which kmheapa() stores at
           32  +		 * (ptr - sizeof sz). see kmheap.c for details. */
           33  +
           34  +		if(kmem_platform_munmap(header, total) == -1) {
           35  +			/* we don't need to bother recovering errno;
           36  +			 * there's only one possible munmap error */
           37  +			return kmcond_bad_address;
           38  +		}
           39  +
           40  +#	else
           41  +		Knoimpl(kmheapa,KVos);
           42  +#		error missing implementation
           43  +#	endif
           44  +	return kmcond_ok;
           45  +}

Added kmem/platform.munmap.fn.x86.lin.64.s version [6d9c3d5edf].

            1  +bits 64
            2  +%include "../arch/x86.lin.64.s"
            3  +%include "../arch/x86.cdecl.64.s"
            4  +; vim: ft=nasm
            5  +
            6  +global kmem_platform_munmap
            7  +kmem_platform_munmap:
            8  +	; to call munmap, we need to translate the cdecl64
            9  +	; register arguments to their appropriate syscall64
           10  +	; registers. all those that matter are the same.
           11  +	  mov sys.reg.1, ccall.reg.0 ;nop - rdi → rdi
           12  +	  mov sys.reg.2, ccall.reg.1 ;nop - rsi → rsi
           13  +
           14  +	mov sys.reg.0, sys.munmap
           15  +	sys.call
           16  +
           17  +	mov ccall.reg.ret, sys.reg.ret ; rax → rdi
           18  +	ret

Added kmem/zero.fn.c version [73ad1fc159].

            1  +#include <k/core.h>
            2  +#include <k/type.h>
            3  +#include <k/mem.h>
            4  +
            5  +/* zero.fn.c - kmzero() "zero region"
            6  + * ~ lexi hale <lexi@hale.su>
            7  + * kmzero() zeroes a region of memory. it is
            8  + * libk's equivalent to libc's bzero().
            9  + */
           10  +
           11  +#define canzero(bits) (_canzero(sizeof(u##bits), bits, size))
           12  +static bool _canzero(sz type, u8 bits, sz size) {
           13  +	return (sizeof (u64) * byte_bits == 64 && size >= sizeof (u64));
           14  +}
           15  +
           16  +void kmzero(void* memory, sz size) {
           17  +	ubyte*       elt = memory,
           18  +	     * const end = elt + size;
           19  +
           20  +	if canzero(64) {
           21  +		u64* p = (u64*) elt;
           22  +		sz segments = (end - elt) / sizeof (u64);
           23  +
           24  +		for(;(p - (u64*)elt) < segments; ++p) *p = 0;
           25  +		elt = (ubyte*) p;
           26  +	}
           27  +
           28  +	for (;elt < end; ++elt) *elt = 0;
           29  +}

Added kstr/ks_to_int.c version [4a1030ebc9].

            1  +#include <k/str.h>
            2  +#include <k/core.h>
            3  +#include <k/type.h>
            4  +
            5  +kscond ks_to_int(ksraw str, enum ksconv mode, u8* dest, sz size) {
            6  +	u8 base = mode & 0xFF;
            7  +	kcendian endian = (mode & ksconv_endh ? kcendian_high   :
            8  +	                   mode & ksconv_endl ? kcendian_low    :
            9  +	                                        kcendian_system);
           10  +	return kscond_unimplemented;
           11  +}

Modified kstr/str.h from [a45d7fa32d] to [a9e92726f6].

    18     18   } ksraw;
    19     19   
    20     20   typedef struct ksmut {
    21     21   	sz size;
    22     22   	char* ptr;
    23     23   } ksmut;
    24     24   
           25  +typedef enum kscond {
           26  +	kscond_ok,
           27  +	kscond_fail,
           28  +	kscond_unimplemented,
           29  +	kscond_nonnumeric,
           30  +} kscond;
           31  +
           32  +enum ksconv {
           33  +	ksconv_default = 0,
           34  +
           35  +	ksconv_raw = 1,
           36  +	ksconv_bin = 2,
           37  +	ksconv_oct = 8,
           38  +	ksconv_dec = 10,
           39  +	ksconv_hex = 16,
           40  +	ksconv_b32 = 32,
           41  +
           42  +	ksconv_partial = 1 <<  7,
           43  +	ksconv_nopfx   = 1 <<  8,
           44  +	ksconv_endh    = 1 <<  9,
           45  +	ksconv_endl    = 1 << 10,
           46  +};
           47  +
           48  +kscond ks_to_int(ksraw str,
           49  +		enum ksconv mode,
           50  +		u8* dest, sz size);
           51  +
           52  +kscond ks_of_int(u8* number, sz size,
           53  +		enum ksconv mode,
           54  +		char* bufstart, sz bufsize);
           55  +
    25     56   #ifdef __cplusplus
    26     57   }
    27     58   #endif
    28     59   
    29     60   #endif

Modified makefile from [d3e7936df2] to [47b194b965].

    92     92   uninstall: $(header-dir)/k $(lib-dir)/k
    93     93   	rm -rf $^
    94     94   
    95     95   lists = moddirs functions assemblies fnobjects rtobjects binaries binmods POSIX
    96     96   dbg:
    97     97   	@echo -e lists: $(foreach var, $(lists), "\\n - \\e[1m$(var)\\e[m = $($(var))")
    98     98   
    99         -%.obj: %/makefile $(TARGET).calls $(OUT)
           99  +%.obj: %/makefile $(TMP)/calls.h $(TMP)/calls.s $(OUT)
   100    100   	cd $* && $(MAKE) obj
   101    101   
   102    102   %.tool: %/makefile $(OUT)
   103    103   	cd $* && $(MAKE) tool
   104    104   
   105    105   %.dbg: %/makefile $(OUT)
   106    106   	cd $* && $(MAKE) dbg
   107    107   
   108    108   %.def: %/makefile $(TMP)/typesize.def $(OUT) $(OUT)/k
   109    109   	cd $* && $(MAKE) def
   110    110   
   111         -%.calls: arch/makefile
   112         -	cd arch && $(MAKE) $(TMP)/calls.$*.s
          111  +.PRECIOUS: $(TMP)/calls.%
          112  +$(TMP)/calls.%: arch/makefile
          113  +	$(MAKE) -C arch $@
   113    114   
   114    115   $(TMP)/typesize.def: arch/makefile $(TMP)
   115         -	cd arch && $(MAKE) $@
          116  +	$(MAKE) -C arch $@
   116    117   
   117    118   $(OUT)/libk.so: $(fnobjects) 
   118    119   	ld -shared $(COMPLIB) -o $@ $^
   119    120   	@# $(CC) -shared -fPIC -nostdlib $(COMPLIB) -o $@ $(OUT)/*.o
   120    121   
   121    122   $(OUT)/boot.o: $(rtobjects)
   122    123   	ld -r $^ -o $(OUT)/boot.o