libk  Check-in [21467a6dc9]

Overview
Comment:updates
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 21467a6dc94ca02c7826385aa0f5df25adabd12ceaa3e2955e41ec432afafa83
User & Date: lexi on 2019-06-27 12:13:43
Other Links: manifest | tags
Context
2019-06-27
12:17
fix embarassing example check-in: 3e3a628048 user: lexi tags: trunk
12:13
updates check-in: 21467a6dc9 user: lexi tags: trunk
09:57
add in mechanism to generate syscall tables for x86 linux check-in: 860229e8ce user: lexi tags: trunk
Changes

Modified arch/makefile from [8e0dfa3404] to [657c34aa94].

1

2
3
4
calls.x86.lin.32.s: /usr/include/asm/unistd_32.h

	grep "#define __NR_" $< | sed "s;^#define __NR_;%define sys.;" > $@
calls.x86.lin.64.s: /usr/include/asm/unistd_64.h
	grep "#define __NR_" $< | sed "s;^#define __NR_;%define sys.;" > $@
|
>

|

1
2
3
4
5
linux-headers = /usr/include/asm/
calls.x86.lin.32.s: $(linux-headers)/unistd_32.h
	grep "#define __NR_" $< | sed "s;^#define __NR_;%define sys.;" > $@
calls.x86.lin.64.s: $(linux-headers)/unistd_64.h
	grep "#define __NR_" $< | sed "s;^#define __NR_;%define sys.;" > $@

Modified arch/x86.lin.64.s from [1f6b1a0933] to [2b600a2718].

5
6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
%include "calls.x86.lin.64.s"

; syscall ops
%define sys.call syscall

; register order for syscall convention
%define sys.reg.n 7

%define sys.reg.0 rax
%define sys.reg.1 rdi
%define sys.reg.2 rsi
%define sys.reg.3 rdx
%define sys.reg.4 r10
%define sys.reg.5 r8
%define sys.reg.6 r9

; register order for ccall convention
%define ccall.reg.ct 6

%define ccall.reg.0 rdi
%define ccall.reg.1 rsi
%define ccall.reg.2 rdx
%define ccall.reg.3 rcx
%define ccall.reg.4 r8
%define ccall.reg.5 r9








>










>







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
%include "calls.x86.lin.64.s"

; syscall ops
%define sys.call syscall

; register order for syscall convention
%define sys.reg.n 7
%define sys.reg.ret rax
%define sys.reg.0 rax
%define sys.reg.1 rdi
%define sys.reg.2 rsi
%define sys.reg.3 rdx
%define sys.reg.4 r10
%define sys.reg.5 r8
%define sys.reg.6 r9

; register order for ccall convention
%define ccall.reg.ct 6
%define ccall.reg.ret rdi
%define ccall.reg.0 rdi
%define ccall.reg.1 rsi
%define ccall.reg.2 rdx
%define ccall.reg.3 rcx
%define ccall.reg.4 r8
%define ccall.reg.5 r9

Added kcli/kcli.md version [91db6a8cad].



























































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# kcli
**kcli** is a module that implements common routines used by command-line utilities, such as option parsing, usage display, and more.

## functions

### kcli_usage(kcli_set, kiochan)
kcli_usage() takes a `kcli_set` and prints a succinct usage summary to a [kiochan](../kio/kio.md).

## types

### struct kcli_set
`kcli_set` is a struct containing information about your program, such as its name, a synopsis of its function, a pointer to `argv`, and a list of `kcli_opt`s.

 * `const char* name` - program name (if null, will be determined from argv instead)
 * `size_t argc` - the number of arguments in the `argv` array.
 * `const char** argv` - the `argv` pointer passed to the `entry` function, representing the command-line arguments passed to the program.
 * `const char* desc` - program description
 * `const kcli_param* params` - a list of options expected by the program.
 * `size_t paramc` - the number of params in the list to process.
 * `const kcli_opt* opts` - a list of options expected by the program.
 * `size_t optc` - the number of options in the list to process.

a kcli_set might be used like so:

    #include <k/core.h>
    #include <k/io.h>
    #include <k/cli.h>
    u8 entry(kenv e) {
    	kcli_flag aardvark;
    	kcli_flag zebra;
    	char* user;
    	char* password;
		long age;
		kcli_param* params = {
    		{ "user", kcli_param_string, kcli_class_required,
    		  &user, "the user to log in as" }
			  // or Kcli_param(user,string,required,"the user to log in as"),

			{ "age", kcli_param_dec, kcli_class_optional,
    		  &age, "the age of the user" }
			  // or Kcli_param(age,dec,optional,"the age of the user"),
		};
    	kcli_opt* options = {
    		{ 'a', "aardvark", kcli_opt_flag, &aardvark,
    		  "a nocturnal burrowing mammal" },
			  // or Kcli_opt(aardvark, 'a', flag, "a nocturnal burrowing mammal")
    		{ 'z', "zebra", kcli_opt_flag, &zebra,
    		  "a striped equine" },
    		{ 'p', "password", kcli_opt_string, &password,
    		  "the password to log in with" }
    	};
    	kcli_set me = {
    		"demo", e.argc, e.argv,
    		"a demonstration of the kcli_set type",
			params, Kmsz(params),
			options, Kmsz(options)
    	},
		size_t args_parsed = kcli_parse(&me);
		if (args_parsed == 0) { kcli_usage(&me, e.err); return 1; }

		return 0;
	}

### struct kcli_opt
a `kcli_opt` is a representation of a command-line flag and its function. each option must have a unique `id` and/or a unique `name`.

 * `char id` - the short single-character form of the flag (or NUL for no short form)
 * `const char* name` - the long string form of the flag (or NULL for no long form)
 * `kcli_opt_kind kind` - enum that describes how the flag will function
 * `void* val` - a pointer to an appropriate type to store the return value in.
 * `const char* desc` - a description of the flag's purpose and function (or NULL for no description)

#### enum kcli_opt_kind

 * `kcli_opt_none` - flag is disabled and will not be shown in usage
 * `kcli_opt_string` - flag tells kcli to add a string to the list of expected parameters; appropriate string will be returned
 * `kcli_opt_oct` - flag tells kcli to add an octal number to the list of expected parameters
 * `kcli_opt_dec` - flag tells kcli to add a decimal number to the list of expected parameters
 * `kcli_opt_hex` - flag tells kcli to add a hexdecimal number to the list of expected parameters
 * `kcli_opt_flag` - flag is an option: will return `kcli_flag_on` if entered at least once, `kcli_flag_off` otherwise.
 * `kcli_opt_toggle` - flag toggles value on and off: will return `kcli_flag_on` if entered an odd number of times, `kcli_flag_off` otherwise.
 * `kcli_opt_accumulate` - flag increments a value every time it is entered; often used to implement `-v (--verbose)`-style options (e.g. `-vvvv` would return a value of `4`).

### struct kcli_param
`kcli_param` describes a parameter that may be passed to the program whether or not any flags are passed.

 * `const char* name` - a short name for the parameter
 * `kcli_param_kind kind` - the kind of parameter passed
 * `kcli_class class` - whether or not the parameter is optional
 * `void* val` - a pointer to an appropriate type of variable to fill
 * `const char* desc` - a description of the parameter's function

#### enum kcli_param_kind
 * `kcli_param_none` - parameter is disabled and will not be expected or accepted
 * `kcli_param_string` - parameter will not be parsed; a raw string will be returned
 * `kcli_param_oct` - parameter will be parsed as an octal number
 * `kcli_param_dec` - parameter will be parsed as a decimal number
 * `kcli_param_hex` - parameter will be parsed as a hexadecimal number

### enum kcli_class
 * `kcli_class_forbidden` - parameter may not be passed
 * `kcli_class_optional` - parameter may or may not be passed
 * `kcli_class_required` - parameter must be passed

### enum kcli_flag
results that an option of kind `kcli_opt_flag` can return.

 * `kcli_flag_off = 0` - flag is off
 * `kcli_flag_on = 1` - flag is on
 
## macros

### Kcli_param(field, kind, class, description)
a convenience macro for filling out parameter lists.

`Kcli_param(field,a,b,"description")` is transformed into:

    { "field", kcli_param_a, kcli_class_b, &field, "description" }

### Kcli_opt(field, kind, class, description)
a convenience macro for filling out option lists.

`Kcli_opt(name,'n',string,"description")` is transformed into:

    { 'n', "name", kcli_opt_string, &name, "description" }

Added kcore/boot.c version [878278ef2e].

















>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
#include "core.h"
extern stat entry(kenv);

stat _boot(unsigned int argc, char** argv) {
	kenv e = { argc, argv };
	return entry(e);
}
	

Added kcore/core.h version [bb457bb91b].

























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef KIcore
#define KIcore

typedef unsigned long long sz;
typedef unsigned char stat;

typedef struct kenv {
	sz argc;
	char** argv;
} kenv;

#endif

Added kcore/kcore.md version [28c0315020].





































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# kcore
**kcore** is the foundation for the rest of libk. it defines types and structs that are needed by every program, and provides the stub that launches a program's "entry" function.

## entry
when using libk, your program's entry point will not be the `int main(int,char**)` function that libc opens into. libk will call the function `stat entry(kenv)` instead. like libc, the value returned by `entry` will be returned to the host platform.

## types
kcore contains fixed-width integer types. note that the available of each depends on your platform; compilation will fail if e.g. you try to use a u64 or a u128 on a 32-bit platform, so where exact lengths are not required, you may wish to use the built-in C types instead.

 * `u8` - an unsigned 8-bit integer
 * `s8` - a signed 8-bit integer
 * `u16` - an unsigned 16-bit integer
 * `s16` - a signed 16-bit integer
 * `u32` - an unsigned 32-bit integer
 * `s32` - a signed 32-bit integer
 * `u64` - an unsigned 64-bit integer
 * `s64` - a signed 64-bit integer
 * `u128` - an unsigned 128-bit integer
 * `s128` - a signed 128-bit integer
 * `word` - an unsigned integer of platform word-length (e.g. 32 bits on x86.32; 64 on x86.64)
 * `sword` - a signed integer of platform word-length (e.g. 32 bits on x86.32; 64 on x86.64)
 * `stat` - the type of process return values expected by the platform (usually u8 on linux)

### struct kenv
`kenv` is a struct that encompasses the environment the program was launched in.
 * `kiochan std` - a stereo IO channel for reading and writing to and from stdout.
 * `kiochan err` - a mono IO channel for writing to stderr.
 * `kvar* env` - a pointer into the program's environment

### struct kvar
`kvar` is a struct that abstracts over platform environment variables.
 * `kstr name` - the name of an environment variable
 * `kstr val` - the value of an environment variable
 * `char* platform` - a pointer into the platform's underlying representation

Added kcore/makefile version [f0df06fe05].



>
1
include ../modmake

Added kcore/start.x86.lin.64.s version [fc26b36617].



































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

_start:
	mov rbp, rsp
	mov rdi, [rbp + 0] ; argc
	lea rsi, [rbp + 8] ; argv

	call _boot;

	mov sys.reg.1, sys.reg.ret
	mov sys.reg.0, sys.exit
	sys.call

Modified libk.md from [d44feffbdd] to [f5443bdd6c].

178
179
180
181
182
183
184
185
186
187

the AGPL may seem like an inappropriately restrictive license for a project with such grandiose ambitions. it is an ideological choice. i selected it because libk is intended very specifically as a contribution to the *free software* community, a community that i hope will continue to grow at the expense of closed-source ecosystems. i have no interest in enabling people or corporations to profit from keeping secrets, especially not with my own free labor (or anyone else's, for that matter).

if you disagree with this philosophy, you are welcome to continue using libc.

## what does the k stand for?

nothing. it was chosen in reference to libc - the letter C was part of the original roman alphabet, while K was added later by analogy to the Greek kappa ‹κ›. in my native language, the older letter ‹c› can make a number of different sounds based on context, including [k] and [s], while ‹k› is fairly consistently used for the sound [k]. hopefully the analogy is obvious.

this project has nothing to do with KDE.







|


178
179
180
181
182
183
184
185
186
187

the AGPL may seem like an inappropriately restrictive license for a project with such grandiose ambitions. it is an ideological choice. i selected it because libk is intended very specifically as a contribution to the *free software* community, a community that i hope will continue to grow at the expense of closed-source ecosystems. i have no interest in enabling people or corporations to profit from keeping secrets, especially not with my own free labor (or anyone else's, for that matter).

if you disagree with this philosophy, you are welcome to continue using libc.

## what does the k stand for?

nothing. it was chosen in reference to libc - the letter C was part of the original roman alphabet, while K was added later by analogy to the Greek kappa ‹κ›. in my native language, the older letter ‹c› can make a number of different sounds based on context, including [k] and [s], while ‹k› is fairly consistently used for the sound [k]. and for orthographical reasons, [k] is often represented by the digraph ‹ck› - that is, a C followed by a K. hopefully the analogies are obvious.

this project has nothing to do with KDE.

Modified modmake from [247b2f15bf] to [e72fb78502].

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#-- linux
# linux uses the ELF{32,64} binary format,  and generating these
# from yasm is trivial.  linux only supports one ABI per format,
# at least with ELF, so that's all we need to do.

#${OUT}/$(mod).%.x86.lin.32.o: %.x86.lin.32.s
$(call arch,x86.lin.32)
	yasm -felf32 $< -o $@

#${OUT}/$(mod).%.x86.lin.64.o: %.x86.lin.64.s
$(call arch,x86.lin.64)
	yasm -felf64 $< -o $@

#-- freebsd
# the freebsd ABI is different, so it will require different code
# (though there might be ways to minimize that). freebsd uses the
# same binary format as Linux  (though it also supports a.out and
# COFF) but because freebsd can interpret multiple different ABIs
# the  object files  need to  be "branded"  with the  correct one







|



|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#-- linux
# linux uses the ELF{32,64} binary format,  and generating these
# from yasm is trivial.  linux only supports one ABI per format,
# at least with ELF, so that's all we need to do.

#${OUT}/$(mod).%.x86.lin.32.o: %.x86.lin.32.s
$(call arch,x86.lin.32)
	yasm -gdwarf2 -felf32 $< -o $@

#${OUT}/$(mod).%.x86.lin.64.o: %.x86.lin.64.s
$(call arch,x86.lin.64)
	yasm -gdwarf2 -felf64 $< -o $@

#-- freebsd
# the freebsd ABI is different, so it will require different code
# (though there might be ways to minimize that). freebsd uses the
# same binary format as Linux  (though it also supports a.out and
# COFF) but because freebsd can interpret multiple different ABIs
# the  object files  need to  be "branded"  with the  correct one