From f69f29c5bb719f85b569ce7c5d08b9f984eb4ac2 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 31 Mar 2023 17:36:34 +0300 Subject: [PATCH] Implementation for userspace interpreter --- Execute/Elf/SharedObjects.cpp | 70 ++++++++++++++++++++--------- SystemCalls/Native.cpp | 84 ++++++++++++++++++++++++++++++++++- include/exec.hpp | 17 +++---- syscalls.h | 5 +++ 4 files changed, 147 insertions(+), 29 deletions(-) diff --git a/Execute/Elf/SharedObjects.cpp b/Execute/Elf/SharedObjects.cpp index 930ffe1..dd965c5 100644 --- a/Execute/Elf/SharedObjects.cpp +++ b/Execute/Elf/SharedObjects.cpp @@ -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(); + } } diff --git a/SystemCalls/Native.cpp b/SystemCalls/Native.cpp index 4051dbb..9266544 100644 --- a/SystemCalls/Native.cpp +++ b/SystemCalls/Native.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -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 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); diff --git a/include/exec.hpp b/include/exec.hpp index 6035b22..463a3f4 100644 --- a/include/exec.hpp +++ b/include/exec.hpp @@ -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__ diff --git a/syscalls.h b/syscalls.h index 5719ed7..2af2a1d 100644 --- a/syscalls.h +++ b/syscalls.h @@ -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;