Refactor filesystem & stl code

This commit is contained in:
EnderIce2
2024-05-18 07:42:01 +03:00
parent 77a291d08b
commit 6801475243
186 changed files with 15784 additions and 9746 deletions

View File

@ -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);
}
}

View File

@ -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()

View File

@ -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 {};
}

View File

@ -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 {};

View File

@ -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;

View File

@ -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 {};

View File

@ -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;
}
}