From a99a2ef34b6feb5e678d663d154cde9837708e67 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 10 Feb 2023 16:31:33 +0200 Subject: [PATCH] Added stub interpreter support --- Execute/Elf/BaseLoad.cpp | 58 +++++++++++++++++++++++++++++++++++++++- Execute/Elf/Exec.cpp | 19 +++++++------ include/exec.hpp | 5 ++++ 3 files changed, 71 insertions(+), 11 deletions(-) diff --git a/Execute/Elf/BaseLoad.cpp b/Execute/Elf/BaseLoad.cpp index 9de940c..0575390 100644 --- a/Execute/Elf/BaseLoad.cpp +++ b/Execute/Elf/BaseLoad.cpp @@ -17,6 +17,51 @@ using VirtualFileSystem::NodeFlags; namespace Execute { + /* Passing arguments as a sanity check and debugging. */ + void ELFInterpreterIPCThread(PCB *Process, char *Path, void *MemoryImage, Vector NeededLibraries) + { + debug("Interpreter thread started for %s", Path); + // Interpreter will create an IPC with token "LOAD". + char UniqueToken[16] = {'L', 'O', 'A', 'D', '\0'}; + InterProcessCommunication::IPCHandle *Handle = nullptr; + while (Handle == nullptr) + { + debug("Searching for IPC with token %s", UniqueToken); + Handle = Process->IPC->SearchByToken(UniqueToken); + if (Handle == nullptr) + debug("Failed"); + TaskManager->Sleep(100); + if (Handle == nullptr) + debug("Retrying..."); + } + debug("IPC found, sending data..."); + RetryIPCWrite: + uintptr_t *TmpBuffer = new uintptr_t[0x1000]; + *(int *)TmpBuffer = 2545; + InterProcessCommunication::IPCErrorCode ret = Process->IPC->Write(Handle->ID, TmpBuffer, 0x1000); + delete[] TmpBuffer; + debug("Write returned %d", ret); + if (ret == InterProcessCommunication::IPCErrorCode::IPCNotListening) + { + debug("IPC not listening, retrying..."); + TaskManager->Sleep(100); + goto RetryIPCWrite; + } + while (1) + ; + } + + PCB *InterpreterTargetProcess; + String *InterpreterTargetPath; /* We can't have String as a constructor :( */ + void *InterpreterMemoryImage; + Vector InterpreterNeededLibraries; + void ELFInterpreterThreadWrapper() + { + ELFInterpreterIPCThread(InterpreterTargetProcess, (char *)InterpreterTargetPath->c_str(), InterpreterMemoryImage, InterpreterNeededLibraries); + delete InterpreterTargetPath; + return; + } + ELFBaseLoad ELFLoad(char *Path, const char **argv, const char **envp, Tasking::TaskCompatibility Compatibility) { /* We get the base name ("app.elf") */ @@ -108,7 +153,6 @@ namespace Execute // for (size_t i = 0; i < TO_PAGES(ElfLazyResolverSize); i++) // pV.Remap((void *)((uintptr_t)ElfLazyResolver + (i * PAGE_SIZE)), (void *)((uintptr_t)ElfLazyResolver + (i * PAGE_SIZE)), Memory::PTFlag::RW | Memory::PTFlag::US); - /* We prepare the ELF for execution (allocate memory, etc...) */ ELFBaseLoad bl; switch (ELFHeader->e_type) @@ -139,6 +183,18 @@ namespace Execute } } + if (bl.Interpreter) + { + InterpreterTargetProcess = Process; + InterpreterTargetPath = new String(Path); /* We store in a String because Path may get changed while outside ELFLoad(). */ + InterpreterMemoryImage = bl.MemoryImage; + InterpreterNeededLibraries = bl.NeededLibraries; + __sync_synchronize(); + TCB *InterpreterIPCThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (IP)ELFInterpreterThreadWrapper); + InterpreterIPCThread->Rename("ELF Interpreter IPC Thread"); + InterpreterIPCThread->SetPriority(TaskPriority::Low); + } + TCB *Thread = TaskManager->CreateThread(Process, bl.InstructionPointer, argv, envp, bl.auxv, diff --git a/Execute/Elf/Exec.cpp b/Execute/Elf/Exec.cpp index 373b56b..53ddf67 100644 --- a/Execute/Elf/Exec.cpp +++ b/Execute/Elf/Exec.cpp @@ -81,8 +81,6 @@ namespace Execute } } - Vector NeededLibraries; - if (!DynamicString) DynamicString = StringTable; @@ -137,10 +135,9 @@ namespace Execute break; } - char *ReqLib = (char *)kmalloc(256); - strcpy(ReqLib, (char *)((uintptr_t)ElfFile + DynamicString->sh_offset + Dynamic[i].d_un.d_ptr)); - debug("DT_NEEDED - Name[%ld]: %s", i, ReqLib); - NeededLibraries.push_back(ReqLib); + String ReqLib = (char *)((uintptr_t)ElfFile + DynamicString->sh_offset + Dynamic[i].d_un.d_val); + debug("DT_NEEDED - Name[%ld]: %s", i, ReqLib.c_str()); + ELFBase.NeededLibraries.push_back(ReqLib); } else if (Dynamic[i].d_tag == DT_NULL) break; @@ -179,7 +176,11 @@ namespace Execute } } - EntryPoint = LoadELFInterpreter(ELFBase.TmpMem, pV, InterpreterPath); + if (strlen(InterpreterPath) > 1) + { + EntryPoint = LoadELFInterpreter(ELFBase.TmpMem, pV, InterpreterPath); + ELFBase.Interpreter = true; + } debug("Entry Point: %#lx", EntryPoint); @@ -197,9 +198,7 @@ namespace Execute ELFBase.auxv.push_back({.archaux = {.a_type = AT_PHDR, .a_un = {.a_val = (uint64_t)ELFHeader->e_phoff}}}); ELFBase.InstructionPointer = EntryPoint; - - foreach (auto var in NeededLibraries) - kfree(var); + ELFBase.MemoryImage = MemoryImage; ELFBase.Success = true; return ELFBase; diff --git a/include/exec.hpp b/include/exec.hpp index 50a8322..3b7338a 100644 --- a/include/exec.hpp +++ b/include/exec.hpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -55,9 +56,13 @@ namespace Execute struct ELFBaseLoad { bool Success; + bool Interpreter; SpawnData sd; Tasking::IP InstructionPointer; + Vector NeededLibraries; + void *MemoryImage; + /* This should be deleted after copying the allocated pages to the thread Intended to be used only inside BaseLoad.cpp */ Memory::MemMgr *TmpMem;