mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Fix sleep syscall
This commit is contained in:
parent
f552b8f6f0
commit
85c0de688d
@ -31,64 +31,69 @@ extern "C" void SystemCallHandlerStub();
|
|||||||
|
|
||||||
extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHandlerStub()
|
extern "C" __naked __used __no_stack_protector __aligned(16) void SystemCallHandlerStub()
|
||||||
{
|
{
|
||||||
asmv("swapgs\n"); /* Swap GS to get the CPUData */
|
asmv("swapgs\n"); /* Swap GS to get the TCB */
|
||||||
asmv("mov %rsp, %gs:0x8\n"); /* We save the current rsp to CPUData->TempStack */
|
asmv("mov %rsp, %gs:0x8\n"); /* We save the current rsp to TCB->TempStack */
|
||||||
asmv("mov %gs:0x0, %rsp\n"); /* Get CPUData->SystemCallStack and set it as rsp */
|
asmv("mov %gs:0x0, %rsp\n"); /* Get TCB->SystemCallStack and set it as rsp */
|
||||||
asmv("push $0x1b\n"); /* Push user data segment for SyscallsFrame */
|
asmv("push $0x1b\n"); /* Push user data segment for SyscallsFrame */
|
||||||
asmv("push %gs:0x8\n"); /* Push CPUData->TempStack (old rsp) for SyscallsFrame */
|
asmv("push %gs:0x8\n"); /* Push TCB->TempStack (old rsp) for SyscallsFrame */
|
||||||
asmv("push %r11\n"); /* Push the flags for SyscallsFrame */
|
asmv("push %r11\n"); /* Push the flags for SyscallsFrame */
|
||||||
asmv("push $0x23\n"); /* Push user code segment for SyscallsFrame */
|
asmv("push $0x23\n"); /* Push user code segment for SyscallsFrame */
|
||||||
asmv("push %rcx\n"); /* Push the return address for SyscallsFrame + sysretq (https://www.felixcloutier.com/x86/sysret) */
|
asmv("push %rcx\n"); /* Push the return address for SyscallsFrame + sysretq (https://www.felixcloutier.com/x86/sysret) */
|
||||||
|
|
||||||
asmv("push %rax\n" /* Push registers */
|
/* Push registers */
|
||||||
"push %rbx\n"
|
asmv("push %rax\n"
|
||||||
"push %rcx\n"
|
"push %rbx\n"
|
||||||
"push %rdx\n"
|
"push %rcx\n"
|
||||||
"push %rsi\n"
|
"push %rdx\n"
|
||||||
"push %rdi\n"
|
"push %rsi\n"
|
||||||
"push %rbp\n"
|
"push %rdi\n"
|
||||||
"push %r8\n"
|
"push %rbp\n"
|
||||||
"push %r9\n"
|
"push %r8\n"
|
||||||
"push %r10\n"
|
"push %r9\n"
|
||||||
"push %r11\n"
|
"push %r10\n"
|
||||||
"push %r12\n"
|
"push %r11\n"
|
||||||
"push %r13\n"
|
"push %r12\n"
|
||||||
"push %r14\n"
|
"push %r13\n"
|
||||||
"push %r15\n");
|
"push %r14\n"
|
||||||
|
"push %r15\n");
|
||||||
|
|
||||||
asmv("mov %rsp, %rdi\n"); /* Set the first argument to the SyscallsFrame pointer */
|
/* Set the first argument to the SyscallsFrame pointer */
|
||||||
asmv("mov $0, %rbp\n");
|
asmv("mov %rsp, %rdi\n");
|
||||||
asmv("call SystemCallsHandler\n");
|
asmv("mov $0, %rbp\n");
|
||||||
|
asmv("call SystemCallsHandler\n");
|
||||||
|
|
||||||
asmv("pop %r15\n" /* Pop registers except rax */
|
/* Pop registers except rax */
|
||||||
"pop %r14\n"
|
asmv("pop %r15\n"
|
||||||
"pop %r13\n"
|
"pop %r14\n"
|
||||||
"pop %r12\n"
|
"pop %r13\n"
|
||||||
"pop %r11\n"
|
"pop %r12\n"
|
||||||
"pop %r10\n"
|
"pop %r11\n"
|
||||||
"pop %r9\n"
|
"pop %r10\n"
|
||||||
"pop %r8\n"
|
"pop %r9\n"
|
||||||
"pop %rbp\n"
|
"pop %r8\n"
|
||||||
"pop %rdi\n"
|
"pop %rbp\n"
|
||||||
"pop %rsi\n"
|
"pop %rdi\n"
|
||||||
"pop %rdx\n"
|
"pop %rsi\n"
|
||||||
"pop %rcx\n"
|
"pop %rdx\n"
|
||||||
"pop %rbx\n");
|
"pop %rcx\n"
|
||||||
|
"pop %rbx\n");
|
||||||
|
|
||||||
asmv("mov %gs:0x8, %rsp\n"); // Restore rsp from CPUData->TempStack
|
/* Restore rsp from TCB->TempStack */
|
||||||
|
asmv("mov %gs:0x8, %rsp\n");
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
asmv("movq $0, %gs:0x8\n"); // Easier to debug stacks // FIXME: Can't use xor
|
/* Easier to debug stacks */
|
||||||
|
asmv("movq $0, %gs:0x8\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
asmv("swapgs\n"); // Swap GS back to the user GS
|
asmv("swapgs\n"); /* Swap GS back to the user GS */
|
||||||
asmv("sti\n"); // Enable interrupts
|
asmv("sti\n"); /* Enable interrupts */
|
||||||
asmv("sysretq\n"); // Return to rcx address in user mode
|
asmv("sysretq\n"); /* Return to rcx address in user mode */
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitializeSystemCalls()
|
void InitializeSystemCalls()
|
||||||
{
|
{
|
||||||
wrmsr(MSR_EFER, rdmsr(MSR_EFER) | 1);
|
wrmsr(MSR_EFER, rdmsr(MSR_EFER) | 1);
|
||||||
wrmsr(MSR_STAR, ((uint64_t)(GDT_KERNEL_CODE) << 32) | ((uint64_t)(GDT_KERNEL_DATA | 3) << 48));
|
wrmsr(MSR_STAR, ((uint64_t)(GDT_KERNEL_CODE) << 32) | ((uint64_t)(GDT_KERNEL_DATA | 3) << 48));
|
||||||
wrmsr(MSR_LSTAR, (uint64_t)SystemCallHandlerStub);
|
wrmsr(MSR_LSTAR, (uint64_t)SystemCallHandlerStub);
|
||||||
wrmsr(MSR_SYSCALL_MASK, (uint64_t)(1 << 9));
|
wrmsr(MSR_SYSCALL_MASK, (uint64_t)(1 << 9));
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,6 @@ namespace CrashHandler
|
|||||||
if (cpu)
|
if (cpu)
|
||||||
{
|
{
|
||||||
EHPrint("\eE46CEBCPU Data Address: %#lx\n", cpu);
|
EHPrint("\eE46CEBCPU Data Address: %#lx\n", cpu);
|
||||||
EHPrint("Syscalls Stack: %#lx, TempStack: %#lx\n", cpu->SystemCallStack, cpu->TempStack);
|
|
||||||
EHPrint("Core Stack: %#lx, Core ID: %ld, Error Code: %ld\n", cpu->Stack, cpu->ID, cpu->ErrorCode);
|
EHPrint("Core Stack: %#lx, Core ID: %ld, Error Code: %ld\n", cpu->Stack, cpu->ID, cpu->ErrorCode);
|
||||||
EHPrint("Is Active: %s\n", cpu->IsActive ? "true" : "false");
|
EHPrint("Is Active: %s\n", cpu->IsActive ? "true" : "false");
|
||||||
EHPrint("Current Process: %#lx, Current Thread: %#lx\n", cpu->CurrentProcess, cpu->CurrentThread);
|
EHPrint("Current Process: %#lx, Current Thread: %#lx\n", cpu->CurrentProcess, cpu->CurrentThread);
|
||||||
|
@ -67,7 +67,6 @@ namespace Interrupts
|
|||||||
CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
|
CPU::x64::wrmsr(CPU::x64::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
|
||||||
CoreData->ID = Core;
|
CoreData->ID = Core;
|
||||||
CoreData->IsActive = true;
|
CoreData->IsActive = true;
|
||||||
CoreData->SystemCallStack = (uint8_t *)((uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE);
|
|
||||||
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
|
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
|
||||||
if (CoreData->Checksum != CPU_DATA_CHECKSUM)
|
if (CoreData->Checksum != CPU_DATA_CHECKSUM)
|
||||||
{
|
{
|
||||||
@ -85,7 +84,6 @@ namespace Interrupts
|
|||||||
CPU::x32::wrmsr(CPU::x32::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
|
CPU::x32::wrmsr(CPU::x32::MSR_SHADOW_GS_BASE, (uint64_t)CoreData);
|
||||||
CoreData->ID = Core;
|
CoreData->ID = Core;
|
||||||
CoreData->IsActive = true;
|
CoreData->IsActive = true;
|
||||||
CoreData->SystemCallStack = (uint8_t *)((uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE);
|
|
||||||
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
|
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
|
||||||
if (CoreData->Checksum != CPU_DATA_CHECKSUM)
|
if (CoreData->Checksum != CPU_DATA_CHECKSUM)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +60,7 @@ namespace Memory
|
|||||||
|
|
||||||
uint64_t MemMgr::GetAllocatedMemorySize()
|
uint64_t MemMgr::GetAllocatedMemorySize()
|
||||||
{
|
{
|
||||||
|
SmartLock(MgrLock);
|
||||||
uint64_t Size = 0;
|
uint64_t Size = 0;
|
||||||
foreach (auto ap in AllocatedPagesList)
|
foreach (auto ap in AllocatedPagesList)
|
||||||
Size += ap.PageCount;
|
Size += ap.PageCount;
|
||||||
@ -68,6 +69,7 @@ namespace Memory
|
|||||||
|
|
||||||
bool MemMgr::Add(void *Address, size_t Count)
|
bool MemMgr::Add(void *Address, size_t Count)
|
||||||
{
|
{
|
||||||
|
SmartLock(MgrLock);
|
||||||
if (Address == nullptr)
|
if (Address == nullptr)
|
||||||
{
|
{
|
||||||
error("Address is null!");
|
error("Address is null!");
|
||||||
@ -124,6 +126,7 @@ namespace Memory
|
|||||||
|
|
||||||
void *MemMgr::RequestPages(size_t Count, bool User)
|
void *MemMgr::RequestPages(size_t Count, bool User)
|
||||||
{
|
{
|
||||||
|
SmartLock(MgrLock);
|
||||||
void *Address = KernelAllocator.RequestPages(Count);
|
void *Address = KernelAllocator.RequestPages(Count);
|
||||||
for (size_t i = 0; i < Count; i++)
|
for (size_t i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
@ -162,6 +165,7 @@ namespace Memory
|
|||||||
|
|
||||||
void MemMgr::FreePages(void *Address, size_t Count)
|
void MemMgr::FreePages(void *Address, size_t Count)
|
||||||
{
|
{
|
||||||
|
SmartLock(MgrLock);
|
||||||
for (size_t i = 0; i < AllocatedPagesList.size(); i++)
|
for (size_t i = 0; i < AllocatedPagesList.size(); i++)
|
||||||
{
|
{
|
||||||
if (AllocatedPagesList[i].Address == Address)
|
if (AllocatedPagesList[i].Address == Address)
|
||||||
@ -205,6 +209,7 @@ namespace Memory
|
|||||||
|
|
||||||
void MemMgr::DetachAddress(void *Address)
|
void MemMgr::DetachAddress(void *Address)
|
||||||
{
|
{
|
||||||
|
SmartLock(MgrLock);
|
||||||
for (size_t i = 0; i < AllocatedPagesList.size(); i++)
|
for (size_t i = 0; i < AllocatedPagesList.size(); i++)
|
||||||
{
|
{
|
||||||
if (AllocatedPagesList[i].Address == Address)
|
if (AllocatedPagesList[i].Address == Address)
|
||||||
@ -226,6 +231,7 @@ namespace Memory
|
|||||||
|
|
||||||
MemMgr::MemMgr(PageTable *Table, VirtualFileSystem::Node *Directory)
|
MemMgr::MemMgr(PageTable *Table, VirtualFileSystem::Node *Directory)
|
||||||
{
|
{
|
||||||
|
SmartLock(MgrLock);
|
||||||
if (Table)
|
if (Table)
|
||||||
this->Table = Table;
|
this->Table = Table;
|
||||||
else
|
else
|
||||||
@ -243,6 +249,7 @@ namespace Memory
|
|||||||
|
|
||||||
MemMgr::~MemMgr()
|
MemMgr::~MemMgr()
|
||||||
{
|
{
|
||||||
|
SmartLock(MgrLock);
|
||||||
foreach (auto ap in AllocatedPagesList)
|
foreach (auto ap in AllocatedPagesList)
|
||||||
{
|
{
|
||||||
KernelAllocator.FreePages(ap.Address, ap.PageCount);
|
KernelAllocator.FreePages(ap.Address, ap.PageCount);
|
||||||
|
@ -60,22 +60,32 @@ EXTERNC __weak __noreturn __no_stack_protector void __stack_chk_fail(void)
|
|||||||
debug("Current stack check guard value: %#lx", __stack_chk_guard);
|
debug("Current stack check guard value: %#lx", __stack_chk_guard);
|
||||||
KPrint("\eFF0000Stack smashing detected!");
|
KPrint("\eFF0000Stack smashing detected!");
|
||||||
|
|
||||||
#if defined(a86)
|
|
||||||
void *Stack = nullptr;
|
void *Stack = nullptr;
|
||||||
|
#if defined(a86)
|
||||||
|
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
asmv("movq %%rsp, %0"
|
asmv("movq %%rsp, %0"
|
||||||
: "=r"(Stack));
|
: "=r"(Stack));
|
||||||
#elif defined(a32)
|
#elif defined(a32)
|
||||||
asmv("movl %%esp, %0"
|
asmv("movl %%esp, %0"
|
||||||
: "=r"(Stack));
|
: "=r"(Stack));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(aa64)
|
||||||
|
|
||||||
|
asmv("mov %%sp, %0"
|
||||||
|
: "=r"(Stack));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
error("Stack address: %#lx", Stack);
|
error("Stack address: %#lx", Stack);
|
||||||
|
|
||||||
while (1)
|
if (DebuggerIsAttached)
|
||||||
asmv("cli; hlt");
|
#ifdef a86
|
||||||
|
asmv("int $0x3");
|
||||||
#elif defined(aa64)
|
#elif defined(aa64)
|
||||||
asmv("wfe");
|
asmv("brk #0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CPU::Stop();
|
CPU::Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,21 +497,20 @@ void KernelMainThread()
|
|||||||
TaskManager->WaitForThread(ret.Thread);
|
TaskManager->WaitForThread(ret.Thread);
|
||||||
ExitCode = ret.Thread->GetExitCode();
|
ExitCode = ret.Thread->GetExitCode();
|
||||||
Exit:
|
Exit:
|
||||||
if (ExitCode != 0)
|
if (ExitCode == 0)
|
||||||
{
|
|
||||||
KPrint("\eE85230Userspace process exited with code %d (%#x)", ExitCode,
|
|
||||||
ExitCode < 0 ? ExitCode * -1 : ExitCode);
|
|
||||||
KPrint("Dropping to recovery screen...");
|
|
||||||
TaskManager->Sleep(2500);
|
|
||||||
TaskManager->WaitForThread(blaThread);
|
|
||||||
RecoveryScreen = new Recovery::KernelRecovery;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
KPrint("\eFF7900%s process exited with code %d and it didn't invoked the shutdown function.",
|
KPrint("\eFF7900%s process exited with code %d and it didn't invoked the shutdown function.",
|
||||||
Config.InitPath, ExitCode);
|
Config.InitPath, ExitCode);
|
||||||
KPrint("System Halted");
|
KPrint("System Halted");
|
||||||
|
CPU::Halt(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KPrint("\eE85230Userspace process exited with code %d (%#x)", ExitCode,
|
||||||
|
ExitCode < 0 ? -ExitCode : ExitCode);
|
||||||
|
KPrint("Dropping to recovery screen...");
|
||||||
|
TaskManager->Sleep(2500);
|
||||||
|
TaskManager->WaitForThread(blaThread);
|
||||||
|
RecoveryScreen = new Recovery::KernelRecovery;
|
||||||
CPU::Halt(true);
|
CPU::Halt(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,105 +16,75 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <syscalls.hpp>
|
#include <syscalls.hpp>
|
||||||
|
|
||||||
#include <memory.hpp>
|
#include <memory.hpp>
|
||||||
#include <lock.hpp>
|
#include <lock.hpp>
|
||||||
#include <exec.hpp>
|
#include <exec.hpp>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include "../syscalls.h"
|
#include "../syscalls.h"
|
||||||
#include "../kernel.h"
|
#include "../kernel.h"
|
||||||
|
|
||||||
#include "../ipc.h"
|
#include "../ipc.h"
|
||||||
|
|
||||||
|
#define SysFrm SyscallsFrame
|
||||||
|
|
||||||
using InterProcessCommunication::IPC;
|
using InterProcessCommunication::IPC;
|
||||||
using InterProcessCommunication::IPCID;
|
using InterProcessCommunication::IPCID;
|
||||||
using Tasking::Token;
|
using Tasking::Token;
|
||||||
using Tasking::TTL;
|
using Tasking::TTL;
|
||||||
|
using Tasking::TaskStatus::Ready;
|
||||||
|
using Tasking::TaskStatus::Terminated;
|
||||||
using Tasking::TTL::Trusted;
|
using Tasking::TTL::Trusted;
|
||||||
using Tasking::TTL::TrustedByKernel;
|
using Tasking::TTL::TrustedByKernel;
|
||||||
using Tasking::TTL::UnknownTrustLevel;
|
using Tasking::TTL::UnknownTrustLevel;
|
||||||
using Tasking::TTL::Untrusted;
|
using Tasking::TTL::Untrusted;
|
||||||
|
|
||||||
static inline bool CheckTrust(int TrustLevel)
|
__noreturn static void sys_exit(SysFrm *, int code)
|
||||||
{
|
{
|
||||||
Token token = TaskManager->GetCurrentThread()->Security.UniqueToken;
|
trace("Userspace thread %s(%d) exited with code %d (%#x)",
|
||||||
if (likely(TaskManager->GetSecurityManager()->IsTokenTrusted(token, TrustLevel)))
|
TaskManager->GetCurrentThread()->Name,
|
||||||
return true;
|
TaskManager->GetCurrentThread()->ID, code,
|
||||||
|
code < 0 ? -code : code);
|
||||||
|
|
||||||
warn("Thread %s(%lld) tried to access a system call \"%s\" with insufficient trust level",
|
|
||||||
TaskManager->GetCurrentThread()->Name, TaskManager->GetCurrentThread()->ID,
|
|
||||||
KernelSymbolTable->GetSymbolFromAddress((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0))));
|
|
||||||
debug("token=%#lx, trust=%d", token, TaskManager->GetSecurityManager()->GetTokenTrustLevel(token));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sys_exit(SyscallsFrame *Frame, int code)
|
|
||||||
{
|
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted | UnknownTrustLevel))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
trace("Userspace thread %s(%lld) exited with code %#llx", TaskManager->GetCurrentThread()->Name, TaskManager->GetCurrentThread()->ID, code);
|
|
||||||
TaskManager->GetCurrentThread()->ExitCode = code;
|
TaskManager->GetCurrentThread()->ExitCode = code;
|
||||||
TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Terminated;
|
TaskManager->GetCurrentThread()->Status = Terminated;
|
||||||
TaskManager->Schedule();
|
TaskManager->Schedule();
|
||||||
|
__builtin_unreachable();
|
||||||
UNUSED(Frame);
|
|
||||||
return SYSCALL_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_print(SyscallsFrame *Frame, char Char, int Index)
|
static int sys_print(SysFrm *, char Char, int Index)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
char ret = Display->Print(Char, Index, true);
|
char ret = Display->Print(Char, Index, true);
|
||||||
if (!Config.BootAnimation && Index == 0)
|
if (!Config.BootAnimation && Index == 0)
|
||||||
#ifdef DEBUG
|
|
||||||
Display->SetBuffer(Index);
|
Display->SetBuffer(Index);
|
||||||
#else
|
|
||||||
if (Char == '\n')
|
|
||||||
Display->SetBuffer(Index);
|
|
||||||
#endif
|
|
||||||
UNUSED(Frame);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t sys_request_pages(SyscallsFrame *Frame, size_t Count)
|
static uintptr_t sys_request_pages(SysFrm *, size_t Count)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
|
||||||
return SYSCALL_ACCESS_DENIED;
|
return (uintptr_t)MemMgr->RequestPages(Count + 1, true);
|
||||||
|
|
||||||
UNUSED(Frame);
|
|
||||||
return (uintptr_t)TaskManager->GetCurrentThread()->Memory->RequestPages(Count + 1, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_free_pages(SyscallsFrame *Frame, uintptr_t Address, size_t Count)
|
static int sys_free_pages(SysFrm *, uintptr_t Address, size_t Count)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
|
||||||
return SYSCALL_ACCESS_DENIED;
|
MemMgr->FreePages((void *)Address, Count + 1);
|
||||||
|
|
||||||
TaskManager->GetCurrentThread()->Memory->FreePages((void *)Address, Count + 1);
|
|
||||||
UNUSED(Frame);
|
|
||||||
return SYSCALL_OK;
|
return SYSCALL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_detach_address(SyscallsFrame *Frame, uintptr_t Address)
|
static int sys_detach_address(SysFrm *, uintptr_t Address)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted))
|
Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
|
||||||
return SYSCALL_ACCESS_DENIED;
|
MemMgr->DetachAddress((void *)Address);
|
||||||
|
|
||||||
TaskManager->GetCurrentThread()->Memory->DetachAddress((void *)Address);
|
|
||||||
UNUSED(Frame);
|
|
||||||
return SYSCALL_OK;
|
return SYSCALL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_memory_map(SyscallsFrame *Frame, uintptr_t VirtualAddress, uintptr_t PhysicalAddress, size_t Size, enum MemoryMapFlags Flags)
|
static int sys_memory_map(SysFrm *, uintptr_t VirtualAddress,
|
||||||
|
uintptr_t PhysicalAddress, size_t Size,
|
||||||
|
enum MemoryMapFlags Flags)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
if (Flags > 7) /* (MAP_PRESENT | MAP_WRITABLE | MAP_USER) */
|
if (Flags > 7) /* (MAP_PRESENT | MAP_WRITABLE | MAP_USER) */
|
||||||
return SYSCALL_INVALID_ARGUMENT;
|
return SYSCALL_INVALID_ARGUMENT;
|
||||||
|
|
||||||
@ -126,15 +96,12 @@ static int sys_memory_map(SyscallsFrame *Frame, uintptr_t VirtualAddress, uintpt
|
|||||||
Size, Flags);
|
Size, Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNUSED(Frame);
|
|
||||||
return SYSCALL_OK;
|
return SYSCALL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_memory_unmap(SyscallsFrame *Frame, uintptr_t VirtualAddress, size_t Size)
|
static int sys_memory_unmap(SysFrm *, uintptr_t VirtualAddress,
|
||||||
|
size_t Size)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
Memory::PageTable *PageTable = TaskManager->GetCurrentProcess()->PageTable;
|
Memory::PageTable *PageTable = TaskManager->GetCurrentProcess()->PageTable;
|
||||||
{
|
{
|
||||||
Memory::Virtual vmm = Memory::Virtual(PageTable);
|
Memory::Virtual vmm = Memory::Virtual(PageTable);
|
||||||
@ -142,19 +109,18 @@ static int sys_memory_unmap(SyscallsFrame *Frame, uintptr_t VirtualAddress, size
|
|||||||
Size);
|
Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
UNUSED(Frame);
|
|
||||||
return SYSCALL_OK;
|
return SYSCALL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
|
static uintptr_t sys_kernelctl(SysFrm *,
|
||||||
|
enum KCtl Command,
|
||||||
|
uint64_t Arg1, uint64_t Arg2,
|
||||||
|
uint64_t Arg3, uint64_t Arg4)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
switch (Command)
|
switch (Command)
|
||||||
{
|
{
|
||||||
case KCTL_GET_PID:
|
case KCTL_GET_PID:
|
||||||
return TaskManager->GetCurrentThread()->Parent->ID;
|
return TaskManager->GetCurrentProcess()->ID;
|
||||||
case KCTL_GET_TID:
|
case KCTL_GET_TID:
|
||||||
return TaskManager->GetCurrentThread()->ID;
|
return TaskManager->GetCurrentThread()->ID;
|
||||||
case KCTL_GET_PAGE_SIZE:
|
case KCTL_GET_PAGE_SIZE:
|
||||||
@ -163,9 +129,6 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
|
|||||||
return TaskManager->GetCurrentThread()->Security.IsCritical;
|
return TaskManager->GetCurrentThread()->Security.IsCritical;
|
||||||
case KCTL_REGISTER_ELF_LIB:
|
case KCTL_REGISTER_ELF_LIB:
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
char *Identifier = (char *)Arg1;
|
char *Identifier = (char *)Arg1;
|
||||||
const char *Path = (const char *)Arg2;
|
const char *Path = (const char *)Arg2;
|
||||||
|
|
||||||
@ -175,7 +138,8 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
|
|||||||
std::string FullPath = Path;
|
std::string FullPath = Path;
|
||||||
int retries = 0;
|
int retries = 0;
|
||||||
RetryReadPath:
|
RetryReadPath:
|
||||||
debug("KCTL_REGISTER_ELF_LIB: Trying to open %s", FullPath.c_str());
|
debug("KCTL_REGISTER_ELF_LIB: Trying to open %s",
|
||||||
|
FullPath.c_str());
|
||||||
VirtualFileSystem::File f = vfs->Open(FullPath.c_str());
|
VirtualFileSystem::File f = vfs->Open(FullPath.c_str());
|
||||||
|
|
||||||
if (!f.IsOK())
|
if (!f.IsOK())
|
||||||
@ -194,7 +158,8 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
|
|||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
VirtualFileSystem::Node *cwd = TaskManager->GetCurrentProcess()->CurrentWorkingDirectory;
|
VirtualFileSystem::Node *cwd =
|
||||||
|
TaskManager->GetCurrentProcess()->CurrentWorkingDirectory;
|
||||||
FullPath = vfs->GetPathFromNode(cwd).get();
|
FullPath = vfs->GetPathFromNode(cwd).get();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -223,9 +188,6 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
|
|||||||
}
|
}
|
||||||
case KCTL_GET_ELF_LIB_MEMORY_IMAGE:
|
case KCTL_GET_ELF_LIB_MEMORY_IMAGE:
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
char *Identifier = (char *)Arg1;
|
char *Identifier = (char *)Arg1;
|
||||||
if (!Identifier)
|
if (!Identifier)
|
||||||
return 0;
|
return 0;
|
||||||
@ -234,17 +196,16 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
|
|||||||
|
|
||||||
if (!lib.MemoryImage)
|
if (!lib.MemoryImage)
|
||||||
{
|
{
|
||||||
debug("Failed to get library memory image %#lx", (uintptr_t)lib.MemoryImage);
|
debug("Failed to get library memory image %#lx",
|
||||||
|
(uintptr_t)lib.MemoryImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Returning memory image %#lx (%s)", (uintptr_t)lib.MemoryImage, Identifier);
|
debug("Returning memory image %#lx (%s)",
|
||||||
|
(uintptr_t)lib.MemoryImage, Identifier);
|
||||||
return (uintptr_t)lib.MemoryImage;
|
return (uintptr_t)lib.MemoryImage;
|
||||||
}
|
}
|
||||||
case KCTL_GET_ABSOLUTE_PATH:
|
case KCTL_GET_ABSOLUTE_PATH:
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
char *Identifier = (char *)Arg1;
|
char *Identifier = (char *)Arg1;
|
||||||
void *Buffer = (void *)Arg2;
|
void *Buffer = (void *)Arg2;
|
||||||
size_t BufferSize = Arg3;
|
size_t BufferSize = Arg3;
|
||||||
@ -274,15 +235,11 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
|
|||||||
UNUSED(Arg2);
|
UNUSED(Arg2);
|
||||||
UNUSED(Arg3);
|
UNUSED(Arg3);
|
||||||
UNUSED(Arg4);
|
UNUSED(Arg4);
|
||||||
UNUSED(Frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t sys_file_open(SyscallsFrame *Frame, const char *Path, uint64_t Flags)
|
static uint64_t sys_file_open(SysFrm *, const char *Path, uint64_t Flags)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
function("%s, %#lx", Path, Flags);
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
debug("(Path: %s, Flags: %#lx)", Path, Flags);
|
|
||||||
VirtualFileSystem::Node *cwd = nullptr;
|
VirtualFileSystem::Node *cwd = nullptr;
|
||||||
if (vfs->PathIsRelative(Path))
|
if (vfs->PathIsRelative(Path))
|
||||||
cwd = TaskManager->GetCurrentProcess()->CurrentWorkingDirectory;
|
cwd = TaskManager->GetCurrentProcess()->CurrentWorkingDirectory;
|
||||||
@ -297,118 +254,111 @@ static uint64_t sys_file_open(SyscallsFrame *Frame, const char *Path, uint64_t F
|
|||||||
return SYSCALL_INTERNAL_ERROR;
|
return SYSCALL_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualFileSystem::File *KernelPrivate = (VirtualFileSystem::File *)TaskManager->GetCurrentThread()->Memory->RequestPages(TO_PAGES(sizeof(VirtualFileSystem::File)));
|
Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
|
||||||
|
|
||||||
|
constexpr size_t FileStructPages =
|
||||||
|
TO_PAGES(sizeof(VirtualFileSystem::File));
|
||||||
|
|
||||||
|
VirtualFileSystem::File *KernelPrivate =
|
||||||
|
(VirtualFileSystem::File *)MemMgr->RequestPages(FileStructPages);
|
||||||
*KernelPrivate = KPObj;
|
*KernelPrivate = KPObj;
|
||||||
debug("Opened file %s (%d)", KPObj.Name, KPObj.Status);
|
debug("Opened file %s (%d)", KPObj.Name, KPObj.Status);
|
||||||
return (uint64_t)KernelPrivate;
|
return (uint64_t)KernelPrivate;
|
||||||
UNUSED(Frame);
|
|
||||||
UNUSED(Flags);
|
UNUSED(Flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_file_close(SyscallsFrame *Frame, void *KernelPrivate)
|
static int sys_file_close(SysFrm *, void *KernelPrivate)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
function("%#lx", KernelPrivate);
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
debug("(KernelPrivate: %#lx)", KernelPrivate);
|
|
||||||
|
|
||||||
if (KernelPrivate)
|
if (KernelPrivate)
|
||||||
{
|
{
|
||||||
VirtualFileSystem::File KPObj = *(VirtualFileSystem::File *)KernelPrivate;
|
VirtualFileSystem::File KPObj = *(VirtualFileSystem::File *)KernelPrivate;
|
||||||
debug("Closed file %s (%d)", KPObj.Name, KPObj.Status);
|
debug("Closed file %s (%d)", KPObj.Name, KPObj.Status);
|
||||||
vfs->Close(KPObj);
|
vfs->Close(KPObj);
|
||||||
TaskManager->GetCurrentThread()->Memory->FreePages(KernelPrivate, TO_PAGES(sizeof(VirtualFileSystem::File)));
|
Memory::MemMgr *MemMgr = TaskManager->GetCurrentThread()->Memory;
|
||||||
|
MemMgr->FreePages(KernelPrivate,
|
||||||
|
TO_PAGES(sizeof(VirtualFileSystem::File)));
|
||||||
return SYSCALL_OK;
|
return SYSCALL_OK;
|
||||||
}
|
}
|
||||||
return SYSCALL_INVALID_ARGUMENT;
|
return SYSCALL_INVALID_ARGUMENT;
|
||||||
UNUSED(Frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t sys_file_read(SyscallsFrame *Frame, void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
|
static uint64_t sys_file_read(SysFrm *, void *KernelPrivate,
|
||||||
|
uint8_t *Buffer, uint64_t Size)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
if (KernelPrivate == nullptr)
|
if (KernelPrivate == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
debug("(KernelPrivate: %#lx, Offset: %#lx, Buffer: %#lx, Size: %#lx)", KernelPrivate, Buffer, Size);
|
debug("(KernelPrivate: %#lx, Offset: %#lx, Buffer: %#lx, Size: %#lx)",
|
||||||
return vfs->Read(*(VirtualFileSystem::File *)KernelPrivate, Buffer, (size_t)Size);
|
KernelPrivate, Buffer, Size);
|
||||||
UNUSED(Frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint64_t sys_file_write(SyscallsFrame *Frame, void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
|
|
||||||
{
|
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
if (KernelPrivate == nullptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
debug("(KernelPrivate: %#lx, Offset: %#lx, Buffer: %#lx, Size: %#lx)", KernelPrivate, Buffer, Size);
|
|
||||||
return vfs->Write(*(VirtualFileSystem::File *)KernelPrivate, Buffer, (size_t)Size);
|
|
||||||
UNUSED(Frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static off_t sys_file_seek(SyscallsFrame *Frame, void *KernelPrivate, off_t Offset, int Whence)
|
|
||||||
{
|
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
if (KernelPrivate == nullptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
debug("(KernelPrivate: %#lx, Offset: %#lx, Whence: %d)", KernelPrivate, Offset, Whence);
|
|
||||||
VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate;
|
VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate;
|
||||||
|
return vfs->Read(*KPObj, Buffer, (size_t)Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t sys_file_write(SysFrm *, void *KernelPrivate,
|
||||||
|
uint8_t *Buffer, uint64_t Size)
|
||||||
|
{
|
||||||
|
if (KernelPrivate == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
debug("(KernelPrivate: %#lx, Offset: %#lx, Buffer: %#lx, Size: %#lx)",
|
||||||
|
KernelPrivate, Buffer, Size);
|
||||||
|
|
||||||
|
VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate;
|
||||||
|
return vfs->Write(*KPObj, Buffer, (size_t)Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static off_t sys_file_seek(SysFrm *, void *KernelPrivate,
|
||||||
|
off_t Offset, int Whence)
|
||||||
|
{
|
||||||
|
if (KernelPrivate == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
debug("(KernelPrivate: %#lx, Offset: %#lx, Whence: %d)",
|
||||||
|
KernelPrivate, Offset, Whence);
|
||||||
|
|
||||||
|
VirtualFileSystem::File *KPObj = (VirtualFileSystem::File *)KernelPrivate;
|
||||||
off_t ret = vfs->Seek(*KPObj, (off_t)Offset, (uint8_t)Whence);
|
off_t ret = vfs->Seek(*KPObj, (off_t)Offset, (uint8_t)Whence);
|
||||||
debug("Seek %s %ld", KPObj->Name, ret);
|
debug("Seek %s %ld", KPObj->Name, ret);
|
||||||
return ret;
|
return ret;
|
||||||
UNUSED(Frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_file_status(SyscallsFrame *Frame)
|
static int sys_file_status(SysFrm *)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
stub;
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
fixme("sys_file_status: %#lx", Frame);
|
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_ipc(SyscallsFrame *Frame, enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size)
|
static int sys_ipc(SysFrm *, enum IPCCommand Command,
|
||||||
|
enum IPCType Type, int ID, int Flags,
|
||||||
|
void *Buffer, size_t Size)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
InterProcessCommunication::IPC *ipc = TaskManager->GetCurrentProcess()->IPC;
|
||||||
return SYSCALL_ACCESS_DENIED;
|
return ipc->HandleSyscall(Command, Type, ID, Flags, Buffer, Size);
|
||||||
|
|
||||||
UNUSED(Frame);
|
|
||||||
return TaskManager->GetCurrentProcess()->IPC->HandleSyscall(Command, Type, ID, Flags, Buffer, Size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_sleep(SyscallsFrame *Frame, uint64_t Milliseconds)
|
static int sys_sleep(SysFrm *, uint64_t Milliseconds)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
TaskManager->Sleep(Milliseconds, true);
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
UNUSED(Frame);
|
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
TaskManager->Sleep(Milliseconds);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_fork(SyscallsFrame *Frame)
|
static int sys_fork(SysFrm *Frame)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
Tasking::PCB *Parent = TaskManager->GetCurrentThread()->Parent;
|
Tasking::PCB *Parent = TaskManager->GetCurrentThread()->Parent;
|
||||||
Tasking::TCB *Thread = TaskManager->GetCurrentThread();
|
Tasking::TCB *Thread = TaskManager->GetCurrentThread();
|
||||||
|
|
||||||
Tasking::PCB *NewProcess = TaskManager->CreateProcess(Parent,
|
void *ProcSymTable = nullptr;
|
||||||
Parent->Name,
|
if (Parent->ELFSymbolTable)
|
||||||
Parent->Security.TrustLevel,
|
ProcSymTable = Parent->ELFSymbolTable->GetImage();
|
||||||
Parent->ELFSymbolTable ? Parent->ELFSymbolTable->GetImage() : nullptr);
|
|
||||||
|
Tasking::PCB *NewProcess =
|
||||||
|
TaskManager->CreateProcess(Parent,
|
||||||
|
Parent->Name,
|
||||||
|
Parent->Security.TrustLevel,
|
||||||
|
ProcSymTable);
|
||||||
|
|
||||||
if (!NewProcess)
|
if (!NewProcess)
|
||||||
{
|
{
|
||||||
@ -419,14 +369,15 @@ static int sys_fork(SyscallsFrame *Frame)
|
|||||||
strncpy(NewProcess->Name, Parent->Name, sizeof(NewProcess->Name));
|
strncpy(NewProcess->Name, Parent->Name, sizeof(NewProcess->Name));
|
||||||
NewProcess->IPC->Fork(Parent->IPC);
|
NewProcess->IPC->Fork(Parent->IPC);
|
||||||
|
|
||||||
Tasking::TCB *NewThread = TaskManager->CreateThread(NewProcess,
|
Tasking::TCB *NewThread =
|
||||||
0,
|
TaskManager->CreateThread(NewProcess,
|
||||||
nullptr,
|
0,
|
||||||
nullptr,
|
nullptr,
|
||||||
std::vector<AuxiliaryVector>(),
|
nullptr,
|
||||||
Thread->Info.Architecture,
|
std::vector<AuxiliaryVector>(),
|
||||||
Thread->Info.Compatibility,
|
Thread->Info.Architecture,
|
||||||
true);
|
Thread->Info.Compatibility,
|
||||||
|
true);
|
||||||
|
|
||||||
strncpy(NewThread->Name, Thread->Name, sizeof(Thread->Name));
|
strncpy(NewThread->Name, Thread->Name, sizeof(Thread->Name));
|
||||||
|
|
||||||
@ -444,7 +395,9 @@ static int sys_fork(SyscallsFrame *Frame)
|
|||||||
|
|
||||||
if (RetChild--)
|
if (RetChild--)
|
||||||
{
|
{
|
||||||
/* We can't just return 0; because the CPUData->SystemCallStack is no longer valid */
|
/* We can't just return 0; because the
|
||||||
|
CPUData->SystemCallStack is no
|
||||||
|
longer valid */
|
||||||
asmv("movq %0, %%rcx\n"
|
asmv("movq %0, %%rcx\n"
|
||||||
:
|
:
|
||||||
: "r"(ReturnAddress));
|
: "r"(ReturnAddress));
|
||||||
@ -454,10 +407,10 @@ static int sys_fork(SyscallsFrame *Frame)
|
|||||||
asmv("mov %0, %%rbp\n"
|
asmv("mov %0, %%rbp\n"
|
||||||
:
|
:
|
||||||
: "r"(ChildStackPointer));
|
: "r"(ChildStackPointer));
|
||||||
asmv("movq $0, %rax\n"); // Return 0 to the child
|
asmv("movq $0, %rax\n"); /* Return 0 to the child */
|
||||||
asmv("swapgs\n"); // Swap GS back to the user GS
|
asmv("swapgs\n"); /* Swap GS back to the user GS */
|
||||||
asmv("sti\n"); // Enable interrupts
|
asmv("sti\n"); /* Enable interrupts */
|
||||||
asmv("sysretq\n"); // Return to rcx address in user mode
|
asmv("sysretq\n"); /* Return to rcx address in user mode */
|
||||||
}
|
}
|
||||||
RetChild = 1;
|
RetChild = 1;
|
||||||
ReturnAddress = Frame->ReturnAddress;
|
ReturnAddress = Frame->ReturnAddress;
|
||||||
@ -470,10 +423,12 @@ static int sys_fork(SyscallsFrame *Frame)
|
|||||||
|
|
||||||
if (Thread->Security.IsCritical)
|
if (Thread->Security.IsCritical)
|
||||||
NewThread->SetCritical(true);
|
NewThread->SetCritical(true);
|
||||||
TaskManager->GetSecurityManager()->TrustToken(NewProcess->Security.UniqueToken,
|
|
||||||
(Tasking::TTL)TaskManager->GetSecurityManager()->GetTokenTrustLevel(Parent->Security.UniqueToken));
|
Tasking::Security *Sec = TaskManager->GetSecurityManager();
|
||||||
TaskManager->GetSecurityManager()->TrustToken(NewThread->Security.UniqueToken,
|
Sec->TrustToken(NewProcess->Security.UniqueToken,
|
||||||
(Tasking::TTL)TaskManager->GetSecurityManager()->GetTokenTrustLevel(Thread->Security.UniqueToken));
|
(TTL)Sec->GetTokenTrustLevel(Parent->Security.UniqueToken));
|
||||||
|
Sec->TrustToken(NewThread->Security.UniqueToken,
|
||||||
|
(TTL)Sec->GetTokenTrustLevel(Thread->Security.UniqueToken));
|
||||||
|
|
||||||
#ifdef a86
|
#ifdef a86
|
||||||
NewThread->ShadowGSBase = Thread->ShadowGSBase;
|
NewThread->ShadowGSBase = Thread->ShadowGSBase;
|
||||||
@ -482,180 +437,358 @@ static int sys_fork(SyscallsFrame *Frame)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
debug("Forked thread \"%s\"(%d) to \"%s\"(%d)", Thread->Name, Thread->ID, NewThread->Name, NewThread->ID);
|
debug("Forked thread \"%s\"(%d) to \"%s\"(%d)", Thread->Name, Thread->ID, NewThread->Name, NewThread->ID);
|
||||||
NewThread->Status = Tasking::TaskStatus::Ready;
|
NewThread->Status = Ready;
|
||||||
return (int)NewThread->ID;
|
return (int)NewThread->ID;
|
||||||
UNUSED(Frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_wait(SyscallsFrame *Frame)
|
static int sys_wait(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_wait: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_kill(SyscallsFrame *Frame)
|
static int sys_kill(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_kill: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_spawn(SyscallsFrame *Frame)
|
static int sys_spawn(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_spawn: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_spawn_thread(SyscallsFrame *Frame, uint64_t InstructionPointer)
|
static int sys_spawn_thread(SysFrm *, uint64_t InstructionPointer)
|
||||||
{
|
{
|
||||||
Tasking::TCB *thread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)InstructionPointer);
|
Tasking::TCB *thread =
|
||||||
|
TaskManager->CreateThread(TaskManager->GetCurrentProcess(),
|
||||||
|
(Tasking::IP)InstructionPointer);
|
||||||
if (thread)
|
if (thread)
|
||||||
return (int)thread->ID;
|
return (int)thread->ID;
|
||||||
return SYSCALL_ERROR;
|
return SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_get_thread_list_of_process(SyscallsFrame *Frame)
|
static int sys_get_thread_list_of_process(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_get_thread_list_of_process: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_get_current_process(SyscallsFrame *Frame)
|
static int sys_get_current_process(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_get_current_process: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_get_current_thread(SyscallsFrame *Frame)
|
static int sys_get_current_thread(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_get_current_thread: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_get_current_process_id(SyscallsFrame *Frame)
|
static int sys_get_current_process_id(SysFrm *)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
return (int)TaskManager->GetCurrentProcess()->ID;
|
return (int)TaskManager->GetCurrentProcess()->ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_get_current_thread_id(SyscallsFrame *Frame)
|
static int sys_get_current_thread_id(SysFrm *)
|
||||||
{
|
{
|
||||||
if (!CheckTrust(TrustedByKernel | Trusted | Untrusted))
|
|
||||||
return SYSCALL_ACCESS_DENIED;
|
|
||||||
|
|
||||||
return (int)TaskManager->GetCurrentThread()->ID;
|
return (int)TaskManager->GetCurrentThread()->ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_get_process_by_pid(SyscallsFrame *Frame)
|
static int sys_get_process_by_pid(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_get_process_by_pid: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_get_thread_by_tid(SyscallsFrame *Frame)
|
static int sys_get_thread_by_tid(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_get_thread_by_tid: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_kill_process(SyscallsFrame *Frame)
|
static int sys_kill_process(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_kill_process: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_kill_thread(SyscallsFrame *Frame)
|
static int sys_kill_thread(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_kill_thread: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_sys_reserved_create_process(SyscallsFrame *Frame)
|
static int sys_sys_reserved_create_process(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_sys_reserved_create_process: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sys_sys_reserved_create_thread(SyscallsFrame *Frame)
|
static int sys_sys_reserved_create_thread(SysFrm *)
|
||||||
{
|
{
|
||||||
fixme("sys_sys_reserved_create_thread: %#lx", Frame);
|
stub;
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *NativeSyscallsTable[_MaxSyscall] = {
|
struct SyscallData
|
||||||
[_Exit] = (void *)sys_exit,
|
{
|
||||||
[_Print] = (void *)sys_print,
|
const char *Name;
|
||||||
|
void *Handler;
|
||||||
[_RequestPages] = (void *)sys_request_pages,
|
int TrustLevel;
|
||||||
[_FreePages] = (void *)sys_free_pages,
|
|
||||||
[_DetachAddress] = (void *)sys_detach_address,
|
|
||||||
[_MemoryMap] = (void *)sys_memory_map,
|
|
||||||
[_MemoryUnmap] = (void *)sys_memory_unmap,
|
|
||||||
|
|
||||||
[_KernelCTL] = (void *)sys_kernelctl,
|
|
||||||
|
|
||||||
[_FileOpen] = (void *)sys_file_open,
|
|
||||||
[_FileClose] = (void *)sys_file_close,
|
|
||||||
[_FileRead] = (void *)sys_file_read,
|
|
||||||
[_FileWrite] = (void *)sys_file_write,
|
|
||||||
[_FileSeek] = (void *)sys_file_seek,
|
|
||||||
[_FileStatus] = (void *)sys_file_status,
|
|
||||||
|
|
||||||
[_IPC] = (void *)sys_ipc,
|
|
||||||
[_Sleep] = (void *)sys_sleep,
|
|
||||||
[_Fork] = (void *)sys_fork,
|
|
||||||
[_Wait] = (void *)sys_wait,
|
|
||||||
[_Kill] = (void *)sys_kill,
|
|
||||||
[_Spawn] = (void *)sys_spawn,
|
|
||||||
[_SpawnThread] = (void *)sys_spawn_thread,
|
|
||||||
[_GetThreadListOfProcess] = (void *)sys_get_thread_list_of_process,
|
|
||||||
[_GetCurrentProcess] = (void *)sys_get_current_process,
|
|
||||||
[_GetCurrentThread] = (void *)sys_get_current_thread,
|
|
||||||
[_GetCurrentProcessID] = (void *)sys_get_current_process_id,
|
|
||||||
[_GetCurrentThreadID] = (void *)sys_get_current_thread_id,
|
|
||||||
[_GetProcessByPID] = (void *)sys_get_process_by_pid,
|
|
||||||
[_GetThreadByTID] = (void *)sys_get_thread_by_tid,
|
|
||||||
[_KillProcess] = (void *)sys_kill_process,
|
|
||||||
[_KillThread] = (void *)sys_kill_thread,
|
|
||||||
[_SysReservedCreateProcess] = (void *)sys_sys_reserved_create_process,
|
|
||||||
[_SysReservedCreateThread] = (void *)sys_sys_reserved_create_thread,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uintptr_t HandleNativeSyscalls(SyscallsFrame *Frame)
|
static SyscallData NativeSyscallsTable[_MaxSyscall] = {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Basic syscalls
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
[_Exit] = {
|
||||||
|
"Exit",
|
||||||
|
(void *)sys_exit,
|
||||||
|
TrustedByKernel | Trusted | Untrusted | UnknownTrustLevel,
|
||||||
|
},
|
||||||
|
[_Print] = {
|
||||||
|
"Print",
|
||||||
|
(void *)sys_print,
|
||||||
|
TrustedByKernel | Trusted,
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Memory syscalls
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
[_RequestPages] = {
|
||||||
|
"RequestPages",
|
||||||
|
(void *)sys_request_pages,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_FreePages] = {
|
||||||
|
"FreePages",
|
||||||
|
(void *)sys_free_pages,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_DetachAddress] = {
|
||||||
|
"DetachAddress",
|
||||||
|
(void *)sys_detach_address,
|
||||||
|
TrustedByKernel | Trusted,
|
||||||
|
},
|
||||||
|
[_MemoryMap] = {
|
||||||
|
"MemoryMap",
|
||||||
|
(void *)sys_memory_map,
|
||||||
|
TrustedByKernel,
|
||||||
|
},
|
||||||
|
[_MemoryUnmap] = {
|
||||||
|
"MemoryUnmap",
|
||||||
|
(void *)sys_memory_unmap,
|
||||||
|
TrustedByKernel,
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Kernel Control syscalls
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
[_KernelCTL] = {
|
||||||
|
"KernelCTL",
|
||||||
|
(void *)sys_kernelctl,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* File syscalls
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
[_FileOpen] = {
|
||||||
|
"FileOpen",
|
||||||
|
(void *)sys_file_open,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_FileClose] = {
|
||||||
|
"FileClose",
|
||||||
|
(void *)sys_file_close,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_FileRead] = {
|
||||||
|
"FileRead",
|
||||||
|
(void *)sys_file_read,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_FileWrite] = {
|
||||||
|
"FileWrite",
|
||||||
|
(void *)sys_file_write,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_FileSeek] = {
|
||||||
|
"FileSeek",
|
||||||
|
(void *)sys_file_seek,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_FileStatus] = {
|
||||||
|
"FileStatus",
|
||||||
|
(void *)sys_file_status,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Process syscalls
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
[_IPC] = {
|
||||||
|
"IPC",
|
||||||
|
(void *)sys_ipc,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_Sleep] = {
|
||||||
|
"Sleep",
|
||||||
|
(void *)sys_sleep,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_Fork] = {
|
||||||
|
"Fork",
|
||||||
|
(void *)sys_fork,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_Wait] = {
|
||||||
|
"Wait",
|
||||||
|
(void *)sys_wait,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_Kill] = {
|
||||||
|
"Kill",
|
||||||
|
(void *)sys_kill,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_Spawn] = {
|
||||||
|
"Spawn",
|
||||||
|
(void *)sys_spawn,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_SpawnThread] = {
|
||||||
|
"SpawnThread",
|
||||||
|
(void *)sys_spawn_thread,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_GetThreadListOfProcess] = {
|
||||||
|
"GetThreadListOfProcess",
|
||||||
|
(void *)sys_get_thread_list_of_process,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_GetCurrentProcess] = {
|
||||||
|
"GetCurrentProcess",
|
||||||
|
(void *)sys_get_current_process,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_GetCurrentThread] = {
|
||||||
|
"GetCurrentThread",
|
||||||
|
(void *)sys_get_current_thread,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_GetCurrentProcessID] = {
|
||||||
|
"GetCurrentProcessID",
|
||||||
|
(void *)sys_get_current_process_id,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_GetCurrentThreadID] = {
|
||||||
|
"GetCurrentThreadID",
|
||||||
|
(void *)sys_get_current_thread_id,
|
||||||
|
TrustedByKernel | Trusted | Untrusted,
|
||||||
|
},
|
||||||
|
[_GetProcessByPID] = {
|
||||||
|
"GetProcessByPID",
|
||||||
|
(void *)sys_get_process_by_pid,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_GetThreadByTID] = {
|
||||||
|
"GetThreadByTID",
|
||||||
|
(void *)sys_get_thread_by_tid,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_KillProcess] = {
|
||||||
|
"KillProcess",
|
||||||
|
(void *)sys_kill_process,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_KillThread] = {
|
||||||
|
"KillThread",
|
||||||
|
(void *)sys_kill_thread,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_SysReservedCreateProcess] = {
|
||||||
|
"SysReservedCreateProcess",
|
||||||
|
(void *)sys_sys_reserved_create_process,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
[_SysReservedCreateThread] = {
|
||||||
|
"SysReservedCreateThread",
|
||||||
|
(void *)sys_sys_reserved_create_thread,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
uintptr_t HandleNativeSyscalls(SysFrm *Frame)
|
||||||
{
|
{
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
if (Frame->rax > sizeof(NativeSyscallsTable))
|
if (unlikely(Frame->rax > _MaxSyscall))
|
||||||
{
|
{
|
||||||
fixme("Syscall %ld not implemented", Frame->rax);
|
fixme("Syscall %ld not implemented.", Frame->rax);
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t (*call)(uintptr_t, ...) = reinterpret_cast<uintptr_t (*)(uintptr_t, ...)>(NativeSyscallsTable[Frame->rax]);
|
SyscallData Syscall = NativeSyscallsTable[Frame->rax];
|
||||||
if (!call)
|
|
||||||
|
uintptr_t (*call)(SysFrm *, uintptr_t, ...) =
|
||||||
|
r_cst(uintptr_t(*)(SysFrm *, uintptr_t, ...),
|
||||||
|
Syscall.Handler);
|
||||||
|
|
||||||
|
if (unlikely(!call))
|
||||||
{
|
{
|
||||||
error("Syscall %#lx failed.", Frame->rax);
|
error("Syscall %#lx not implemented.", Frame->rax);
|
||||||
return SYSCALL_INTERNAL_ERROR;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("[%#lx]->( %#lx %#lx %#lx %#lx %#lx %#lx )",
|
Token token = TaskManager->GetCurrentThread()->Security.UniqueToken;
|
||||||
Frame->rax,
|
Tasking::Security *Sec = TaskManager->GetSecurityManager();
|
||||||
Frame->rdi, Frame->rsi, Frame->rdx, Frame->rcx, Frame->r8, Frame->r9);
|
if (unlikely(!Sec->IsTokenTrusted(token, Syscall.TrustLevel)))
|
||||||
|
{
|
||||||
|
warn("Thread %s(%d) tried to access a system call \"%s\" with insufficient trust level",
|
||||||
|
TaskManager->GetCurrentThread()->Name,
|
||||||
|
TaskManager->GetCurrentThread()->ID,
|
||||||
|
Syscall.Name);
|
||||||
|
|
||||||
uintptr_t ret = call((uintptr_t)Frame, Frame->rdi, Frame->rsi, Frame->rdx, Frame->r10, Frame->r8, Frame->r9);
|
#ifdef DEBUG
|
||||||
Frame->rax = ret;
|
int TknTl = Sec->GetTokenTrustLevel(token);
|
||||||
return ret;
|
debug("token=%#lx, trust=%d%d%d%d",token,
|
||||||
|
TknTl & TrustedByKernel ? 1 : 0,
|
||||||
|
TknTl & Trusted ? 1 : 0,
|
||||||
|
TknTl & Untrusted ? 1 : 0,
|
||||||
|
TknTl & UnknownTrustLevel ? 1 : 0);
|
||||||
|
#endif
|
||||||
|
return SYSCALL_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("[%d:\"%s\"]->( %#lx %#lx %#lx %#lx %#lx %#lx )",
|
||||||
|
Frame->rax, Syscall.Name,
|
||||||
|
Frame->rdi, Frame->rsi, Frame->rdx,
|
||||||
|
Frame->r10, Frame->r8, Frame->r9);
|
||||||
|
|
||||||
|
return call(Frame,
|
||||||
|
Frame->rdi, Frame->rsi, Frame->rdx,
|
||||||
|
Frame->r10, Frame->r8, Frame->r9);
|
||||||
#elif defined(a32)
|
#elif defined(a32)
|
||||||
if (Frame->eax > sizeof(NativeSyscallsTable))
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
{
|
|
||||||
fixme("Syscall %ld not implemented", Frame->eax);
|
|
||||||
return SYSCALL_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ... */
|
|
||||||
|
|
||||||
return SYSCALL_INTERNAL_ERROR;
|
|
||||||
#elif defined(aa64)
|
#elif defined(aa64)
|
||||||
return SYSCALL_INTERNAL_ERROR;
|
return SYSCALL_NOT_IMPLEMENTED;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,8 @@
|
|||||||
|
|
||||||
#include "../kernel.h"
|
#include "../kernel.h"
|
||||||
|
|
||||||
NewLock(SyscallsLock);
|
|
||||||
|
|
||||||
extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
|
extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
|
||||||
{
|
{
|
||||||
SmartLock(SyscallsLock); /* TODO: This should be replaced or moved somewhere else. */
|
|
||||||
|
|
||||||
Tasking::TaskInfo *Ptinfo = &TaskManager->GetCurrentProcess()->Info;
|
Tasking::TaskInfo *Ptinfo = &TaskManager->GetCurrentProcess()->Info;
|
||||||
Tasking::TaskInfo *Ttinfo = &TaskManager->GetCurrentThread()->Info;
|
Tasking::TaskInfo *Ttinfo = &TaskManager->GetCurrentThread()->Info;
|
||||||
uint64_t TempTimeCalc = TimeManager->GetCounter();
|
uint64_t TempTimeCalc = TimeManager->GetCounter();
|
||||||
|
@ -248,17 +248,24 @@ namespace Tasking
|
|||||||
CPU::Pause();
|
CPU::Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Task::Sleep(uint64_t Milliseconds)
|
void Task::Sleep(uint64_t Milliseconds, bool NoSwitch)
|
||||||
{
|
{
|
||||||
SmartLock(TaskingLock);
|
|
||||||
TCB *thread = this->GetCurrentThread();
|
TCB *thread = this->GetCurrentThread();
|
||||||
|
PCB *process = this->GetCurrentProcess();
|
||||||
|
|
||||||
thread->Status = TaskStatus::Sleeping;
|
thread->Status = TaskStatus::Sleeping;
|
||||||
if (thread->Parent->Threads.size() == 1)
|
if (process->Threads.size() == 1)
|
||||||
thread->Parent->Status = TaskStatus::Sleeping;
|
process->Status = TaskStatus::Sleeping;
|
||||||
thread->Info.SleepUntil = TimeManager->CalculateTarget(Milliseconds, Time::Units::Milliseconds);
|
|
||||||
tskdbg("Thread \"%s\"(%d) is going to sleep until %llu", thread->Name, thread->ID, thread->Info.SleepUntil);
|
thread->Info.SleepUntil =
|
||||||
TaskingLock.Unlock();
|
TimeManager->CalculateTarget(Milliseconds,
|
||||||
this->Schedule();
|
Time::Units::Milliseconds);
|
||||||
|
|
||||||
|
debug("Thread \"%s\"(%d) is going to sleep until %llu",
|
||||||
|
thread->Name, thread->ID, thread->Info.SleepUntil);
|
||||||
|
|
||||||
|
if (!NoSwitch)
|
||||||
|
this->Schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Task::SignalShutdown()
|
void Task::SignalShutdown()
|
||||||
@ -410,6 +417,8 @@ namespace Tasking
|
|||||||
{
|
{
|
||||||
Thread->Security.IsCritical = true;
|
Thread->Security.IsCritical = true;
|
||||||
Thread->Stack = new Memory::StackGuard(false, Parent->PageTable);
|
Thread->Stack = new Memory::StackGuard(false, Parent->PageTable);
|
||||||
|
Thread->SyscallStack = __UINTPTR_MAX__;
|
||||||
|
Thread->TempStack = __UINTPTR_MAX__;
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
SecurityManager.TrustToken(Thread->Security.UniqueToken, TTL::TrustedByKernel);
|
SecurityManager.TrustToken(Thread->Security.UniqueToken, TTL::TrustedByKernel);
|
||||||
Thread->ShadowGSBase = CPU::x64::rdmsr(CPU::x64::MSRID::MSR_SHADOW_GS_BASE);
|
Thread->ShadowGSBase = CPU::x64::rdmsr(CPU::x64::MSRID::MSR_SHADOW_GS_BASE);
|
||||||
@ -430,9 +439,11 @@ namespace Tasking
|
|||||||
case TaskTrustLevel::User:
|
case TaskTrustLevel::User:
|
||||||
{
|
{
|
||||||
Thread->Stack = new Memory::StackGuard(true, Parent->PageTable);
|
Thread->Stack = new Memory::StackGuard(true, Parent->PageTable);
|
||||||
|
Thread->SyscallStack = (uintptr_t)Thread->Memory->RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE;
|
||||||
|
Thread->TempStack = 0x0;
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
SecurityManager.TrustToken(Thread->Security.UniqueToken, TTL::Untrusted);
|
SecurityManager.TrustToken(Thread->Security.UniqueToken, TTL::Untrusted);
|
||||||
Thread->ShadowGSBase = (uint64_t)GetCurrentCPU();
|
Thread->ShadowGSBase = (uintptr_t)Thread;
|
||||||
Thread->GSBase = 0;
|
Thread->GSBase = 0;
|
||||||
Thread->FSBase = 0;
|
Thread->FSBase = 0;
|
||||||
Thread->Registers.cs = GDT_USER_CODE;
|
Thread->Registers.cs = GDT_USER_CODE;
|
||||||
@ -742,7 +753,6 @@ namespace Tasking
|
|||||||
|
|
||||||
Task::Task(const IP EntryPoint) : Interrupts::Handler(16) /* IRQ16 */
|
Task::Task(const IP EntryPoint) : Interrupts::Handler(16) /* IRQ16 */
|
||||||
{
|
{
|
||||||
SmartLock(TaskingLock);
|
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
// Map the IRQ16 to the first CPU.
|
// Map the IRQ16 to the first CPU.
|
||||||
((APIC::APIC *)Interrupts::apic[0])->RedirectIRQ(0, CPU::x86::IRQ16 - CPU::x86::IRQ0, 1);
|
((APIC::APIC *)Interrupts::apic[0])->RedirectIRQ(0, CPU::x86::IRQ16 - CPU::x86::IRQ0, 1);
|
||||||
@ -750,7 +760,6 @@ namespace Tasking
|
|||||||
#elif defined(aa64)
|
#elif defined(aa64)
|
||||||
#endif
|
#endif
|
||||||
KPrint("Starting Tasking With Instruction Pointer: %p (\e666666%s\eCCCCCC)", EntryPoint, KernelSymbolTable->GetSymbolFromAddress(EntryPoint));
|
KPrint("Starting Tasking With Instruction Pointer: %p (\e666666%s\eCCCCCC)", EntryPoint, KernelSymbolTable->GetSymbolFromAddress(EntryPoint));
|
||||||
TaskingLock.Unlock();
|
|
||||||
|
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
TaskArchitecture Arch = TaskArchitecture::x64;
|
TaskArchitecture Arch = TaskArchitecture::x64;
|
||||||
@ -765,7 +774,6 @@ namespace Tasking
|
|||||||
TCB *kthrd = CreateThread(kproc, EntryPoint, nullptr, nullptr, std::vector<AuxiliaryVector>(), Arch);
|
TCB *kthrd = CreateThread(kproc, EntryPoint, nullptr, nullptr, std::vector<AuxiliaryVector>(), Arch);
|
||||||
kthrd->Rename("Main Thread");
|
kthrd->Rename("Main Thread");
|
||||||
debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name);
|
debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name);
|
||||||
TaskingLock.Lock(__FUNCTION__);
|
|
||||||
|
|
||||||
bool MONITORSupported = false;
|
bool MONITORSupported = false;
|
||||||
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
|
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
|
||||||
@ -792,7 +800,6 @@ namespace Tasking
|
|||||||
CPU::Interrupts(CPU::Enable);
|
CPU::Interrupts(CPU::Enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskingLock.Unlock();
|
|
||||||
IdleProcess = CreateProcess(nullptr, (char *)"Idle", TaskTrustLevel::Kernel);
|
IdleProcess = CreateProcess(nullptr, (char *)"Idle", TaskTrustLevel::Kernel);
|
||||||
IdleProcess->ELFSymbolTable = KernelSymbolTable;
|
IdleProcess->ELFSymbolTable = KernelSymbolTable;
|
||||||
for (int i = 0; i < SMP::CPUCores; i++)
|
for (int i = 0; i < SMP::CPUCores; i++)
|
||||||
|
@ -1076,6 +1076,7 @@ namespace Memory
|
|||||||
~MemMgr();
|
~MemMgr();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
NewLock(MgrLock);
|
||||||
Bitmap PageBitmap;
|
Bitmap PageBitmap;
|
||||||
PageTable *Table;
|
PageTable *Table;
|
||||||
VirtualFileSystem::Node *Directory;
|
VirtualFileSystem::Node *Directory;
|
||||||
|
@ -41,14 +41,8 @@ struct CPUArchData
|
|||||||
|
|
||||||
struct CPUData
|
struct CPUData
|
||||||
{
|
{
|
||||||
/** @brief Used by syscall handler */
|
|
||||||
uint8_t *SystemCallStack; /* gs+0x0 */
|
|
||||||
|
|
||||||
/** @brief Used by syscall handler */
|
|
||||||
uintptr_t TempStack; /* gs+0x8 */
|
|
||||||
|
|
||||||
/** @brief Used by CPU */
|
/** @brief Used by CPU */
|
||||||
uintptr_t Stack; /* gs+0x10 */
|
uintptr_t Stack;
|
||||||
|
|
||||||
/** @brief CPU ID. */
|
/** @brief CPU ID. */
|
||||||
int ID;
|
int ID;
|
||||||
|
@ -122,6 +122,12 @@ namespace Tasking
|
|||||||
|
|
||||||
struct TCB
|
struct TCB
|
||||||
{
|
{
|
||||||
|
/** @brief Used by syscall handler */
|
||||||
|
uintptr_t SyscallStack; /* gs+0x0 */
|
||||||
|
|
||||||
|
/** @brief Used by syscall handler */
|
||||||
|
uintptr_t TempStack; /* gs+0x8 */
|
||||||
|
|
||||||
TID ID;
|
TID ID;
|
||||||
char Name[256];
|
char Name[256];
|
||||||
struct PCB *Parent;
|
struct PCB *Parent;
|
||||||
@ -132,12 +138,12 @@ namespace Tasking
|
|||||||
TaskStatus Status;
|
TaskStatus Status;
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
CPU::x64::TrapFrame Registers;
|
CPU::x64::TrapFrame Registers;
|
||||||
uint64_t ShadowGSBase, GSBase, FSBase;
|
uintptr_t ShadowGSBase, GSBase, FSBase;
|
||||||
#elif defined(a32)
|
#elif defined(a32)
|
||||||
CPU::x32::TrapFrame Registers; // TODO
|
CPU::x32::TrapFrame Registers; // TODO
|
||||||
uint64_t ShadowGSBase, GSBase, FSBase;
|
uintptr_t ShadowGSBase, GSBase, FSBase;
|
||||||
#elif defined(aa64)
|
#elif defined(aa64)
|
||||||
uint64_t Registers; // TODO
|
uintptr_t Registers; // TODO
|
||||||
#endif
|
#endif
|
||||||
uintptr_t IPHistory[128];
|
uintptr_t IPHistory[128];
|
||||||
TaskSecurity Security;
|
TaskSecurity Security;
|
||||||
@ -244,7 +250,8 @@ namespace Tasking
|
|||||||
Untrusted = 0b0010,
|
Untrusted = 0b0010,
|
||||||
Trusted = 0b0100,
|
Trusted = 0b0100,
|
||||||
TrustedByKernel = 0b1000,
|
TrustedByKernel = 0b1000,
|
||||||
FullTrust = Trusted | TrustedByKernel
|
FullTrust = Trusted | TrustedByKernel,
|
||||||
|
AllFlags = 0b1111
|
||||||
};
|
};
|
||||||
|
|
||||||
class Security
|
class Security
|
||||||
@ -379,7 +386,7 @@ namespace Tasking
|
|||||||
*
|
*
|
||||||
* @param Milliseconds Amount of milliseconds to sleep
|
* @param Milliseconds Amount of milliseconds to sleep
|
||||||
*/
|
*/
|
||||||
void Sleep(uint64_t Milliseconds);
|
void Sleep(uint64_t Milliseconds, bool NoSwitch = false);
|
||||||
|
|
||||||
PCB *CreateProcess(PCB *Parent,
|
PCB *CreateProcess(PCB *Parent,
|
||||||
const char *Name,
|
const char *Name,
|
||||||
|
@ -76,12 +76,12 @@ namespace std
|
|||||||
#ifdef DEBUG_MEM_ALLOCATION
|
#ifdef DEBUG_MEM_ALLOCATION
|
||||||
debug("VECTOR INIT: vector( <vector> )->Size: %lld", VectorSize);
|
debug("VECTOR INIT: vector( <vector> )->Size: %lld", VectorSize);
|
||||||
#endif
|
#endif
|
||||||
if (VectorSize > 0)
|
if (!v.VectorBuffer || VectorSize <= 0)
|
||||||
{
|
return;
|
||||||
VectorBuffer = new T[VectorSize];
|
|
||||||
for (size_t i = 0; i < VectorSize; i++)
|
VectorBuffer = new T[VectorSize];
|
||||||
VectorBuffer[i] = v.VectorBuffer[i];
|
for (size_t i = 0; i < VectorSize; i++)
|
||||||
}
|
VectorBuffer[i] = v.VectorBuffer[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
NIF ~vector()
|
NIF ~vector()
|
||||||
|
614
syscalls.h
614
syscalls.h
@ -8,15 +8,15 @@
|
|||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice, this
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
list of conditions and the following disclaimer.
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
this list of conditions and the following disclaimer in the documentation
|
this list of conditions and the following disclaimer in the documentation
|
||||||
and/or other materials provided with the distribution.
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
3. Neither the name of the copyright holder nor the names of its
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
contributors may be used to endorse or promote products derived from
|
contributors may be used to endorse or promote products derived from
|
||||||
this software without specific prior written permission.
|
this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
@ -49,47 +49,47 @@
|
|||||||
|
|
||||||
enum MemoryMapFlags
|
enum MemoryMapFlags
|
||||||
{
|
{
|
||||||
MAP_PRESENT = 1 << 0,
|
MAP_PRESENT = 1 << 0,
|
||||||
MAP_WRITABLE = 1 << 1,
|
MAP_WRITABLE = 1 << 1,
|
||||||
MAP_USER = 1 << 2,
|
MAP_USER = 1 << 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum KCtl
|
enum KCtl
|
||||||
{
|
{
|
||||||
KCTL_NULL,
|
KCTL_NULL,
|
||||||
|
|
||||||
KCTL_GET_PID,
|
KCTL_GET_PID,
|
||||||
KCTL_GET_TID,
|
KCTL_GET_TID,
|
||||||
KCTL_GET_UID,
|
KCTL_GET_UID,
|
||||||
KCTL_GET_GID,
|
KCTL_GET_GID,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the page size
|
* @brief Get the page size
|
||||||
*/
|
*/
|
||||||
KCTL_GET_PAGE_SIZE,
|
KCTL_GET_PAGE_SIZE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check whether the current thread is critical
|
* @brief Check whether the current thread is critical
|
||||||
*/
|
*/
|
||||||
KCTL_IS_CRITICAL,
|
KCTL_IS_CRITICAL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Register an ELF library
|
* @brief Register an ELF library
|
||||||
* @fn int RegisterELFLib(char *Identifier, char *Path)
|
* @fn int RegisterELFLib(char *Identifier, char *Path)
|
||||||
*/
|
*/
|
||||||
KCTL_REGISTER_ELF_LIB,
|
KCTL_REGISTER_ELF_LIB,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get an ELF library
|
* @brief Get an ELF library
|
||||||
* @fn uintptr_t GetELFLib(char *Identifier);
|
* @fn uintptr_t GetELFLib(char *Identifier);
|
||||||
*/
|
*/
|
||||||
KCTL_GET_ELF_LIB_MEMORY_IMAGE,
|
KCTL_GET_ELF_LIB_MEMORY_IMAGE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the absolute path of a library file
|
* @brief Get the absolute path of a library file
|
||||||
* @fn int GetAbsolutePath(char *Identifier, char *Buffer, size_t BufferSize)
|
* @fn int GetAbsolutePath(char *Identifier, char *Buffer, size_t BufferSize)
|
||||||
*/
|
*/
|
||||||
KCTL_GET_ABSOLUTE_PATH,
|
KCTL_GET_ABSOLUTE_PATH,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,230 +98,230 @@ enum KCtl
|
|||||||
*/
|
*/
|
||||||
enum NativeSyscalls
|
enum NativeSyscalls
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Basic syscalls
|
* Basic syscalls
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @brief Exit the process.
|
/** @brief Exit the process.
|
||||||
* @fn int Exit(int Code)
|
* @fn int Exit(int Code)
|
||||||
* This syscall is used to exit the current process with the provided exit code.
|
* This syscall is used to exit the current process with the provided exit code.
|
||||||
*/
|
*/
|
||||||
_Exit = 0,
|
_Exit = 0,
|
||||||
|
|
||||||
/** @brief Print a message to the kernel console
|
/** @brief Print a message to the kernel console
|
||||||
* @fn int Print(char Char, int Index)
|
* @fn int Print(char Char, int Index)
|
||||||
* This syscall is used to print a message to the kernel console.
|
* This syscall is used to print a message to the kernel console.
|
||||||
*/
|
*/
|
||||||
_Print,
|
_Print,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Memory syscalls
|
* Memory syscalls
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @brief Request pages of memory
|
/** @brief Request pages of memory
|
||||||
* @fn uintptr_t RequestPages(size_t Count)
|
* @fn uintptr_t RequestPages(size_t Count)
|
||||||
* This syscall is used to request a specific number of pages of memory from the kernel.
|
* This syscall is used to request a specific number of pages of memory from the kernel.
|
||||||
*/
|
*/
|
||||||
_RequestPages,
|
_RequestPages,
|
||||||
|
|
||||||
/** @brief Free pages of memory
|
/** @brief Free pages of memory
|
||||||
* @fn int FreePages(uintptr_t Address, size_t Count)
|
* @fn int FreePages(uintptr_t Address, size_t Count)
|
||||||
* This syscall is used to free a specific number of pages of memory that were previously requested.
|
* This syscall is used to free a specific number of pages of memory that were previously requested.
|
||||||
*/
|
*/
|
||||||
_FreePages,
|
_FreePages,
|
||||||
|
|
||||||
/** @brief Detach memory address
|
/** @brief Detach memory address
|
||||||
* @fn int DetachAddress(uintptr_t Address)
|
* @fn int DetachAddress(uintptr_t Address)
|
||||||
* This syscall is used to detach a specific memory address from the current process.
|
* This syscall is used to detach a specific memory address from the current process.
|
||||||
*/
|
*/
|
||||||
_DetachAddress,
|
_DetachAddress,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Map memory address
|
* @brief Map memory address
|
||||||
* @fn int MapAddress(uintptr_t VirtualAddress, uintptr_t PhysicalAddress, size_t Size, enum MemoryMapFlags Flags)
|
* @fn int MapAddress(uintptr_t VirtualAddress, uintptr_t PhysicalAddress, size_t Size, enum MemoryMapFlags Flags)
|
||||||
* This syscall is used to map a specific memory address to the current process.
|
* This syscall is used to map a specific memory address to the current process.
|
||||||
*
|
*
|
||||||
* @param Size The size of the memory region to map. Not pages.
|
* @param Size The size of the memory region to map. Not pages.
|
||||||
*/
|
*/
|
||||||
_MemoryMap,
|
_MemoryMap,
|
||||||
|
|
||||||
/** @brief Unmap memory address
|
/** @brief Unmap memory address
|
||||||
* @fn int UnmapAddress(uintptr_t VirtualAddress, size_t Size)
|
* @fn int UnmapAddress(uintptr_t VirtualAddress, size_t Size)
|
||||||
* This syscall is used to unmap a specific memory address from the current process.
|
* This syscall is used to unmap a specific memory address from the current process.
|
||||||
*
|
*
|
||||||
* @param Size The size of the memory region to unmap. Not pages.
|
* @param Size The size of the memory region to unmap. Not pages.
|
||||||
*/
|
*/
|
||||||
_MemoryUnmap,
|
_MemoryUnmap,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Kernel Control syscalls
|
* Kernel Control syscalls
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @brief Kernel Control
|
/** @brief Kernel Control
|
||||||
* @fn uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
|
* @fn uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4)
|
||||||
* This syscall is used to control certain aspects of the kernel or get information about it.
|
* This syscall is used to control certain aspects of the kernel or get information about it.
|
||||||
*/
|
*/
|
||||||
_KernelCTL,
|
_KernelCTL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* File syscalls
|
* File syscalls
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @brief Open a file
|
/** @brief Open a file
|
||||||
* @fn void *FileOpen(const char *Path, uint64_t Flags)
|
* @fn void *FileOpen(const char *Path, uint64_t Flags)
|
||||||
* This syscall is used to open a file with the provided path and flags.
|
* This syscall is used to open a file with the provided path and flags.
|
||||||
*/
|
*/
|
||||||
_FileOpen,
|
_FileOpen,
|
||||||
|
|
||||||
/** @brief Close a file
|
/** @brief Close a file
|
||||||
* @fn int FileClose(void *KernelPrivate)
|
* @fn int FileClose(void *KernelPrivate)
|
||||||
* This syscall is used to close a file that was previously opened.
|
* This syscall is used to close a file that was previously opened.
|
||||||
*/
|
*/
|
||||||
_FileClose,
|
_FileClose,
|
||||||
|
|
||||||
/** @brief Read from a file
|
/** @brief Read from a file
|
||||||
* @fn uint64_t FileRead(void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
|
* @fn uint64_t FileRead(void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
|
||||||
* This syscall is used to read a specific number of bytes from a file at a specific offset.
|
* This syscall is used to read a specific number of bytes from a file at a specific offset.
|
||||||
*/
|
*/
|
||||||
_FileRead,
|
_FileRead,
|
||||||
|
|
||||||
/** @brief Write to a file
|
/** @brief Write to a file
|
||||||
* @fn uint64_t FileWrite(void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
|
* @fn uint64_t FileWrite(void *KernelPrivate, uint8_t *Buffer, uint64_t Size)
|
||||||
* This syscall is used to write a specific number of bytes to a file at a specific offset.
|
* This syscall is used to write a specific number of bytes to a file at a specific offset.
|
||||||
*/
|
*/
|
||||||
_FileWrite,
|
_FileWrite,
|
||||||
|
|
||||||
/** @brief Seek in a file
|
/** @brief Seek in a file
|
||||||
* @fn off_t FileSeek(void *KernelPrivate, off_t Offset, int Whence)
|
* @fn off_t FileSeek(void *KernelPrivate, off_t Offset, int Whence)
|
||||||
* This syscall is used to change the current offset in a file.
|
* This syscall is used to change the current offset in a file.
|
||||||
*/
|
*/
|
||||||
_FileSeek,
|
_FileSeek,
|
||||||
|
|
||||||
/** @brief Get file status
|
/** @brief Get file status
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to retrieve information about a file such as its size, permissions, etc.
|
* This syscall is used to retrieve information about a file such as its size, permissions, etc.
|
||||||
*/
|
*/
|
||||||
_FileStatus,
|
_FileStatus,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Process syscalls
|
* Process syscalls
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates/Reads/Writes/Deletes an IPC Pipe/Shared Memory/Message Queue/etc.
|
* @brief Creates/Reads/Writes/Deletes an IPC Pipe/Shared Memory/Message Queue/etc.
|
||||||
* @fn int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size)
|
* @fn int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size)
|
||||||
* This syscall is used to create, read, write or delete an IPC Pipe/Shared Memory/Message Queue/etc.
|
* This syscall is used to create, read, write or delete an IPC Pipe/Shared Memory/Message Queue/etc.
|
||||||
*/
|
*/
|
||||||
_IPC,
|
_IPC,
|
||||||
|
|
||||||
/** @brief Sleep for a specific amount of time
|
/** @brief Sleep for a specific amount of time
|
||||||
* @fn int Sleep(uint64_t Milliseconds)
|
* @fn int Sleep(uint64_t Milliseconds)
|
||||||
* This syscall is used to sleep the current thread for a specific amount of time.
|
* This syscall is used to sleep the current thread for a specific amount of time.
|
||||||
*/
|
*/
|
||||||
_Sleep,
|
_Sleep,
|
||||||
|
|
||||||
/** @brief Fork the current process
|
/** @brief Fork the current process
|
||||||
* @fn int Fork()
|
* @fn int Fork()
|
||||||
* This syscall is used to create a new process that is a copy of the current process.
|
* This syscall is used to create a new process that is a copy of the current process.
|
||||||
*/
|
*/
|
||||||
_Fork,
|
_Fork,
|
||||||
|
|
||||||
/** @brief Wait for a process or a thread
|
/** @brief Wait for a process or a thread
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to wait for a specific process or thread to terminate. It returns the exit code of the process or thread.
|
* This syscall is used to wait for a specific process or thread to terminate. It returns the exit code of the process or thread.
|
||||||
*/
|
*/
|
||||||
_Wait,
|
_Wait,
|
||||||
|
|
||||||
/** @brief Kill a process or a thread
|
/** @brief Kill a process or a thread
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to send a termination signal to a specific process or thread
|
* This syscall is used to send a termination signal to a specific process or thread
|
||||||
*/
|
*/
|
||||||
_Kill,
|
_Kill,
|
||||||
|
|
||||||
/** @brief Spawn a new process
|
/** @brief Spawn a new process
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to create a new process with the provided path and arguments.
|
* This syscall is used to create a new process with the provided path and arguments.
|
||||||
*/
|
*/
|
||||||
_Spawn,
|
_Spawn,
|
||||||
|
|
||||||
/** @brief Spawn a new thread
|
/** @brief Spawn a new thread
|
||||||
* @fn int SpawnThread(uint64_t InstructionPointer)
|
* @fn int SpawnThread(uint64_t InstructionPointer)
|
||||||
* This syscall is used to create a new thread within the current process with the provided function and arguments.
|
* This syscall is used to create a new thread within the current process with the provided function and arguments.
|
||||||
*/
|
*/
|
||||||
_SpawnThread,
|
_SpawnThread,
|
||||||
|
|
||||||
/** @brief Get thread list of a process
|
/** @brief Get thread list of a process
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to retrieve a list of all the threads within a specific process.
|
* This syscall is used to retrieve a list of all the threads within a specific process.
|
||||||
*/
|
*/
|
||||||
_GetThreadListOfProcess,
|
_GetThreadListOfProcess,
|
||||||
|
|
||||||
/** @brief Get current process
|
/** @brief Get current process
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to retrieve information about the current process.
|
* This syscall is used to retrieve information about the current process.
|
||||||
*/
|
*/
|
||||||
_GetCurrentProcess,
|
_GetCurrentProcess,
|
||||||
|
|
||||||
/** @brief Get current thread
|
/** @brief Get current thread
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to retrieve information about the current thread.
|
* This syscall is used to retrieve information about the current thread.
|
||||||
*/
|
*/
|
||||||
_GetCurrentThread,
|
_GetCurrentThread,
|
||||||
|
|
||||||
/** @brief Get current process ID
|
/** @brief Get current process ID
|
||||||
* @fn int GetCurrentProcessID()
|
* @fn int GetCurrentProcessID()
|
||||||
* This syscall is used to retrieve information about the current process.
|
* This syscall is used to retrieve information about the current process.
|
||||||
*/
|
*/
|
||||||
_GetCurrentProcessID,
|
_GetCurrentProcessID,
|
||||||
|
|
||||||
/** @brief Get current thread ID
|
/** @brief Get current thread ID
|
||||||
* @fn int GetCurrentThreadID()
|
* @fn int GetCurrentThreadID()
|
||||||
* This syscall is used to retrieve information about the current thread.
|
* This syscall is used to retrieve information about the current thread.
|
||||||
*/
|
*/
|
||||||
_GetCurrentThreadID,
|
_GetCurrentThreadID,
|
||||||
|
|
||||||
/** @brief Get process by PID
|
/** @brief Get process by PID
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to retrieve information about a specific process by its PID.
|
* This syscall is used to retrieve information about a specific process by its PID.
|
||||||
*/
|
*/
|
||||||
_GetProcessByPID,
|
_GetProcessByPID,
|
||||||
|
|
||||||
/** @brief Get thread by TID
|
/** @brief Get thread by TID
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to retrieve information about a specific thread by its TID.
|
* This syscall is used to retrieve information about a specific thread by its TID.
|
||||||
*/
|
*/
|
||||||
_GetThreadByTID,
|
_GetThreadByTID,
|
||||||
|
|
||||||
/** @brief Kill a process
|
/** @brief Kill a process
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to send a termination signal to a specific process.
|
* This syscall is used to send a termination signal to a specific process.
|
||||||
*/
|
*/
|
||||||
_KillProcess,
|
_KillProcess,
|
||||||
|
|
||||||
/** @brief Kill a thread
|
/** @brief Kill a thread
|
||||||
* @fn
|
* @fn
|
||||||
* This syscall is used to send a termination signal to a specific thread.
|
* This syscall is used to send a termination signal to a specific thread.
|
||||||
*/
|
*/
|
||||||
_KillThread,
|
_KillThread,
|
||||||
|
|
||||||
/** @brief Reserved syscall */
|
/** @brief Reserved syscall */
|
||||||
_SysReservedCreateProcess,
|
_SysReservedCreateProcess,
|
||||||
|
|
||||||
/** @brief Reserved syscall */
|
/** @brief Reserved syscall */
|
||||||
_SysReservedCreateThread,
|
_SysReservedCreateThread,
|
||||||
|
|
||||||
/** @brief Not a real syscall */
|
/** @brief Not a real syscall */
|
||||||
_MaxSyscall
|
_MaxSyscall
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -330,122 +330,122 @@ enum NativeSyscalls
|
|||||||
*/
|
*/
|
||||||
enum SyscallsErrorCodes
|
enum SyscallsErrorCodes
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @brief Access denied
|
* @brief Access denied
|
||||||
* This error code is returned when the current thread does not have the required permissions to perform the requested operation.
|
* This error code is returned when the current thread does not have the required permissions to perform the requested operation.
|
||||||
*/
|
*/
|
||||||
SYSCALL_ACCESS_DENIED = -0xDEADACC,
|
SYSCALL_ACCESS_DENIED = -0xDEADACC,
|
||||||
/**
|
/**
|
||||||
* @brief Invalid argument
|
* @brief Invalid argument
|
||||||
* This error code is returned when an invalid argument is passed to a syscall.
|
* This error code is returned when an invalid argument is passed to a syscall.
|
||||||
*/
|
*/
|
||||||
SYSCALL_INVALID_ARGUMENT = -0xBADAEE,
|
SYSCALL_INVALID_ARGUMENT = -0xBADAEE,
|
||||||
/**
|
/**
|
||||||
* @brief Invalid syscall
|
* @brief Invalid syscall
|
||||||
* This error code is returned when an invalid syscall number is passed to the syscall handler.
|
* This error code is returned when an invalid syscall number is passed to the syscall handler.
|
||||||
*/
|
*/
|
||||||
SYSCALL_INVALID_SYSCALL = -0xBAD55CA,
|
SYSCALL_INVALID_SYSCALL = -0xBAD55CA,
|
||||||
/**
|
/**
|
||||||
* @brief Internal error
|
* @brief Internal error
|
||||||
* This error code is returned when an internal error occurs in the syscall handler.
|
* This error code is returned when an internal error occurs in the syscall handler.
|
||||||
*/
|
*/
|
||||||
SYSCALL_INTERNAL_ERROR = -0xBADBAD5,
|
SYSCALL_INTERNAL_ERROR = -0xBADBAD5,
|
||||||
/**
|
/**
|
||||||
* @brief Not implemented
|
* @brief Not implemented
|
||||||
* This error code is returned when a syscall is not implemented.
|
* This error code is returned when a syscall is not implemented.
|
||||||
*/
|
*/
|
||||||
SYSCALL_NOT_IMPLEMENTED = -0xBAD5EED,
|
SYSCALL_NOT_IMPLEMENTED = -0xBAD5EED,
|
||||||
/**
|
/**
|
||||||
* @brief Generic error
|
* @brief Generic error
|
||||||
* This error code is returned when a syscall fails for an unknown reason.
|
* This error code is returned when a syscall fails for an unknown reason.
|
||||||
*/
|
*/
|
||||||
SYSCALL_ERROR = -1,
|
SYSCALL_ERROR = -1,
|
||||||
/**
|
/**
|
||||||
* @brief Success
|
* @brief Success
|
||||||
* This error code is returned when a syscall succeeds.
|
* This error code is returned when a syscall succeeds.
|
||||||
*/
|
*/
|
||||||
SYSCALL_OK = 0,
|
SYSCALL_OK = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool IsSyscallError(long ret)
|
static inline bool IsSyscallError(long ret)
|
||||||
{
|
{
|
||||||
return ret < 0;
|
return ret < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long syscall0(long syscall)
|
static inline long syscall0(long syscall)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
: "=a"(ret)
|
: "=a"(ret)
|
||||||
: "a"(syscall)
|
: "a"(syscall)
|
||||||
: "rcx", "r11", "memory");
|
: "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long syscall1(long syscall, long arg1)
|
static inline long syscall1(long syscall, long arg1)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
: "=a"(ret)
|
: "=a"(ret)
|
||||||
: "a"(syscall), "D"(arg1)
|
: "a"(syscall), "D"(arg1)
|
||||||
: "rcx", "r11", "memory");
|
: "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long syscall2(long syscall, long arg1, long arg2)
|
static inline long syscall2(long syscall, long arg1, long arg2)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
: "=a"(ret)
|
: "=a"(ret)
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2)
|
: "a"(syscall), "D"(arg1), "S"(arg2)
|
||||||
: "rcx", "r11", "memory");
|
: "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long syscall3(long syscall, long arg1, long arg2, long arg3)
|
static inline long syscall3(long syscall, long arg1, long arg2, long arg3)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
: "=a"(ret)
|
: "=a"(ret)
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
|
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3)
|
||||||
: "rcx", "r11", "memory");
|
: "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long syscall4(long syscall, long arg1, long arg2, long arg3, long arg4)
|
static inline long syscall4(long syscall, long arg1, long arg2, long arg3, long arg4)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
register long r10 __asm__("r10") = arg4;
|
register long r10 __asm__("r10") = arg4;
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
: "=a"(ret)
|
: "=a"(ret)
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
|
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10)
|
||||||
: "rcx", "r11", "memory");
|
: "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long syscall5(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5)
|
static inline long syscall5(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
register long r10 __asm__("r10") = arg4;
|
register long r10 __asm__("r10") = arg4;
|
||||||
register long r8 __asm__("r8") = arg5;
|
register long r8 __asm__("r8") = arg5;
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
: "=a"(ret)
|
: "=a"(ret)
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
|
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8)
|
||||||
: "rcx", "r11", "memory");
|
: "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline long syscall6(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
|
static inline long syscall6(long syscall, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
register long r10 __asm__("r10") = arg4;
|
register long r10 __asm__("r10") = arg4;
|
||||||
register long r8 __asm__("r8") = arg5;
|
register long r8 __asm__("r8") = arg5;
|
||||||
register long r9 __asm__("r9") = arg6;
|
register long r9 __asm__("r9") = arg6;
|
||||||
__asm__ __volatile__("syscall"
|
__asm__ __volatile__("syscall"
|
||||||
: "=a"(ret)
|
: "=a"(ret)
|
||||||
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
|
: "a"(syscall), "D"(arg1), "S"(arg2), "d"(arg3), "r"(r10), "r"(r8), "r"(r9)
|
||||||
: "rcx", "r11", "memory");
|
: "rcx", "r11", "memory");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !__FENNIX_KERNEL_SYSCALLS_LIST_H__
|
#endif // !__FENNIX_KERNEL_SYSCALLS_LIST_H__
|
||||||
|
Loading…
x
Reference in New Issue
Block a user