mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 07:24:37 +00:00
Implementation for userspace interpreter
This commit is contained in:
parent
8747a54fea
commit
f69f29c5bb
@ -26,47 +26,60 @@ namespace Execute
|
|||||||
void StartExecuteService()
|
void StartExecuteService()
|
||||||
{
|
{
|
||||||
mem = new Memory::MemMgr;
|
mem = new Memory::MemMgr;
|
||||||
// return;
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
ExecuteServiceLock.Lock(__FUNCTION__);
|
|
||||||
foreach (auto &Lib in Libs)
|
|
||||||
{
|
{
|
||||||
if (Lib.RefCount > 0)
|
SmartLock(ExecuteServiceLock);
|
||||||
|
foreach (auto &Lib in Libs)
|
||||||
{
|
{
|
||||||
Lib.Timeout = TimeManager->CalculateTarget(600000);
|
if (Lib.RefCount > 0)
|
||||||
debug("Reset timeout for %s", Lib.Identifier);
|
{
|
||||||
continue;
|
Lib.Timeout = TimeManager->CalculateTarget(600000);
|
||||||
|
debug("Reset timeout for %s", Lib.Identifier);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Lib.Timeout < TimeManager->GetCounter())
|
||||||
|
{
|
||||||
|
// TODO: Remove
|
||||||
|
fixme("Removed library %s because of timeout", Lib.Identifier);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
debug("Timeout for %s is %ld", Lib.Identifier, Lib.Timeout);
|
||||||
}
|
}
|
||||||
if (Lib.Timeout < TimeManager->GetCounter())
|
debug("Waiting 10 seconds...");
|
||||||
{
|
|
||||||
// TODO: Remove
|
|
||||||
fixme("Removed library %s because of timeout", Lib.Identifier);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
debug("Timeout for %s is %ld", Lib.Identifier, Lib.Timeout);
|
|
||||||
}
|
}
|
||||||
debug("Waiting 10 seconds...");
|
|
||||||
ExecuteServiceLock.Unlock();
|
|
||||||
TaskManager->Sleep(10000);
|
TaskManager->Sleep(10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedLibraries *AddLibrary(char *Identifier, void *ElfImage, size_t Length, const Memory::Virtual &pV)
|
bool AddLibrary(char *Identifier, void *ElfImage, size_t Length, const Memory::Virtual &pV)
|
||||||
{
|
{
|
||||||
SmartLock(ExecuteServiceLock);
|
SmartLock(ExecuteServiceLock);
|
||||||
SharedLibraries sl;
|
SharedLibraries sl;
|
||||||
|
|
||||||
|
foreach (auto lib in Libs)
|
||||||
|
{
|
||||||
|
if (strcmp(lib.Identifier, Identifier) == 0)
|
||||||
|
{
|
||||||
|
debug("Library %s already loaded", Identifier);
|
||||||
|
lib.RefCount++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
strcpy(sl.Identifier, Identifier);
|
strcpy(sl.Identifier, Identifier);
|
||||||
sl.Timeout = TimeManager->CalculateTarget(600000); /* 10 minutes */
|
sl.Timeout = TimeManager->CalculateTarget(600000); /* 10 minutes */
|
||||||
sl.RefCount = 0;
|
sl.RefCount = 0;
|
||||||
|
|
||||||
void *LibFile = mem->RequestPages(TO_PAGES(Length), true);
|
void *LibFile = mem->RequestPages(TO_PAGES(Length), true);
|
||||||
|
debug("LibFile: %#lx", LibFile);
|
||||||
memcpy(LibFile, (void *)ElfImage, Length);
|
memcpy(LibFile, (void *)ElfImage, Length);
|
||||||
|
Memory::Virtual().Map(LibFile, LibFile, TO_PAGES(Length), Memory::RW | Memory::US | Memory::G);
|
||||||
|
|
||||||
Memory::Virtual ncpV = pV;
|
Memory::Virtual ncpV = pV;
|
||||||
sl.MemoryImage = ELFCreateMemoryImage(mem, ncpV, LibFile, Length).Phyiscal;
|
sl.MemoryImage = r_cst(uint64_t, ELFCreateMemoryImage(mem, ncpV, LibFile, Length).Phyiscal);
|
||||||
|
debug("MemoryImage: %#lx", sl.MemoryImage);
|
||||||
|
|
||||||
{
|
{
|
||||||
uintptr_t BaseAddress = UINTPTR_MAX;
|
uintptr_t BaseAddress = UINTPTR_MAX;
|
||||||
@ -99,17 +112,34 @@ namespace Execute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sl.Address = LibFile;
|
sl.Address = r_cst(uint64_t, LibFile);
|
||||||
|
debug("Casted LibFile %#lx -> %#lx", LibFile, sl.Address);
|
||||||
sl.Length = Length;
|
sl.Length = Length;
|
||||||
|
|
||||||
debug("Library %s loaded at %#lx (full file: %#lx)", Identifier, sl.MemoryImage, LibFile);
|
debug("Library %s loaded at %#lx (full file: %#lx)", Identifier, sl.MemoryImage, LibFile);
|
||||||
|
|
||||||
Libs.push_back(sl);
|
Libs.push_back(sl);
|
||||||
return &Libs[Libs.size() - 1];
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchLibrary(char *Identifier)
|
void SearchLibrary(char *Identifier)
|
||||||
{
|
{
|
||||||
SmartLock(ExecuteServiceLock);
|
SmartLock(ExecuteServiceLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SharedLibraries GetLibrary(char *Identifier)
|
||||||
|
{
|
||||||
|
SmartLock(ExecuteServiceLock);
|
||||||
|
foreach (auto Lib in Libs)
|
||||||
|
{
|
||||||
|
if (strcmp(Lib.Identifier, Identifier) == 0)
|
||||||
|
{
|
||||||
|
Lib.RefCount++;
|
||||||
|
debug("Library %s found (%#lx %#lx)", Identifier, Lib.Address, Lib.MemoryImage);
|
||||||
|
return Lib;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// throw std::runtime_error("Library not found");
|
||||||
|
return SharedLibraries();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <syscalls.hpp>
|
#include <syscalls.hpp>
|
||||||
#include <memory.hpp>
|
#include <memory.hpp>
|
||||||
#include <lock.hpp>
|
#include <lock.hpp>
|
||||||
|
#include <exec.hpp>
|
||||||
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
@ -53,9 +54,12 @@ static int sys_print(SyscallsFrame *Frame, char Char, int Index)
|
|||||||
return SYSCALL_ACCESS_DENIED;
|
return SYSCALL_ACCESS_DENIED;
|
||||||
|
|
||||||
char ret = Display->Print(Char, Index, true);
|
char ret = Display->Print(Char, Index, true);
|
||||||
#ifdef DEBUG
|
|
||||||
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
|
#endif
|
||||||
UNUSED(Frame);
|
UNUSED(Frame);
|
||||||
return ret;
|
return ret;
|
||||||
@ -106,6 +110,84 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
|
|||||||
return PAGE_SIZE;
|
return PAGE_SIZE;
|
||||||
case KCTL_IS_CRITICAL:
|
case KCTL_IS_CRITICAL:
|
||||||
return TaskManager->GetCurrentThread()->Security.IsCritical;
|
return TaskManager->GetCurrentThread()->Security.IsCritical;
|
||||||
|
case KCTL_REGISTER_ELF_LIB:
|
||||||
|
{
|
||||||
|
char *Identifier = (char *)Arg1;
|
||||||
|
const char *Path = (const char *)Arg2;
|
||||||
|
|
||||||
|
if (!Identifier || !Path)
|
||||||
|
return SYSCALL_INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
std::string FullPath = Path;
|
||||||
|
int retries = 0;
|
||||||
|
RetryReadPath:
|
||||||
|
debug("KCTL_REGISTER_ELF_LIB: Trying to open %s", FullPath.c_str());
|
||||||
|
std::shared_ptr<VirtualFileSystem::File> f = vfs->Open(FullPath.c_str());
|
||||||
|
|
||||||
|
if (f->Status != VirtualFileSystem::FileStatus::OK)
|
||||||
|
{
|
||||||
|
FullPath.clear();
|
||||||
|
switch (retries)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
FullPath = "/system/lib/";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
FullPath = "/system/lib64/";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
FullPath = "/system/";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
// TODO: Check process binary path
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
vfs->Close(f);
|
||||||
|
return SYSCALL_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FullPath += Path;
|
||||||
|
vfs->Close(f);
|
||||||
|
retries++;
|
||||||
|
goto RetryReadPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
vfs->Close(f);
|
||||||
|
if (Execute::AddLibrary(Identifier, (void *)f->node->Address, f->node->Length))
|
||||||
|
return SYSCALL_OK;
|
||||||
|
else
|
||||||
|
return SYSCALL_INTERNAL_ERROR;
|
||||||
|
}
|
||||||
|
case KCTL_GET_ELF_LIB_FILE:
|
||||||
|
{
|
||||||
|
char *Identifier = (char *)Arg1;
|
||||||
|
if (!Identifier)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Execute::SharedLibraries lib = Execute::GetLibrary(Identifier);
|
||||||
|
if (!lib.Address)
|
||||||
|
debug("Failed to get library address %#lx", (uintptr_t)lib.Address);
|
||||||
|
|
||||||
|
debug("Returning library address %#lx", (uintptr_t)lib.Address);
|
||||||
|
return (uintptr_t)lib.Address;
|
||||||
|
}
|
||||||
|
case KCTL_GET_ELF_LIB_MEMORY_IMAGE:
|
||||||
|
{
|
||||||
|
char *Identifier = (char *)Arg1;
|
||||||
|
if (!Identifier)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Execute::SharedLibraries lib = Execute::GetLibrary(Identifier);
|
||||||
|
|
||||||
|
if (!lib.MemoryImage)
|
||||||
|
debug("Failed to get library memory image %#lx", (uintptr_t)lib.MemoryImage);
|
||||||
|
|
||||||
|
debug("Returning memory image %#lx", (uintptr_t)lib.MemoryImage);
|
||||||
|
return (uintptr_t)lib.MemoryImage;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
warn("KernelCTL: Unknown command: %lld", Command);
|
warn("KernelCTL: Unknown command: %lld", Command);
|
||||||
|
@ -44,12 +44,12 @@ namespace Execute
|
|||||||
|
|
||||||
struct SharedLibraries
|
struct SharedLibraries
|
||||||
{
|
{
|
||||||
char Identifier[256];
|
char Identifier[64];
|
||||||
uint64_t Timeout;
|
uint64_t Timeout;
|
||||||
long RefCount;
|
int RefCount;
|
||||||
|
|
||||||
void *Address;
|
uintptr_t Address;
|
||||||
void *MemoryImage;
|
uintptr_t MemoryImage;
|
||||||
size_t Length;
|
size_t Length;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,11 +120,12 @@ namespace Execute
|
|||||||
Tasking::PCB *Process);
|
Tasking::PCB *Process);
|
||||||
|
|
||||||
void StartExecuteService();
|
void StartExecuteService();
|
||||||
SharedLibraries *AddLibrary(char *Identifier,
|
bool AddLibrary(char *Identifier,
|
||||||
void *ElfImage,
|
void *ElfImage,
|
||||||
size_t Length,
|
size_t Length,
|
||||||
const Memory::Virtual &pV = Memory::Virtual());
|
const Memory::Virtual &pV = Memory::Virtual());
|
||||||
void SearchLibrary(char *Identifier);
|
void SearchLibrary(char *Identifier);
|
||||||
|
SharedLibraries GetLibrary(char *Identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !__FENNIX_KERNEL_FILE_EXECUTE_H__
|
#endif // !__FENNIX_KERNEL_FILE_EXECUTE_H__
|
||||||
|
@ -210,6 +210,11 @@ enum SyscallsErrorCodes
|
|||||||
SYSCALL_OK = 0,
|
SYSCALL_OK = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline bool IsSyscallError(long ret)
|
||||||
|
{
|
||||||
|
return ret < 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline long syscall0(long syscall)
|
static inline long syscall0(long syscall)
|
||||||
{
|
{
|
||||||
unsigned long ret;
|
unsigned long ret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user