summaryrefslogtreecommitdiffhomepage
path: root/src/loader/library.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/loader/library.c')
-rw-r--r--src/loader/library.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/src/loader/library.c b/src/loader/library.c
new file mode 100644
index 0000000..4317a8e
--- /dev/null
+++ b/src/loader/library.c
@@ -0,0 +1,172 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#include <library.h>
+
+/**
+ * Common string functions
+ */
+
+u32 strlen(const char *str)
+{
+ const char *s = str;
+ while (*s)
+ s++;
+ return s - str;
+}
+
+u32 strnlen(const char *str, u32 max)
+{
+ const char *s = str;
+ while (max && *s) {
+ s++;
+ max--;
+ }
+ return s - str;
+}
+
+u32 strlcpy(char *dst, const char *src, u32 size)
+{
+ const char *orig = src;
+ u32 left = size;
+
+ if (left)
+ while (--left)
+ if (!(*dst++ = *src++))
+ break;
+
+ if (!left) {
+ if (size)
+ *dst = 0;
+ while (*src++)
+ ;
+ }
+
+ return src - orig - 1;
+}
+
+s32 strncmp(const char *s1, const char *s2, u32 n)
+{
+ const u8 *c1 = (const u8 *)s1;
+ const u8 *c2 = (const u8 *)s2;
+ u8 ch;
+ s32 d = 0;
+
+ while (n--) {
+ d = (s32)(ch = *c1++) - (s32)*c2++;
+ if (d || !ch)
+ break;
+ }
+
+ return d;
+}
+
+/**
+ * Common memory functions
+ */
+
+void *memcpy(void *dest, const void *src, u32 n)
+{
+ // Inspired by jgraef at osdev
+ u32 num_dwords = n / 4;
+ u32 num_bytes = n % 4;
+ u32 *dest32 = (u32 *)dest;
+ const u32 *src32 = (const u32 *)src;
+ u8 *dest8 = ((u8 *)dest) + num_dwords * 4;
+ const u8 *src8 = ((const u8 *)src) + num_dwords * 4;
+
+ __asm__ volatile("rep movsl\n"
+ : "=S"(src32), "=D"(dest32), "=c"(num_dwords)
+ : "S"(src32), "D"(dest32), "c"(num_dwords)
+ : "memory");
+
+ for (u32 i = 0; i < num_bytes; i++)
+ dest8[i] = src8[i];
+
+ return dest;
+}
+
+void *memset(void *dest, u32 val, u32 n)
+{
+ // Inspired by jgraef at osdev
+ u32 uval = val;
+ u32 num_dwords = n / 4;
+ u32 num_bytes = n % 4;
+ u32 *dest32 = (u32 *)dest;
+ u8 *dest8 = ((u8 *)dest) + num_dwords * 4;
+ u8 val8 = (u8)val;
+ u32 val32 = uval | (uval << 8) | (uval << 16) | (uval << 24);
+
+ __asm__ volatile("rep stosl\n"
+ : "=D"(dest32), "=c"(num_dwords)
+ : "D"(dest32), "c"(num_dwords), "a"(val32)
+ : "memory");
+
+ for (u32 i = 0; i < num_bytes; i++)
+ dest8[i] = val8;
+
+ return dest;
+}
+
+s32 memcmp(const void *s1, const void *s2, u32 n)
+{
+ const u8 *a = (const u8 *)s1;
+ const u8 *b = (const u8 *)s2;
+ for (u32 i = 0; i < n; i++) {
+ if (a[i] < b[i])
+ return -1;
+ else if (b[i] < a[i])
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Conversion
+ */
+
+s32 itoa(s32 value, char *buffer, u32 base)
+{
+ char tmp[16];
+ char *tp = tmp;
+ s32 i;
+ unsigned v;
+
+ s32 sign = (base == 10 && value < 0);
+ if (sign)
+ v = -value;
+ else
+ v = (unsigned)value;
+
+ while (v || tp == tmp) {
+ i = v % base;
+ v /= base;
+ if (i < 10)
+ *tp++ = i + '0';
+ else
+ *tp++ = i + 'a' - 10;
+ }
+
+ s32 len = tp - tmp;
+
+ if (sign) {
+ *buffer++ = '-';
+ len++;
+ }
+
+ while (tp > tmp)
+ *buffer++ = *--tp;
+ *buffer = '\0';
+
+ return len;
+}
+
+// From stackoverflow
+s32 atoi(const char *inp)
+{
+ s32 ret = 0;
+ while (*inp) {
+ ret = (ret << 3) + (ret << 1) + (*inp) - '0';
+ inp++;
+ }
+ return ret;
+}