Added stub interpreter support

This commit is contained in:
Alex 2023-02-10 16:31:33 +02:00
parent 5bbef13d6a
commit a99a2ef34b
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
3 changed files with 71 additions and 11 deletions

View File

@ -17,6 +17,51 @@ using VirtualFileSystem::NodeFlags;
namespace Execute namespace Execute
{ {
/* Passing arguments as a sanity check and debugging. */
void ELFInterpreterIPCThread(PCB *Process, char *Path, void *MemoryImage, Vector<String> 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<String> 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) ELFBaseLoad ELFLoad(char *Path, const char **argv, const char **envp, Tasking::TaskCompatibility Compatibility)
{ {
/* We get the base name ("app.elf") */ /* We get the base name ("app.elf") */
@ -108,7 +153,6 @@ namespace Execute
// for (size_t i = 0; i < TO_PAGES(ElfLazyResolverSize); i++) // 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); // 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; ELFBaseLoad bl;
switch (ELFHeader->e_type) 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, TCB *Thread = TaskManager->CreateThread(Process,
bl.InstructionPointer, bl.InstructionPointer,
argv, envp, bl.auxv, argv, envp, bl.auxv,

View File

@ -81,8 +81,6 @@ namespace Execute
} }
} }
Vector<char *> NeededLibraries;
if (!DynamicString) if (!DynamicString)
DynamicString = StringTable; DynamicString = StringTable;
@ -137,10 +135,9 @@ namespace Execute
break; break;
} }
char *ReqLib = (char *)kmalloc(256); String ReqLib = (char *)((uintptr_t)ElfFile + DynamicString->sh_offset + Dynamic[i].d_un.d_val);
strcpy(ReqLib, (char *)((uintptr_t)ElfFile + DynamicString->sh_offset + Dynamic[i].d_un.d_ptr)); debug("DT_NEEDED - Name[%ld]: %s", i, ReqLib.c_str());
debug("DT_NEEDED - Name[%ld]: %s", i, ReqLib); ELFBase.NeededLibraries.push_back(ReqLib);
NeededLibraries.push_back(ReqLib);
} }
else if (Dynamic[i].d_tag == DT_NULL) else if (Dynamic[i].d_tag == DT_NULL)
break; 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); 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.auxv.push_back({.archaux = {.a_type = AT_PHDR, .a_un = {.a_val = (uint64_t)ELFHeader->e_phoff}}});
ELFBase.InstructionPointer = EntryPoint; ELFBase.InstructionPointer = EntryPoint;
ELFBase.MemoryImage = MemoryImage;
foreach (auto var in NeededLibraries)
kfree(var);
ELFBase.Success = true; ELFBase.Success = true;
return ELFBase; return ELFBase;

View File

@ -4,6 +4,7 @@
#include <types.h> #include <types.h>
#include <filesystem.hpp> #include <filesystem.hpp>
#include <string.hpp>
#include <task.hpp> #include <task.hpp>
#include <elf.h> #include <elf.h>
@ -55,9 +56,13 @@ namespace Execute
struct ELFBaseLoad struct ELFBaseLoad
{ {
bool Success; bool Success;
bool Interpreter;
SpawnData sd; SpawnData sd;
Tasking::IP InstructionPointer; Tasking::IP InstructionPointer;
Vector<String> NeededLibraries;
void *MemoryImage;
/* This should be deleted after copying the allocated pages to the thread /* This should be deleted after copying the allocated pages to the thread
Intended to be used only inside BaseLoad.cpp */ Intended to be used only inside BaseLoad.cpp */
Memory::MemMgr *TmpMem; Memory::MemMgr *TmpMem;