mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 07:24:37 +00:00
Added stub interpreter support
This commit is contained in:
parent
5bbef13d6a
commit
a99a2ef34b
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user