From c92305221770bb1316d026c200d569ca4e930e42 Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Thu, 28 Aug 2025 16:20:17 -0400 Subject: merge libc files, new init methods for libjove --- Makefile | 2 +- apps/init/arch/x86_64/paging.c | 8 +- apps/init/main.c | 13 +- config.mk | 5 +- initrd/files/bin/init | Bin 20784 -> 20800 bytes lib/libc-headless/Makefile | 15 -- lib/libc-headless/ctype/toupper.c | 9 - lib/libc-headless/include/ctype.h | 7 - lib/libc-headless/include/errno.h | 0 lib/libc-headless/include/stdint.h | 319 --------------------------------- lib/libc-headless/include/stdio.h | 32 ---- lib/libc-headless/include/stdlib.h | 17 -- lib/libc-headless/include/string.h | 11 -- lib/libc-headless/include/sys/types.h | 6 - lib/libc-headless/include/time.h | 4 - lib/libc-headless/include/unistd.h | 11 -- lib/libc-headless/stdio/sprintf.c | 124 ------------- lib/libc-headless/string/memcpy.c | 10 -- lib/libc-headless/string/memset.c | 7 - lib/libc-jove/Makefile | 15 -- lib/libc-jove/stdlib/heap.c | 139 -------------- lib/libc-jove/stdlib/heap.h | 19 -- lib/libc/Makefile | 15 ++ lib/libc/ctype/toupper.c | 9 + lib/libc/include/assert.h | 16 ++ lib/libc/include/ctype.h | 7 + lib/libc/include/errno.h | 0 lib/libc/include/stdint.h | 319 +++++++++++++++++++++++++++++++++ lib/libc/include/stdio.h | 32 ++++ lib/libc/include/stdlib.h | 21 +++ lib/libc/include/string.h | 11 ++ lib/libc/include/sys/types.h | 6 + lib/libc/include/time.h | 4 + lib/libc/include/unistd.h | 11 ++ lib/libc/stdio/sprintf.c | 124 +++++++++++++ lib/libc/stdlib/malloc.c | 9 + lib/libc/string/memcpy.c | 10 ++ lib/libc/string/memset.c | 7 + lib/libjove/Makefile | 4 +- lib/libjove/arch/x86_64/libjove.c | 14 ++ lib/libjove/heap/heap.c | 142 +++++++++++++++ lib/libjove/heap/heap.h | 19 ++ lib/libjove/include/arch/x86_64/jove.h | 6 + lib/libjove/libjove.c | 34 ++++ 44 files changed, 831 insertions(+), 762 deletions(-) delete mode 100644 lib/libc-headless/Makefile delete mode 100644 lib/libc-headless/ctype/toupper.c delete mode 100644 lib/libc-headless/include/ctype.h delete mode 100644 lib/libc-headless/include/errno.h delete mode 100644 lib/libc-headless/include/stdint.h delete mode 100644 lib/libc-headless/include/stdio.h delete mode 100644 lib/libc-headless/include/stdlib.h delete mode 100644 lib/libc-headless/include/string.h delete mode 100644 lib/libc-headless/include/sys/types.h delete mode 100644 lib/libc-headless/include/time.h delete mode 100644 lib/libc-headless/include/unistd.h delete mode 100644 lib/libc-headless/stdio/sprintf.c delete mode 100644 lib/libc-headless/string/memcpy.c delete mode 100644 lib/libc-headless/string/memset.c delete mode 100644 lib/libc-jove/Makefile delete mode 100644 lib/libc-jove/stdlib/heap.c delete mode 100644 lib/libc-jove/stdlib/heap.h create mode 100644 lib/libc/Makefile create mode 100644 lib/libc/ctype/toupper.c create mode 100644 lib/libc/include/assert.h create mode 100644 lib/libc/include/ctype.h create mode 100644 lib/libc/include/errno.h create mode 100644 lib/libc/include/stdint.h create mode 100644 lib/libc/include/stdio.h create mode 100644 lib/libc/include/stdlib.h create mode 100644 lib/libc/include/string.h create mode 100644 lib/libc/include/sys/types.h create mode 100644 lib/libc/include/time.h create mode 100644 lib/libc/include/unistd.h create mode 100644 lib/libc/stdio/sprintf.c create mode 100644 lib/libc/stdlib/malloc.c create mode 100644 lib/libc/string/memcpy.c create mode 100644 lib/libc/string/memset.c create mode 100644 lib/libjove/arch/x86_64/libjove.c create mode 100644 lib/libjove/heap/heap.c create mode 100644 lib/libjove/heap/heap.h create mode 100644 lib/libjove/include/arch/x86_64/jove.h diff --git a/Makefile b/Makefile index c9eb674..cbb52f4 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ $(SYSROOTDIR)/lib/%.a : $(SYSROOTDIR) FORCE .PHONY: $(SYSROOTDIR)/usr/include $(SYSROOTDIR)/usr/include: rm -rf $(SYSROOTDIR)/usr/include - cp -r $(LIBDIR)/libc-headless/include $(SYSROOTDIR)/usr/include + cp -r $(LIBDIR)/libc/include $(SYSROOTDIR)/usr/include cp -r $(KERNELDIR)/include/ $(SYSROOTDIR)/usr/include/kernel cp -r $(LIBDIR)/libjove/include $(SYSROOTDIR)/usr/include/jove diff --git a/apps/init/arch/x86_64/paging.c b/apps/init/arch/x86_64/paging.c index 36fe950..1423bec 100644 --- a/apps/init/arch/x86_64/paging.c +++ b/apps/init/arch/x86_64/paging.c @@ -5,12 +5,10 @@ #include #include +extern void __libjove_pager_init(uint8_t); + void pager_setup(void) { - _jove_alloc_pagemap_inplace(&__jove_pagemap, &__rootdir, INIT_OBJECT_PAGEMAP); - - size_t lastfree = jove_objdir_lastmemb(&__rootdir) + 1; - __jove_work_obj.membi = lastfree; - __jove_work_obj.parent = &__rootdir; + __libjove_pager_init(INIT_OBJECT_PAGEMAP); } diff --git a/apps/init/main.c b/apps/init/main.c index 6deb12c..b802bf4 100644 --- a/apps/init/main.c +++ b/apps/init/main.c @@ -14,18 +14,19 @@ spin_fail(void) for(;;); } -extern void __libc_heap_init(uintptr_t); +extern void __libjove_init(uint8_t, void*); +extern void __libjove_init_untypeddir(uint8_t); +extern void __libjove_heap_init(uintptr_t); void main(void *message_ptr) { - __jove_syscall_obj = INIT_OBJECT_MESSAGE; - __jove_syscall_ptr = message_ptr; - _jove_alloc_objdir_inplace(&__jove_untyped_directory, &__rootdir, INIT_OBJECT_UNTYPED_DIR); + __libjove_init(INIT_OBJECT_MESSAGE, message_ptr); + __libjove_init_untypeddir(INIT_OBJECT_UNTYPED_DIR); + pager_setup(); + __libjove_heap_init((uintptr_t)message_ptr + KO_MESSAGE_BYTES); jove_kprintf("Hello, Userland!\n"); - pager_setup(); - __libc_heap_init((uintptr_t)message_ptr + KO_MESSAGE_BYTES); for(;;); } diff --git a/config.mk b/config.mk index f01a853..b17fb69 100644 --- a/config.mk +++ b/config.mk @@ -17,9 +17,8 @@ TARGET_BOOTLOADER = limine APPS := $(INITRDDIR)/files/bin/init -STATICLIBS := $(SYSROOTDIR)/lib/libc-jove.a \ - $(SYSROOTDIR)/lib/libjove.a \ - $(SYSROOTDIR)/lib/libc-headless.a \ +STATICLIBS := $(SYSROOTDIR)/lib/libjove.a \ + $(SYSROOTDIR)/lib/libc.a CC := $(TOOLSDIR)/bin/$(TARGET_TRIPLET)-gcc LD := $(TOOLSDIR)/bin/$(TARGET_TRIPLET)-ld diff --git a/initrd/files/bin/init b/initrd/files/bin/init index 575c604..40e3105 100755 Binary files a/initrd/files/bin/init and b/initrd/files/bin/init differ diff --git a/lib/libc-headless/Makefile b/lib/libc-headless/Makefile deleted file mode 100644 index 59de6c8..0000000 --- a/lib/libc-headless/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include $(CONFIG) - -CDIRS := stdio ctype string - -CFILES += $(foreach dir,$(CDIRS),$(wildcard $(dir)/*.c)) - -OFILES := $(patsubst %.c,%.o,$(CFILES)) - -CFLAGS := -ffreestanding -nostdlib - -all: ${OFILES} - ar rcs $(OUT)/libc-headless.a $(OFILES) - -%.o:%.c - $(CC) $(CFLAGS) -c $< -o $@ diff --git a/lib/libc-headless/ctype/toupper.c b/lib/libc-headless/ctype/toupper.c deleted file mode 100644 index fe1e1e2..0000000 --- a/lib/libc-headless/ctype/toupper.c +++ /dev/null @@ -1,9 +0,0 @@ -#include - -/* TODO: Faster toupper */ -int -toupper(int c) -{ - if(c >= 'a' && c <= 'z') c += 'A' - 'a'; - return c; -} diff --git a/lib/libc-headless/include/ctype.h b/lib/libc-headless/include/ctype.h deleted file mode 100644 index 9dfcc3b..0000000 --- a/lib/libc-headless/include/ctype.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _CTYPE_H -#define _CTYPE_H 1 - -int toupper(int c); -int tolower(int c); - -#endif diff --git a/lib/libc-headless/include/errno.h b/lib/libc-headless/include/errno.h deleted file mode 100644 index e69de29..0000000 diff --git a/lib/libc-headless/include/stdint.h b/lib/libc-headless/include/stdint.h deleted file mode 100644 index 165a201..0000000 --- a/lib/libc-headless/include/stdint.h +++ /dev/null @@ -1,319 +0,0 @@ -/* Copyright (C) 1997-2023 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -/* - * ISO C99: 7.18 Integer types - */ - -#ifndef _STDINT_H -#define _STDINT_H 1 - -#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION -#include -#include -#include -#include - -/* Exact integral types. */ - -/* Signed. */ -#include - -/* Unsigned. */ -#include - - -/* Small types. */ - -/* Signed. */ -typedef __int_least8_t int_least8_t; -typedef __int_least16_t int_least16_t; -typedef __int_least32_t int_least32_t; -typedef __int_least64_t int_least64_t; - -/* Unsigned. */ -typedef __uint_least8_t uint_least8_t; -typedef __uint_least16_t uint_least16_t; -typedef __uint_least32_t uint_least32_t; -typedef __uint_least64_t uint_least64_t; - - -/* Fast types. */ - -/* Signed. */ -typedef signed char int_fast8_t; -#if __WORDSIZE == 64 -typedef long int int_fast16_t; -typedef long int int_fast32_t; -typedef long int int_fast64_t; -#else -typedef int int_fast16_t; -typedef int int_fast32_t; -__extension__ -typedef long long int int_fast64_t; -#endif - -/* Unsigned. */ -typedef unsigned char uint_fast8_t; -#if __WORDSIZE == 64 -typedef unsigned long int uint_fast16_t; -typedef unsigned long int uint_fast32_t; -typedef unsigned long int uint_fast64_t; -#else -typedef unsigned int uint_fast16_t; -typedef unsigned int uint_fast32_t; -__extension__ -typedef unsigned long long int uint_fast64_t; -#endif - - -/* Types for `void *' pointers. */ -#if __WORDSIZE == 64 -# ifndef __intptr_t_defined -typedef long int intptr_t; -# define __intptr_t_defined -# endif -typedef unsigned long int uintptr_t; -#else -# ifndef __intptr_t_defined -typedef int intptr_t; -# define __intptr_t_defined -# endif -typedef unsigned int uintptr_t; -#endif - - -/* Largest integral types. */ -typedef __intmax_t intmax_t; -typedef __uintmax_t uintmax_t; - - -# if __WORDSIZE == 64 -# define __INT64_C(c) c ## L -# define __UINT64_C(c) c ## UL -# else -# define __INT64_C(c) c ## LL -# define __UINT64_C(c) c ## ULL -# endif - -/* Limits of integral types. */ - -/* Minimum of signed integral types. */ -# define INT8_MIN (-128) -# define INT16_MIN (-32767-1) -# define INT32_MIN (-2147483647-1) -# define INT64_MIN (-__INT64_C(9223372036854775807)-1) -/* Maximum of signed integral types. */ -# define INT8_MAX (127) -# define INT16_MAX (32767) -# define INT32_MAX (2147483647) -# define INT64_MAX (__INT64_C(9223372036854775807)) - -/* Maximum of unsigned integral types. */ -# define UINT8_MAX (255) -# define UINT16_MAX (65535) -# define UINT32_MAX (4294967295U) -# define UINT64_MAX (__UINT64_C(18446744073709551615)) - - -/* Minimum of signed integral types having a minimum size. */ -# define INT_LEAST8_MIN (-128) -# define INT_LEAST16_MIN (-32767-1) -# define INT_LEAST32_MIN (-2147483647-1) -# define INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1) -/* Maximum of signed integral types having a minimum size. */ -# define INT_LEAST8_MAX (127) -# define INT_LEAST16_MAX (32767) -# define INT_LEAST32_MAX (2147483647) -# define INT_LEAST64_MAX (__INT64_C(9223372036854775807)) - -/* Maximum of unsigned integral types having a minimum size. */ -# define UINT_LEAST8_MAX (255) -# define UINT_LEAST16_MAX (65535) -# define UINT_LEAST32_MAX (4294967295U) -# define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615)) - - -/* Minimum of fast signed integral types having a minimum size. */ -# define INT_FAST8_MIN (-128) -# if __WORDSIZE == 64 -# define INT_FAST16_MIN (-9223372036854775807L-1) -# define INT_FAST32_MIN (-9223372036854775807L-1) -# else -# define INT_FAST16_MIN (-2147483647-1) -# define INT_FAST32_MIN (-2147483647-1) -# endif -# define INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1) -/* Maximum of fast signed integral types having a minimum size. */ -# define INT_FAST8_MAX (127) -# if __WORDSIZE == 64 -# define INT_FAST16_MAX (9223372036854775807L) -# define INT_FAST32_MAX (9223372036854775807L) -# else -# define INT_FAST16_MAX (2147483647) -# define INT_FAST32_MAX (2147483647) -# endif -# define INT_FAST64_MAX (__INT64_C(9223372036854775807)) - -/* Maximum of fast unsigned integral types having a minimum size. */ -# define UINT_FAST8_MAX (255) -# if __WORDSIZE == 64 -# define UINT_FAST16_MAX (18446744073709551615UL) -# define UINT_FAST32_MAX (18446744073709551615UL) -# else -# define UINT_FAST16_MAX (4294967295U) -# define UINT_FAST32_MAX (4294967295U) -# endif -# define UINT_FAST64_MAX (__UINT64_C(18446744073709551615)) - - -/* Values to test for integral types holding `void *' pointer. */ -# if __WORDSIZE == 64 -# define INTPTR_MIN (-9223372036854775807L-1) -# define INTPTR_MAX (9223372036854775807L) -# define UINTPTR_MAX (18446744073709551615UL) -# else -# define INTPTR_MIN (-2147483647-1) -# define INTPTR_MAX (2147483647) -# define UINTPTR_MAX (4294967295U) -# endif - - -/* Minimum for largest signed integral type. */ -# define INTMAX_MIN (-__INT64_C(9223372036854775807)-1) -/* Maximum for largest signed integral type. */ -# define INTMAX_MAX (__INT64_C(9223372036854775807)) - -/* Maximum for largest unsigned integral type. */ -# define UINTMAX_MAX (__UINT64_C(18446744073709551615)) - - -/* Limits of other integer types. */ - -/* Limits of `ptrdiff_t' type. */ -# if __WORDSIZE == 64 -# define PTRDIFF_MIN (-9223372036854775807L-1) -# define PTRDIFF_MAX (9223372036854775807L) -# else -# if __WORDSIZE32_PTRDIFF_LONG -# define PTRDIFF_MIN (-2147483647L-1) -# define PTRDIFF_MAX (2147483647L) -# else -# define PTRDIFF_MIN (-2147483647-1) -# define PTRDIFF_MAX (2147483647) -# endif -# endif - -/* Limits of `sig_atomic_t'. */ -# define SIG_ATOMIC_MIN (-2147483647-1) -# define SIG_ATOMIC_MAX (2147483647) - -/* Limit of `size_t' type. */ -# if __WORDSIZE == 64 -# define SIZE_MAX (18446744073709551615UL) -# else -# if __WORDSIZE32_SIZE_ULONG -# define SIZE_MAX (4294967295UL) -# else -# define SIZE_MAX (4294967295U) -# endif -# endif - -/* Limits of `wchar_t'. */ -# ifndef WCHAR_MIN -/* These constants might also be defined in . */ -# define WCHAR_MIN __WCHAR_MIN -# define WCHAR_MAX __WCHAR_MAX -# endif - -/* Limits of `wint_t'. */ -# define WINT_MIN (0u) -# define WINT_MAX (4294967295u) - -/* Signed. */ -# define INT8_C(c) c -# define INT16_C(c) c -# define INT32_C(c) c -# if __WORDSIZE == 64 -# define INT64_C(c) c ## L -# else -# define INT64_C(c) c ## LL -# endif - -/* Unsigned. */ -# define UINT8_C(c) c -# define UINT16_C(c) c -# define UINT32_C(c) c ## U -# if __WORDSIZE == 64 -# define UINT64_C(c) c ## UL -# else -# define UINT64_C(c) c ## ULL -# endif - -/* Maximal type. */ -# if __WORDSIZE == 64 -# define INTMAX_C(c) c ## L -# define UINTMAX_C(c) c ## UL -# else -# define INTMAX_C(c) c ## LL -# define UINTMAX_C(c) c ## ULL -# endif - -#if __GLIBC_USE (IEC_60559_BFP_EXT_C2X) - -# define INT8_WIDTH 8 -# define UINT8_WIDTH 8 -# define INT16_WIDTH 16 -# define UINT16_WIDTH 16 -# define INT32_WIDTH 32 -# define UINT32_WIDTH 32 -# define INT64_WIDTH 64 -# define UINT64_WIDTH 64 - -# define INT_LEAST8_WIDTH 8 -# define UINT_LEAST8_WIDTH 8 -# define INT_LEAST16_WIDTH 16 -# define UINT_LEAST16_WIDTH 16 -# define INT_LEAST32_WIDTH 32 -# define UINT_LEAST32_WIDTH 32 -# define INT_LEAST64_WIDTH 64 -# define UINT_LEAST64_WIDTH 64 - -# define INT_FAST8_WIDTH 8 -# define UINT_FAST8_WIDTH 8 -# define INT_FAST16_WIDTH __WORDSIZE -# define UINT_FAST16_WIDTH __WORDSIZE -# define INT_FAST32_WIDTH __WORDSIZE -# define UINT_FAST32_WIDTH __WORDSIZE -# define INT_FAST64_WIDTH 64 -# define UINT_FAST64_WIDTH 64 - -# define INTPTR_WIDTH __WORDSIZE -# define UINTPTR_WIDTH __WORDSIZE - -# define INTMAX_WIDTH 64 -# define UINTMAX_WIDTH 64 - -# define PTRDIFF_WIDTH __WORDSIZE -# define SIG_ATOMIC_WIDTH 32 -# define SIZE_WIDTH __WORDSIZE -# define WCHAR_WIDTH 32 -# define WINT_WIDTH 32 - -#endif - -#endif /* stdint.h */ diff --git a/lib/libc-headless/include/stdio.h b/lib/libc-headless/include/stdio.h deleted file mode 100644 index cd29004..0000000 --- a/lib/libc-headless/include/stdio.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _STDIO_H -#define _STDIO_H 1 - -#include -#include - -#define SEEK_SET 0 -typedef struct { int unused; } FILE; - -extern FILE *stderr; -#define stderr stderr - -int fclose(FILE *file); -int fflush(FILE *file); -FILE *fopen(const char *path, const char *flags); - -size_t fread(void *buf, size_t size, size_t nmemb, FILE* file); -int fseek(FILE *file, long offset, int whence); -long ftell(FILE *file); -size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *file); -void setbuf(FILE *file, char *buf); - -int fprintf(FILE *file, const char *fmt, ...); -int vfprintf(FILE *file, const char *fmt, va_list ap); - -int sprintf(char *restrict str, const char *restrict format, ...); -int vsprintf(char *restrict str, const char *restrict format, va_list ap); - -int snprintf(char *restrict str, size_t size, const char *restrict format, ...); -int vsnprintf(char *restrict str, size_t size, const char *restrict format, va_list ap); - -#endif diff --git a/lib/libc-headless/include/stdlib.h b/lib/libc-headless/include/stdlib.h deleted file mode 100644 index f29cce7..0000000 --- a/lib/libc-headless/include/stdlib.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _STDLIB_H -#define _STDLIB_H 1 - -#include - -__attribute__((noreturn)) void abort(void); -int atexit(void (*callback)(void)); - -int atoi(const char*); - -void free(void *ptr); -void *malloc(size_t size); -void *calloc(size_t nmemb, size_t size); - -char *getenv(const char *key); - -#endif diff --git a/lib/libc-headless/include/string.h b/lib/libc-headless/include/string.h deleted file mode 100644 index d55bc37..0000000 --- a/lib/libc-headless/include/string.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _STRING_H -#define _STRING_H 1 - -#include - -void *memcpy(void *dest, const void *src, size_t size); -void *memset(void *dest, int byte, size_t size); -char *strcpy(char *dest, const char *src); -size_t strlen(const char *str); - -#endif diff --git a/lib/libc-headless/include/sys/types.h b/lib/libc-headless/include/sys/types.h deleted file mode 100644 index 058c38a..0000000 --- a/lib/libc-headless/include/sys/types.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _SYS_TYPES_H -#define _SYS_TYPES_H 1 - -typedef int pid_t; - -#endif diff --git a/lib/libc-headless/include/time.h b/lib/libc-headless/include/time.h deleted file mode 100644 index c73ee97..0000000 --- a/lib/libc-headless/include/time.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef _TIME_H -#define _TIME_H 1 - -#endif diff --git a/lib/libc-headless/include/unistd.h b/lib/libc-headless/include/unistd.h deleted file mode 100644 index 4e14be9..0000000 --- a/lib/libc-headless/include/unistd.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _UNISTD_H -#define _UNISTD_H 1 - -#include - -int execv(const char *pathname, char *const argv[]); -int execve(const char *pathname, char *const argv[], char *const envp[]); -int execvp(const char *pathname, char *const argv[]); -pid_t fork(void); - -#endif diff --git a/lib/libc-headless/stdio/sprintf.c b/lib/libc-headless/stdio/sprintf.c deleted file mode 100644 index dd78572..0000000 --- a/lib/libc-headless/stdio/sprintf.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#include -#include - -#define VSNPRINTF_PUTC(c) if(size > written) str[written++] = c; else written++ - -int -vsnprintf(char *restrict str, size_t size, const char *restrict format, va_list ap) -{ - int written = 0; - for(int fmti = 0; format[fmti] != 0; fmti++) { - char fmtc = format[fmti]; - if(fmtc != '%') { - VSNPRINTF_PUTC(fmtc); - continue; - } - - /* Flags */ - bool alternate = false; - bool zeropad = false; - bool leftadj = false; - bool signspace = false; - bool showplus = false; - fmtc = format[++fmti]; - - switch(fmtc) { - case '#': alternate = true; fmti++; break; - case '0': zeropad = true; fmti++; break; - case '-': leftadj = true; fmti++; break; - case ' ': signspace = true; fmti++; break; - case '+': showplus = true; fmti++; break; - default: break; - } - - /* Field width. */ - fmtc = format[fmti]; - //TODO: Implement field width - - /* Precision. */ - fmtc = format[fmti]; - //TODO: Implement precision - - /* Length modifier */ - fmtc = format[fmti]; - //TODO: Implement length modifier. - - /* Conversion specifier. */ - bool is_signed = true; - bool is_caps = false; - int radix = 10; - fmtc = format[fmti]; - switch(fmtc) - { - case 'X': - is_caps = true; - case 'x': - radix = 16; - case 'u': - is_signed = false; - case 'd': - case 'i': - goto conversion_int; - case 'p': - alternate = true; - radix = 16; - is_signed = false; - is_caps = true; - goto conversion_int; - case '%': - VSNPRINTF_PUTC('%'); - break; - } - continue; - -conversion_int: - { - uintmax_t value = va_arg(ap, uintmax_t); - bool negative = is_signed && (intmax_t)value < 0; - if(negative) value = (uintmax_t)(-(intmax_t)value); - size_t numc = 0; - - /*Count the number of characters to put in the buffer to represent - * the value in ASCII.*/ - for(uintmax_t v = value; v != 0; v /= radix, numc++); - if(numc == 0) numc++; - - /* Reserve space for alternate repersentation.*/ - if(showplus && !negative) { VSNPRINTF_PUTC('+'); } - if(negative) { VSNPRINTF_PUTC('-'); } - if(signspace && !negative) { VSNPRINTF_PUTC(' '); } - if(alternate) { - VSNPRINTF_PUTC('0'); - if(radix == 16) { - VSNPRINTF_PUTC('x'); - } - if(alternate && radix == 2) { - VSNPRINTF_PUTC('b'); - } - } - - /* Try to put characters into the buffer*/ - if(value == 0) { - VSNPRINTF_PUTC('0'); - } - else { - for(uintmax_t v = value, i = numc - 1; v != 0; v /= radix, i--) { - if(written + i >= size) continue; - int digit = v % radix; - char c = digit >= 10 ? (digit + 'a' - 10) : (digit + '0'); - if(is_caps) c = toupper(c); - str[written + i] = c; - } - written += numc; - } - continue; - } - } - VSNPRINTF_PUTC(0); - return written - 1; -} - - diff --git a/lib/libc-headless/string/memcpy.c b/lib/libc-headless/string/memcpy.c deleted file mode 100644 index f71444d..0000000 --- a/lib/libc-headless/string/memcpy.c +++ /dev/null @@ -1,10 +0,0 @@ -#include - -void* -memcpy(void *dest, const void *src, size_t n) -{ - const unsigned char *s = src; - for(unsigned char *d = dest; n; n--) - *(d++) = *(s++); - return dest; -} diff --git a/lib/libc-headless/string/memset.c b/lib/libc-headless/string/memset.c deleted file mode 100644 index f79a4b4..0000000 --- a/lib/libc-headless/string/memset.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -void -memset(void *s, int c, size_t n) -{ - for(unsigned char *sb = s; n; n--) *(sb++) = c; -} diff --git a/lib/libc-jove/Makefile b/lib/libc-jove/Makefile deleted file mode 100644 index a084ca6..0000000 --- a/lib/libc-jove/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include $(CONFIG) - -CDIRS := stdio ctype string stdlib - -CFILES += $(foreach dir,$(CDIRS),$(wildcard $(dir)/*.c)) - -OFILES := $(patsubst %.c,%.o,$(CFILES)) - -CFLAGS := -ffreestanding -nostdlib - -all: ${OFILES} - ar rcs $(OUT)/libc-jove.a $(OFILES) - -%.o:%.c - $(CC) $(CFLAGS) -c $< -o $@ diff --git a/lib/libc-jove/stdlib/heap.c b/lib/libc-jove/stdlib/heap.c deleted file mode 100644 index 034278c..0000000 --- a/lib/libc-jove/stdlib/heap.c +++ /dev/null @@ -1,139 +0,0 @@ -#include "heap.h" -#include -#include -#include -#include - -static heap_bin_t *freelist_tail; - -uintptr_t __heap_start; -uintptr_t __heap_end; - -#define HEAP_BIN_SIZE(bin) (bin->size_taken & (~1ULL)) -#define HEAP_BIN_TAKEN(bin) (bin->size_taken & 1) - -#define HEAP_BIN_AFTER(bin) ((heap_bin_t*)((uintptr_t)bin->data + HEAP_BIN_SIZE(bin) + sizeof(uintptr_t))) -#define HEAP_BIN_BEFORE(bin) ((heap_bin_t*)*((uintptr_t*)bin - 1)) - -static void -heap_grow(uintptr_t to) -{ - jove_mem_ensure_range(__heap_end, to); - __heap_end = to; -} - -static heap_bin_t* -heap_newbin(uintptr_t at, size_t size, heap_bin_t *next) -{ - uintptr_t headat = (at + sizeof(heap_bin_t) + size); - uintptr_t endat = headat + sizeof(uintptr_t); - - if(endat > __heap_end) heap_grow(endat); - - heap_bin_t *newbin = (heap_bin_t*)at; - newbin->size_taken = size; - newbin->next = next; - - *((uintptr_t*)headat) = at; - return newbin; -} - -static heap_bin_t* -heap_find_bestfit(size_t rsize) -{ - heap_bin_t *best = freelist_tail; - if(best == NULL) return NULL; - size_t bestsize = best->size_taken; - - for(heap_bin_t *bin = best->next; bin; bin = bin->next) - { - if(bin->size_taken < rsize) continue; - if(bin->size_taken < bestsize) { - best = bin; - bestsize = bin->size_taken; - } - } - return best; -} - -static void -heap_split(heap_bin_t *bin, size_t splitsize) -{ - size_t size_diff = bin->size_taken - splitsize; - if(size_diff < LIBC_HEAP_MINSPLIT) return; - - size_t newsize = size_diff - sizeof(heap_bin_t) - sizeof(uintptr_t); - uintptr_t newat = ((uintptr_t)bin->data) + splitsize + sizeof(uintptr_t); - jove_kprintf("Split %p to %p [%x]\n", bin, newat, newsize); - - bin->size_taken = splitsize; - freelist_tail = heap_newbin(newat, newsize, freelist_tail); -} - -static void* -heap_alloc(size_t size) -{ - if(size & 1) size++; - if(size < LIBC_HEAP_MINALLOC) size = LIBC_HEAP_MINALLOC; - - heap_bin_t *bestfit = heap_find_bestfit(size); - if(bestfit == NULL) { - bestfit = heap_newbin(__heap_end, size, NULL); - }else{ - if(bestfit == freelist_tail) { - freelist_tail = bestfit->next; - } - size_t bestsize = bestfit->size_taken; - - if(bestsize < size) { - jove_kprintf("Growing bin %p [%x] to %x\n", bestfit, bestsize, size); - heap_newbin((uintptr_t)bestfit, size, NULL); - }else if(bestsize > size) { - heap_split(bestfit, size); - } - } - bestfit->size_taken |= 1; - return bestfit->data; -} - -static void -heap_free(void *ptr) -{ - uintptr_t binptr = (uintptr_t)ptr - sizeof(heap_bin_t); - if(binptr > __heap_end || binptr < __heap_start) return; - - heap_bin_t *bin = (heap_bin_t*)binptr; - bin->size_taken &= ~1ULL; - bin->next = freelist_tail; - freelist_tail = bin; - -start_merge_loop: { - heap_bin_t *prevbin = HEAP_BIN_BEFORE(bin); - heap_bin_t *nextbin = HEAP_BIN_AFTER(bin); - - if((uintptr_t)prevbin >= __heap_start) { - if(!HEAP_BIN_TAKEN(prevbin)) { - jove_kprintf("Merge back bin %p into %p\n", bin, prevbin); - freelist_tail = prevbin; - prevbin->size_taken += bin->size_taken + sizeof(heap_bin_t) + sizeof(uintptr_t); - bin = prevbin; - goto start_merge_loop; - } - } - if((uintptr_t)nextbin < __heap_end) { - if(!HEAP_BIN_TAKEN(nextbin)) { - jove_kprintf("Merge forward bin %p into %p\n", bin, nextbin); - if(bin->next == nextbin) bin->next = nextbin->next; - bin->size_taken += nextbin->size_taken + sizeof(heap_bin_t) + sizeof(uintptr_t); - goto start_merge_loop; - } - } - } -} - -void -__libc_heap_init(uintptr_t program_end) -{ - __heap_start = __heap_end = program_end; - freelist_tail = heap_newbin(__heap_start, LIBC_HEAP_INIT_SIZE, NULL); -} diff --git a/lib/libc-jove/stdlib/heap.h b/lib/libc-jove/stdlib/heap.h deleted file mode 100644 index 9628444..0000000 --- a/lib/libc-jove/stdlib/heap.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _LIBC_JOVE_HEAP_H -#define _LIBC_JOVE_HEAP_H 1 - -#include -#include - -#define LIBC_HEAP_INIT_SIZE (0x1000) -#define LIBC_HEAP_MINALLOC (0x10) -#define LIBC_HEAP_MINSPLIT (sizeof(heap_bin_t) + sizeof(uintptr_t) + LIBC_HEAP_MINALLOC) - -typedef struct heap_bin { - struct heap_bin *next; - size_t size_taken; - char data[]; -} heap_bin_t; - -void __libc_heap_init(uintptr_t program_end); - -#endif diff --git a/lib/libc/Makefile b/lib/libc/Makefile new file mode 100644 index 0000000..8163b2e --- /dev/null +++ b/lib/libc/Makefile @@ -0,0 +1,15 @@ +include $(CONFIG) + +CDIRS := stdio ctype string + +CFILES += $(foreach dir,$(CDIRS),$(wildcard $(dir)/*.c)) + +OFILES := $(patsubst %.c,%.o,$(CFILES)) + +CFLAGS := -ffreestanding -nostdlib + +all: ${OFILES} + ar rcs $(OUT)/libc.a $(OFILES) + +%.o:%.c + $(CC) $(CFLAGS) -c $< -o $@ diff --git a/lib/libc/ctype/toupper.c b/lib/libc/ctype/toupper.c new file mode 100644 index 0000000..fe1e1e2 --- /dev/null +++ b/lib/libc/ctype/toupper.c @@ -0,0 +1,9 @@ +#include + +/* TODO: Faster toupper */ +int +toupper(int c) +{ + if(c >= 'a' && c <= 'z') c += 'A' - 'a'; + return c; +} diff --git a/lib/libc/include/assert.h b/lib/libc/include/assert.h new file mode 100644 index 0000000..4b8fbf8 --- /dev/null +++ b/lib/libc/include/assert.h @@ -0,0 +1,16 @@ +#ifndef _ASSERT_H +#define _ASSERT_H 1 + +#ifdef NDEBUG +#define assert(ignore)((void)0) +#else +#include +#define assert(condition) \ + if(!(condition)) { \ + fprintf(stderr, "%s:%s:%s: Assertion '%s' failed!\n", \ + __FILE__, __LINE__, __FUNCTION__, #condition); \ + abort(); \ + } +#endif + +#endif diff --git a/lib/libc/include/ctype.h b/lib/libc/include/ctype.h new file mode 100644 index 0000000..9dfcc3b --- /dev/null +++ b/lib/libc/include/ctype.h @@ -0,0 +1,7 @@ +#ifndef _CTYPE_H +#define _CTYPE_H 1 + +int toupper(int c); +int tolower(int c); + +#endif diff --git a/lib/libc/include/errno.h b/lib/libc/include/errno.h new file mode 100644 index 0000000..e69de29 diff --git a/lib/libc/include/stdint.h b/lib/libc/include/stdint.h new file mode 100644 index 0000000..165a201 --- /dev/null +++ b/lib/libc/include/stdint.h @@ -0,0 +1,319 @@ +/* Copyright (C) 1997-2023 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* + * ISO C99: 7.18 Integer types + */ + +#ifndef _STDINT_H +#define _STDINT_H 1 + +#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION +#include +#include +#include +#include + +/* Exact integral types. */ + +/* Signed. */ +#include + +/* Unsigned. */ +#include + + +/* Small types. */ + +/* Signed. */ +typedef __int_least8_t int_least8_t; +typedef __int_least16_t int_least16_t; +typedef __int_least32_t int_least32_t; +typedef __int_least64_t int_least64_t; + +/* Unsigned. */ +typedef __uint_least8_t uint_least8_t; +typedef __uint_least16_t uint_least16_t; +typedef __uint_least32_t uint_least32_t; +typedef __uint_least64_t uint_least64_t; + + +/* Fast types. */ + +/* Signed. */ +typedef signed char int_fast8_t; +#if __WORDSIZE == 64 +typedef long int int_fast16_t; +typedef long int int_fast32_t; +typedef long int int_fast64_t; +#else +typedef int int_fast16_t; +typedef int int_fast32_t; +__extension__ +typedef long long int int_fast64_t; +#endif + +/* Unsigned. */ +typedef unsigned char uint_fast8_t; +#if __WORDSIZE == 64 +typedef unsigned long int uint_fast16_t; +typedef unsigned long int uint_fast32_t; +typedef unsigned long int uint_fast64_t; +#else +typedef unsigned int uint_fast16_t; +typedef unsigned int uint_fast32_t; +__extension__ +typedef unsigned long long int uint_fast64_t; +#endif + + +/* Types for `void *' pointers. */ +#if __WORDSIZE == 64 +# ifndef __intptr_t_defined +typedef long int intptr_t; +# define __intptr_t_defined +# endif +typedef unsigned long int uintptr_t; +#else +# ifndef __intptr_t_defined +typedef int intptr_t; +# define __intptr_t_defined +# endif +typedef unsigned int uintptr_t; +#endif + + +/* Largest integral types. */ +typedef __intmax_t intmax_t; +typedef __uintmax_t uintmax_t; + + +# if __WORDSIZE == 64 +# define __INT64_C(c) c ## L +# define __UINT64_C(c) c ## UL +# else +# define __INT64_C(c) c ## LL +# define __UINT64_C(c) c ## ULL +# endif + +/* Limits of integral types. */ + +/* Minimum of signed integral types. */ +# define INT8_MIN (-128) +# define INT16_MIN (-32767-1) +# define INT32_MIN (-2147483647-1) +# define INT64_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum of signed integral types. */ +# define INT8_MAX (127) +# define INT16_MAX (32767) +# define INT32_MAX (2147483647) +# define INT64_MAX (__INT64_C(9223372036854775807)) + +/* Maximum of unsigned integral types. */ +# define UINT8_MAX (255) +# define UINT16_MAX (65535) +# define UINT32_MAX (4294967295U) +# define UINT64_MAX (__UINT64_C(18446744073709551615)) + + +/* Minimum of signed integral types having a minimum size. */ +# define INT_LEAST8_MIN (-128) +# define INT_LEAST16_MIN (-32767-1) +# define INT_LEAST32_MIN (-2147483647-1) +# define INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum of signed integral types having a minimum size. */ +# define INT_LEAST8_MAX (127) +# define INT_LEAST16_MAX (32767) +# define INT_LEAST32_MAX (2147483647) +# define INT_LEAST64_MAX (__INT64_C(9223372036854775807)) + +/* Maximum of unsigned integral types having a minimum size. */ +# define UINT_LEAST8_MAX (255) +# define UINT_LEAST16_MAX (65535) +# define UINT_LEAST32_MAX (4294967295U) +# define UINT_LEAST64_MAX (__UINT64_C(18446744073709551615)) + + +/* Minimum of fast signed integral types having a minimum size. */ +# define INT_FAST8_MIN (-128) +# if __WORDSIZE == 64 +# define INT_FAST16_MIN (-9223372036854775807L-1) +# define INT_FAST32_MIN (-9223372036854775807L-1) +# else +# define INT_FAST16_MIN (-2147483647-1) +# define INT_FAST32_MIN (-2147483647-1) +# endif +# define INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum of fast signed integral types having a minimum size. */ +# define INT_FAST8_MAX (127) +# if __WORDSIZE == 64 +# define INT_FAST16_MAX (9223372036854775807L) +# define INT_FAST32_MAX (9223372036854775807L) +# else +# define INT_FAST16_MAX (2147483647) +# define INT_FAST32_MAX (2147483647) +# endif +# define INT_FAST64_MAX (__INT64_C(9223372036854775807)) + +/* Maximum of fast unsigned integral types having a minimum size. */ +# define UINT_FAST8_MAX (255) +# if __WORDSIZE == 64 +# define UINT_FAST16_MAX (18446744073709551615UL) +# define UINT_FAST32_MAX (18446744073709551615UL) +# else +# define UINT_FAST16_MAX (4294967295U) +# define UINT_FAST32_MAX (4294967295U) +# endif +# define UINT_FAST64_MAX (__UINT64_C(18446744073709551615)) + + +/* Values to test for integral types holding `void *' pointer. */ +# if __WORDSIZE == 64 +# define INTPTR_MIN (-9223372036854775807L-1) +# define INTPTR_MAX (9223372036854775807L) +# define UINTPTR_MAX (18446744073709551615UL) +# else +# define INTPTR_MIN (-2147483647-1) +# define INTPTR_MAX (2147483647) +# define UINTPTR_MAX (4294967295U) +# endif + + +/* Minimum for largest signed integral type. */ +# define INTMAX_MIN (-__INT64_C(9223372036854775807)-1) +/* Maximum for largest signed integral type. */ +# define INTMAX_MAX (__INT64_C(9223372036854775807)) + +/* Maximum for largest unsigned integral type. */ +# define UINTMAX_MAX (__UINT64_C(18446744073709551615)) + + +/* Limits of other integer types. */ + +/* Limits of `ptrdiff_t' type. */ +# if __WORDSIZE == 64 +# define PTRDIFF_MIN (-9223372036854775807L-1) +# define PTRDIFF_MAX (9223372036854775807L) +# else +# if __WORDSIZE32_PTRDIFF_LONG +# define PTRDIFF_MIN (-2147483647L-1) +# define PTRDIFF_MAX (2147483647L) +# else +# define PTRDIFF_MIN (-2147483647-1) +# define PTRDIFF_MAX (2147483647) +# endif +# endif + +/* Limits of `sig_atomic_t'. */ +# define SIG_ATOMIC_MIN (-2147483647-1) +# define SIG_ATOMIC_MAX (2147483647) + +/* Limit of `size_t' type. */ +# if __WORDSIZE == 64 +# define SIZE_MAX (18446744073709551615UL) +# else +# if __WORDSIZE32_SIZE_ULONG +# define SIZE_MAX (4294967295UL) +# else +# define SIZE_MAX (4294967295U) +# endif +# endif + +/* Limits of `wchar_t'. */ +# ifndef WCHAR_MIN +/* These constants might also be defined in . */ +# define WCHAR_MIN __WCHAR_MIN +# define WCHAR_MAX __WCHAR_MAX +# endif + +/* Limits of `wint_t'. */ +# define WINT_MIN (0u) +# define WINT_MAX (4294967295u) + +/* Signed. */ +# define INT8_C(c) c +# define INT16_C(c) c +# define INT32_C(c) c +# if __WORDSIZE == 64 +# define INT64_C(c) c ## L +# else +# define INT64_C(c) c ## LL +# endif + +/* Unsigned. */ +# define UINT8_C(c) c +# define UINT16_C(c) c +# define UINT32_C(c) c ## U +# if __WORDSIZE == 64 +# define UINT64_C(c) c ## UL +# else +# define UINT64_C(c) c ## ULL +# endif + +/* Maximal type. */ +# if __WORDSIZE == 64 +# define INTMAX_C(c) c ## L +# define UINTMAX_C(c) c ## UL +# else +# define INTMAX_C(c) c ## LL +# define UINTMAX_C(c) c ## ULL +# endif + +#if __GLIBC_USE (IEC_60559_BFP_EXT_C2X) + +# define INT8_WIDTH 8 +# define UINT8_WIDTH 8 +# define INT16_WIDTH 16 +# define UINT16_WIDTH 16 +# define INT32_WIDTH 32 +# define UINT32_WIDTH 32 +# define INT64_WIDTH 64 +# define UINT64_WIDTH 64 + +# define INT_LEAST8_WIDTH 8 +# define UINT_LEAST8_WIDTH 8 +# define INT_LEAST16_WIDTH 16 +# define UINT_LEAST16_WIDTH 16 +# define INT_LEAST32_WIDTH 32 +# define UINT_LEAST32_WIDTH 32 +# define INT_LEAST64_WIDTH 64 +# define UINT_LEAST64_WIDTH 64 + +# define INT_FAST8_WIDTH 8 +# define UINT_FAST8_WIDTH 8 +# define INT_FAST16_WIDTH __WORDSIZE +# define UINT_FAST16_WIDTH __WORDSIZE +# define INT_FAST32_WIDTH __WORDSIZE +# define UINT_FAST32_WIDTH __WORDSIZE +# define INT_FAST64_WIDTH 64 +# define UINT_FAST64_WIDTH 64 + +# define INTPTR_WIDTH __WORDSIZE +# define UINTPTR_WIDTH __WORDSIZE + +# define INTMAX_WIDTH 64 +# define UINTMAX_WIDTH 64 + +# define PTRDIFF_WIDTH __WORDSIZE +# define SIG_ATOMIC_WIDTH 32 +# define SIZE_WIDTH __WORDSIZE +# define WCHAR_WIDTH 32 +# define WINT_WIDTH 32 + +#endif + +#endif /* stdint.h */ diff --git a/lib/libc/include/stdio.h b/lib/libc/include/stdio.h new file mode 100644 index 0000000..cd29004 --- /dev/null +++ b/lib/libc/include/stdio.h @@ -0,0 +1,32 @@ +#ifndef _STDIO_H +#define _STDIO_H 1 + +#include +#include + +#define SEEK_SET 0 +typedef struct { int unused; } FILE; + +extern FILE *stderr; +#define stderr stderr + +int fclose(FILE *file); +int fflush(FILE *file); +FILE *fopen(const char *path, const char *flags); + +size_t fread(void *buf, size_t size, size_t nmemb, FILE* file); +int fseek(FILE *file, long offset, int whence); +long ftell(FILE *file); +size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *file); +void setbuf(FILE *file, char *buf); + +int fprintf(FILE *file, const char *fmt, ...); +int vfprintf(FILE *file, const char *fmt, va_list ap); + +int sprintf(char *restrict str, const char *restrict format, ...); +int vsprintf(char *restrict str, const char *restrict format, va_list ap); + +int snprintf(char *restrict str, size_t size, const char *restrict format, ...); +int vsnprintf(char *restrict str, size_t size, const char *restrict format, va_list ap); + +#endif diff --git a/lib/libc/include/stdlib.h b/lib/libc/include/stdlib.h new file mode 100644 index 0000000..9bb4bb1 --- /dev/null +++ b/lib/libc/include/stdlib.h @@ -0,0 +1,21 @@ +#ifndef _STDLIB_H +#define _STDLIB_H 1 + +#include + +__attribute__((noreturn)) void abort(void); +int atexit(void (*callback)(void)); + +int atoi(const char*); + +void *(*__libc_malloc)(size_t); +void (*__libc_free)(void*); +void *(*__libc_calloc)(size_t, size_t); + +void free(void *ptr); +void *malloc(size_t size); +void *calloc(size_t nmemb, size_t size); + +char *getenv(const char *key); + +#endif diff --git a/lib/libc/include/string.h b/lib/libc/include/string.h new file mode 100644 index 0000000..d55bc37 --- /dev/null +++ b/lib/libc/include/string.h @@ -0,0 +1,11 @@ +#ifndef _STRING_H +#define _STRING_H 1 + +#include + +void *memcpy(void *dest, const void *src, size_t size); +void *memset(void *dest, int byte, size_t size); +char *strcpy(char *dest, const char *src); +size_t strlen(const char *str); + +#endif diff --git a/lib/libc/include/sys/types.h b/lib/libc/include/sys/types.h new file mode 100644 index 0000000..058c38a --- /dev/null +++ b/lib/libc/include/sys/types.h @@ -0,0 +1,6 @@ +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H 1 + +typedef int pid_t; + +#endif diff --git a/lib/libc/include/time.h b/lib/libc/include/time.h new file mode 100644 index 0000000..c73ee97 --- /dev/null +++ b/lib/libc/include/time.h @@ -0,0 +1,4 @@ +#ifndef _TIME_H +#define _TIME_H 1 + +#endif diff --git a/lib/libc/include/unistd.h b/lib/libc/include/unistd.h new file mode 100644 index 0000000..4e14be9 --- /dev/null +++ b/lib/libc/include/unistd.h @@ -0,0 +1,11 @@ +#ifndef _UNISTD_H +#define _UNISTD_H 1 + +#include + +int execv(const char *pathname, char *const argv[]); +int execve(const char *pathname, char *const argv[], char *const envp[]); +int execvp(const char *pathname, char *const argv[]); +pid_t fork(void); + +#endif diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c new file mode 100644 index 0000000..dd78572 --- /dev/null +++ b/lib/libc/stdio/sprintf.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include +#include + +#define VSNPRINTF_PUTC(c) if(size > written) str[written++] = c; else written++ + +int +vsnprintf(char *restrict str, size_t size, const char *restrict format, va_list ap) +{ + int written = 0; + for(int fmti = 0; format[fmti] != 0; fmti++) { + char fmtc = format[fmti]; + if(fmtc != '%') { + VSNPRINTF_PUTC(fmtc); + continue; + } + + /* Flags */ + bool alternate = false; + bool zeropad = false; + bool leftadj = false; + bool signspace = false; + bool showplus = false; + fmtc = format[++fmti]; + + switch(fmtc) { + case '#': alternate = true; fmti++; break; + case '0': zeropad = true; fmti++; break; + case '-': leftadj = true; fmti++; break; + case ' ': signspace = true; fmti++; break; + case '+': showplus = true; fmti++; break; + default: break; + } + + /* Field width. */ + fmtc = format[fmti]; + //TODO: Implement field width + + /* Precision. */ + fmtc = format[fmti]; + //TODO: Implement precision + + /* Length modifier */ + fmtc = format[fmti]; + //TODO: Implement length modifier. + + /* Conversion specifier. */ + bool is_signed = true; + bool is_caps = false; + int radix = 10; + fmtc = format[fmti]; + switch(fmtc) + { + case 'X': + is_caps = true; + case 'x': + radix = 16; + case 'u': + is_signed = false; + case 'd': + case 'i': + goto conversion_int; + case 'p': + alternate = true; + radix = 16; + is_signed = false; + is_caps = true; + goto conversion_int; + case '%': + VSNPRINTF_PUTC('%'); + break; + } + continue; + +conversion_int: + { + uintmax_t value = va_arg(ap, uintmax_t); + bool negative = is_signed && (intmax_t)value < 0; + if(negative) value = (uintmax_t)(-(intmax_t)value); + size_t numc = 0; + + /*Count the number of characters to put in the buffer to represent + * the value in ASCII.*/ + for(uintmax_t v = value; v != 0; v /= radix, numc++); + if(numc == 0) numc++; + + /* Reserve space for alternate repersentation.*/ + if(showplus && !negative) { VSNPRINTF_PUTC('+'); } + if(negative) { VSNPRINTF_PUTC('-'); } + if(signspace && !negative) { VSNPRINTF_PUTC(' '); } + if(alternate) { + VSNPRINTF_PUTC('0'); + if(radix == 16) { + VSNPRINTF_PUTC('x'); + } + if(alternate && radix == 2) { + VSNPRINTF_PUTC('b'); + } + } + + /* Try to put characters into the buffer*/ + if(value == 0) { + VSNPRINTF_PUTC('0'); + } + else { + for(uintmax_t v = value, i = numc - 1; v != 0; v /= radix, i--) { + if(written + i >= size) continue; + int digit = v % radix; + char c = digit >= 10 ? (digit + 'a' - 10) : (digit + '0'); + if(is_caps) c = toupper(c); + str[written + i] = c; + } + written += numc; + } + continue; + } + } + VSNPRINTF_PUTC(0); + return written - 1; +} + + diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c new file mode 100644 index 0000000..69a03bc --- /dev/null +++ b/lib/libc/stdlib/malloc.c @@ -0,0 +1,9 @@ +#include +#include + +void* +malloc(size_t size) +{ + assert(__libc_malloc); + return __libc_malloc(size); +} diff --git a/lib/libc/string/memcpy.c b/lib/libc/string/memcpy.c new file mode 100644 index 0000000..f71444d --- /dev/null +++ b/lib/libc/string/memcpy.c @@ -0,0 +1,10 @@ +#include + +void* +memcpy(void *dest, const void *src, size_t n) +{ + const unsigned char *s = src; + for(unsigned char *d = dest; n; n--) + *(d++) = *(s++); + return dest; +} diff --git a/lib/libc/string/memset.c b/lib/libc/string/memset.c new file mode 100644 index 0000000..f79a4b4 --- /dev/null +++ b/lib/libc/string/memset.c @@ -0,0 +1,7 @@ +#include + +void +memset(void *s, int c, size_t n) +{ + for(unsigned char *sb = s; n; n--) *(sb++) = c; +} diff --git a/lib/libjove/Makefile b/lib/libjove/Makefile index b82de22..9633c85 100644 --- a/lib/libjove/Makefile +++ b/lib/libjove/Makefile @@ -1,6 +1,6 @@ include $(CONFIG) -CDIRS := syscall object pager +CDIRS := syscall object pager heap CFILES := $(wildcard *.c) CFILES += $(foreach dir,$(CDIRS),$(wildcard $(dir)/*.c)) @@ -9,7 +9,7 @@ CFILES += $(foreach dir,$(CDIRS),$(wildcard arch/$(TARGET_MACHINE)/$(dir)/*.c)) OFILES := $(patsubst %.c,%.o,$(CFILES)) -CFLAGS := -ffreestanding -nostdlib -Iinclude -g +CFLAGS := -Iinclude -Wall -Wextra all: ${OFILES} ar rcs $(OUT)/libjove.a $(OFILES) diff --git a/lib/libjove/arch/x86_64/libjove.c b/lib/libjove/arch/x86_64/libjove.c new file mode 100644 index 0000000..0abc6b6 --- /dev/null +++ b/lib/libjove/arch/x86_64/libjove.c @@ -0,0 +1,14 @@ +#include "jove.h" +#include "arch/x86_64/pager.h" + +void +__libjove_arch_init(void) +{ + +} + +void +__libjove_pager_init(uint8_t pml_obji) +{ + _jove_alloc_pagemap_inplace(&__jove_pagemap, &__rootdir, pml_obji); +} diff --git a/lib/libjove/heap/heap.c b/lib/libjove/heap/heap.c new file mode 100644 index 0000000..ab313ae --- /dev/null +++ b/lib/libjove/heap/heap.c @@ -0,0 +1,142 @@ +#include "heap.h" +#include +#include +#include +#include + +static heap_bin_t *freelist_tail; + +uintptr_t __heap_start; +uintptr_t __heap_end; + +#define HEAP_BIN_SIZE(bin) (bin->size_taken & (~1ULL)) +#define HEAP_BIN_TAKEN(bin) (bin->size_taken & 1) + +#define HEAP_BIN_AFTER(bin) ((heap_bin_t*)((uintptr_t)bin->data + HEAP_BIN_SIZE(bin) + sizeof(uintptr_t))) +#define HEAP_BIN_BEFORE(bin) ((heap_bin_t*)*((uintptr_t*)bin - 1)) + +static void +heap_grow(uintptr_t to) +{ + jove_mem_ensure_range(__heap_end, to); + __heap_end = to; +} + +static heap_bin_t* +heap_newbin(uintptr_t at, size_t size, heap_bin_t *next) +{ + uintptr_t headat = (at + sizeof(heap_bin_t) + size); + uintptr_t endat = headat + sizeof(uintptr_t); + + if(endat > __heap_end) heap_grow(endat); + + heap_bin_t *newbin = (heap_bin_t*)at; + newbin->size_taken = size; + newbin->next = next; + + *((uintptr_t*)headat) = at; + return newbin; +} + +static heap_bin_t* +heap_find_bestfit(size_t rsize) +{ + heap_bin_t *best = freelist_tail; + if(best == NULL) return NULL; + size_t bestsize = best->size_taken; + + for(heap_bin_t *bin = best->next; bin; bin = bin->next) + { + if(bin->size_taken < rsize) continue; + if(bin->size_taken < bestsize) { + best = bin; + bestsize = bin->size_taken; + } + } + return best; +} + +static void +heap_split(heap_bin_t *bin, size_t splitsize) +{ + size_t size_diff = bin->size_taken - splitsize; + if(size_diff < LIBC_HEAP_MINSPLIT) return; + + size_t newsize = size_diff - sizeof(heap_bin_t) - sizeof(uintptr_t); + uintptr_t newat = ((uintptr_t)bin->data) + splitsize + sizeof(uintptr_t); + jove_kprintf("Split %p to %p [%x]\n", bin, newat, newsize); + + bin->size_taken = splitsize; + freelist_tail = heap_newbin(newat, newsize, freelist_tail); +} + +static void* +heap_alloc(size_t size) +{ + if(size & 1) size++; + if(size < LIBC_HEAP_MINALLOC) size = LIBC_HEAP_MINALLOC; + + heap_bin_t *bestfit = heap_find_bestfit(size); + if(bestfit == NULL) { + bestfit = heap_newbin(__heap_end, size, NULL); + }else{ + if(bestfit == freelist_tail) { + freelist_tail = bestfit->next; + } + size_t bestsize = bestfit->size_taken; + + if(bestsize < size) { + jove_kprintf("Growing bin %p [%x] to %x\n", bestfit, bestsize, size); + heap_newbin((uintptr_t)bestfit, size, NULL); + }else if(bestsize > size) { + heap_split(bestfit, size); + } + } + bestfit->size_taken |= 1; + return bestfit->data; +} + +static void +heap_free(void *ptr) +{ + uintptr_t binptr = (uintptr_t)ptr - sizeof(heap_bin_t); + if(binptr > __heap_end || binptr < __heap_start) return; + + heap_bin_t *bin = (heap_bin_t*)binptr; + bin->size_taken &= ~1ULL; + bin->next = freelist_tail; + freelist_tail = bin; + +start_merge_loop: { + heap_bin_t *prevbin = HEAP_BIN_BEFORE(bin); + heap_bin_t *nextbin = HEAP_BIN_AFTER(bin); + + if((uintptr_t)prevbin >= __heap_start) { + if(!HEAP_BIN_TAKEN(prevbin)) { + jove_kprintf("Merge back bin %p into %p\n", bin, prevbin); + freelist_tail = prevbin; + prevbin->size_taken += bin->size_taken + sizeof(heap_bin_t) + sizeof(uintptr_t); + bin = prevbin; + goto start_merge_loop; + } + } + if((uintptr_t)nextbin < __heap_end) { + if(!HEAP_BIN_TAKEN(nextbin)) { + jove_kprintf("Merge forward bin %p into %p\n", bin, nextbin); + if(bin->next == nextbin) bin->next = nextbin->next; + bin->size_taken += nextbin->size_taken + sizeof(heap_bin_t) + sizeof(uintptr_t); + goto start_merge_loop; + } + } + } +} + +void +__libjove_heap_init(uintptr_t program_end) +{ + __heap_start = __heap_end = program_end; + freelist_tail = heap_newbin(__heap_start, LIBC_HEAP_INIT_SIZE, NULL); + + __libc_malloc = heap_alloc; + __libc_free = heap_free; +} diff --git a/lib/libjove/heap/heap.h b/lib/libjove/heap/heap.h new file mode 100644 index 0000000..8a02655 --- /dev/null +++ b/lib/libjove/heap/heap.h @@ -0,0 +1,19 @@ +#ifndef _LIBC_JOVE_HEAP_H +#define _LIBC_JOVE_HEAP_H 1 + +#include +#include + +#define LIBC_HEAP_INIT_SIZE (0x1000) +#define LIBC_HEAP_MINALLOC (0x10) +#define LIBC_HEAP_MINSPLIT (sizeof(heap_bin_t) + sizeof(uintptr_t) + LIBC_HEAP_MINALLOC) + +typedef struct heap_bin { + struct heap_bin *next; + size_t size_taken; + char data[]; +} heap_bin_t; + +void __libjove_heap_init(uintptr_t program_end); + +#endif diff --git a/lib/libjove/include/arch/x86_64/jove.h b/lib/libjove/include/arch/x86_64/jove.h new file mode 100644 index 0000000..36303f4 --- /dev/null +++ b/lib/libjove/include/arch/x86_64/jove.h @@ -0,0 +1,6 @@ +#ifndef _JOVE_x86_64_JOVE_H +#define _JOVE_x86_64_JOVE_H 1 + + + +#endif diff --git a/lib/libjove/libjove.c b/lib/libjove/libjove.c index 6b40a54..ef5d7e6 100644 --- a/lib/libjove/libjove.c +++ b/lib/libjove/libjove.c @@ -1,6 +1,7 @@ #include "include/jove.h" #include "include/object-untyped.h" #include "error.h" +#include "heap/heap.h" uintmax_t __jove_syscall_obj = 0; void *__jove_syscall_ptr = 0; @@ -15,3 +16,36 @@ uintptr_t __program_end; void *(*_jove_alloc)(size_t) = NULL; void (*_jove_free)(void*) = NULL; void *(*_jove_realloc)(void*, size_t) = NULL; + +extern void __libjove_arch_init(void); + +void +__libjove_init(uint8_t syscall_obj, void *syscall_ptr) +{ + __rootdir = (KernelObjectDirectory) { + .typed = { + .type = KO_OBJECT_DIRECTORY, + .membi = 0, + .parent = NULL + }, + .firstfree = -1, + .lastmemb = -1 + }; + + __jove_syscall_obj = syscall_obj; + __jove_syscall_ptr = syscall_ptr; + + __jove_work_obj = (KernelObjectTyped) { + .membi = jove_objdir_lastmemb(&__rootdir), + .parent = &__rootdir, + .type = KO_NONE + }; + + __libjove_arch_init(); +} + +void +__libjove_init_untypeddir(uint8_t diri) +{ + _jove_alloc_objdir_inplace(&__jove_untyped_directory, &__rootdir, diri); +} -- cgit v1.2.1