diff --git a/kernel/include/sys/Syscall.h b/kernel/include/sys/Syscall.h index 8d8e3202..d129cf25 100644 --- a/kernel/include/sys/Syscall.h +++ b/kernel/include/sys/Syscall.h @@ -25,8 +25,6 @@ namespace Syscall { void entry(Context* context); - - char* strdup_from_user(const char* user_string); } void sys_exit(Context* context, int status); diff --git a/kernel/include/sys/UserMemory.h b/kernel/include/sys/UserMemory.h new file mode 100644 index 00000000..9948b4b0 --- /dev/null +++ b/kernel/include/sys/UserMemory.h @@ -0,0 +1,29 @@ +#pragma once +#include "memory/MemoryManager.h" +#include "memory/VMM.h" +#include "misc/utils.h" + +char* strdup_from_user(const char* user_string); + +template T* user_address_to_typed_pointer(V address) +{ + uint64_t phys = VMM::get_physical((uint64_t)address); + if (phys == (uint64_t)-1) return nullptr; + return (T*)MemoryManager::get_unaligned_mappings((void*)phys, Utilities::get_blocks_from_size(PAGE_SIZE, S), + MAP_READ_WRITE); +} + +template void free_user_typed_pointer(T* ptr) +{ + MemoryManager::release_unaligned_mappings(ptr, Utilities::get_blocks_from_size(PAGE_SIZE, S)); +} + +template T* obtain_user_ref(T* user_ptr) +{ + return user_address_to_typed_pointer(user_ptr); +} + +template void release_user_ref(T* ptr) +{ + return free_user_typed_pointer(ptr); +} \ No newline at end of file diff --git a/kernel/src/sys/Syscall.cpp b/kernel/src/sys/Syscall.cpp index c6d9565f..f813bd1b 100644 --- a/kernel/src/sys/Syscall.cpp +++ b/kernel/src/sys/Syscall.cpp @@ -33,11 +33,4 @@ void Syscall::entry(Context* context) default: context->rax = -ENOSYS; break; } VMM::exit_syscall_context(); -} - -char* Syscall::strdup_from_user(const char* user_string) // FIXME: This function is a little hacky. -{ - uint64_t phys = VMM::get_physical((uint64_t)user_string); - if (phys == (uint64_t)-1) { return nullptr; } - return strdup((const char*)phys); } \ No newline at end of file diff --git a/kernel/src/sys/UserMemory.cpp b/kernel/src/sys/UserMemory.cpp new file mode 100644 index 00000000..6ca659ff --- /dev/null +++ b/kernel/src/sys/UserMemory.cpp @@ -0,0 +1,10 @@ +#include "sys/UserMemory.h" +#include "std/string.h" + +char* strdup_from_user( + const char* user_string) // FIXME: This function is a little hacky. Use the obtain_user_ref and similar functions. +{ + uint64_t phys = VMM::get_physical((uint64_t)user_string); + if (phys == (uint64_t)-1) { return nullptr; } + return strdup((const char*)phys); +} \ No newline at end of file diff --git a/kernel/src/sys/exec.cpp b/kernel/src/sys/exec.cpp index 74b37999..f0cfedcb 100644 --- a/kernel/src/sys/exec.cpp +++ b/kernel/src/sys/exec.cpp @@ -10,6 +10,7 @@ #include "std/stdlib.h" #include "std/string.h" #include "sys/Syscall.h" +#include "sys/UserMemory.h" #include "sys/elf/ELFLoader.h" #include "thread/Scheduler.h" @@ -57,7 +58,7 @@ void sys_fork(Context* context) void sys_exec(Context* context, const char* pathname) { - char* kpathname = Syscall::strdup_from_user(pathname); + char* kpathname = strdup_from_user(pathname); if (!kpathname) { context->rax = -EFAULT; diff --git a/kernel/src/sys/stdio.cpp b/kernel/src/sys/stdio.cpp index 9ad01b8f..d9c22625 100644 --- a/kernel/src/sys/stdio.cpp +++ b/kernel/src/sys/stdio.cpp @@ -8,6 +8,7 @@ #include "render/TextRenderer.h" #include "std/stdlib.h" #include "sys/Syscall.h" +#include "sys/UserMemory.h" #include "thread/Scheduler.h" #include "thread/Task.h" @@ -145,7 +146,7 @@ void sys_open(Context* context, const char* filename, int flags) return; } - char* kernel_filename = Syscall::strdup_from_user(filename); + char* kernel_filename = strdup_from_user(filename); if (!kernel_filename) { context->rax = -EFAULT; @@ -225,7 +226,7 @@ void sys_close(Context* context, int fd) void sys_mkdir(Context* context, const char* filename) { - char* kfilename = Syscall::strdup_from_user(filename); + char* kfilename = strdup_from_user(filename); if (!kfilename) { context->rax = -EFAULT;