rumpk/core/cstubs.c

97 lines
2.9 KiB
C

// C runtime stubs for freestanding Nim
#include <stddef.h>
/* Duplicates provided by libnexus.a (clib.o) */
#if 0
void *memcpy(void *dest, const void *src, size_t n) { ... }
void *memset(void *s, int c, size_t n) { ... }
void *memmove(void *dest, const void *src, size_t n) { ... }
int memcmp(const void *s1, const void *s2, size_t n) { ... }
/* Externs from libnexus.a */
extern size_t strlen(const char *s);
extern int atoi(const char *nptr);
extern int strncmp(const char *s1, const char *s2, size_t n);
char *strcpy(char *dest, const char *src) { ... }
int strcmp(const char *s1, const char *s2) { ... }
char *strncpy(char *dest, const char *src, size_t n) { ... }
#endif
// panic is used by abort/exit
void panic(const char* msg) {
extern void console_write(const char*, unsigned long);
extern size_t strlen(const char*);
console_write("\n[KERNEL PANIC] ", 16);
if (msg) console_write(msg, strlen(msg));
else console_write("Unknown Error", 13);
console_write("\n", 1);
while(1) {
// Halt
}
}
// abort is used by Nim panic
void abort(void) {
panic("abort() called");
while(1) {}
}
#if 0
/* Stdio stubs - these call into Zig UART */
extern void console_write(const char*, unsigned long);
int puts(const char *s) { ... }
int putchar(int c) { ... }
// ... (printf, etc)
int snprintf(char *str, size_t size, const char *format, ...) { ... }
int fflush(void *stream) { ... }
unsigned long fwrite(const void *ptr, unsigned long size, unsigned long nmemb, void *stream) { ... }
sighandler_t signal(int signum, sighandler_t handler) { ... }
int raise(int sig) { ... }
int sprintf(char *str, const char *format, ...) { ... }
double strtod(const char *nptr, char **endptr) { ... }
#endif
/* Exit stubs */
void exit(int status) {
extern void panic(const char*);
panic("exit() called - system halt");
while(1) {}
}
void _Exit(int status) {
exit(status);
}
// qsort uses existing memcpy
// Note: We need memcpy for qsort!
// libnexus.a provides memcpy. We need to declare it.
extern void *memcpy(void *dest, const void *src, size_t n);
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
// Bubble sort for simplicity (O(n^2))
if (nmemb < 2) return;
char *b = (char *)base;
char tmp[256]; // Max item size 256 bytes for swap
// Verify size? If size > 256, we fail or use loop.
// mu_Container* is pointer size (8).
for (size_t i = 0; i < nmemb - 1; i++) {
for (size_t j = 0; j < nmemb - i - 1; j++) {
char *p1 = b + j * size;
char *p2 = b + (j + 1) * size;
if (compar(p1, p2) > 0) {
// Swap
if (size <= 256) {
memcpy(tmp, p1, size);
memcpy(p1, p2, size);
memcpy(p2, tmp, size);
}
}
}
}
}
// int errno = 0; // Provided by clib.c