DELETED kcore/boot.c Index: kcore/boot.c ================================================================== --- kcore/boot.c +++ kcore/boot.c @@ -1,14 +0,0 @@ -#include -extern stat entry(kenv); - -stat _boot(unsigned int argc, char** argv) { - kenv e = { - // todo: determine terminal class and set term vs ansi correctly! - { {kiostream_term, 0}, {kiostream_term, 1} }, // chan std - { {kiostream_closed}, {kiostream_term, 2} }, // chan err - argc, argv, - null // no environment yet - }; - return entry(e); -} - ADDED kcore/boot.rt.c Index: kcore/boot.rt.c ================================================================== --- kcore/boot.rt.c +++ kcore/boot.rt.c @@ -0,0 +1,14 @@ +#include +extern stat entry(kenv); + +stat _boot(unsigned int argc, char** argv) { + kenv e = { + // todo: determine terminal class and set term vs ansi correctly! + { {kiostream_term, 0}, {kiostream_term, 1} }, // chan std + { {kiostream_closed}, {kiostream_term, 2} }, // chan err + argc, argv, + null // no environment yet + }; + return entry(e); +} + ADDED kcore/boot.rt.x86.lin.64.s Index: kcore/boot.rt.x86.lin.64.s ================================================================== --- kcore/boot.rt.x86.lin.64.s +++ kcore/boot.rt.x86.lin.64.s @@ -0,0 +1,17 @@ +; vim: ft=nasm +bits 64 +%include "../arch/x86.lin.64.s" +global _start:function +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 DELETED kcore/boot.x86.lin.64.s Index: kcore/boot.x86.lin.64.s ================================================================== --- kcore/boot.x86.lin.64.s +++ kcore/boot.x86.lin.64.s @@ -1,17 +0,0 @@ -; vim: ft=nasm -bits 64 -%include "../arch/x86.lin.64.s" -global _start:function -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 ADDED kcore/def.h Index: kcore/def.h ================================================================== --- kcore/def.h +++ kcore/def.h @@ -0,0 +1,21 @@ +#include +/* + * ~ lexi hale + * define flags so we can reason about + * our environment. */ + +#if (KVos == lin) ||\ + (KVos == fbsd) ||\ + (KVos == obsd) ||\ + (KVos == nbsd) ||\ + (KVos == dar) ||\ + (KVos == and) +# define KFenv_unix +#endif + +#if defined(KFenv_unix) ||\ + (KVos == hai) ||\ + (KVos == mgw) +# define KFenv_posix +#endif + ADDED kcore/def.win.i Index: kcore/def.win.i ================================================================== --- kcore/def.win.i +++ kcore/def.win.i @@ -0,0 +1,2 @@ +#define KVos win +typedef u32 stat; Index: kcore/makefile ================================================================== --- kcore/makefile +++ kcore/makefile @@ -25,13 +25,13 @@ # generating C source in makeā€¦ yaaay define arch = ${TMP}/type.$(1).%.$(2).i: type.$(1).$(2).i def.%.i ${TMP} echo '#ifndef KItype' > $$@ echo '#define KItype' >> $$@ - cat def.$$*.i >> $$@ cat $$< >> $$@ + cat def.$$*.i >> $$@ echo '#endif' >> $$@ endef $(eval $(call arch,x86,32)) $(eval $(call arch,x86,64)) ADDED kgraft/attach.exe.c Index: kgraft/attach.exe.c ================================================================== --- kgraft/attach.exe.c +++ kgraft/attach.exe.c @@ -0,0 +1,4 @@ +#include +stat entry(kenv e) { + return 0; +} DELETED kgraft/exe.attach.c Index: kgraft/exe.attach.c ================================================================== --- kgraft/exe.attach.c +++ kgraft/exe.attach.c @@ -1,4 +0,0 @@ -#include -stat entry(kenv e) { - return 0; -} Index: kio/io.h ================================================================== --- kio/io.h +++ kio/io.h @@ -6,11 +6,13 @@ * structures. it is the same for all platforms. * platform-specific code is found in the *.platform.h * files. */ +#include #include +#include typedef enum kiostream_kind { kiostream_closed, // this kiostream cannot be written to kiostream_file, @@ -38,16 +40,19 @@ // text can be read from this stream kiostream out; // text can be written to this stream } kiochan; -unsigned long long kiosend(kiochan); // send data to a channel -unsigned long long kiorecv(kiochan); // receive data from a channel - typedef enum kiocond { kiocond_ok, // success kiocond_fail, // action failed } kiocond; +kiocond kiosend(kiochan, ksraw, sz*); // send data to a channel +kiocond kiorecv(kiochan, ksraw*); // receive data from a channel +kmptr kiorecvall(kiochan, kmcell*, kmkind); // automatically allocate a bufer for a channel + // kmkind is only used if kmcell* is NULL +kiocond kiocon(kiochan, kiochan); // connect one channel to another + #endif ADDED kio/kio_posix_fd_write.fn.x86.lin.32.s Index: kio/kio_posix_fd_write.fn.x86.lin.32.s ================================================================== --- kio/kio_posix_fd_write.fn.x86.lin.32.s +++ kio/kio_posix_fd_write.fn.x86.lin.32.s @@ -0,0 +1,14 @@ +bits 32 +global kio_posix_fd_write + +%include "../arch/x86.lin.32.s" +; vim: ft=nasm + +kio_posix_fd_write: + mov sys.reg.0, sys.call.write + mov sys.reg.1, [esp + 4] ; holy god but this took the most + mov sys.reg.2, [esp + 8] ; stupidly long time to fucking + mov sys.reg.3, [esp + 12]; figure out + sys.call + ret + ADDED kio/kio_posix_fd_write.fn.x86.lin.64.s Index: kio/kio_posix_fd_write.fn.x86.lin.64.s ================================================================== --- kio/kio_posix_fd_write.fn.x86.lin.64.s +++ kio/kio_posix_fd_write.fn.x86.lin.64.s @@ -0,0 +1,14 @@ +bits 64 +global kio_posix_fd_write + +%include "../arch/x86.lin.64.s" +; vim: ft=nasm + +kio_posix_fd_write: + mov sys.reg.0, sys.write + ; mov sys.reg.1, ccall.reg.0 - nop + ; mov sys.reg.2, ccall.reg.1 - nop + ; mov sys.reg.3, ccall.reg.2 - nop + sys.call + ret + DELETED kio/kio_posix_fd_write.x86.lin.32.s Index: kio/kio_posix_fd_write.x86.lin.32.s ================================================================== --- kio/kio_posix_fd_write.x86.lin.32.s +++ kio/kio_posix_fd_write.x86.lin.32.s @@ -1,14 +0,0 @@ -bits 32 -global kio_posix_fd_write - -%include "../arch/x86.lin.32.s" -; vim: ft=nasm - -kio_posix_fd_write: - mov sys.reg.0, sys.call.write - mov sys.reg.1, [esp + 4] ; holy god but this took the most - mov sys.reg.2, [esp + 8] ; stupidly long time to fucking - mov sys.reg.3, [esp + 12]; figure out - sys.call - ret - DELETED kio/kio_posix_fd_write.x86.lin.64.s Index: kio/kio_posix_fd_write.x86.lin.64.s ================================================================== --- kio/kio_posix_fd_write.x86.lin.64.s +++ kio/kio_posix_fd_write.x86.lin.64.s @@ -1,14 +0,0 @@ -bits 64 -global kio_posix_fd_write - -%include "../arch/x86.lin.64.s" -; vim: ft=nasm - -kio_posix_fd_write: - mov sys.reg.0, sys.write - ; mov sys.reg.1, ccall.reg.0 - nop - ; mov sys.reg.2, ccall.reg.1 - nop - ; mov sys.reg.3, ccall.reg.2 - nop - sys.call - ret - ADDED kio/send.fn.c Index: kio/send.fn.c ================================================================== --- kio/send.fn.c +++ kio/send.fn.c @@ -0,0 +1,33 @@ +#include +#include +#include +/* send.c - kiosend() + * ~ lexi hale + * kiosend() writes to a channel with an open out stream + */ + +// 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 +extern sz kio_posix_fd_write(int fd, const char* buf, sz len); + +kiocond kiosend(kiochan target, ksraw string, sz* len) { +# ifdef KFenv_posix + sz size = kio_posix_fd_write(target.out.platform_fd, string.ptr, string.size); + if (size == -1) return kiocond_fail; //TODO: retrieve errno and offer more specific errors +# else +# if KVos == win +# error windows IO send function not yet defined +# else + _Pragma("GCC diagnostic error \"" // fancy error for gcc + "IO send fn for platform " #KVos " not defined" + "\"")) +# error IO send fn not defined for platform + // boring error for plebs +# endif +# endif + + if (len != null) *len = size; + return kiocond_ok; +} Index: libk.md ================================================================== --- libk.md +++ libk.md @@ -101,19 +101,23 @@ total segregation is maintained between source code, temporary files, and output objects. source is found in module directories (`k*/`). the destination for temporary files and output objects are retargetable via the `make` parameters `TMP= OUT=`, but default to `tmp/` and `out/`, which are excluded from repo with fossil's `ignore-glob` setting. all libk code is dispersed into modules: `kcore` for internals, `kio` for I/O, `kgraft` for binary packing, etc. each module has a folder in the root directory. (libk does not have submodules.) inside each module's directory should be a header with the same name as the module (see **naming conventions** above). -each function should be kept in a separate file within its module's directory. when OS or architecture-specific code is needed, the file's name should be a list of one or more of the fields [arch, OS, bits, format] separated by a `.` -- for instance, the 32-bit x86 haiku version of a function called `write` defined in assembly would be named `write.x86.hai.32.s`. however, if a function has an extraordinarily large number of versions, they may instead be stored in a folder with the same name as the function. +each function should be kept in a separate file within its module's directory. the file's name should consist of the dot-separated fields [name, class, "c"] for C sources, or [name, class, arch, OS, bits, format, "s"] for assembly sources, where "name" is the name of the function without the module prefix and "class" is `rt` if the file is part of the libk runtime, or `fn` otherwise. this distinction is necessary because while the static library `libk.a` can include runtime objects, the shared library `libk.so` cannot. examples: + + * a C file in the module `kstr` named `kscomp` would be named `kstr/comp.fn.c` + * a runtime assembly file called `boot` in the module `kcore` for x86-64 linux would be named `kcore/boot.rt.x86.lin.64.s` + * the 32-bit x86 haiku version of a function called `kiowrite` defined in assembly would be named `kio/write.fn.x86.hai.32.s`. each module should have a header named the same thing as the module except without the `k` prefix. (e.g. the header for `kio` is `kio/io.h`) located in its folder. this is the header that the end-user will be importing, and should handle any user-defined flags to present the API the user has selected. each module directory should contain a makefile that can build that module. see **makefiles** below. all makefiles should be named `makefile` (**not** `Makefile`). each module should contain a markdown file. this file's name should be the name of the parent directory suffixed with `.md`; for instance, `kterm` should contain the file `kterm/kterm.md`. this file should document the module as thoroughly as possible -each module may contain any number of files of the name `exe.*.c`. this files will be treated as *tools* by the build system and compiled as executables, rather than libraries. they should be compiled to `out/$module.$tool` +each module may contain any number of files of the name `*.exe.c`. this files will be treated as *tools* by the build system and compiled as executables, rather than libraries. they should be compiled to `out/$module.$tool` the repository root and each module may also contain the directory `misc`. this directory may be used to store miscellaneous data such as ABI references, developer discussions, and roadmaps. if the `misc` directory is deleted, this must not affect the library or build system's function in any way - that is, nothing outside a `misc` folder may reference a `misc` folder or anything inside it, including documentation. the `misc` directory should be removed when its contents are no longer needed. in most cases, the repository wiki and forum should be used instead of the `misc` folder. the folder `arch` in the root of the repository contains syscall tables and ABI implementations for various architectures. Index: makefile ================================================================== --- makefile +++ makefile @@ -6,13 +6,34 @@ export TMP = $(PWD)/tmp export TARGET = $(ARCH).$(OS).$(BITS) moddirs = $(wildcard k*) -binaries = $(wildcard */exe.*.c) +binaries = $(wildcard k*/*.exe.c) +functions = $(wildcard k*/*.fn.c) +assemblies = $(wildcard k*/*.fn.${TARGET}.s) binmods = $(sort $(dir $(binaries))) +# i'm sorry +collect = $(strip $(foreach dir,$(moddirs),$(addprefix $(OUT)/$(dir).,$(notdir $(wildcard $(dir)/$1))))) + +cfnsources = $(call collect,*.fn.c) +sfnsources = $(call collect,*.fn.${TARGET}.s) +crtsources = $(call collect,*.rt.c) +srtsources = $(call collect,*.rt.${TARGET}.s) +fnsources = $(cfnsources) $(sfnsources) +rtsources = $(crtsources) $(srtsources) +sources = $(fnsources) $(rtsources) + +cfnobjects = $(cfnsources:%.c=%.o) +sfnobjects = $(sfnsources:%.s=%.o) +crtobjects = $(crtsources:%.c=%.o) +srtobjects = $(srtsources:%.s=%.o) +fnobjects = $(cfnobjects) $(sfnobjects) +rtobjects = $(crtobjects) $(srtobjects) +objects = $(fnobjects) $(rtobjects) + header-dir = /usr/include lib-dir = /usr/lib posix-oses = lin fbsd dar and hai mgw @@ -25,11 +46,11 @@ # include libgcc.a in gcc builds, just in case ifeq ($(CC),gcc) export COMPLIB = -lgcc endif -all: defs obj tool lib.static lib.shared +all: $(OUT) defs obj tool lib.static $(OUT)/boot.o lib.shared lib.static: defs obj $(OUT)/libk.a lib.shared: defs obj $(OUT)/libk.so obj: $(moddirs:%=%.obj) defs: $(moddirs:%=%.def) tool: $(OUT)/libk.a $(binmods:%=%.tool) @@ -44,11 +65,11 @@ $(lib-dir)/k/ -o root -g wheel -m 0644 uninstall: $(header-dir)/k $(lib-dir)/k rm -rf $^ -lists = moddirs objects binaries binmods POSIX +lists = moddirs functions assemblies cfnobjects sfnobjects crtobjects srtobjects 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 @@ -63,20 +84,20 @@ cd $* && $(MAKE) def %.calls: arch/makefile cd arch && $(MAKE) $(TMP)/calls.$*.s -$(OUT)/libk.so: obj $(OUT) $(OUT)/boot.o - ld -shared $(COMPLIB) -o $@ $(filter-out kcore.boot.%, $(wildcard *.o)) - # $(CC) -shared -fPIC -nostdlib $(COMPLIB) -o $@ $(OUT)/*.o +$(OUT)/libk.so: $(fnobjects) + ld -shared $(COMPLIB) -o $@ $^ + @# $(CC) -shared -fPIC -nostdlib $(COMPLIB) -o $@ $(OUT)/*.o -$(OUT)/boot.o: $(OUT)/kcore.boot.o $(OUT)/kcore.boot.$(TARGET).o +$(OUT)/boot.o: $(rtobjects) ld -r $^ -o $(OUT)/boot.o -$(OUT)/libk.a: obj $(OUT) - # using `ar rc` and ranlib here instead of - # `ar rcs` in case `ar` isn't the GNU version +$(OUT)/libk.a: $(fnobjects) $(rtobjects) obj $(OUT) + @# using `ar rc` and ranlib here instead of + @# `ar rcs` in case `ar` isn't the GNU version ar rc $@ $(OUT)/*.o ranlib $@ $(OUT) $(OUT)/k: mkdir -p $@ Index: modmake ================================================================== --- modmake +++ modmake @@ -6,20 +6,20 @@ mod = $(notdir $(PWD)) src = $(wildcard *.c) $(wildcard *.s) bare = $(mod:k%=%) headers = $(wildcard *.h) $(gen-headers) -tools = $(filter exe.%.c, $(src)) -nontools = $(filter-out exe.%.c, $(src)) +tools = $(filter %.exe.c, $(src)) +nontools = $(filter-out %.exe.c, $(src)) cobjects = $(filter %.c, $(nontools)) sobjects = $(filter %.${TARGET}.s, $(nontools)) cflags = -isystem ${OUT} -fPIC -nostdlib ${COMPLIB} -L${OUT} -lk obj: $(cobjects:%.c=${OUT}/$(mod).%.o) \ $(sobjects:%.s=${OUT}/$(mod).%.o) -tool: $(tools:exe.%.c=${OUT}/$(mod).%) \ +tool: $(tools:%.exe.c=${OUT}/$(mod).%) \ ${OUT}/libk.a def: $(headers:%=${OUT}/k/%) dbg: @@ -34,11 +34,11 @@ $(CC) $(cflags) -c $< -o $@ ${OUT}/k/%.h: %.h cp $< $@ -${OUT}/$(mod).%: exe.%.c +${OUT}/$(mod).%: %.exe.c $(CC) $(cflags) $< -o $@ ${TMP}: mkdir -p ${TMP}