From 729772ccbe51e5546348830f0e108786da042b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20R=C3=B6ger?= Date: Tue, 21 Apr 2026 01:25:06 +0200 Subject: [PATCH] feat(sys): add malloc --- CMakeLists.txt | 8 +++++--- app/nolibc.c | 15 ++++++++++++++- include/c-libs/sys/memory.h | 17 +++++++++++++++++ include/c-libs/sys/syscall.h | 25 +++++++++++++++++++++++-- src/sys/memory.c | 2 ++ src/sys/syscall.s | 13 ++++++++++++- 6 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 include/c-libs/sys/memory.h create mode 100644 src/sys/memory.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 01afdc6..ddf0286 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,8 @@ add_library( sys STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/sys/entry.s ${CMAKE_CURRENT_SOURCE_DIR}/src/sys/syscall.s - ${CMAKE_CURRENT_SOURCE_DIR}/src/sys/syscall.c) + ${CMAKE_CURRENT_SOURCE_DIR}/src/sys/syscall.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/sys/memory.c) target_include_directories( sys PUBLIC $ $) @@ -29,8 +30,9 @@ target_include_directories( add_executable(nolibc ${CMAKE_CURRENT_SOURCE_DIR}/app/nolibc.c) target_link_libraries(nolibc PRIVATE sys) target_compile_options( - nolibc PRIVATE -fno-asynchronous-unwind-tables -fno-unwind-tables - -fno-stack-protector -ffunction-sections -fdata-sections) + nolibc + PRIVATE -fno-asynchronous-unwind-tables -fno-unwind-tables + -fno-stack-protector -ffunction-sections -fdata-sections -fno-builtin) target_link_options( nolibc PRIVATE diff --git a/app/nolibc.c b/app/nolibc.c index 5085c71..9d69505 100644 --- a/app/nolibc.c +++ b/app/nolibc.c @@ -1,6 +1,19 @@ +#include #include +void strcpy(char *dst, const char *src) { + int ix = 0; + do { + dst[ix] = src[ix]; + } while (src[ix++]); +} + int main() { - write(0, "Hello World!\n", 13); + char *str = malloc(14); + strcpy(str, "Hello World!\n"); + + write(0, str, 13); + + munmap(str, 14); return 0; } diff --git a/include/c-libs/sys/memory.h b/include/c-libs/sys/memory.h new file mode 100644 index 0000000..41026b3 --- /dev/null +++ b/include/c-libs/sys/memory.h @@ -0,0 +1,17 @@ +#ifndef CLIBS_SYS_MEMORY_H +#define CLIBS_SYS_MEMORY_H + +#include +#include + +void *malloc(__u64 size); + +#endif + +#ifdef CLIBS_SYS_MEMORY_IMPL + +void *malloc(__u64 size) { + return mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, + 0); +} +#endif diff --git a/include/c-libs/sys/syscall.h b/include/c-libs/sys/syscall.h index d1e02bf..4144b5c 100644 --- a/include/c-libs/sys/syscall.h +++ b/include/c-libs/sys/syscall.h @@ -1,14 +1,22 @@ #ifndef CLIBS_SYS_SYSCALL_H #define CLIBS_SYS_SYSCALL_H -#include -#include +#include +#include void *syscall5(void *number, void *arg1, void *arg2, void *arg3, void *arg4, void *arg5); +void *syscall6(void *number, void *arg1, void *arg2, void *arg3, void *arg4, + void *arg5, void *arg6); + __s64 write(int fd, void const *data, __u64 nbytes); +void *mmap(void *addr, __u64 len, __u64 prot, __u64 flags, __u64 fd, + __s64 offset); + +int munmap(void *addr, __u64 len); + #endif #ifdef CLIBS_SYS_SYSCALL_IMPL @@ -18,4 +26,17 @@ __s64 write(int fd, void const *data, __u64 nbytes) { (void *)nbytes, 0, 0); } +void *mmap(void *addr, __u64 len, __u64 prot, __u64 flags, __u64 fd, + __s64 offset) { + return syscall6((void *)__NR_mmap, (void *)addr, (void *)len, (void *)prot, + (void *)flags, (void *)fd, (void *)offset); +} + +int munmap(void *addr, __u64 len) { + long val = (long)syscall5((void *)__NR_munmap, addr, (void *)len, (void *)0, + (void *)0, (void *)0); + + return (int)val; +} + #endif diff --git a/src/sys/memory.c b/src/sys/memory.c new file mode 100644 index 0000000..79b2cb1 --- /dev/null +++ b/src/sys/memory.c @@ -0,0 +1,2 @@ +#define CLIBS_SYS_MEMORY_IMPL +#include diff --git a/src/sys/syscall.s b/src/sys/syscall.s index 48da149..3309447 100644 --- a/src/sys/syscall.s +++ b/src/sys/syscall.s @@ -1,4 +1,4 @@ -.global syscall5 +.global syscall5, syscall6 syscall5: mov %rdi, %rax /* %rax (syscall number) = func param 1 (%rdi) */ @@ -9,5 +9,16 @@ syscall5: mov %r9, %r8 /* %r8 (syscall param 5) = func param 6 (%r9) */ syscall /* Enter a syscall (return value in %rax) */ ret /* Return value is already in %rax, we can return. */ + +syscall6: + mov %rdi, %rax /* %rax (syscall number) = func param 1 (%rdi) */ + mov %rsi, %rdi /* %rdi (syscall param 1) = func param 2 (%rsi) */ + mov %rdx, %rsi /* %rsi (syscall param 2) = func param 3 (%rdx) */ + mov %rcx, %rdx /* %rdx (syscall param 3) = func param 4 (%rcx) */ + mov %r8, %r10 /* %r10 (syscall param 4) = func param 5 (%r8) */ + mov %r9, %r8 /* %r8 (syscall param 5) = func param 6 (%r9) */ + mov 8(%rsp), %r9 /* %r9 (syscall param 6) = stack-value */ + syscall /* Enter a syscall (return value in %rax) */ + ret /* Return value is already in %rax, we can return. */ .section .note.GNU-stack,"",@progbits