summaryrefslogtreecommitdiff
path: root/libk
diff options
context:
space:
mode:
authorDanny Holman <dholman@gymli.org>2024-05-27 13:53:52 -0500
committerDanny Holman <dholman@gymli.org>2024-05-27 13:53:52 -0500
commitaaf7355c5ededfcdc877c7f2989fb1ba02dfb848 (patch)
tree0c4588650fe1fc1fa1af2972353a2bc920cf1e68 /libk
parent41cff28f5447b5f669db62ce2a73be98bc5bce37 (diff)
libk: create a subset libc for kernel use
Create a subset of the C library for use inside the kernel. Signed-off-by: Danny Holman <dholman@gymli.org>
Diffstat (limited to 'libk')
-rw-r--r--libk/io.c78
-rw-r--r--libk/stack_protector.c11
-rw-r--r--libk/string.c133
3 files changed, 222 insertions, 0 deletions
diff --git a/libk/io.c b/libk/io.c
new file mode 100644
index 0000000..eedc171
--- /dev/null
+++ b/libk/io.c
@@ -0,0 +1,78 @@
+#include <libk/io.h>
+#include <libk/string.h>
+#include <kernel/video/framebuffer.h>
+#include <kernel/tty/tty_vga.h>
+
+char* convert(unsigned int num, int base) {
+ static char rep[] = "0123456789ABCDEF";
+ static char buffer[50];
+ char *ptr;
+
+ ptr = &buffer[49];
+ *ptr = '\0';
+
+ do {
+ *--ptr = rep[num%base];
+ num /= base;
+ } while (num != 0);
+
+ return ptr;
+}
+
+int vkprintf(const char *fmt, va_list args) {
+ char *s;
+ int i;
+
+ char buffer[4096];
+ memset(buffer, 0, 4096);
+ for (size_t n = 0; n < strlen(fmt); n++) {
+ if (fmt[n] != '%') {
+ buffer[strlen(buffer)] = fmt[n];
+ continue;
+ } else {
+ n++;
+ }
+
+ switch (fmt[n]) {
+ case 'c':
+ i = va_arg(args, int);
+ buffer[strlen(buffer)] = i;
+ break;
+ case 's':
+ s = va_arg(args, char*);
+ strcat(buffer, s);
+ break;
+ case 'd':
+ i = va_arg(args, int);
+ if (i < 0) {
+ i = -i;
+ strcat(buffer, "-");
+ }
+ strcat(buffer, convert(i, 10));
+ break;
+ case 'o':
+ i = va_arg(args, unsigned int);
+ strcat(buffer, convert(i, 10));
+ break;
+ case 'x':
+ i = va_arg(args, unsigned int);
+ strcat(buffer, convert(i, 16));
+ break;
+ }
+ }
+ //tty_write(buffer, strlen(buffer));
+ fb_write(buffer, strlen(buffer));
+ memset(buffer, 0, 4096);
+ return 0;
+}
+
+int kprintf(const char *fmt, ...) {
+ va_list args;
+ int done;
+
+ va_start(args, fmt);
+ done = vkprintf(fmt, args);
+ va_end(args);
+
+ return done;
+}
diff --git a/libk/stack_protector.c b/libk/stack_protector.c
new file mode 100644
index 0000000..78d0302
--- /dev/null
+++ b/libk/stack_protector.c
@@ -0,0 +1,11 @@
+#include <kernel/panic.h>
+#include <stdint.h>
+#include <stddef.h>
+
+#define STACK_CHK_GUARD 0x32E3429E
+
+uintptr_t __stack_chk_guard = STACK_CHK_GUARD;
+
+__attribute__((noreturn)) void __stack_chk_fail(void) {
+ panic("STACK SMASHING IN KERNEL ADDRESS SPACE");
+}
diff --git a/libk/string.c b/libk/string.c
new file mode 100644
index 0000000..be59397
--- /dev/null
+++ b/libk/string.c
@@ -0,0 +1,133 @@
+#include <libk/string.h>
+
+int memcmp(const void *str1, const void *str2, size_t n) {
+ unsigned char const *p1 = str1;
+ unsigned char const *p2 = str2;
+ int ret = 0;
+
+ if (str1 == str2)
+ return 0;
+
+ while (n > 0) {
+ if (*p1 != *p2) {
+ ret = (*p1 > *p2)?1:-1;
+ break;
+ }
+ n--;
+ p1++;
+ p2++;
+ }
+ return ret;
+}
+
+void* memcpy(void* __restrict dest, const void* __restrict src, size_t n) {
+ if (dest == src)
+ return dest;
+
+ unsigned char *pdest = dest;
+ unsigned char const *psrc = src;
+ for (size_t i = 0; i < n; i++)
+ pdest[i] = psrc[i];
+ return dest;
+}
+
+char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
+ for (size_t i = 0; i < n; i++) {
+ if (src[i] == '\0')
+ break;
+ dest[i] = src[i];
+ }
+ return dest;
+}
+
+char* strcpy(char* __restrict dest, const char* __restrict src) {
+ return (char*)memcpy(dest, src, strlen(src));
+}
+
+char* strcat(char* __restrict dest, const char* __restrict src) {
+ return (char*)memcpy(&dest[strlen(dest)], src, strlen(src));
+}
+
+char* strncat(char* __restrict dest, const char* __restrict src, size_t n) {
+ return (char*)memcpy(&dest[strlen(dest)], src, n);
+}
+
+void* memmove(void* __restrict dest, const void* __restrict src, size_t n) {
+ if (dest == src)
+ return dest;
+
+ unsigned char const *psrc = src;
+ unsigned char buffer[n];
+
+ for (size_t i = 0; i < n; i++)
+ buffer[i] = psrc[i];
+ return memcpy(dest, (void*)buffer, n);
+}
+
+void* memset(void *str, int c, size_t n) {
+ unsigned char *p = str;
+ for (size_t i = 0; i < n; i++)
+ p[i] = (unsigned char)c;
+ return str;
+}
+
+int strncmp(const char *str1, const char *str2, size_t n) {
+ return memcmp(str1, str2, n);
+}
+
+int strcmp(const char *str1, const char *str2) {
+ size_t str1_sz = strlen(str1);
+ size_t str2_sz = strlen(str2);
+ if (str1_sz > str2_sz)
+ return memcmp(str1, str2, str2_sz);
+ return memcmp(str1, str2, str1_sz);
+}
+
+size_t strlen(const char *str) {
+ size_t i = 0;
+ while (str[i] != '\0')
+ i++;
+ return i;
+}
+
+int _is_delim(char c, const char *delim) {
+ while (*delim != '\0') {
+ if (c == *delim)
+ return 1;
+ delim++;
+ }
+ return 0;
+}
+
+char* strtok(char* __restrict str, const char* __restrict delim) {
+ static char *old_str;
+
+ if (str == NULL)
+ str = old_str;
+
+ while (1) {
+ if (_is_delim(*str, delim)) {
+ str++;
+ continue;
+ }
+
+ if (*str == '\0')
+ return NULL;
+ break;
+ }
+
+ char *ret = str;
+ while (1) {
+ if (*str == '\0') {
+ old_str = str;
+ return ret;
+ }
+
+ if (_is_delim(*str, delim)) {
+ *str = '\0';
+ old_str = str + 1;
+ return ret;
+ }
+ str++;
+ }
+}