Implementation for userspace interpreter

This commit is contained in:
Alex 2023-03-31 17:36:34 +03:00
parent 8747a54fea
commit f69f29c5bb
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
4 changed files with 147 additions and 29 deletions

View File

@ -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();
}
} }

View File

@ -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);

View File

@ -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__

View File

@ -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;