mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-10 23:09:18 +00:00
Refactor filesystem & stl code
This commit is contained in:
@ -18,63 +18,65 @@
|
||||
#include <exec.hpp>
|
||||
|
||||
#include <msexec.h>
|
||||
#include <macho.h>
|
||||
#include <memory>
|
||||
|
||||
#include "../kernel.h"
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
BinaryType GetBinaryType(const char *Path)
|
||||
BinaryType GetBinaryType(FileNode *Node)
|
||||
{
|
||||
debug("Checking binary type of %s(ptr: %#lx)",
|
||||
Path, Path);
|
||||
debug("Checking binary type of %s", Node->Path.c_str());
|
||||
BinaryType Type;
|
||||
vfs::RefNode *fd = fs->Open(Path);
|
||||
|
||||
if (fd == nullptr)
|
||||
{
|
||||
debug("Failed to open file %s", Path);
|
||||
return (BinaryType)-ENOENT;
|
||||
}
|
||||
if (Node == nullptr)
|
||||
ReturnLogError((BinaryType)-ENOENT, "Node is null");
|
||||
|
||||
debug("File opened: %s, descriptor %d", Path, fd);
|
||||
Memory::SmartHeap sh = Memory::SmartHeap(1024);
|
||||
fd->read(sh, 128);
|
||||
Elf32_Ehdr ELFHeader;
|
||||
Node->Read(&ELFHeader, sizeof(Elf32_Ehdr), 0);
|
||||
|
||||
Elf32_Ehdr *ELFHeader = (Elf32_Ehdr *)sh.Get();
|
||||
IMAGE_DOS_HEADER *MZHeader = (IMAGE_DOS_HEADER *)sh.Get();
|
||||
mach_header MachHeader;
|
||||
Node->Read(&MachHeader, sizeof(mach_header), 0);
|
||||
|
||||
IMAGE_DOS_HEADER MZHeader;
|
||||
Node->Read(&MZHeader, sizeof(IMAGE_DOS_HEADER), 0);
|
||||
|
||||
/* Check ELF header. */
|
||||
if (ELFHeader->e_ident[EI_MAG0] == ELFMAG0 &&
|
||||
ELFHeader->e_ident[EI_MAG1] == ELFMAG1 &&
|
||||
ELFHeader->e_ident[EI_MAG2] == ELFMAG2 &&
|
||||
ELFHeader->e_ident[EI_MAG3] == ELFMAG3)
|
||||
if (ELFHeader.e_ident[EI_MAG0] == ELFMAG0 &&
|
||||
ELFHeader.e_ident[EI_MAG1] == ELFMAG1 &&
|
||||
ELFHeader.e_ident[EI_MAG2] == ELFMAG2 &&
|
||||
ELFHeader.e_ident[EI_MAG3] == ELFMAG3)
|
||||
{
|
||||
debug("Image - ELF");
|
||||
Type = BinaryType::BinTypeELF;
|
||||
goto Success;
|
||||
}
|
||||
|
||||
/* Check MZ header. */
|
||||
else if (MZHeader->e_magic == IMAGE_DOS_SIGNATURE)
|
||||
if (MachHeader.magic == MH_MAGIC || MachHeader.magic == MH_CIGAM)
|
||||
{
|
||||
fd->seek(MZHeader->e_lfanew, SEEK_SET);
|
||||
fd->read(sh, 512);
|
||||
IMAGE_NT_HEADERS *PEHeader =
|
||||
(IMAGE_NT_HEADERS *)(((char *)sh.Get()) +
|
||||
MZHeader->e_lfanew);
|
||||
debug("Image - Mach-O");
|
||||
Type = BinaryType::BinTypeMachO;
|
||||
goto Success;
|
||||
}
|
||||
|
||||
IMAGE_OS2_HEADER *NEHeader =
|
||||
(IMAGE_OS2_HEADER *)(((char *)sh.Get()) +
|
||||
MZHeader->e_lfanew);
|
||||
/* Check MZ header. */
|
||||
else if (MZHeader.e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
IMAGE_NT_HEADERS PEHeader;
|
||||
Node->Read(&PEHeader, sizeof(IMAGE_NT_HEADERS), MZHeader.e_lfanew);
|
||||
|
||||
IMAGE_OS2_HEADER NEHeader;
|
||||
Node->Read(&NEHeader, sizeof(IMAGE_OS2_HEADER), MZHeader.e_lfanew);
|
||||
|
||||
/* TODO: LE, EDOS */
|
||||
if (PEHeader->Signature == IMAGE_NT_SIGNATURE)
|
||||
if (PEHeader.Signature == IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
debug("Image - PE");
|
||||
Type = BinaryType::BinTypePE;
|
||||
goto Success;
|
||||
}
|
||||
else if (NEHeader->ne_magic == IMAGE_OS2_SIGNATURE)
|
||||
else if (NEHeader.ne_magic == IMAGE_OS2_SIGNATURE)
|
||||
{
|
||||
debug("Image - NE");
|
||||
Type = BinaryType::BinTypeNE;
|
||||
@ -92,7 +94,12 @@ namespace Execute
|
||||
|
||||
Type = BinaryType::BinTypeUnknown;
|
||||
Success:
|
||||
delete fd;
|
||||
return Type;
|
||||
}
|
||||
|
||||
BinaryType GetBinaryType(std::string Path)
|
||||
{
|
||||
FileNode *node = fs->GetByPath(Path.c_str(), nullptr);
|
||||
return GetBinaryType(node);
|
||||
}
|
||||
}
|
||||
|
@ -33,15 +33,16 @@ using namespace vfs;
|
||||
namespace Execute
|
||||
{
|
||||
void ELFObject::GenerateAuxiliaryVector_x86_32(Memory::VirtualMemoryArea *vma,
|
||||
vfs::RefNode *fd,
|
||||
FileNode *fd,
|
||||
Elf32_Ehdr ELFHeader,
|
||||
uint32_t EntryPoint,
|
||||
uint32_t BaseAddress)
|
||||
{
|
||||
assert(!"Function not implemented");
|
||||
}
|
||||
|
||||
void ELFObject::GenerateAuxiliaryVector_x86_64(Memory::VirtualMemoryArea *vma,
|
||||
vfs::RefNode *fd,
|
||||
FileNode *fd,
|
||||
Elf64_Ehdr ELFHeader,
|
||||
uint64_t EntryPoint,
|
||||
uint64_t BaseAddress)
|
||||
@ -50,8 +51,8 @@ namespace Execute
|
||||
char *aux_platform = (char *)vma->RequestPages(1, true); /* TODO: 4KiB is too much for this */
|
||||
strcpy(aux_platform, "x86_64");
|
||||
|
||||
void *execfn_str = vma->RequestPages(TO_PAGES(strlen(fd->node->FullPath) + 1), true);
|
||||
strcpy((char *)execfn_str, fd->node->FullPath);
|
||||
void *execfn_str = vma->RequestPages(TO_PAGES(fd->Path.size() + 1), true);
|
||||
strcpy((char *)execfn_str, fd->Path.c_str());
|
||||
void *at_random = vma->RequestPages(1, true);
|
||||
*(uint64_t *)at_random = Random::rand16();
|
||||
|
||||
@ -93,22 +94,21 @@ namespace Execute
|
||||
#endif
|
||||
}
|
||||
|
||||
void ELFObject::LoadExec_x86_32(vfs::RefNode *, PCB *)
|
||||
void ELFObject::LoadExec_x86_32(FileNode *, PCB *)
|
||||
{
|
||||
stub;
|
||||
assert(!"Function not implemented");
|
||||
}
|
||||
|
||||
void ELFObject::LoadExec_x86_64(vfs::RefNode *fd, PCB *TargetProcess)
|
||||
void ELFObject::LoadExec_x86_64(FileNode *fd, PCB *TargetProcess)
|
||||
{
|
||||
#if defined(a64)
|
||||
std::vector<Elf64_Phdr> PhdrINTERP = ELFGetSymbolType_x86_64(fd, PT_INTERP);
|
||||
foreach (auto Interp in PhdrINTERP)
|
||||
{
|
||||
Memory::SmartHeap InterpreterPath = Memory::SmartHeap(256);
|
||||
fd->seek(Interp.p_offset, SEEK_SET);
|
||||
fd->read(InterpreterPath, 256);
|
||||
fd->Read(InterpreterPath, 256, Interp.p_offset);
|
||||
|
||||
vfs::RefNode *ifd = fs->Open((const char *)InterpreterPath.Get());
|
||||
FileNode *ifd = fs->GetByPath((const char *)InterpreterPath.Get(), TargetProcess->Info.RootNode);
|
||||
if (ifd == nullptr)
|
||||
{
|
||||
warn("Failed to open interpreter file: %s",
|
||||
@ -121,7 +121,6 @@ namespace Execute
|
||||
{
|
||||
warn("Interpreter %s is not an ELF file",
|
||||
(const char *)InterpreterPath.Get());
|
||||
delete ifd;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -130,15 +129,13 @@ namespace Execute
|
||||
/* FIXME: specify argv[1] as the location for the interpreter */
|
||||
|
||||
debug("Interpreter loaded successfully");
|
||||
delete ifd;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Elf64_Ehdr ELFHeader;
|
||||
fd->seek(0, SEEK_SET);
|
||||
fd->read((uint8_t *)&ELFHeader, sizeof(Elf64_Ehdr));
|
||||
Elf64_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
|
||||
uintptr_t EntryPoint = ELFHeader.e_entry;
|
||||
debug("Entry point is %#lx", EntryPoint);
|
||||
|
||||
@ -152,8 +149,7 @@ namespace Execute
|
||||
Elf64_Phdr ProgramHeader;
|
||||
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
|
||||
{
|
||||
fd->seek(ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)), SEEK_SET);
|
||||
fd->read((uint8_t *)&ProgramHeader, sizeof(Elf64_Phdr));
|
||||
fd->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
|
||||
switch (ProgramHeader.p_type)
|
||||
{
|
||||
case PT_LOAD:
|
||||
@ -182,10 +178,8 @@ namespace Execute
|
||||
|
||||
if (ProgramHeader.p_filesz > 0)
|
||||
{
|
||||
debug("%d %#lx %d", ProgramHeader.p_offset,
|
||||
(uint8_t *)pAddr + SegDestOffset, ProgramHeader.p_filesz);
|
||||
fd->seek(ProgramHeader.p_offset, SEEK_SET);
|
||||
fd->read((uint8_t *)pAddr + SegDestOffset, ProgramHeader.p_filesz);
|
||||
debug("%d %#lx %d", ProgramHeader.p_offset, (uint8_t *)pAddr + SegDestOffset, ProgramHeader.p_filesz);
|
||||
fd->Read((uint8_t *)pAddr + SegDestOffset, ProgramHeader.p_filesz, ProgramHeader.p_offset);
|
||||
}
|
||||
|
||||
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
|
||||
@ -203,40 +197,35 @@ namespace Execute
|
||||
case PT_NOTE:
|
||||
{
|
||||
Elf64_Nhdr NoteHeader;
|
||||
fd->seek(ProgramHeader.p_offset, SEEK_SET);
|
||||
fd->read((uint8_t *)&NoteHeader, sizeof(Elf64_Nhdr));
|
||||
fd->Read(&NoteHeader, sizeof(Elf64_Nhdr), ProgramHeader.p_offset);
|
||||
|
||||
switch (NoteHeader.n_type)
|
||||
{
|
||||
case NT_PRSTATUS:
|
||||
{
|
||||
Elf64_Prstatus prstatus;
|
||||
fd->seek(ProgramHeader.p_offset + sizeof(Elf64_Nhdr), SEEK_SET);
|
||||
fd->read((uint8_t *)&prstatus, sizeof(Elf64_Prstatus));
|
||||
fd->Read(&prstatus, sizeof(Elf64_Prstatus), ProgramHeader.p_offset + sizeof(Elf64_Nhdr));
|
||||
debug("PRSTATUS: %#lx", prstatus.pr_reg[0]);
|
||||
break;
|
||||
}
|
||||
case NT_PRPSINFO:
|
||||
{
|
||||
Elf64_Prpsinfo prpsinfo;
|
||||
fd->seek(ProgramHeader.p_offset + sizeof(Elf64_Nhdr), SEEK_SET);
|
||||
fd->read((uint8_t *)&prpsinfo, sizeof(Elf64_Prpsinfo));
|
||||
fd->Read(&prpsinfo, sizeof(Elf64_Prpsinfo), ProgramHeader.p_offset + sizeof(Elf64_Nhdr));
|
||||
debug("PRPSINFO: %s", prpsinfo.pr_fname);
|
||||
break;
|
||||
}
|
||||
case NT_PLATFORM:
|
||||
{
|
||||
char platform[256];
|
||||
fd->seek(ProgramHeader.p_offset + sizeof(Elf64_Nhdr), SEEK_SET);
|
||||
fd->read((uint8_t *)&platform, 256);
|
||||
fd->Read(&platform, sizeof(platform), ProgramHeader.p_offset + sizeof(Elf64_Nhdr));
|
||||
debug("PLATFORM: %s", platform);
|
||||
break;
|
||||
}
|
||||
case NT_AUXV:
|
||||
{
|
||||
Elf64_auxv_t auxv;
|
||||
fd->seek(ProgramHeader.p_offset + sizeof(Elf64_Nhdr), SEEK_SET);
|
||||
fd->read((uint8_t *)&auxv, sizeof(Elf64_auxv_t));
|
||||
fd->Read(&auxv, sizeof(Elf64_auxv_t), ProgramHeader.p_offset + sizeof(Elf64_Nhdr));
|
||||
debug("AUXV: %#lx", auxv.a_un.a_val);
|
||||
break;
|
||||
}
|
||||
@ -254,8 +243,7 @@ namespace Execute
|
||||
debug("TLS Size: %ld (%ld pages)",
|
||||
tlsSize, TO_PAGES(tlsSize));
|
||||
void *tlsMemory = vma->RequestPages(TO_PAGES(tlsSize));
|
||||
fd->seek(ProgramHeader.p_offset, SEEK_SET);
|
||||
fd->read((uint8_t *)tlsMemory, tlsSize);
|
||||
fd->Read(tlsMemory, tlsSize, ProgramHeader.p_offset);
|
||||
TargetProcess->TLS = {
|
||||
.pBase = uintptr_t(tlsMemory),
|
||||
.vBase = ProgramHeader.p_vaddr,
|
||||
@ -323,23 +311,22 @@ namespace Execute
|
||||
#endif
|
||||
}
|
||||
|
||||
void ELFObject::LoadDyn_x86_32(vfs::RefNode *, PCB *)
|
||||
void ELFObject::LoadDyn_x86_32(FileNode *, PCB *)
|
||||
{
|
||||
stub;
|
||||
assert(!"Function not implemented");
|
||||
}
|
||||
|
||||
void ELFObject::LoadDyn_x86_64(vfs::RefNode *fd, PCB *TargetProcess)
|
||||
void ELFObject::LoadDyn_x86_64(FileNode *fd, PCB *TargetProcess)
|
||||
{
|
||||
#if defined(a64)
|
||||
std::vector<Elf64_Phdr> PhdrINTERP = ELFGetSymbolType_x86_64(fd, PT_INTERP);
|
||||
foreach (auto Interp in PhdrINTERP)
|
||||
{
|
||||
Memory::SmartHeap InterpreterPath = Memory::SmartHeap(256);
|
||||
fd->seek(Interp.p_offset, SEEK_SET);
|
||||
fd->read(InterpreterPath, 256);
|
||||
fd->Read(InterpreterPath, 256, Interp.p_offset);
|
||||
InterpreterPath = InterpreterPath;
|
||||
|
||||
vfs::RefNode *ifd = fs->Open((const char *)InterpreterPath.Get());
|
||||
FileNode *ifd = fs->GetByPath((const char *)InterpreterPath.Get(), TargetProcess->Info.RootNode);
|
||||
if (ifd == nullptr)
|
||||
{
|
||||
warn("Failed to open interpreter file: %s",
|
||||
@ -352,22 +339,19 @@ namespace Execute
|
||||
{
|
||||
warn("Interpreter %s is not an ELF file",
|
||||
(const char *)InterpreterPath.Get());
|
||||
delete ifd;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LoadInterpreter(ifd, TargetProcess))
|
||||
{
|
||||
debug("Interpreter loaded successfully");
|
||||
delete ifd;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Elf64_Ehdr ELFHeader;
|
||||
fd->seek(0, SEEK_SET);
|
||||
fd->read((uint8_t *)&ELFHeader, sizeof(Elf64_Ehdr));
|
||||
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
|
||||
uintptr_t EntryPoint = ELFHeader.e_entry;
|
||||
debug("Entry point is %#lx", EntryPoint);
|
||||
|
||||
@ -383,8 +367,7 @@ namespace Execute
|
||||
size_t SegmentsSize = 0;
|
||||
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
|
||||
{
|
||||
fd->seek(ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)), SEEK_SET);
|
||||
fd->read((uint8_t *)&ProgramHeader, sizeof(Elf64_Phdr));
|
||||
fd->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
|
||||
|
||||
if (ProgramHeader.p_type == PT_LOAD ||
|
||||
ProgramHeader.p_type == PT_DYNAMIC)
|
||||
@ -408,8 +391,7 @@ namespace Execute
|
||||
|
||||
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
|
||||
{
|
||||
fd->seek(ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)), SEEK_SET);
|
||||
fd->read((uint8_t *)&ProgramHeader, sizeof(Elf64_Phdr));
|
||||
fd->Read(&ProgramHeader, sizeof(Elf64_Phdr), ELFHeader.e_phoff + (i * sizeof(Elf64_Phdr)));
|
||||
|
||||
switch (ProgramHeader.p_type)
|
||||
{
|
||||
@ -428,8 +410,7 @@ namespace Execute
|
||||
|
||||
if (ProgramHeader.p_filesz > 0)
|
||||
{
|
||||
fd->seek(ProgramHeader.p_offset, SEEK_SET);
|
||||
fd->read((uint8_t *)SegmentDestination, ProgramHeader.p_filesz);
|
||||
fd->Read(SegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
|
||||
}
|
||||
|
||||
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
|
||||
@ -455,8 +436,7 @@ namespace Execute
|
||||
|
||||
if (ProgramHeader.p_filesz > 0)
|
||||
{
|
||||
fd->seek(ProgramHeader.p_offset, SEEK_SET);
|
||||
fd->read((uint8_t *)DynamicSegmentDestination, ProgramHeader.p_filesz);
|
||||
fd->Read(DynamicSegmentDestination, ProgramHeader.p_filesz, ProgramHeader.p_offset);
|
||||
}
|
||||
|
||||
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
|
||||
@ -559,14 +539,11 @@ namespace Execute
|
||||
// Elf64_Shdr shdr;
|
||||
// for (Elf64_Half i = 0; i < ELFHeader.e_shnum; i++)
|
||||
// {
|
||||
// fd->seek(ELFHeader.e_shoff + i * sizeof(Elf64_Shdr), SEEK_SET);
|
||||
// fd->read((uint8_t *)&shdr, sizeof(Elf64_Shdr));
|
||||
// fd->Read(&shdr, sizeof(Elf64_Shdr), ELFHeader.e_shoff + i * sizeof(Elf64_Shdr));
|
||||
// char sectionName[32];
|
||||
// Elf64_Shdr n_shdr;
|
||||
// fd->seek(ELFHeader.e_shoff + ELFHeader.e_shstrndx * sizeof(Elf64_Shdr), SEEK_SET);
|
||||
// fd->read((uint8_t *)&n_shdr, sizeof(Elf64_Shdr));
|
||||
// fd->seek(n_shdr.sh_offset + shdr.sh_name, SEEK_SET);
|
||||
// fd->read((uint8_t *)sectionName, 32);
|
||||
// fd->Read(&n_shdr, sizeof(Elf64_Shdr), ELFHeader.e_shoff + ELFHeader.e_shstrndx * sizeof(Elf64_Shdr));
|
||||
// fd->Read(sectionName, sizeof(sectionName), n_shdr.sh_offset + shdr.sh_name);
|
||||
// debug("shdr: %s", sectionName);
|
||||
// if (strcmp(sectionName, ".rela.plt") == 0)
|
||||
// {
|
||||
@ -692,8 +669,7 @@ namespace Execute
|
||||
// // STT_OBJECT
|
||||
// Elf64_Xword numEntries = shdr.sh_size / shdr.sh_entsize;
|
||||
// Elf64_Sym *SymArray = new Elf64_Sym[numEntries];
|
||||
// fd->seek(shdr.sh_offset, SEEK_SET);
|
||||
// fd->read((uint8_t *)SymArray, shdr.sh_size);
|
||||
// fd->Read(SymArray, shdr.sh_size, shdr.sh_offset);
|
||||
// debug("start %#lx (off %#lx), entries %ld",
|
||||
// SymArray, shdr.sh_addr, numEntries);
|
||||
// for (Elf64_Xword j = 0; j < numEntries; j++)
|
||||
@ -734,10 +710,10 @@ namespace Execute
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ELFObject::LoadInterpreter(vfs::RefNode *fd, PCB *TargetProcess)
|
||||
bool ELFObject::LoadInterpreter(FileNode *fd, PCB *TargetProcess)
|
||||
{
|
||||
Elf32_Ehdr ELFHeader;
|
||||
fd->read((uint8_t *)&ELFHeader, sizeof(Elf32_Ehdr));
|
||||
fd->Read(&ELFHeader, sizeof(Elf32_Ehdr), 0);
|
||||
|
||||
switch (ELFHeader.e_type)
|
||||
{
|
||||
@ -805,24 +781,24 @@ namespace Execute
|
||||
return false;
|
||||
}
|
||||
|
||||
ELFObject::ELFObject(char *AbsolutePath,
|
||||
ELFObject::ELFObject(std::string AbsolutePath,
|
||||
PCB *TargetProcess,
|
||||
const char **argv,
|
||||
const char **envp)
|
||||
{
|
||||
if (GetBinaryType(AbsolutePath) != BinaryType::BinTypeELF)
|
||||
{
|
||||
error("%s is not an ELF file or is invalid.", AbsolutePath);
|
||||
error("%s is not an ELF file or is invalid.", AbsolutePath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
vfs::RefNode *fd = fs->Open(AbsolutePath);
|
||||
FileNode *fd = fs->GetByPath(AbsolutePath.c_str(), TargetProcess->Info.RootNode);
|
||||
if (fd == nullptr)
|
||||
{
|
||||
error("Failed to open %s, errno: %d", AbsolutePath, fd);
|
||||
error("Failed to open %s, errno: %d", AbsolutePath.c_str(), fd);
|
||||
return;
|
||||
}
|
||||
debug("Opened %s", AbsolutePath);
|
||||
debug("Opened %s", AbsolutePath.c_str());
|
||||
|
||||
int argc = 0;
|
||||
int envc = 0;
|
||||
@ -833,17 +809,15 @@ namespace Execute
|
||||
envc++;
|
||||
|
||||
Elf32_Ehdr ELFHeader;
|
||||
fd->read((uint8_t *)&ELFHeader, sizeof(Elf32_Ehdr));
|
||||
fd->Read(&ELFHeader, sizeof(Elf32_Ehdr), 0);
|
||||
|
||||
std::vector<Elf64_Phdr> PhdrINTERP = ELFGetSymbolType_x86_64(fd, PT_INTERP);
|
||||
const char *ElfInterpPath = nullptr;
|
||||
if (!PhdrINTERP.empty() && ELFHeader.e_type == ET_DYN)
|
||||
{
|
||||
fd->seek(PhdrINTERP.front().p_offset, SEEK_SET);
|
||||
ElfInterpPath = new char[256];
|
||||
fd->read((uint8_t *)ElfInterpPath, 256);
|
||||
fd->Read(ElfInterpPath, 256, PhdrINTERP.front().p_offset);
|
||||
debug("Interpreter: %s", ElfInterpPath);
|
||||
fd->seek(0, SEEK_SET);
|
||||
argc++;
|
||||
}
|
||||
|
||||
@ -945,8 +919,6 @@ namespace Execute
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete fd;
|
||||
}
|
||||
|
||||
ELFObject::~ELFObject()
|
||||
|
@ -58,7 +58,7 @@ namespace Execute
|
||||
return StringTable + Offset;
|
||||
}
|
||||
|
||||
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name)
|
||||
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, std::string Name)
|
||||
{
|
||||
Elf64_Shdr *SymbolTable = nullptr;
|
||||
Elf64_Shdr *StringTable = nullptr;
|
||||
@ -86,36 +86,31 @@ namespace Execute
|
||||
{
|
||||
Elf64_Sym *Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
|
||||
char *String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
|
||||
if (strcmp(String, Name) == 0)
|
||||
if (strcmp(String, Name.c_str()) == 0)
|
||||
return Symbol;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Elf64_Sym ELFLookupSymbol(vfs::RefNode *fd, const char *Name)
|
||||
Elf64_Sym ELFLookupSymbol(FileNode *fd, std::string Name)
|
||||
{
|
||||
#if defined(a64)
|
||||
off_t OldOffset = fd->seek(0, SEEK_CUR);
|
||||
Elf64_Ehdr Header{};
|
||||
fd->Read(&Header, sizeof(Elf64_Ehdr), 0);
|
||||
|
||||
Elf64_Ehdr Header;
|
||||
fd->seek(0, SEEK_SET);
|
||||
fd->read((uint8_t *)&Header, sizeof(Elf64_Ehdr));
|
||||
|
||||
Elf64_Shdr SymbolTable;
|
||||
Elf64_Shdr StringTable;
|
||||
Elf64_Shdr SymbolTable{};
|
||||
Elf64_Shdr StringTable{};
|
||||
|
||||
for (Elf64_Half i = 0; i < Header.e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr shdr;
|
||||
fd->seek(Header.e_shoff + (i * sizeof(Elf64_Shdr)), SEEK_SET);
|
||||
fd->read((uint8_t *)&shdr, sizeof(Elf64_Shdr));
|
||||
fd->Read(&shdr, sizeof(Elf64_Shdr), Header.e_shoff + (i * sizeof(Elf64_Shdr)));
|
||||
|
||||
switch (shdr.sh_type)
|
||||
{
|
||||
case SHT_SYMTAB:
|
||||
SymbolTable = shdr;
|
||||
fd->seek(Header.e_shoff + (shdr.sh_link * sizeof(Elf64_Shdr)), SEEK_SET);
|
||||
fd->read((uint8_t *)&StringTable, sizeof(Elf64_Shdr));
|
||||
fd->Read(&StringTable, sizeof(Elf64_Shdr), Header.e_shoff + (shdr.sh_link * sizeof(Elf64_Shdr)));
|
||||
break;
|
||||
default:
|
||||
{
|
||||
@ -124,11 +119,9 @@ namespace Execute
|
||||
}
|
||||
}
|
||||
|
||||
if (SymbolTable.sh_name == 0 ||
|
||||
StringTable.sh_name == 0)
|
||||
if (SymbolTable.sh_name == 0 || StringTable.sh_name == 0)
|
||||
{
|
||||
error("Symbol table not found.");
|
||||
fd->seek(OldOffset, SEEK_SET);
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -136,22 +129,16 @@ namespace Execute
|
||||
{
|
||||
// Elf64_Sym *Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
|
||||
Elf64_Sym Symbol;
|
||||
fd->seek(SymbolTable.sh_offset + (i * sizeof(Elf64_Sym)), SEEK_SET);
|
||||
fd->read((uint8_t *)&Symbol, sizeof(Elf64_Sym));
|
||||
fd->Read(&Symbol, sizeof(Elf64_Sym), SymbolTable.sh_offset + (i * sizeof(Elf64_Sym)));
|
||||
|
||||
// char *String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
|
||||
char String[256];
|
||||
fd->seek(StringTable.sh_offset + Symbol.st_name, SEEK_SET);
|
||||
fd->read((uint8_t *)&String, 256);
|
||||
fd->Read(&String, sizeof(String), StringTable.sh_offset + Symbol.st_name);
|
||||
|
||||
if (strcmp(String, Name) == 0)
|
||||
{
|
||||
fd->seek(OldOffset, SEEK_SET);
|
||||
if (strcmp(String, Name.c_str()) == 0)
|
||||
return Symbol;
|
||||
}
|
||||
}
|
||||
error("Symbol not found.");
|
||||
fd->seek(OldOffset, SEEK_SET);
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
@ -21,16 +21,14 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
std::vector<Elf64_Dyn> ELFGetDynamicTag_x86_64(vfs::RefNode *fd,
|
||||
std::vector<Elf64_Dyn> ELFGetDynamicTag_x86_64(FileNode *fd,
|
||||
DynamicArrayTags Tag)
|
||||
{
|
||||
#if defined(a64) || defined(aa64)
|
||||
off_t OldOffset = fd->seek(0, SEEK_CUR);
|
||||
std::vector<Elf64_Dyn> Ret;
|
||||
|
||||
Elf64_Ehdr ELFHeader;
|
||||
fd->seek(0, SEEK_SET);
|
||||
fd->read((uint8_t *)&ELFHeader, sizeof(Elf64_Ehdr));
|
||||
Elf64_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
|
||||
|
||||
std::vector<Elf64_Phdr> DYNAMICPhdrs = ELFGetSymbolType_x86_64(fd, PT_DYNAMIC);
|
||||
|
||||
@ -42,11 +40,10 @@ namespace Execute
|
||||
|
||||
foreach (auto Phdr in DYNAMICPhdrs)
|
||||
{
|
||||
Elf64_Dyn Dynamic;
|
||||
Elf64_Dyn Dynamic{};
|
||||
for (size_t i = 0; i < Phdr.p_filesz / sizeof(Elf64_Dyn); i++)
|
||||
{
|
||||
fd->seek(Phdr.p_offset + (i * sizeof(Elf64_Dyn)), SEEK_SET);
|
||||
fd->read((uint8_t *)&Dynamic, sizeof(Elf64_Dyn));
|
||||
fd->Read(&Dynamic, sizeof(Elf64_Dyn), Phdr.p_offset + (i * sizeof(Elf64_Dyn)));
|
||||
|
||||
if (Dynamic.d_tag != Tag)
|
||||
continue;
|
||||
@ -57,7 +54,6 @@ namespace Execute
|
||||
}
|
||||
}
|
||||
|
||||
fd->seek(OldOffset, SEEK_SET);
|
||||
return Ret;
|
||||
#elif defined(a32)
|
||||
return {};
|
||||
|
@ -21,24 +21,20 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
std::vector<Elf64_Shdr> ELFGetSections_x86_64(vfs::RefNode *fd,
|
||||
std::vector<Elf64_Shdr> ELFGetSections_x86_64(FileNode *fd,
|
||||
const char *SectionName)
|
||||
{
|
||||
#if defined(a64) || defined(aa64)
|
||||
off_t OldOffset = fd->seek(0, SEEK_CUR);
|
||||
std::vector<Elf64_Shdr> Ret;
|
||||
|
||||
Elf64_Ehdr ELFHeader;
|
||||
fd->seek(0, SEEK_SET);
|
||||
fd->read((uint8_t *)&ELFHeader, sizeof(Elf64_Ehdr));
|
||||
Elf64_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
|
||||
|
||||
Elf64_Shdr *SectionHeaders = new Elf64_Shdr[ELFHeader.e_shnum];
|
||||
fd->seek(ELFHeader.e_shoff, SEEK_SET);
|
||||
fd->read((uint8_t *)SectionHeaders, sizeof(Elf64_Shdr) * ELFHeader.e_shnum);
|
||||
fd->Read(SectionHeaders, sizeof(Elf64_Shdr) * ELFHeader.e_shnum, ELFHeader.e_shoff);
|
||||
|
||||
char *SectionNames = new char[SectionHeaders[ELFHeader.e_shstrndx].sh_size];
|
||||
fd->seek(SectionHeaders[ELFHeader.e_shstrndx].sh_offset, SEEK_SET);
|
||||
fd->read((uint8_t *)SectionNames, SectionHeaders[ELFHeader.e_shstrndx].sh_size);
|
||||
fd->Read(SectionNames, SectionHeaders[ELFHeader.e_shstrndx].sh_size, SectionHeaders[ELFHeader.e_shstrndx].sh_offset);
|
||||
|
||||
for (Elf64_Half i = 0; i < ELFHeader.e_shnum; ++i)
|
||||
{
|
||||
@ -47,7 +43,6 @@ namespace Execute
|
||||
Ret.push_back(SectionHeaders[i]);
|
||||
}
|
||||
|
||||
fd->seek(OldOffset, SEEK_SET);
|
||||
delete[] SectionHeaders;
|
||||
delete[] SectionNames;
|
||||
return Ret;
|
||||
|
@ -21,31 +21,28 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
std::vector<Elf64_Phdr> ELFGetSymbolType_x86_64(vfs::RefNode *fd,
|
||||
std::vector<Elf64_Phdr> ELFGetSymbolType_x86_64(FileNode *fd,
|
||||
SegmentTypes Tag)
|
||||
{
|
||||
#if defined(a64) || defined(aa64)
|
||||
off_t OldOffset = fd->seek(0, SEEK_CUR);
|
||||
std::vector<Elf64_Phdr> Ret;
|
||||
|
||||
Elf64_Ehdr ELFHeader;
|
||||
fd->seek(0, SEEK_SET);
|
||||
fd->read((uint8_t *)&ELFHeader, sizeof(Elf64_Ehdr));
|
||||
Elf64_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
|
||||
|
||||
Elf64_Phdr ProgramHeaders;
|
||||
fd->seek(ELFHeader.e_phoff, SEEK_SET);
|
||||
fd->read((uint8_t *)&ProgramHeaders, sizeof(Elf64_Phdr));
|
||||
Elf64_Phdr ProgramHeaders{};
|
||||
fd->Read(&ProgramHeaders, sizeof(Elf64_Phdr), ELFHeader.e_phoff);
|
||||
|
||||
off_t currentOffset = ELFHeader.e_phoff;
|
||||
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
|
||||
{
|
||||
if (ProgramHeaders.p_type == Tag)
|
||||
Ret.push_back(ProgramHeaders);
|
||||
|
||||
fd->seek(sizeof(Elf64_Phdr), SEEK_CUR);
|
||||
fd->read((uint8_t *)&ProgramHeaders, sizeof(Elf64_Phdr));
|
||||
currentOffset += sizeof(Elf64_Phdr);
|
||||
fd->Read(&ProgramHeaders, sizeof(Elf64_Phdr), currentOffset);
|
||||
}
|
||||
|
||||
fd->seek(OldOffset, SEEK_SET);
|
||||
return Ret;
|
||||
#elif defined(a32)
|
||||
return {};
|
||||
|
@ -35,15 +35,12 @@ namespace Execute
|
||||
Tasking::TaskCompatibility Compatibility,
|
||||
bool Critical)
|
||||
{
|
||||
vfs::RefNode *fd = fs->Open(Path);
|
||||
FileNode *fd = fs->GetByPath(Path, nullptr);
|
||||
if (fd == nullptr)
|
||||
return -ENOENT;
|
||||
|
||||
if (fd->node->Type == vfs::NodeType::DIRECTORY)
|
||||
{
|
||||
delete fd;
|
||||
return -EISDIR;
|
||||
}
|
||||
if (!fd->IsRegularFile())
|
||||
return -ENOEXEC;
|
||||
|
||||
switch (GetBinaryType(Path))
|
||||
{
|
||||
@ -53,7 +50,7 @@ namespace Execute
|
||||
const char *BaseName;
|
||||
cwk_path_get_basename(Path, &BaseName, nullptr);
|
||||
Elf32_Ehdr ELFHeader;
|
||||
fd->read((uint8_t *)&ELFHeader, sizeof(Elf32_Ehdr));
|
||||
fd->Read(&ELFHeader, sizeof(Elf32_Ehdr), 0);
|
||||
|
||||
switch (ELFHeader.e_machine)
|
||||
{
|
||||
@ -119,22 +116,20 @@ namespace Execute
|
||||
if (Parent == nullptr)
|
||||
Parent = thisProcess;
|
||||
|
||||
Process = TaskManager->CreateProcess(Parent,
|
||||
BaseName,
|
||||
Process = TaskManager->CreateProcess(Parent, BaseName,
|
||||
TaskExecutionMode::User,
|
||||
false, 0, 0);
|
||||
Process->Info.Compatibility = Compatibility;
|
||||
Process->Info.Architecture = Arch;
|
||||
}
|
||||
|
||||
Process->SetWorkingDirectory(fs->GetNodeFromPath(Path)->Parent);
|
||||
Process->SetWorkingDirectory(fs->GetByPath(Path, nullptr)->Parent);
|
||||
Process->SetExe(Path);
|
||||
|
||||
ELFObject *obj = new ELFObject(Path, Process, argv, envp);
|
||||
if (!obj->IsValid)
|
||||
{
|
||||
error("Failed to load ELF object");
|
||||
delete fd;
|
||||
delete Process;
|
||||
return -ENOEXEC;
|
||||
}
|
||||
@ -142,23 +137,20 @@ namespace Execute
|
||||
vfs::FileDescriptorTable *pfdt = Parent->FileDescriptors;
|
||||
vfs::FileDescriptorTable *fdt = Process->FileDescriptors;
|
||||
|
||||
auto ForkStdio = [pfdt, fdt](Node *SearchNode)
|
||||
auto ForkStdio = [pfdt, fdt](FileNode *SearchNode)
|
||||
{
|
||||
if (unlikely(SearchNode == nullptr))
|
||||
return false;
|
||||
|
||||
std::vector<FileDescriptorTable::Fildes>
|
||||
pfds = pfdt->GetFileDescriptors();
|
||||
|
||||
foreach (auto ffd in pfds)
|
||||
foreach (const auto &ffd in pfdt->FileMap)
|
||||
{
|
||||
if (ffd.Flags & O_CLOEXEC)
|
||||
if (ffd.second.Flags & O_CLOEXEC)
|
||||
continue;
|
||||
|
||||
if (ffd.Handle->node == SearchNode)
|
||||
if (ffd.second.Node == SearchNode)
|
||||
{
|
||||
fdt->_open(ffd.Handle->node->FullPath,
|
||||
ffd.Flags, ffd.Mode);
|
||||
fdt->usr_open(ffd.second.Node->Path.c_str(),
|
||||
ffd.second.Flags, ffd.second.Mode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -166,37 +158,31 @@ namespace Execute
|
||||
};
|
||||
|
||||
if (!ForkStdio(Parent->stdin))
|
||||
fdt->_open("/dev/kcon", O_RDWR, 0666);
|
||||
fdt->usr_open("/dev/kcon", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
|
||||
if (!ForkStdio(Parent->stdout))
|
||||
fdt->_open("/dev/kcon", O_RDWR, 0666);
|
||||
fdt->usr_open("/dev/kcon", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
|
||||
if (!ForkStdio(Parent->stderr))
|
||||
fdt->_open("/dev/kcon", O_RDWR, 0666);
|
||||
fdt->usr_open("/dev/kcon", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
|
||||
TCB *Thread = nullptr;
|
||||
{
|
||||
CriticalSection cs;
|
||||
Thread = TaskManager->CreateThread(Process,
|
||||
obj->InstructionPointer,
|
||||
Thread = TaskManager->CreateThread(Process, obj->InstructionPointer,
|
||||
obj->argv, obj->envp, obj->auxv,
|
||||
Arch,
|
||||
Compatibility);
|
||||
Arch, Compatibility);
|
||||
Thread->SetCritical(Critical);
|
||||
}
|
||||
delete fd;
|
||||
return Thread->ID;
|
||||
}
|
||||
default:
|
||||
{
|
||||
debug("Unknown binary type: %d",
|
||||
GetBinaryType(Path));
|
||||
delete fd;
|
||||
debug("Unknown binary type: %d", GetBinaryType(Path));
|
||||
return -ENOEXEC;
|
||||
}
|
||||
}
|
||||
|
||||
delete fd;
|
||||
return -ENOEXEC;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user