#include #include #include // Types needed for stubs typedef int32_t pid_t; typedef int32_t uid_t; typedef int32_t gid_t; typedef int64_t off_t; typedef int32_t mode_t; struct stat { int st_mode; }; int errno = 0; // Basic memory stubs extern void* malloc(size_t size); extern void free(void* ptr); // Forward declare memset (defined below) void* memset(void* s, int c, size_t n); // LwIP Panic Handler (for Membrane stack) extern void console_write(const void* p, size_t len); size_t strlen(const char* s) { size_t i = 0; while(s[i]) i++; return i; } // nexus_lwip_panic moved to sys_arch.c to avoid duplicate symbols int strncmp(const char *s1, const char *s2, size_t n) { for (size_t i = 0; i < n; i++) { if (s1[i] != s2[i]) return (unsigned char)s1[i] - (unsigned char)s2[i]; if (s1[i] == 0) return 0; } return 0; } int atoi(const char* nptr) { return 0; } double strtod(const char* nptr, char** endptr) { if (endptr) *endptr = (char*)nptr; return 0.0; } double pow(double x, double y) { return 0.0; } double log10(double x) { return 0.0; } // --- SYSCALL INTERFACE --- #ifdef RUMPK_KERNEL extern long k_handle_syscall(long nr, long a0, long a1, long a2); #endif long syscall(long nr, long a0, long a1, long a2) { #ifdef RUMPK_KERNEL return k_handle_syscall(nr, a0, a1, a2); #else long res; #if defined(__riscv) register long a7 asm("a7") = nr; register long _a0 asm("a0") = a0; register long _a1 asm("a1") = a1; register long _a2 asm("a2") = a2; asm volatile("ecall" : "+r"(_a0) : "r"(a7), "r"(_a1), "r"(_a2) : "memory"); res = _a0; #else res = -1; #endif return res; #endif } // IO stubs (Real Syscalls) int write(int fd, const void *buf, size_t count) { // 0x204 = SYS_WRITE return (int)syscall(0x204, fd, (long)buf, count); } int read(int fd, void *buf, size_t count) { // 0x203 = SYS_READ return (int)syscall(0x203, fd, (long)buf, count); } int open(const char *pathname, int flags, ...) { // 0x200 = SYS_OPEN return (int)syscall(0x200, (long)pathname, flags, 0); } int close(int fd) { // 0x201 = SYS_CLOSE return (int)syscall(0x201, fd, 0, 0); } int execv(const char *path, char *const argv[]) { // 0x600 = KEXEC (Replace current fiber/process) // Note: argv is currently ignored by kernel kexec, it just runs the binary return (int)syscall(0x600, (long)path, 0, 0); } // Robust Formatter typedef struct { char *buf; size_t size; size_t pos; } OutCtx; static void out_char(OutCtx *ctx, char c) { if (ctx->buf && ctx->size > 0 && ctx->pos < ctx->size - 1) { ctx->buf[ctx->pos] = c; } ctx->pos++; } static void out_num(OutCtx *ctx, unsigned long n, int base, int width, int zeropad, int upper) { char buf[64]; const char *digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; int i = 0; if (n == 0) buf[i++] = '0'; else while (n > 0) { buf[i++] = digits[n % base]; n /= base; } while (i < width) buf[i++] = (zeropad ? '0' : ' '); while (i > 0) out_char(ctx, buf[--i]); } static int vformat(OutCtx *ctx, const char *fmt, va_list ap) { if (!fmt) return 0; const char *p = fmt; ctx->pos = 0; while (*p) { if (*p != '%') { out_char(ctx, *p++); continue; } p++; // skip % if (!*p) break; int zeropad = 0, width = 0, l_mod = 0, h_mod = 0; if (*p == '0') { zeropad = 1; p++; } while (*p >= '0' && *p <= '9') { width = width * 10 + (*p - '0'); p++; } while (*p == 'l') { l_mod++; p++; } if (*p == 'h') { h_mod = 1; p++; } if (!*p) break; switch (*p) { case 's': { const char *s = va_arg(ap, const char *); if (!s) s = "(null)"; while (*s) out_char(ctx, *s++); break; } case 'c': out_char(ctx, (char)va_arg(ap, int)); break; case 'd': case 'i': { long n = (l_mod >= 1) ? va_arg(ap, long) : va_arg(ap, int); unsigned long un; if (n < 0) { out_char(ctx, '-'); un = 0UL - (unsigned long)n; } else un = (unsigned long)n; out_num(ctx, un, 10, width, zeropad, 0); break; } case 'u': { unsigned long n = (l_mod >= 1) ? va_arg(ap, unsigned long) : va_arg(ap, unsigned int); out_num(ctx, n, 10, width, zeropad, 0); break; } case 'p': case 'x': case 'X': { unsigned long n; if (*p == 'p') n = (unsigned long)va_arg(ap, void *); else n = (l_mod >= 1) ? va_arg(ap, unsigned long) : va_arg(ap, unsigned int); out_num(ctx, n, 16, width, zeropad, (*p == 'X')); break; } case '%': out_char(ctx, '%'); break; default: out_char(ctx, '%'); out_char(ctx, *p); break; } p++; } if (ctx->buf && ctx->size > 0) { size_t end = (ctx->pos < ctx->size) ? ctx->pos : ctx->size - 1; ctx->buf[end] = '\0'; } return (int)ctx->pos; } int vsnprintf(char *str, size_t size, const char *format, va_list ap) { OutCtx ctx = { .buf = str, .size = size, .pos = 0 }; return vformat(&ctx, format, ap); } int snprintf(char *str, size_t size, const char *format, ...) { va_list ap; va_start(ap, format); int res = vsnprintf(str, size, format, ap); va_end(ap); return res; } int sprintf(char *str, const char *format, ...) { va_list ap; va_start(ap, format); int res = vsnprintf(str, (size_t)-1, format, ap); va_end(ap); return res; } int vprintf(const char *format, va_list ap) { char tmp[1024]; int n = vsnprintf(tmp, sizeof(tmp), format, ap); if (n > 0) console_write(tmp, (n < (int)sizeof(tmp)) ? (size_t)n : sizeof(tmp)-1); return n; } int printf(const char *format, ...) { va_list ap; va_start(ap, format); int res = vprintf(format, ap); va_end(ap); return res; } int fwrite(const void *ptr, size_t size, size_t nmemb, void *stream) { return write(1, ptr, size * nmemb); } int fflush(void *stream) { return 0; } // System stubs extern void nexus_yield(void); // void exit(int status) { while(1) { nexus_yield(); } } // Moved to libc_shim.zig void (*signal(int sig, void (*func)(int)))(int) { return NULL; } // LwIP Time - moved to sys_arch.c // uint32_t sys_now() { return 0; } // RNG for LwIP (Project Prometheus) int libc_rand(void) { static unsigned long next = 1; next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768; } // Utils uint16_t htons(uint16_t h) { return (h << 8) | (h >> 8); } void* memcpy(void* dest, const void* src, size_t n) { uint8_t* d = dest; const uint8_t* s = src; for (size_t i = 0; i < n; i++) d[i] = s[i]; return dest; } void* memset(void* s, int c, size_t n) { uint8_t* p = s; for (size_t i = 0; i < n; i++) p[i] = (uint8_t)c; return s; } int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; for (size_t i = 0; i < n; i++) { if (p1[i] != p2[i]) return p1[i] - p2[i]; } return 0; } void *memmove(void *dest, const void *src, size_t n) { char *d = (char *)dest; const char *s = (const char *)src; if (d < s) { for (size_t i = 0; i < n; i++) d[i] = s[i]; } else { for (size_t i = n; i > 0; i--) d[i - 1] = s[i - 1]; } return dest; } char *strchr(const char *s, int c) { while (*s != (char)c) { if (!*s++) return NULL; } return (char *)s; } char *strcpy(char *dest, const char *src) { char *d = dest; while ((*d++ = *src++)); return dest; } int strcmp(const char *s1, const char *s2) { while(*s1 && (*s1 == *s2)) { s1++; s2++; } return *(const unsigned char*)s1 - *(const unsigned char*)s2; } size_t strspn(const char *s, const char *accept) { const char *p = s; const char *a; while (*p) { for (a = accept; *a; a++) { if (*p == *a) break; } if (*a == '\0') return p - s; p++; } return p - s; } size_t strcspn(const char *s, const char *reject) { const char *p = s; const char *r; while (*p) { for (r = reject; *r; r++) { if (*p == *r) return p - s; } p++; } return p - s; } uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) { static const uint32_t rtable[16] = { 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c, }; const uint8_t *data = (const uint8_t *)buffer; for (size_t i = 0; i < size; i++) { crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 0)) & 0xf]; crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 4)) & 0xf]; } return crc; } #ifdef RUMPK_KERNEL // Kernel Mode: Direct UART extern void hal_console_write(const char* ptr, size_t len); void console_write(const void* p, size_t len) { hal_console_write(p, len); } #else // User Mode: Syscall void console_write(const void* p, size_t len) { write(1, p, len); } #endif void ion_egress_to_port(uint16_t port, void* pkt); int execve(const char *pathname, char *const argv[], char *const envp[]) { return -1; } pid_t fork(void) { return -1; } pid_t wait(int *status) { return -1; }