summaryrefslogtreecommitdiffstats
path: root/lib/libc-headless
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2025-08-10 15:46:33 -0400
committerJon Santmyer <jon@jonsantmyer.com>2025-08-10 15:46:33 -0400
commit65ba015d6c1f248d36ad01a653bc49637804b15b (patch)
treea77c3fb3ca7ecac8f65eb9638d152f1e90307d0a /lib/libc-headless
downloadjove-os-65ba015d6c1f248d36ad01a653bc49637804b15b.tar.gz
jove-os-65ba015d6c1f248d36ad01a653bc49637804b15b.tar.bz2
jove-os-65ba015d6c1f248d36ad01a653bc49637804b15b.zip
working usermode objdir iteration
Diffstat (limited to 'lib/libc-headless')
-rw-r--r--lib/libc-headless/Makefile15
-rw-r--r--lib/libc-headless/ctype/toupper.c9
-rw-r--r--lib/libc-headless/include/ctype.h7
-rw-r--r--lib/libc-headless/include/errno.h0
-rw-r--r--lib/libc-headless/include/stdint.h319
-rw-r--r--lib/libc-headless/include/stdio.h32
-rw-r--r--lib/libc-headless/include/stdlib.h17
-rw-r--r--lib/libc-headless/include/string.h11
-rw-r--r--lib/libc-headless/include/sys/types.h6
-rw-r--r--lib/libc-headless/include/time.h4
-rw-r--r--lib/libc-headless/include/unistd.h11
-rw-r--r--lib/libc-headless/stdio/sprintf.c124
-rw-r--r--lib/libc-headless/string/memcpy.c10
-rw-r--r--lib/libc-headless/string/memset.c7
14 files changed, 572 insertions, 0 deletions
diff --git a/lib/libc-headless/Makefile b/lib/libc-headless/Makefile
new file mode 100644
index 0000000..59de6c8
--- /dev/null
+++ b/lib/libc-headless/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-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
new file mode 100644
index 0000000..fe1e1e2
--- /dev/null
+++ b/lib/libc-headless/ctype/toupper.c
@@ -0,0 +1,9 @@
+#include <ctype.h>
+
+/* 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
new file mode 100644
index 0000000..9dfcc3b
--- /dev/null
+++ b/lib/libc-headless/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-headless/include/errno.h b/lib/libc-headless/include/errno.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/libc-headless/include/errno.h
diff --git a/lib/libc-headless/include/stdint.h b/lib/libc-headless/include/stdint.h
new file mode 100644
index 0000000..165a201
--- /dev/null
+++ b/lib/libc-headless/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
+ <https://www.gnu.org/licenses/>. */
+
+/*
+ * ISO C99: 7.18 Integer types <stdint.h>
+ */
+
+#ifndef _STDINT_H
+#define _STDINT_H 1
+
+#define __GLIBC_INTERNAL_STARTING_HEADER_IMPLEMENTATION
+#include <bits/libc-header-start.h>
+#include <bits/types.h>
+#include <bits/wchar.h>
+#include <bits/wordsize.h>
+
+/* Exact integral types. */
+
+/* Signed. */
+#include <bits/stdint-intn.h>
+
+/* Unsigned. */
+#include <bits/stdint-uintn.h>
+
+
+/* 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 <wchar.h>. */
+# 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
new file mode 100644
index 0000000..cd29004
--- /dev/null
+++ b/lib/libc-headless/include/stdio.h
@@ -0,0 +1,32 @@
+#ifndef _STDIO_H
+#define _STDIO_H 1
+
+#include <stdarg.h>
+#include <stddef.h>
+
+#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
new file mode 100644
index 0000000..f29cce7
--- /dev/null
+++ b/lib/libc-headless/include/stdlib.h
@@ -0,0 +1,17 @@
+#ifndef _STDLIB_H
+#define _STDLIB_H 1
+
+#include <stddef.h>
+
+__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
new file mode 100644
index 0000000..d55bc37
--- /dev/null
+++ b/lib/libc-headless/include/string.h
@@ -0,0 +1,11 @@
+#ifndef _STRING_H
+#define _STRING_H 1
+
+#include <stddef.h>
+
+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
new file mode 100644
index 0000000..058c38a
--- /dev/null
+++ b/lib/libc-headless/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-headless/include/time.h b/lib/libc-headless/include/time.h
new file mode 100644
index 0000000..c73ee97
--- /dev/null
+++ b/lib/libc-headless/include/time.h
@@ -0,0 +1,4 @@
+#ifndef _TIME_H
+#define _TIME_H 1
+
+#endif
diff --git a/lib/libc-headless/include/unistd.h b/lib/libc-headless/include/unistd.h
new file mode 100644
index 0000000..4e14be9
--- /dev/null
+++ b/lib/libc-headless/include/unistd.h
@@ -0,0 +1,11 @@
+#ifndef _UNISTD_H
+#define _UNISTD_H 1
+
+#include <sys/types.h>
+
+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
new file mode 100644
index 0000000..2881bd5
--- /dev/null
+++ b/lib/libc-headless/stdio/sprintf.c
@@ -0,0 +1,124 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <ctype.h>
+
+#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
new file mode 100644
index 0000000..f71444d
--- /dev/null
+++ b/lib/libc-headless/string/memcpy.c
@@ -0,0 +1,10 @@
+#include <stddef.h>
+
+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
new file mode 100644
index 0000000..f79a4b4
--- /dev/null
+++ b/lib/libc-headless/string/memset.c
@@ -0,0 +1,7 @@
+#include <stddef.h>
+
+void
+memset(void *s, int c, size_t n)
+{
+ for(unsigned char *sb = s; n; n--) *(sb++) = c;
+}