Kernel: Add a few convenience functions to manipulate userland memory
This commit is contained in:
parent
755242719c
commit
48d4a5910a
@ -25,8 +25,6 @@
|
|||||||
namespace Syscall
|
namespace Syscall
|
||||||
{
|
{
|
||||||
void entry(Context* context);
|
void entry(Context* context);
|
||||||
|
|
||||||
char* strdup_from_user(const char* user_string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sys_exit(Context* context, int status);
|
void sys_exit(Context* context, int status);
|
||||||
|
29
kernel/include/sys/UserMemory.h
Normal file
29
kernel/include/sys/UserMemory.h
Normal file
@ -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 <typename T, unsigned long S = sizeof(T), typename V> 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 <typename T, unsigned long S = sizeof(T)> void free_user_typed_pointer(T* ptr)
|
||||||
|
{
|
||||||
|
MemoryManager::release_unaligned_mappings(ptr, Utilities::get_blocks_from_size(PAGE_SIZE, S));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> T* obtain_user_ref(T* user_ptr)
|
||||||
|
{
|
||||||
|
return user_address_to_typed_pointer<T>(user_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void release_user_ref(T* ptr)
|
||||||
|
{
|
||||||
|
return free_user_typed_pointer(ptr);
|
||||||
|
}
|
@ -33,11 +33,4 @@ void Syscall::entry(Context* context)
|
|||||||
default: context->rax = -ENOSYS; break;
|
default: context->rax = -ENOSYS; break;
|
||||||
}
|
}
|
||||||
VMM::exit_syscall_context();
|
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);
|
|
||||||
}
|
}
|
10
kernel/src/sys/UserMemory.cpp
Normal file
10
kernel/src/sys/UserMemory.cpp
Normal file
@ -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);
|
||||||
|
}
|
@ -10,6 +10,7 @@
|
|||||||
#include "std/stdlib.h"
|
#include "std/stdlib.h"
|
||||||
#include "std/string.h"
|
#include "std/string.h"
|
||||||
#include "sys/Syscall.h"
|
#include "sys/Syscall.h"
|
||||||
|
#include "sys/UserMemory.h"
|
||||||
#include "sys/elf/ELFLoader.h"
|
#include "sys/elf/ELFLoader.h"
|
||||||
#include "thread/Scheduler.h"
|
#include "thread/Scheduler.h"
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ void sys_fork(Context* context)
|
|||||||
|
|
||||||
void sys_exec(Context* context, const char* pathname)
|
void sys_exec(Context* context, const char* pathname)
|
||||||
{
|
{
|
||||||
char* kpathname = Syscall::strdup_from_user(pathname);
|
char* kpathname = strdup_from_user(pathname);
|
||||||
if (!kpathname)
|
if (!kpathname)
|
||||||
{
|
{
|
||||||
context->rax = -EFAULT;
|
context->rax = -EFAULT;
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "render/TextRenderer.h"
|
#include "render/TextRenderer.h"
|
||||||
#include "std/stdlib.h"
|
#include "std/stdlib.h"
|
||||||
#include "sys/Syscall.h"
|
#include "sys/Syscall.h"
|
||||||
|
#include "sys/UserMemory.h"
|
||||||
#include "thread/Scheduler.h"
|
#include "thread/Scheduler.h"
|
||||||
#include "thread/Task.h"
|
#include "thread/Task.h"
|
||||||
|
|
||||||
@ -145,7 +146,7 @@ void sys_open(Context* context, const char* filename, int flags)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* kernel_filename = Syscall::strdup_from_user(filename);
|
char* kernel_filename = strdup_from_user(filename);
|
||||||
if (!kernel_filename)
|
if (!kernel_filename)
|
||||||
{
|
{
|
||||||
context->rax = -EFAULT;
|
context->rax = -EFAULT;
|
||||||
@ -225,7 +226,7 @@ void sys_close(Context* context, int fd)
|
|||||||
|
|
||||||
void sys_mkdir(Context* context, const char* filename)
|
void sys_mkdir(Context* context, const char* filename)
|
||||||
{
|
{
|
||||||
char* kfilename = Syscall::strdup_from_user(filename);
|
char* kfilename = strdup_from_user(filename);
|
||||||
if (!kfilename)
|
if (!kfilename)
|
||||||
{
|
{
|
||||||
context->rax = -EFAULT;
|
context->rax = -EFAULT;
|
||||||
|
Loading…
Reference in New Issue
Block a user