user: implement mlibc as the libc, finally.

It's finally done..

Signed-off-by: kaguya <vpshinomiya@protonmail.com>
This commit is contained in:
kaguya
2026-05-02 03:31:49 -04:00
parent 2fa39ad85a
commit 9a9b91c940
2387 changed files with 152741 additions and 315 deletions
@@ -0,0 +1,129 @@
#include <abi-bits/fcntl.h>
#include <abi-bits/pid_t.h>
#include <menix/archctl.hpp>
#include <menix/syscall.hpp>
#include <mlibc/internal-sysdeps.hpp>
#include <mlibc/tcb.hpp>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
namespace mlibc {
void sys_libc_log(const char *message) {
menix_syscall(SYSCALL_WRITE, 1, (size_t)message, strlen(message));
menix_syscall(SYSCALL_WRITE, 1, (size_t)"\n", 1);
}
[[noreturn]] void sys_libc_panic() {
sys_libc_log("mlibc panic!");
menix_syscall(SYSCALL_EXIT, 1);
__builtin_unreachable();
}
int sys_tcb_set(void *pointer) {
#if defined(__x86_64__)
return menix_syscall(SYSCALL_ARCHCTL, ARCHCTL_SET_FSBASE, (size_t)pointer).error;
#elif defined(__aarch64__)
uintptr_t thread_data = reinterpret_cast<uintptr_t>(pointer) + sizeof(Tcb) - 0x10;
asm volatile("msr tpidr_el0, %0" ::"r"(thread_data));
return 0;
#elif defined(__riscv)
uintptr_t thread_data = reinterpret_cast<uintptr_t>(pointer) + sizeof(Tcb);
asm volatile("mv tp, %0" ::"r"(thread_data));
return 0;
#elif defined(__loongarch64)
uintptr_t thread_data = reinterpret_cast<uintptr_t>(pointer) + sizeof(Tcb);
asm volatile("move $tp, %0" ::"r"(thread_data));
return 0;
#else
#error "Unsupported architecture!"
#endif
}
int sys_futex_tid() { return menix_syscall(SYSCALL_GETTID).value; }
int sys_futex_wait(int *pointer, int expected, const struct timespec *time) {
return menix_syscall(SYSCALL_FUTEX_WAIT, (size_t)pointer, expected, (size_t)time).error;
}
int sys_futex_wake(int *pointer) {
return menix_syscall(SYSCALL_FUTEX_WAKE, (size_t)pointer).error;
}
int sys_anon_allocate(size_t size, void **pointer) {
auto r = menix_syscall(
SYSCALL_MMAP, 0, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0
);
if (r.error)
return r.error;
*pointer = (void *)r.value;
return 0;
}
int sys_anon_free(void *pointer, size_t size) {
return menix_syscall(SYSCALL_MUNMAP, (size_t)pointer, size).error;
}
int sys_openat(int dirfd, const char *path, int flags, mode_t mode, int *fd) {
auto r = menix_syscall(SYSCALL_OPENAT, dirfd, (size_t)path, flags, mode);
if (r.error)
return r.error;
*fd = (int)r.value;
return 0;
}
int sys_open(const char *pathname, int flags, mode_t mode, int *fd) {
return sys_openat(AT_FDCWD, pathname, flags, mode, fd);
}
int sys_read(int fd, void *buf, size_t count, ssize_t *bytes_read) {
auto r = menix_syscall(SYSCALL_READ, fd, (size_t)buf, count);
if (r.error)
return r.error;
*bytes_read = (ssize_t)r.value;
return 0;
}
int sys_seek(int fd, off_t offset, int whence, off_t *new_offset) {
auto r = menix_syscall(SYSCALL_SEEK, fd, offset, whence);
if (r.error)
return r.error;
*new_offset = r.value;
return 0;
}
int sys_close(int fd) { return menix_syscall(SYSCALL_CLOSE, fd).error; }
int sys_stat(fsfd_target fsfdt, int fd, const char *path, int flags, struct stat *statbuf) {
switch (fsfdt) {
case fsfd_target::path:
return menix_syscall(SYSCALL_FSTATAT, AT_FDCWD, (size_t)path, (size_t)statbuf, flags)
.error;
case fsfd_target::fd_path:
return menix_syscall(SYSCALL_FSTATAT, fd, (size_t)path, (size_t)statbuf, flags).error;
case fsfd_target::fd:
return menix_syscall(SYSCALL_FSTAT, fd, (size_t)statbuf).error;
default:
return EINVAL;
}
}
int sys_vm_map(void *hint, size_t size, int prot, int flags, int fd, off_t offset, void **window) {
auto r = menix_syscall(SYSCALL_MMAP, (size_t)hint, size, prot, flags, fd, offset);
if (r.error)
return r.error;
*window = (void *)r.value;
return 0;
}
int sys_vm_unmap(void *pointer, size_t size) {
return menix_syscall(SYSCALL_MUNMAP, (size_t)pointer, size).error;
}
int sys_vm_protect(void *pointer, size_t size, int prot) {
return menix_syscall(SYSCALL_MPROTECT, (size_t)pointer, size, prot).error;
}
} // namespace mlibc