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
2
3
4
5
6
7
8
9






10
11
12
13
${TMP}:
	mkdir -p ${TMP}

${TMP}/calls.x86.lin.32.s: ${lin-headers}/unistd_32.h ${TMP}
	grep "#define __NR_" $< | sed 's;^#define __NR_;%define sys.;' > $@
${TMP}/calls.x86.lin.64.s: ${lin-headers}/unistd_64.h ${TMP}
	grep "#define __NR_" $< | sed 's;^#define __NR_;%define sys.;' > $@
${TMP}/calls.x86.fbsd.%.s: ${fbsd-headers}/syscall.h ${TMP}
	grep "#define	SYS_" $< | sed 's;^#define	SYS_;%define sys.;' > $@






${TMP}/typesize: typesize.c
	$(CC) -std=c11 $< -o $@
${TMP}/typesize.def: ${TMP}/typesize
	$< > $@



|
|
|
|
|
|
>
>
>
>
>
>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
${TMP}:
	mkdir -p ${TMP}

${TMP}/calls.x86.lin.32.tbl: ${lin-headers}/unistd_32.h ${TMP}
	grep "#define __NR_" $< | sed 's;^#define __NR_;;' > $@
${TMP}/calls.x86.lin.64.tbl: ${lin-headers}/unistd_64.h ${TMP}
	grep "#define __NR_" $< | sed 's;^#define __NR_;;' > $@
${TMP}/calls.x86.fbsd.%.tbl: ${fbsd-headers}/syscall.h ${TMP}
	grep "#define	SYS_" $< | sed 's;^#define	SYS_;;' | sed 's;[\t ]\+; ;' > $@

${TMP}/calls.s: ${TMP}/calls.${TARGET}.tbl
	awk -f syscall.awk -v out=asm <$< >$@
${TMP}/calls.h: ${TMP}/calls.${TARGET}.tbl
	awk -f syscall.awk -v out=header <$< >$@

${TMP}/typesize: typesize.c
	$(CC) -std=c11 $< -o $@
${TMP}/typesize.def: ${TMP}/typesize
	$< > $@

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











































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/* arch/posix.h - posix constants
 *  ? this file defines posix magic numbers
 *    needed in syscalls, both cross-platform
 *    ones and os-dependent ones. note that
 *    the values may change depending on the
 *    OS specified! */

#include <k/def.h>
#include <k/type.h>

enum posix_prot {
	posix_prot_none  = 0,
	posix_prot_read  = 1 << 0,
	posix_prot_write = 1 << 1,
	posix_prot_exec  = 1 << 2
};

enum posix_map {
	posix_map_shared  = 1,
	posix_map_private = 2
};

enum posix_flag {
	posix_flag_fixed     = 0x10,
#if KVos == KA_os_lin
	posix_flag_anonymous = 0x20,
#elif KVos == KA_os_fbsd
	posix_flag_anonymous = 0x1000,
#endif

	/* platform flags */
	posix_flag_linux_hugetlb = 0x40000
};

struct kposix_syscall_result { long ret, error; }

kposix_syscall(enum kposix_syscall syscall, sz argct, long args[]);

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



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BEGIN {
	if (out == "header") {
		print "#ifndef KIplatform_syscalls"
		print "#define KIplatform_syscalls"
		print "enum /* syscall numbers */ {"
	}
}

out == "header" { print "\tk_platform_syscall_"$1" = "$2"," }
out == "asm"    { print "%define sys."$1" "$2 }

END {
	if (out == "header") {
		print "}"
		print "#endif"
	}
}

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

24
25
26
27
28
29
30




31
32
33
34
35
36
37
38
39
40
	if (!found_sz && sizeof(type) == sizeof(size_t)) \
		found_sz = 1, sflag(type_sz, "unsigned " #type); \
	if (!found_ofs && sizeof(type) == sizeof(ptrdiff_t)) \
		found_ofs = 1, sflag(type_offset, "signed " #type); \
}

int main() {




	int found_sz = 0, found_ofs = 0, found_type = 0;
	iflag(arch_byte_bits,CHAR_BIT);
	describe_integral(char,char);
	describe_integral(short,short);
	describe_integral(int,int);
	describe_integral(long,long);
	describe_integral(long long,llong);
	printf("\n");
	return 0;
}







>
>
>
>










24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
	if (!found_sz && sizeof(type) == sizeof(size_t)) \
		found_sz = 1, sflag(type_sz, "unsigned " #type); \
	if (!found_ofs && sizeof(type) == sizeof(ptrdiff_t)) \
		found_ofs = 1, sflag(type_offset, "signed " #type); \
}

int main() {
	unsigned char etest[sizeof(int)] = {0xFF,0x00};
	if ((*(int*)etest) == 0xFF) sflag(prop_endian,"low");
		else sflag(prop_endian,"high");
	
	int found_sz = 0, found_ofs = 0, found_type = 0;
	iflag(arch_byte_bits,CHAR_BIT);
	describe_integral(char,char);
	describe_integral(short,short);
	describe_integral(int,int);
	describe_integral(long,long);
	describe_integral(long long,llong);
	printf("\n");
	return 0;
}

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

1
2
3
4
5
6
7
8
9
10
11
12
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall numbers - syscall table must be created first!
%include "calls.x86.fbsd.32.s"

; extremely stupid freebsd-ism: expects the syscall to
; come from a function
_syscall: int 0x80
          ret

%define sys.call call _syscall




|







1
2
3
4
5
6
7
8
9
10
11
12
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall numbers - syscall table must be created first!
%include "calls.s"

; extremely stupid freebsd-ism: expects the syscall to
; come from a function
_syscall: int 0x80
          ret

%define sys.call call _syscall

Modified arch/x86.lin.32.s from [fed93e863f] to [cef64f4a20].

1
2
3
4
5
6
7
8
9
10
11
12
;; abi definition file for x86 linux 32-bit
; vim: ft=nasm

; syscall32 numbers - syscall table must be created first!
%include "calls.x86.lin.32.s"

; syscall32 registers
%define sys.reg.n 6
%define sys.reg.0 eax
%define sys.reg.1 ebx
%define sys.reg.2 ecx
%define sys.reg.3 edx




|







1
2
3
4
5
6
7
8
9
10
11
12
;; abi definition file for x86 linux 32-bit
; vim: ft=nasm

; syscall32 numbers - syscall table must be created first!
%include "calls.s"

; syscall32 registers
%define sys.reg.n 6
%define sys.reg.0 eax
%define sys.reg.1 ebx
%define sys.reg.2 ecx
%define sys.reg.3 edx

Modified arch/x86.lin.64.s from [f2e5b4d4ec] to [2072c8d435].

1
2
3
4
5
6
7
8
9
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall64 numbers - syscall table must be created first!
%include "calls.x86.lin.64.s"

; linux uses the common x86-64 ABI
%include "x86.syscall.64.s"





|




1
2
3
4
5
6
7
8
9
;; abi definition file for x86 linux 64-bit
; vim: ft=nasm

; syscall64 numbers - syscall table must be created first!
%include "calls.s"

; linux uses the common x86-64 ABI
%include "x86.syscall.64.s"

Added kbuild/kbuild.md version [a7d1456a88].



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# kbuild

**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.

kbuild is not intended to replace complex build systems like gmake, nor is it intended to be used only with libk binaries.

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.

kbuild passes a series of variables through to the preprocessor, providing information about the current system that can be useful for conditional compilation.

these are the phases of the kbuild process:


# pragmas

to support automatic linking, kbuild handles the following pragmas.

 * `#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`).
 * `#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.
 * `#pragma k link` adds a flag to the final linker command line
 * `#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.

pragmas are scanned from the preprocessed file, meaning `#if` blocks can be used to control whether a library is linked or flag is passed.

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
--- kcore/def.h.m → <k/def.h>
--- ~ lexi hale <lexi@hale.su>
--- this file gathers information on the environment it's
--- being compiled in, setting macros that other headers
--- need. it will be emitted as <k/def.h>.
--- vim: ft=c
#ifndef KIdef
#define KIdef

[ifdef atom_target_bits]
	[define target: [atom_target_arch].[atom_target_os].[atom_target_bits]]
	#define KVbits [atom_target_bits]
[else]
	[define target: [atom_target_arch].[atom_target_os]]
[endif]
#define KVtarget [target]
#define KVos [atom_target_os]
#define KVarch [atom_target_arch]
[if [target_unix] == yes]
	#define KFenv_unix
	#define KFenv_posix
[else]
	[if [target_posix] == yes]
		#define KFenv_posix
	[endif]
[endif]

#define Kpragma(p) _Pragma(#p)
#if defined(__GNUC__) || defined(__clang__)
#   define Kerror(msg) Kpragma(GCC error #msg) 
#else
#   define Kerror(msg) Kpragma(message #msg)
#endif
#define Knoimpl(fn) Kerror(no implementation of fn for platform [target])

#endif

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













































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
--- kcore/type.h.m → <k/type.h>
--- ~ lexi hale <lexi@hale.su>
--- this file gathers information on the environment it's
--- being compiled in, defining types that our code
--- needs. it will be emitted as <k/type.h>.
--- vim: ft=c
#ifndef KItype
#define KItype

/* we define 64-bit types first due to an oddity in how
 * 128-bit types are handled: we want kc_?big to reference
 * the absolute largest type available to the compiler,
 * but in some cases, 128-bits may not be among the
 * standard C types despite being supported by the
 * compiler. to work around this, we first check whether
 * 64-bit types are available (__int128_t only works on
 * 64-bit systems) and then whether the compiler is one
 * that supports the 128-bit extension - but only if a
 * native 128-bit type is not available.
 * 
 * once this is done, we can be certain that u128 will
 * reference the largest available integer type and can
 * safely define kc_?big by reference to it. */

[ifdef type_bit64]
	typedef unsigned [type_bit64] u64;
	typedef   signed [type_bit64] s64;
	[ifndef type_bit128]
	/* even if no native type is 128 bits long, clang and
	 * gcc have extensions to support 128 bit arithmetic
	 * on 64-bit hardware */
#		if defined(__GNUC__) || defined(__clang__)
			typedef unsigned __int128_t u128;
			typedef   signed __int128_t s128;
#		else
			/* if we don't have access to that extension
			 * or native 128-bit types, then we just use
			 * the largest native type specified in the
			 * C standard */
			typedef unsigned long long u128;
			typedef   signed long long s128;
#		endif
	[endif]
[else]
	typedef unsigned long long u64;
	typedef   signed long long s64;

	typedef u64 u128;
	typedef	s64 s128;
[endif]

[ifdef type_bit128]
	typedef unsigned [type_bit128] u128;
	typedef   signed [type_bit128] s128;
[endif]

typedef unsigned char ubyte;
typedef   signed char sbyte;
typedef          u128 ubig;
typedef          s128 sbig;

[ifdef type_bit8]
	typedef unsigned [type_bit8] u8;
	typedef   signed [type_bit8] s8;
[else]
	typedef ubyte u8;
	typedef	sbyte s8;
[endif]

[ifdef type_bit16]
	typedef unsigned [type_bit16] u16;
	typedef   signed [type_bit16] s16;
[else]
	typedef ubig u16;
	typedef	sbig s16;
[endif]

[ifdef type_bit32]
	typedef unsigned [type_bit32] u32;
	typedef   signed [type_bit32] s32;
[else]
	typedef ubig u32;
	typedef	sbig s32;
[endif]

enum /* max-min values of each type */ {
	byte_bits = [byte_bits],

	  u8_min = 0,   u8_max = ((u8)-1),
	 u16_min = 0,  u16_max = ((u16)-1),
	 u32_min = 0,  u32_max = ((u32)-1),
	 u64_min = 0,  u32_max = ((u64)-1),
	u128_min = 0, u128_max = ((u128)-1),

	/* assuming two's complement. TODO: check math */
	[define merge: $1$2]
	[define [sspec type]:
		[merge [type],_min] = 0 - ((1 << sizeof([type]) * kc_byte_bits) / 2),
		[merge [type],_max] =      (1 << sizeof([type]) * kc_byte_bits) / 2 - 1]

	[sspec s8], [sspec s16], [sspec s32],
	[sspec s64], [sspec s128],

	kc_uchar_min  = 0, kc_uchar_max  = [type_max_u_char],
	kc_ushort_min = 0, kc_ushort_max = [type_max_u_short],
	kc_uint_min   = 0, kc_uint_max   = [type_max_u_int],
	kc_ulong_min  = 0, kc_ulong_max  = [type_max_u_long],
	kc_ullong_min = 0, kc_ullong_max = [type_max_u_llong],

	kc_schar_min  = [type_min_s_char],  kc_schar_max  = [type_max_s_char],
	kc_sshort_min = [type_min_s_short], kc_sshort_max = [type_max_s_short],
	kc_sint_min   = [type_min_s_int],   kc_sint_max   = [type_max_s_int],
	kc_slong_min  = [type_min_s_long],  kc_slong_max  = [type_max_s_long],
	kc_sllong_min = [type_min_s_llong], kc_sllong_max = [type_max_s_llong],

	ubig_min = u128_min, ubig_max = u128_max,
	sbig_min = s128_min, sbig_max = s128_max,

	ubyte_min = kc_uchar_min, ubyte_max = kc_uchar_max,
	sbyte_min = kc_schar_min, sbyte_max = kc_schar_max,
};

[ifdef type_sz]
	typedef [type_sz] sz;
[else]
#	ifdef __cplusplus
 	   /* C++ gives us a clean, standardized way to do this */
 	   typedef decltype (sizeof(char)) sz;
#	else
#		if defined(__GNUC__) || defined(__clang__)
			typedef __typeof__ (sizeof(char)) sz;
#		else
			/* we're stumped - set sz to the safest possible value under
			 * the circumstances, and warn the user. */
#			warning no authoritative sz (size_t) type definition \
			        available; defaulting to largest unsigned integer type
			typedef ubig sz;
#		endif
#	endif
[endif]

[ifdef type_offset]
	typedef [type_offset] offset;
[else]
#	ifdef __cplusplus
 	   /* C++ gives us a clean, standardized way to do this */
		typedef decltype (((void*)-1) - 1) offset;
#	else
#		if defined(__GNUC__) || defined(__clang__)
			typedef __typeof__ (((void*)10) - ((void*)5)) offset;
#		else
			/* no dice - set offset to the safest possible value under
			 * the circumstances, and warn the user. */
#			warning no authoritative offset (ptrdiff_t) type definition \
			        available; defaulting to largest unsigned integer type
			typedef sbig offset;
#		endif
#	endif
[endif]

// exit status integer types - pls use kbad in <k/magic.h> instead
[if [target_posix] == yes]
	/* by convention, posix return values are 8-bit,
	 * but note that many modern UNIXes do technically
	 * support higher-bit values. for this reason,
	 * longstat is defined differently under posix. */
	typedef u8 stat;
	typedef u32 stat_long;
[else]
	[if ([atom_target_os] == win) ||
		([atom_target_os] == vms)]
		typedef u32 stat;
	[else]
		typedef u8 stat;
		/* we don't know a specific exit status type
		 * for your arch so we're going with a sane
		 * default. if this is wrong, help us fix it! */
	[endif]
	typedef stat stat_long;
[endif]

#endif

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

17
18
19
20
21
22
23
24
25
26
27


28
29
30

31
32

33
34
35
	maybe = no;

	if (kiosend(e.std, ptr, null) == kiocond_ok) {
		/* great, continue */
	} else {
		return kbad_io;
	}
	kmptr object = kmheapao(sizeof (struct object) * 16);
	if (object.kind == kmkind_fail) return kbad_mem;

	/* struct object* block = kmheapa(sizeof (struct object) * 4); */


	
	struct object* block = object.ref;
	block[5].a = 5;


	if (kmfree(object) != kmcond_ok) return kbad_mem;


	return kbad_ok;
}







<
<

<
>
>
|
<
<
>

<
>



17
18
19
20
21
22
23


24

25
26
27


28
29

30
31
32
33
	maybe = no;

	if (kiosend(e.std, ptr, null) == kiocond_ok) {
		/* great, continue */
	} else {
		return kbad_io;
	}




	void* region = kmheapa(2048);
	if (region == null) return kbad_mem;



	kmzero(region,2048);


	if (kmheapf(region) >= kmcond_fail) return kbad_mem;

	return kbad_ok;
}

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

79
80
81
82
83
84
85







86
87
88
89
90
91
92
ifdef(“type_bit32”,“
	typedef unsigned type_bit32 u32;
	typedef   signed type_bit32 s32;
”,“
	typedef ubig u32;
	typedef	sbig s32;
”)dnl








enum /* max-min values of each type */ {
	byte_bits = arch_byte_bits,

	  u8_min = 0,   u8_max = ((u8)-1),
	 u16_min = 0,  u16_max = ((u16)-1),
	 u32_min = 0,  u32_max = ((u32)-1),







>
>
>
>
>
>
>







79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
ifdef(“type_bit32”,“
	typedef unsigned type_bit32 u32;
	typedef   signed type_bit32 s32;
”,“
	typedef ubig u32;
	typedef	sbig s32;
”)dnl

define(“cat”, “$1$2”)
typedef enum kcendian {
	kcendian_high,
	kcendian_low,
	kcendian_system = cat(kcendian_,prop_endian), 
} kcendian;

enum /* max-min values of each type */ {
	byte_bits = arch_byte_bits,

	  u8_min = 0,   u8_max = ((u8)-1),
	 u16_min = 0,  u16_max = ((u16)-1),
	 u32_min = 0,  u32_max = ((u32)-1),

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































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef KIdbg
#define KIdbg
#ifdef __cplusplus
extern "C" {
#endif

#include <k/type.h>
#include <k/io.h>

void kdbg_hexdump(kiochan, void*, sz);

#ifdef __cplusplus
}
#endif
#endif

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











>
>
>
>
>
1
2
3
4
5
# kdbg
kdbg is a module offering convenience functions, useful primarily for debugging purposes.

## functions
 * `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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <k/mem.h>
#include <k/core.h>
#include <k/def.h>
#include <k/type.h>

/* free.fn.c - kmfree() "arbitrary free"
 * ~ lexi hale <lexi@hale.su>
 * kmfree() frees memory allocated in any manner.
 * it ignores non-dynamically allocated memory,
 * returning kmcond_unnecessary. to check for
 * success, compare result < kmcond_fail.
 */

kmcond kmfree(kmptr ptr) {
	if (ptr.kind <= kmkind_fail) return kmcond_unnecessary;
	switch (ptr.kind) {
		case kmkind_heap: return kmheapf(ptr.ref);
	}

	return kmcond_unhandled;
}

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



































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <k/core.h>
#include <k/mem.h>
/* heapao.fn.c - kmheapao() "allocate heap object"
 * ~ lexi hale <lexi@hale.su>
 * 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);
	kmptr p = {
		.kind = (ptr != null ? kmkind_heap : kmkind_fail),
		.ref = ptr,
		.shred = false,
	}; return p;
}

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



























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <k/mem.h>
#include <k/core.h>
#include <k/def.h>
#include <k/type.h>
#include <posix.h>
/* heapf.c - kmheapf() "heap free"
 * ~ lexi hale <lexi@hale.su>
 * kmheapf() frees a region on the heap à la libc free()
 * see also: kmheapa() "heap alloc"
 */

/* we define all platform functions here,
 * whether or not they're for the correct
 * platform - only the ones actually called
 * by the generated code will be linked,
 * linker errors are our friend here! */
extern int kmem_platform_munmap(void* addr, unsigned long sz);

kmcond kmheapf(void* ptr) {
	/* take an object allocated on the heap and free it,
	 * returning kmcond_ok on success or an appropriate
	 * value on failure. */
	struct kmbox* header = (kmbox*)
		(((ubyte*)ptr) - sizeof (kmbox));
	sz const total = header -> size + sizeof (kmbox);

	if (header -> kind != kmkind_heap) return kmcond_mismatch;
#	ifdef KFenv_posix
		/* currently allocation is handled on posix by naive use
		 * of MAP_ANONYMOUS. munmap needs to be told the size of
		 * the region to unmap (free), which kmheapa() stores at
		 * (ptr - sizeof sz). see kmheap.c for details. */

		if(kmem_platform_munmap(header, total) == -1) {
			/* we don't need to bother recovering errno;
			 * there's only one possible munmap error */
			return kmcond_bad_address;
		}

#	else
		Knoimpl(kmheapa,KVos);
#		error missing implementation
#	endif
	return kmcond_ok;
}

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





































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bits 64
%include "../arch/x86.lin.64.s"
%include "../arch/x86.cdecl.64.s"
; vim: ft=nasm

global kmem_platform_munmap
kmem_platform_munmap:
	; to call munmap, we need to translate the cdecl64
	; register arguments to their appropriate syscall64
	; registers. all those that matter are the same.
	  mov sys.reg.1, ccall.reg.0 ;nop - rdi → rdi
	  mov sys.reg.2, ccall.reg.1 ;nop - rsi → rsi

	mov sys.reg.0, sys.munmap
	sys.call

	mov ccall.reg.ret, sys.reg.ret ; rax → rdi
	ret

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



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <k/core.h>
#include <k/type.h>
#include <k/mem.h>

/* zero.fn.c - kmzero() "zero region"
 * ~ lexi hale <lexi@hale.su>
 * kmzero() zeroes a region of memory. it is
 * libk's equivalent to libc's bzero().
 */

#define canzero(bits) (_canzero(sizeof(u##bits), bits, size))
static bool _canzero(sz type, u8 bits, sz size) {
	return (sizeof (u64) * byte_bits == 64 && size >= sizeof (u64));
}

void kmzero(void* memory, sz size) {
	ubyte*       elt = memory,
	     * const end = elt + size;

	if canzero(64) {
		u64* p = (u64*) elt;
		sz segments = (end - elt) / sizeof (u64);

		for(;(p - (u64*)elt) < segments; ++p) *p = 0;
		elt = (ubyte*) p;
	}

	for (;elt < end; ++elt) *elt = 0;
}

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























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
#include <k/str.h>
#include <k/core.h>
#include <k/type.h>

kscond ks_to_int(ksraw str, enum ksconv mode, u8* dest, sz size) {
	u8 base = mode & 0xFF;
	kcendian endian = (mode & ksconv_endh ? kcendian_high   :
	                   mode & ksconv_endl ? kcendian_low    :
	                                        kcendian_system);
	return kscond_unimplemented;
}

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

18
19
20
21
22
23
24































25
26
27
28
29
} ksraw;

typedef struct ksmut {
	sz size;
	char* ptr;
} ksmut;
































#ifdef __cplusplus
}
#endif

#endif







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
} ksraw;

typedef struct ksmut {
	sz size;
	char* ptr;
} ksmut;

typedef enum kscond {
	kscond_ok,
	kscond_fail,
	kscond_unimplemented,
	kscond_nonnumeric,
} kscond;

enum ksconv {
	ksconv_default = 0,

	ksconv_raw = 1,
	ksconv_bin = 2,
	ksconv_oct = 8,
	ksconv_dec = 10,
	ksconv_hex = 16,
	ksconv_b32 = 32,

	ksconv_partial = 1 <<  7,
	ksconv_nopfx   = 1 <<  8,
	ksconv_endh    = 1 <<  9,
	ksconv_endl    = 1 << 10,
};

kscond ks_to_int(ksraw str,
		enum ksconv mode,
		u8* dest, sz size);

kscond ks_of_int(u8* number, sz size,
		enum ksconv mode,
		char* bufstart, sz bufsize);

#ifdef __cplusplus
}
#endif

#endif

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

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
uninstall: $(header-dir)/k $(lib-dir)/k
	rm -rf $^

lists = moddirs functions assemblies fnobjects rtobjects binaries binmods POSIX
dbg:
	@echo -e lists: $(foreach var, $(lists), "\\n - \\e[1m$(var)\\e[m = $($(var))")

%.obj: %/makefile $(TARGET).calls $(OUT)
	cd $* && $(MAKE) obj

%.tool: %/makefile $(OUT)
	cd $* && $(MAKE) tool

%.dbg: %/makefile $(OUT)
	cd $* && $(MAKE) dbg

%.def: %/makefile $(TMP)/typesize.def $(OUT) $(OUT)/k
	cd $* && $(MAKE) def

%.calls: arch/makefile
	cd arch && $(MAKE) $(TMP)/calls.$*.s


$(TMP)/typesize.def: arch/makefile $(TMP)
	cd arch && $(MAKE) $@

$(OUT)/libk.so: $(fnobjects) 
	ld -shared $(COMPLIB) -o $@ $^
	@# $(CC) -shared -fPIC -nostdlib $(COMPLIB) -o $@ $(OUT)/*.o

$(OUT)/boot.o: $(rtobjects)
	ld -r $^ -o $(OUT)/boot.o







|











|
|
>


|







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
uninstall: $(header-dir)/k $(lib-dir)/k
	rm -rf $^

lists = moddirs functions assemblies fnobjects rtobjects binaries binmods POSIX
dbg:
	@echo -e lists: $(foreach var, $(lists), "\\n - \\e[1m$(var)\\e[m = $($(var))")

%.obj: %/makefile $(TMP)/calls.h $(TMP)/calls.s $(OUT)
	cd $* && $(MAKE) obj

%.tool: %/makefile $(OUT)
	cd $* && $(MAKE) tool

%.dbg: %/makefile $(OUT)
	cd $* && $(MAKE) dbg

%.def: %/makefile $(TMP)/typesize.def $(OUT) $(OUT)/k
	cd $* && $(MAKE) def

.PRECIOUS: $(TMP)/calls.%
$(TMP)/calls.%: arch/makefile
	$(MAKE) -C arch $@

$(TMP)/typesize.def: arch/makefile $(TMP)
	$(MAKE) -C arch $@

$(OUT)/libk.so: $(fnobjects) 
	ld -shared $(COMPLIB) -o $@ $^
	@# $(CC) -shared -fPIC -nostdlib $(COMPLIB) -o $@ $(OUT)/*.o

$(OUT)/boot.o: $(rtobjects)
	ld -r $^ -o $(OUT)/boot.o