diff options
author | Jon Santmyer <jon@jonsantmyer.com> | 2025-08-10 15:40:19 -0400 |
---|---|---|
committer | Jon Santmyer <jon@jonsantmyer.com> | 2025-08-10 15:40:19 -0400 |
commit | c4f8ef91f18d854a4ede7a94e95b2eab898d6963 (patch) | |
tree | c2772c4f380a684b6fa347f03b13f9476bf9500c /syscall/invoke-untyped.c | |
parent | b905869a35f062a4e5072f10bec3a2ba3db0e365 (diff) | |
download | jove-kernel-c4f8ef91f18d854a4ede7a94e95b2eab898d6963.tar.gz jove-kernel-c4f8ef91f18d854a4ede7a94e95b2eab898d6963.tar.bz2 jove-kernel-c4f8ef91f18d854a4ede7a94e95b2eab898d6963.zip |
working usermode objdir iteration
Diffstat (limited to 'syscall/invoke-untyped.c')
-rw-r--r-- | syscall/invoke-untyped.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/syscall/invoke-untyped.c b/syscall/invoke-untyped.c new file mode 100644 index 0000000..6b9199f --- /dev/null +++ b/syscall/invoke-untyped.c @@ -0,0 +1,96 @@ +#include "handles.h" +#include "syscall.h" +#include "error.h" +#include "memory.h" +#include "print.h" + +static int +s_handle_invoke_untyped_size( + objdir_t *root_dir, + objdir_entry_t *target, + uint8_t *payload, + size_t payload_at + ) +{ + size_t *dest; + SYSCALL_PAYLOAD_TAKEP(payload, payload_at, dest, size_t); + + size_t *untyped = ko_entry_data(target); +#ifdef DBG_SYSCALL + klogf("root_dir %p target %p data %p\n", root_dir, target, untyped); +#endif + *dest = *untyped; + return 0; +} + +static int +s_handle_invoke_untyped_alignment( + objdir_t *root_dir, + objdir_entry_t *target, + uint8_t *payload, + size_t payload_at + ) +{ + size_t *dest; + SYSCALL_PAYLOAD_TAKEP(payload, payload_at, dest, size_t); +#ifdef DBG_SYSCALL + klogf("root_dir %p target %p data %p\n", root_dir, target, target->data); +#endif + + *dest = target->data & 0xFFF; + return 0; +} + +static int +s_handle_invoke_untyped_split( + objdir_t *root_dir, + objdir_entry_t *target, + uint8_t *payload, + size_t payload_at + ) +{ + size_t dest_pathw; + size_t dest_bytes; + objdir_entry_t *dest_entry; + + SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, dest_pathw, dest_entry); + if(dest_entry->type != KO_NONE) return -KE_BADOBJ; + + size_t *untyped = (size_t*)target->data; + size_t untyped_size = *untyped; + + SYSCALL_PAYLOAD_TAKEL(payload, payload_at, dest_bytes, size_t); + if(untyped_size - sizeof(size_t) <= dest_bytes) return -KE_TOOSMALL; + + size_t *split = (size_t*)(((uintptr_t)untyped) + untyped_size - dest_bytes); + *untyped -= dest_bytes; + *split = dest_bytes; + + *dest_entry = (objdir_entry_t) { + .type = KO_MEMORY_UNTYPED, + .data = (uintptr_t)split + }; + return 0; +} + +static int (*s_invoke_handles[])(objdir_t*, objdir_entry_t*, uint8_t*, size_t) = { + [INVOKE_UNTYPED_SIZE] = s_handle_invoke_untyped_size, + [INVOKE_UNTYPED_SPLIT] = s_handle_invoke_untyped_split, + + [INVOKE_UNTYPED_ALIGNMENT] = s_handle_invoke_untyped_alignment +}; +static size_t s_invoke_handles_count = sizeof(s_invoke_handles) / sizeof(void*); + +int +syscall_handle_invoke_untyped( + objdir_t *root_dir, + objdir_entry_t *target, + uint8_t *payload, + size_t payload_at) +{ + uint8_t funcid; + SYSCALL_PAYLOAD_TAKEL(payload, payload_at, funcid, uint8_t); + + if(funcid >= s_invoke_handles_count) return -KE_BADFUNC; + return s_invoke_handles[funcid](root_dir, target, payload, payload_at); +} |