From 9ac97f1e9d50f4b99b4b4fd728ed096f4f312620 Mon Sep 17 00:00:00 2001 From: flysand7 Date: Sun, 30 Jul 2023 18:45:14 +1100 Subject: [PATCH] Memory manager on linux + remove C23 attributes for now --- include/stdint.h | 8 ++++---- include/stdlib.h | 8 ++++---- include/tinyrt.h | 6 +++--- src/impl/cia-mem/allocator.c | 2 +- src/impl/stdlib-program/program.c | 8 ++++---- src/linux/syscall.c | 26 +++++++++++++++++++++++--- src/linux/tinyrt.c | 20 +++++++++++++++++++- src/linux/tinyrt.json | 2 +- src/windows/tinyrt.c | 2 +- 9 files changed, 60 insertions(+), 22 deletions(-) diff --git a/include/stdint.h b/include/stdint.h index f17d3de..829b224 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -37,10 +37,10 @@ typedef uint32_t uint_fast32_t, uint_least32_t; typedef uint64_t uint_fast64_t, uint_least64_t; // TODO: verify what size it is (on windows and linux) -typedef intmax_t int64_t; -typedef intptr_t int64_t; -typedef uintmax_t uint64_t; -typedef uintptr_t uint64_t; +typedef int64_t intmax_t; +typedef int64_t intptr_t; +typedef uint64_t uintmax_t; +typedef uint64_t uintptr_t; // Constant expandors #define INT8_C(n) (n) diff --git a/include/stdlib.h b/include/stdlib.h index 97e1ac3..cdd6193 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -5,7 +5,7 @@ int atexit(void (*func)(void)); int at_quick_exit(void (*func)(void)); -[[noreturn]] void abort(void); -[[noreturn]] void exit(int code); -[[noreturn]] void _Exit(int code); -[[noreturn]] void quick_exit(int code); \ No newline at end of file +_Noreturn void abort(void); +_Noreturn void exit(int code); +_Noreturn void _Exit(int code); +_Noreturn void quick_exit(int code); \ No newline at end of file diff --git a/include/tinyrt.h b/include/tinyrt.h index 2da36d6..6dc2d87 100644 --- a/include/tinyrt.h +++ b/include/tinyrt.h @@ -42,7 +42,7 @@ static _RT_Status _rt_deinit(); // Program API #if _RT_API_PROGRAM == 1 - [[noreturn]] static void _rt_program_exit(int code); + _Noreturn static void _rt_program_exit(int code); #endif // Environment API @@ -73,6 +73,6 @@ struct _RT_File { // Memory API #if _RT_API_MEMORY == 1 - static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 min_size, void **out_addr); - static _RT_Status _rt_mem_free(void *ptr); + static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 size, void **out_addr); + static _RT_Status _rt_mem_free(void *ptr, u64 size); #endif diff --git a/src/impl/cia-mem/allocator.c b/src/impl/cia-mem/allocator.c index 8ecc03b..5091784 100644 --- a/src/impl/cia-mem/allocator.c +++ b/src/impl/cia-mem/allocator.c @@ -25,7 +25,7 @@ static void *page_allocator_proc(void *ctx, int optype, void *old_ptr, u64 old_s return addr; } break; case CIA_MEM_OP_FREE: { - _rt_mem_free(old_ptr); + _rt_mem_free(old_ptr, old_size); } break; case CIA_MEM_OP_FREE_ALL: { return NULL; diff --git a/src/impl/stdlib-program/program.c b/src/impl/stdlib-program/program.c index 8bfe326..e73c60c 100644 --- a/src/impl/stdlib-program/program.c +++ b/src/impl/stdlib-program/program.c @@ -25,13 +25,13 @@ int at_quick_exit(void (*func)(void)) { return 0; } -[[noreturn]] void abort(void) { +_Noreturn void abort(void) { // TODO: Ideally do a debug trap if the process is being debugged _rt_program_exit(1); __builtin_unreachable(); } -[[noreturn]] void exit(int code) { +_Noreturn void exit(int code) { for(u64 i = n_atexit_handlers-1; i-- != 0; ) { void (*handler)(void) = atexit_handlers[i]; handler(); @@ -42,12 +42,12 @@ int at_quick_exit(void (*func)(void)) { __builtin_unreachable(); } -[[noreturn]] void _Exit(int code) { +_Noreturn void _Exit(int code) { _rt_program_exit(code); __builtin_unreachable(); } -[[noreturn]] void quick_exit(int code) { +_Noreturn void quick_exit(int code) { for(u64 i = n_at_quick_exit_handlers-1; i-- != 0; ) { void (*handler)(void) = at_quick_exit_handlers[i]; handler(); diff --git a/src/linux/syscall.c b/src/linux/syscall.c index 06c144f..6fb3b25 100644 --- a/src/linux/syscall.c +++ b/src/linux/syscall.c @@ -4,7 +4,7 @@ #define STDOUT_FILENO 1 #define STDERR_FILENO 2 -// arch_prctl syscall codes +// arch_prctl() syscall codes #define ARCH_SET_GS 0x1001 #define ARCH_SET_FS 0x1002 #define ARCH_GET_FS 0x1003 @@ -12,7 +12,7 @@ #define ARCH_GET_CPUID 0x1011 #define ARCH_SET_CPUID 0x1012 -// open syscall modes +// open() syscall modes #define O_ACCMODE 0003 #define O_RDONLY 00 #define O_WRONLY 01 @@ -28,6 +28,18 @@ #define O_FSYNC O_SYNC #define O_ASYNC 020000 +// mmap() protection modes, flags and constants +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 +#define PROT_EXEC 0x4 +#define PROT_NONE 0x0 +#define PROT_GROWSDOWN 0x01000000 +#define PROT_GROWSUP 0x02000000 +#define MAP_FILE 0 +#define MAP_ANONYMOUS 0x20 +#define MAP_32BIT 0x40 +#define MAP_FAILED (void *)() + #define SYS_read 0 #define SYS_write 1 #define SYS_open 2 @@ -165,7 +177,15 @@ static inline i64 syscall_close(u32 fd) { return __syscall1(SYS_close, fd); } -static inline noreturn void syscall_exit(int code) { +static inline void *syscall_mmap(u64 addr, u64 len, u64 prot, u64 flags, u64 fd, u64 offset) { + return (void *)__syscall6(SYS_mmap, addr, len, prot, flags, fd, offset); +} + +static inline i64 syscall_munmap(void *addr, u64 len) { + return __syscall2(SYS_munmap, (u64)addr, len); +} + +_Noreturn static inline void syscall_exit(int code) { __syscall1(SYS_exit, (i64)code); __builtin_unreachable(); } diff --git a/src/linux/tinyrt.c b/src/linux/tinyrt.c index 9916061..fc0aeb7 100644 --- a/src/linux/tinyrt.c +++ b/src/linux/tinyrt.c @@ -65,6 +65,24 @@ static _RT_Status _rt_file_close(_RT_File *file) { return _RT_STATUS_OK; } -[[noreturn]] static void _rt_program_exit(int code) { +_Noreturn static void _rt_program_exit(int code) { syscall_exit(code); } + +static _RT_Status _rt_mem_alloc(void *optional_desired_addr, u64 size, void **out_addr) { + void *addr = syscall_mmap((u64)optional_desired_addr, size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS, -1, 0); + if(addr == NULL) { + return _RT_ERROR_GENERIC; + } + *out_addr = addr; + return _RT_STATUS_OK; +} + +static _RT_Status _rt_mem_free(void *ptr, u64 len) { + i64 result = syscall_munmap(ptr, len); + if(result == -1) { + return _RT_ERROR_GENERIC; + } + return _RT_STATUS_OK; +} + diff --git a/src/linux/tinyrt.json b/src/linux/tinyrt.json index 32d09dd..53bb423 100644 --- a/src/linux/tinyrt.json +++ b/src/linux/tinyrt.json @@ -7,4 +7,4 @@ rt_api_file: true, rt_api_program: true, rt_api_shell: false, -rt_api_memory: false, +rt_api_memory: true, diff --git a/src/windows/tinyrt.c b/src/windows/tinyrt.c index af72ab2..2b57d33 100644 --- a/src/windows/tinyrt.c +++ b/src/windows/tinyrt.c @@ -69,7 +69,7 @@ static _RT_Status _rt_file_close(_RT_File *file) { return _RT_STATUS_OK; } -[[noreturn]] static void _rt_program_exit(int code) { +_Noreturn static void _rt_program_exit(int code) { ExitProcess(code); __builtin_unreachable(); }