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()
{
mem = new Memory::MemMgr;
// return;
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);
debug("Reset timeout for %s", Lib.Identifier);
continue;
if (Lib.RefCount > 0)
{
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())
{
// 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...");
}
debug("Waiting 10 seconds...");
ExecuteServiceLock.Unlock();
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);
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);
sl.Timeout = TimeManager->CalculateTarget(600000); /* 10 minutes */
sl.RefCount = 0;
void *LibFile = mem->RequestPages(TO_PAGES(Length), true);
debug("LibFile: %#lx", LibFile);
memcpy(LibFile, (void *)ElfImage, Length);
Memory::Virtual().Map(LibFile, LibFile, TO_PAGES(Length), Memory::RW | Memory::US | Memory::G);
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;
@ -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;
debug("Library %s loaded at %#lx (full file: %#lx)", Identifier, sl.MemoryImage, LibFile);
Libs.push_back(sl);
return &Libs[Libs.size() - 1];
return true;
}
void SearchLibrary(char *Identifier)
{
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 <memory.hpp>
#include <lock.hpp>
#include <exec.hpp>
#include <debug.h>
@ -53,9 +54,12 @@ static int sys_print(SyscallsFrame *Frame, char Char, int Index)
return SYSCALL_ACCESS_DENIED;
char ret = Display->Print(Char, Index, true);
#ifdef DEBUG
if (!Config.BootAnimation && Index == 0)
#ifdef DEBUG
Display->SetBuffer(Index);
#else
if (Char == '\n')
Display->SetBuffer(Index);
#endif
UNUSED(Frame);
return ret;
@ -106,6 +110,84 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
return PAGE_SIZE;
case KCTL_IS_CRITICAL:
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:
{
warn("KernelCTL: Unknown command: %lld", Command);

View File

@ -44,12 +44,12 @@ namespace Execute
struct SharedLibraries
{
char Identifier[256];
char Identifier[64];
uint64_t Timeout;
long RefCount;
int RefCount;
void *Address;
void *MemoryImage;
uintptr_t Address;
uintptr_t MemoryImage;
size_t Length;
};
@ -120,11 +120,12 @@ namespace Execute
Tasking::PCB *Process);
void StartExecuteService();
SharedLibraries *AddLibrary(char *Identifier,
void *ElfImage,
size_t Length,
const Memory::Virtual &pV = Memory::Virtual());
bool AddLibrary(char *Identifier,
void *ElfImage,
size_t Length,
const Memory::Virtual &pV = Memory::Virtual());
void SearchLibrary(char *Identifier);
SharedLibraries GetLibrary(char *Identifier);
}
#endif // !__FENNIX_KERNEL_FILE_EXECUTE_H__

View File

@ -210,6 +210,11 @@ enum SyscallsErrorCodes
SYSCALL_OK = 0,
};
static inline bool IsSyscallError(long ret)
{
return ret < 0;
}
static inline long syscall0(long syscall)
{
unsigned long ret;