mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-10 23:09:18 +00:00
Update kernel
This commit is contained in:
@ -19,52 +19,34 @@
|
||||
|
||||
#include <msexec.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
#include "../Fex.hpp"
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
BinaryType GetBinaryType(const char *Path)
|
||||
{
|
||||
debug("Checking binary type of %s(ptr: %#lx)",
|
||||
Path, Path);
|
||||
BinaryType Type;
|
||||
int fd = fopen(Path, "r");
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
debug("Failed to open file %s: %s",
|
||||
Path, strerror(fd));
|
||||
return (BinaryType)fd;
|
||||
}
|
||||
|
||||
debug("File opened: %s, descriptor %d", Path, fd);
|
||||
Memory::SmartHeap sh = Memory::SmartHeap(1024);
|
||||
fread(fd, sh, 128);
|
||||
|
||||
Fex *FexHdr = (Fex *)sh.Get();
|
||||
Elf32_Ehdr *ELFHeader = (Elf32_Ehdr *)sh.Get();
|
||||
IMAGE_DOS_HEADER *MZHeader = (IMAGE_DOS_HEADER *)sh.Get();
|
||||
|
||||
/* Check Fex header. */
|
||||
if (FexHdr->Magic[0] == 'F' &&
|
||||
FexHdr->Magic[1] == 'E' &&
|
||||
FexHdr->Magic[2] == 'X' &&
|
||||
FexHdr->Magic[3] == '\0')
|
||||
{
|
||||
/* If the fex type is driver, we shouldn't return as Fex. */
|
||||
if (FexHdr->Type == FexFormatType_Executable)
|
||||
{
|
||||
debug("Image - Fex");
|
||||
Type = BinaryType::BinTypeFex;
|
||||
goto Success;
|
||||
}
|
||||
else if (FexHdr->Type == FexFormatType_Module)
|
||||
{
|
||||
fixme("Fex Module is not supposed to be executed.");
|
||||
/* TODO: Module installation pop-up. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Check ELF header. */
|
||||
else 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;
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <abi.h>
|
||||
|
||||
#include "../../kernel.h"
|
||||
#include "../../Fex.hpp"
|
||||
|
||||
using namespace Tasking;
|
||||
using namespace vfs;
|
||||
@ -162,8 +161,9 @@ namespace Execute
|
||||
uintptr_t EntryPoint = ELFHeader.e_entry;
|
||||
debug("Entry point is %#lx", EntryPoint);
|
||||
|
||||
Memory::Virtual vmm = Memory::Virtual(TargetProcess->PageTable);
|
||||
Memory::Virtual vmm(TargetProcess->PageTable);
|
||||
Memory::VirtualMemoryArea *vma = TargetProcess->vma;
|
||||
debug("Target process page table is %#lx", TargetProcess->PageTable);
|
||||
|
||||
LoadPhdrs_x86_64(fd, ELFHeader, vma, TargetProcess);
|
||||
|
||||
@ -188,9 +188,10 @@ namespace Execute
|
||||
|
||||
vmm.Map(vAddr, pAddr,
|
||||
ProgramHeader.p_memsz,
|
||||
Memory::P | Memory::RW | Memory::US);
|
||||
Memory::RW | Memory::US);
|
||||
|
||||
debug("Mapped %#lx to %#lx", vAddr, pAddr);
|
||||
debug("Mapped %#lx to %#lx (%ld bytes)",
|
||||
vAddr, pAddr, ProgramHeader.p_memsz);
|
||||
debug("Segment Offset is %#lx", SegDestOffset);
|
||||
|
||||
debug("Copying segment to p: %#lx-%#lx; v: %#lx-%#lx (%ld file bytes, %ld mem bytes)",
|
||||
@ -202,6 +203,8 @@ namespace Execute
|
||||
|
||||
if (ProgramHeader.p_filesz > 0)
|
||||
{
|
||||
debug("%d %#lx %d", ProgramHeader.p_offset,
|
||||
(uint8_t *)pAddr + SegDestOffset, ProgramHeader.p_filesz);
|
||||
lseek(fd, ProgramHeader.p_offset, SEEK_SET);
|
||||
fread(fd, (uint8_t *)pAddr + SegDestOffset, ProgramHeader.p_filesz);
|
||||
}
|
||||
@ -209,11 +212,100 @@ namespace Execute
|
||||
if (ProgramHeader.p_memsz - ProgramHeader.p_filesz > 0)
|
||||
{
|
||||
void *zAddr = (void *)(uintptr_t(pAddr) + SegDestOffset + ProgramHeader.p_filesz);
|
||||
|
||||
debug("Zeroing %d bytes at %#lx",
|
||||
ProgramHeader.p_memsz - ProgramHeader.p_filesz, zAddr);
|
||||
|
||||
memset(zAddr, 0, ProgramHeader.p_memsz - ProgramHeader.p_filesz);
|
||||
}
|
||||
ProgramBreakHeader = ProgramHeader;
|
||||
break;
|
||||
}
|
||||
case PT_NOTE:
|
||||
{
|
||||
Elf64_Nhdr NoteHeader;
|
||||
lseek(fd, ProgramHeader.p_offset, SEEK_SET);
|
||||
fread(fd, (uint8_t *)&NoteHeader, sizeof(Elf64_Nhdr));
|
||||
|
||||
switch (NoteHeader.n_type)
|
||||
{
|
||||
case NT_PRSTATUS:
|
||||
{
|
||||
Elf64_Prstatus prstatus;
|
||||
lseek(fd, ProgramHeader.p_offset + sizeof(Elf64_Nhdr), SEEK_SET);
|
||||
fread(fd, (uint8_t *)&prstatus, sizeof(Elf64_Prstatus));
|
||||
debug("PRSTATUS: %#lx", prstatus.pr_reg[0]);
|
||||
break;
|
||||
}
|
||||
case NT_PRPSINFO:
|
||||
{
|
||||
Elf64_Prpsinfo prpsinfo;
|
||||
lseek(fd, ProgramHeader.p_offset + sizeof(Elf64_Nhdr), SEEK_SET);
|
||||
fread(fd, (uint8_t *)&prpsinfo, sizeof(Elf64_Prpsinfo));
|
||||
debug("PRPSINFO: %s", prpsinfo.pr_fname);
|
||||
break;
|
||||
}
|
||||
case NT_PLATFORM:
|
||||
{
|
||||
char platform[256];
|
||||
lseek(fd, ProgramHeader.p_offset + sizeof(Elf64_Nhdr), SEEK_SET);
|
||||
fread(fd, (uint8_t *)&platform, 256);
|
||||
debug("PLATFORM: %s", platform);
|
||||
break;
|
||||
}
|
||||
case NT_AUXV:
|
||||
{
|
||||
Elf64_auxv_t auxv;
|
||||
lseek(fd, ProgramHeader.p_offset + sizeof(Elf64_Nhdr), SEEK_SET);
|
||||
fread(fd, (uint8_t *)&auxv, sizeof(Elf64_auxv_t));
|
||||
debug("AUXV: %#lx", auxv.a_un.a_val);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("Unhandled note type: %#lx", NoteHeader.n_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PT_TLS:
|
||||
{
|
||||
size_t tlsSize = ProgramHeader.p_memsz;
|
||||
debug("TLS Size: %ld (%ld pages)",
|
||||
tlsSize, TO_PAGES(tlsSize));
|
||||
void *tlsMemory = vma->RequestPages(TO_PAGES(tlsSize));
|
||||
lseek(fd, ProgramHeader.p_offset, SEEK_SET);
|
||||
fread(fd, (uint8_t *)tlsMemory, tlsSize);
|
||||
TargetProcess->TLS = {
|
||||
.pBase = uintptr_t(tlsMemory),
|
||||
.vBase = ProgramHeader.p_vaddr,
|
||||
.Align = ProgramHeader.p_align,
|
||||
.Size = ProgramHeader.p_memsz,
|
||||
.fSize = ProgramHeader.p_filesz,
|
||||
};
|
||||
break;
|
||||
}
|
||||
case 0x6474E550: /* PT_GNU_EH_FRAME */
|
||||
{
|
||||
fixme("PT_GNU_EH_FRAME");
|
||||
break;
|
||||
}
|
||||
case 0x6474e551: /* PT_GNU_STACK */
|
||||
{
|
||||
fixme("PT_GNU_STACK");
|
||||
break;
|
||||
}
|
||||
case 0x6474e552: /* PT_GNU_RELRO */
|
||||
{
|
||||
fixme("PT_GNU_RELRO");
|
||||
break;
|
||||
}
|
||||
case 0x6474e553: /* PT_GNU_PROPERTY */
|
||||
{
|
||||
fixme("PT_GNU_PROPERTY");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("Unhandled program header type: %#lx",
|
||||
@ -238,6 +330,11 @@ namespace Execute
|
||||
fread(fd, sh, statbuf.st_size);
|
||||
TargetProcess->ELFSymbolTable->AppendSymbols(uintptr_t(sh.Get()));
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!TargetProcess->ELFSymbolTable->SymTableExists)
|
||||
debug("NO SYMBOL TABLE FOUND?");
|
||||
#endif
|
||||
|
||||
debug("Entry Point: %#lx", EntryPoint);
|
||||
|
||||
this->GenerateAuxiliaryVector_x86_64(vma, fd, ELFHeader,
|
||||
@ -299,7 +396,7 @@ namespace Execute
|
||||
uintptr_t EntryPoint = ELFHeader.e_entry;
|
||||
debug("Entry point is %#lx", EntryPoint);
|
||||
|
||||
Memory::Virtual vmm = Memory::Virtual(TargetProcess->PageTable);
|
||||
Memory::Virtual vmm(TargetProcess->PageTable);
|
||||
Memory::VirtualMemoryArea *vma = TargetProcess->vma;
|
||||
uintptr_t BaseAddress = 0;
|
||||
|
||||
@ -396,6 +493,26 @@ namespace Execute
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x6474E550: /* PT_GNU_EH_FRAME */
|
||||
{
|
||||
fixme("PT_GNU_EH_FRAME");
|
||||
break;
|
||||
}
|
||||
case 0x6474e551: /* PT_GNU_STACK */
|
||||
{
|
||||
fixme("PT_GNU_STACK");
|
||||
break;
|
||||
}
|
||||
case 0x6474e552: /* PT_GNU_RELRO */
|
||||
{
|
||||
fixme("PT_GNU_RELRO");
|
||||
break;
|
||||
}
|
||||
case 0x6474e553: /* PT_GNU_PROPERTY */
|
||||
{
|
||||
fixme("PT_GNU_PROPERTY");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("Unhandled program header type: %#lx",
|
||||
@ -417,240 +534,209 @@ namespace Execute
|
||||
EntryPoint += BaseAddress;
|
||||
debug("The new ep is %#lx", EntryPoint);
|
||||
|
||||
std::vector<Elf64_Dyn> JmpRel = ELFGetDynamicTag_x86_64(fd, DT_JMPREL);
|
||||
std::vector<Elf64_Dyn> SymTab = ELFGetDynamicTag_x86_64(fd, DT_SYMTAB);
|
||||
std::vector<Elf64_Dyn> StrTab = ELFGetDynamicTag_x86_64(fd, DT_STRTAB);
|
||||
std::vector<Elf64_Dyn> RelaDyn = ELFGetDynamicTag_x86_64(fd, DT_RELA);
|
||||
std::vector<Elf64_Dyn> RelaDynSize = ELFGetDynamicTag_x86_64(fd, DT_RELASZ);
|
||||
|
||||
size_t JmpRelSize = JmpRel.size();
|
||||
size_t SymTabSize = SymTab.size();
|
||||
size_t StrTabSize = StrTab.size();
|
||||
size_t RelaDynSize_v = RelaDyn.size();
|
||||
|
||||
if (JmpRelSize < 1)
|
||||
{
|
||||
debug("No DT_JMPREL");
|
||||
}
|
||||
|
||||
if (SymTabSize < 1)
|
||||
{
|
||||
debug("No DT_SYMTAB");
|
||||
}
|
||||
|
||||
if (StrTabSize < 1)
|
||||
{
|
||||
debug("No DT_STRTAB");
|
||||
}
|
||||
|
||||
if (RelaDynSize_v < 1)
|
||||
{
|
||||
debug("No DT_RELA");
|
||||
}
|
||||
|
||||
if (RelaDynSize[0].d_un.d_val < 1)
|
||||
{
|
||||
debug("DT_RELASZ is < 1");
|
||||
}
|
||||
|
||||
if (JmpRelSize > 0 && SymTabSize > 0 && StrTabSize > 0)
|
||||
{
|
||||
debug("JmpRel: %#lx, SymTab: %#lx, StrTab: %#lx",
|
||||
JmpRel[0].d_un.d_ptr, SymTab[0].d_un.d_ptr,
|
||||
StrTab[0].d_un.d_ptr);
|
||||
|
||||
Elf64_Rela *_JmpRel = (Elf64_Rela *)((uintptr_t)BaseAddress + JmpRel[0].d_un.d_ptr);
|
||||
Elf64_Sym *_SymTab = (Elf64_Sym *)((uintptr_t)BaseAddress + SymTab[0].d_un.d_ptr);
|
||||
char *_DynStr = (char *)((uintptr_t)BaseAddress + StrTab[0].d_un.d_ptr);
|
||||
Elf64_Rela *_RelaDyn = (Elf64_Rela *)((uintptr_t)BaseAddress + RelaDyn[0].d_un.d_ptr);
|
||||
|
||||
Elf64_Shdr shdr;
|
||||
for (Elf64_Half i = 0; i < ELFHeader.e_shnum; i++)
|
||||
{
|
||||
lseek(fd, ELFHeader.e_shoff + i * sizeof(Elf64_Shdr), SEEK_SET);
|
||||
fread(fd, (uint8_t *)&shdr, sizeof(Elf64_Shdr));
|
||||
|
||||
char sectionName[32];
|
||||
Elf64_Shdr n_shdr;
|
||||
lseek(fd, ELFHeader.e_shoff + ELFHeader.e_shstrndx * sizeof(Elf64_Shdr), SEEK_SET);
|
||||
fread(fd, (uint8_t *)&n_shdr, sizeof(Elf64_Shdr));
|
||||
lseek(fd, n_shdr.sh_offset + shdr.sh_name, SEEK_SET);
|
||||
fread(fd, (uint8_t *)sectionName, 32);
|
||||
debug("shdr: %s", sectionName);
|
||||
|
||||
if (strcmp(sectionName, ".rela.plt") == 0)
|
||||
{
|
||||
// .rela.plt
|
||||
// R_X86_64_JUMP_SLOT
|
||||
Elf64_Xword numEntries = shdr.sh_size / shdr.sh_entsize;
|
||||
for (Elf64_Xword i = 0; i < numEntries; i++)
|
||||
{
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)(shdr.sh_addr +
|
||||
BaseAddress +
|
||||
i * sizeof(Elf64_Addr));
|
||||
Elf64_Rela *Rel = _JmpRel + i;
|
||||
Elf64_Xword RelType = ELF64_R_TYPE(Rel->r_info);
|
||||
|
||||
switch (RelType)
|
||||
{
|
||||
case R_X86_64_JUMP_SLOT:
|
||||
{
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(Rel->r_info);
|
||||
Elf64_Sym *Sym = _SymTab + SymIndex;
|
||||
|
||||
if (Sym->st_name)
|
||||
{
|
||||
char *SymName = _DynStr + Sym->st_name;
|
||||
debug("SymName: %s", SymName);
|
||||
|
||||
Elf64_Sym LibSym = ELFLookupSymbol(fd, SymName);
|
||||
if (LibSym.st_value)
|
||||
{
|
||||
*GOTEntry = (Elf64_Addr)(BaseAddress + LibSym.st_value);
|
||||
debug("GOT[%ld](%#lx): %#lx",
|
||||
i, uintptr_t(GOTEntry) - BaseAddress,
|
||||
*GOTEntry);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("Unhandled relocation type: %#lx", RelType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(sectionName, ".rela.dyn") == 0)
|
||||
{
|
||||
// .rela.dyn
|
||||
// R_X86_64_RELATIVE
|
||||
// R_X86_64_GLOB_DAT
|
||||
if (RelaDynSize_v < 1 || RelaDynSize[0].d_un.d_val < 1)
|
||||
continue;
|
||||
Elf64_Xword numRelaDynEntries = RelaDynSize[0].d_un.d_val / sizeof(Elf64_Rela);
|
||||
for (Elf64_Xword i = 0; i < numRelaDynEntries; i++)
|
||||
{
|
||||
Elf64_Rela *Rel = _RelaDyn + i;
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset + BaseAddress);
|
||||
Elf64_Xword RelType = ELF64_R_TYPE(Rel->r_info);
|
||||
|
||||
switch (RelType)
|
||||
{
|
||||
case R_X86_64_RELATIVE:
|
||||
{
|
||||
*GOTEntry = (Elf64_Addr)(BaseAddress + Rel->r_addend);
|
||||
debug("GOT[%ld](%#lx): %#lx (R_X86_64_RELATIVE)",
|
||||
i, uintptr_t(GOTEntry) - BaseAddress,
|
||||
*GOTEntry);
|
||||
break;
|
||||
}
|
||||
case R_X86_64_GLOB_DAT:
|
||||
{
|
||||
Elf64_Xword SymIndex = ELF64_R_SYM(Rel->r_info);
|
||||
Elf64_Sym *Sym = _SymTab + SymIndex;
|
||||
|
||||
if (Sym->st_name)
|
||||
{
|
||||
char *SymName = _DynStr + Sym->st_name;
|
||||
debug("SymName: %s", SymName);
|
||||
|
||||
Elf64_Sym LibSym = ELFLookupSymbol(fd, SymName);
|
||||
if (LibSym.st_value)
|
||||
{
|
||||
*GOTEntry = (Elf64_Addr)(BaseAddress + LibSym.st_value);
|
||||
debug("GOT[%ld](%#lx): %#lx (R_X86_64_GLOB_DAT)",
|
||||
i, uintptr_t(GOTEntry) - BaseAddress,
|
||||
*GOTEntry);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("Unhandled relocation type: %#lx", RelType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(sectionName, ".dynsym") == 0)
|
||||
{
|
||||
// .dynsym
|
||||
// STT_OBJECT
|
||||
|
||||
Elf64_Sym *SymArray = (Elf64_Sym *)(shdr.sh_addr + BaseAddress);
|
||||
Elf64_Xword numEntries = shdr.sh_size / shdr.sh_entsize;
|
||||
debug("start %#lx (off %#lx), entries %ld",
|
||||
SymArray, shdr.sh_addr, numEntries);
|
||||
for (Elf64_Xword j = 0; j < numEntries; j++)
|
||||
{
|
||||
Elf64_Sym Sym = SymArray[j];
|
||||
|
||||
if (Sym.st_shndx == SHN_UNDEF)
|
||||
continue;
|
||||
|
||||
if (Sym.st_value == 0)
|
||||
continue;
|
||||
|
||||
unsigned char SymType = ELF64_ST_TYPE(Sym.st_info);
|
||||
|
||||
if (SymType == STT_OBJECT)
|
||||
{
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Sym.st_value + BaseAddress);
|
||||
*GOTEntry = (Elf64_Addr)(BaseAddress + Sym.st_value);
|
||||
|
||||
debug("%ld: \"%s\" %#lx -> %#lx", j,
|
||||
_DynStr + Sym.st_name,
|
||||
uintptr_t(GOTEntry) - BaseAddress,
|
||||
*GOTEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(sectionName, ".symtab") == 0)
|
||||
{
|
||||
// .symtab
|
||||
// STT_OBJECT
|
||||
|
||||
Elf64_Xword numEntries = shdr.sh_size / shdr.sh_entsize;
|
||||
Elf64_Sym *SymArray = new Elf64_Sym[numEntries];
|
||||
lseek(fd, shdr.sh_offset, SEEK_SET);
|
||||
fread(fd, (uint8_t *)SymArray, shdr.sh_size);
|
||||
|
||||
debug("start %#lx (off %#lx), entries %ld",
|
||||
SymArray, shdr.sh_addr, numEntries);
|
||||
for (Elf64_Xword j = 0; j < numEntries; j++)
|
||||
{
|
||||
Elf64_Sym Sym = SymArray[j];
|
||||
|
||||
if (Sym.st_shndx == SHN_UNDEF)
|
||||
continue;
|
||||
|
||||
if (Sym.st_value == 0)
|
||||
continue;
|
||||
|
||||
unsigned char SymType = ELF64_ST_TYPE(Sym.st_info);
|
||||
|
||||
if (SymType == STT_OBJECT)
|
||||
{
|
||||
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Sym.st_value + BaseAddress);
|
||||
*GOTEntry = (Elf64_Addr)(BaseAddress + Sym.st_value);
|
||||
|
||||
debug("%ld: \"<fixme>\" %#lx -> %#lx", j,
|
||||
/*_DynStr + Sym.st_name,*/
|
||||
uintptr_t(GOTEntry) - BaseAddress,
|
||||
*GOTEntry);
|
||||
}
|
||||
}
|
||||
delete[] SymArray;
|
||||
}
|
||||
|
||||
// if (shdr.sh_type == SHT_PROGBITS &&
|
||||
// (shdr.sh_flags & SHF_WRITE) &&
|
||||
// (shdr.sh_flags & SHF_ALLOC))
|
||||
}
|
||||
}
|
||||
// std::vector<Elf64_Dyn> JmpRel = ELFGetDynamicTag_x86_64(fd, DT_JMPREL);
|
||||
// std::vector<Elf64_Dyn> SymTab = ELFGetDynamicTag_x86_64(fd, DT_SYMTAB);
|
||||
// std::vector<Elf64_Dyn> StrTab = ELFGetDynamicTag_x86_64(fd, DT_STRTAB);
|
||||
// std::vector<Elf64_Dyn> RelaDyn = ELFGetDynamicTag_x86_64(fd, DT_RELA);
|
||||
// std::vector<Elf64_Dyn> RelaDynSize = ELFGetDynamicTag_x86_64(fd, DT_RELASZ);
|
||||
// size_t JmpRelSize = JmpRel.size();
|
||||
// size_t SymTabSize = SymTab.size();
|
||||
// size_t StrTabSize = StrTab.size();
|
||||
// size_t RelaDynSize_v = RelaDyn.size();
|
||||
// if (JmpRelSize < 1)
|
||||
// {
|
||||
// debug("No DT_JMPREL");
|
||||
// }
|
||||
// if (SymTabSize < 1)
|
||||
// {
|
||||
// debug("No DT_SYMTAB");
|
||||
// }
|
||||
// if (StrTabSize < 1)
|
||||
// {
|
||||
// debug("No DT_STRTAB");
|
||||
// }
|
||||
// if (RelaDynSize_v < 1)
|
||||
// {
|
||||
// debug("No DT_RELA");
|
||||
// }
|
||||
// if (RelaDynSize[0].d_un.d_val < 1)
|
||||
// {
|
||||
// debug("DT_RELASZ is < 1");
|
||||
// }
|
||||
// if (JmpRelSize > 0 && SymTabSize > 0 && StrTabSize > 0)
|
||||
// {
|
||||
// debug("JmpRel: %#lx, SymTab: %#lx, StrTab: %#lx",
|
||||
// JmpRel[0].d_un.d_ptr, SymTab[0].d_un.d_ptr,
|
||||
// StrTab[0].d_un.d_ptr);
|
||||
// Elf64_Rela *_JmpRel = (Elf64_Rela *)((uintptr_t)BaseAddress + JmpRel[0].d_un.d_ptr);
|
||||
// Elf64_Sym *_SymTab = (Elf64_Sym *)((uintptr_t)BaseAddress + SymTab[0].d_un.d_ptr);
|
||||
// char *_DynStr = (char *)((uintptr_t)BaseAddress + StrTab[0].d_un.d_ptr);
|
||||
// Elf64_Rela *_RelaDyn = (Elf64_Rela *)((uintptr_t)BaseAddress + RelaDyn[0].d_un.d_ptr);
|
||||
// Elf64_Shdr shdr;
|
||||
// for (Elf64_Half i = 0; i < ELFHeader.e_shnum; i++)
|
||||
// {
|
||||
// lseek(fd, ELFHeader.e_shoff + i * sizeof(Elf64_Shdr), SEEK_SET);
|
||||
// fread(fd, (uint8_t *)&shdr, sizeof(Elf64_Shdr));
|
||||
// char sectionName[32];
|
||||
// Elf64_Shdr n_shdr;
|
||||
// lseek(fd, ELFHeader.e_shoff + ELFHeader.e_shstrndx * sizeof(Elf64_Shdr), SEEK_SET);
|
||||
// fread(fd, (uint8_t *)&n_shdr, sizeof(Elf64_Shdr));
|
||||
// lseek(fd, n_shdr.sh_offset + shdr.sh_name, SEEK_SET);
|
||||
// fread(fd, (uint8_t *)sectionName, 32);
|
||||
// debug("shdr: %s", sectionName);
|
||||
// if (strcmp(sectionName, ".rela.plt") == 0)
|
||||
// {
|
||||
// // .rela.plt
|
||||
// // R_X86_64_JUMP_SLOT
|
||||
// Elf64_Xword numEntries = shdr.sh_size / shdr.sh_entsize;
|
||||
// for (Elf64_Xword i = 0; i < numEntries; i++)
|
||||
// {
|
||||
// Elf64_Addr *GOTEntry = (Elf64_Addr *)(shdr.sh_addr +
|
||||
// BaseAddress +
|
||||
// i * sizeof(Elf64_Addr));
|
||||
// Elf64_Rela *Rel = _JmpRel + i;
|
||||
// Elf64_Xword RelType = ELF64_R_TYPE(Rel->r_info);
|
||||
// switch (RelType)
|
||||
// {
|
||||
// case R_X86_64_JUMP_SLOT:
|
||||
// {
|
||||
// Elf64_Xword SymIndex = ELF64_R_SYM(Rel->r_info);
|
||||
// Elf64_Sym *Sym = _SymTab + SymIndex;
|
||||
// if (Sym->st_name)
|
||||
// {
|
||||
// char *SymName = _DynStr + Sym->st_name;
|
||||
// debug("SymName: %s", SymName);
|
||||
// Elf64_Sym LibSym = ELFLookupSymbol(fd, SymName);
|
||||
// if (LibSym.st_value)
|
||||
// {
|
||||
// *GOTEntry = (Elf64_Addr)(BaseAddress + LibSym.st_value);
|
||||
// debug("GOT[%ld](%#lx): %#lx",
|
||||
// i, uintptr_t(GOTEntry) - BaseAddress,
|
||||
// *GOTEntry);
|
||||
// }
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
// default:
|
||||
// {
|
||||
// fixme("Unhandled relocation type: %#lx", RelType);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (strcmp(sectionName, ".rela.dyn") == 0)
|
||||
// {
|
||||
// // .rela.dyn
|
||||
// // R_X86_64_RELATIVE
|
||||
// // R_X86_64_GLOB_DAT
|
||||
// if (RelaDynSize_v < 1 || RelaDynSize[0].d_un.d_val < 1)
|
||||
// continue;
|
||||
// Elf64_Xword numRelaDynEntries = RelaDynSize[0].d_un.d_val / sizeof(Elf64_Rela);
|
||||
// for (Elf64_Xword i = 0; i < numRelaDynEntries; i++)
|
||||
// {
|
||||
// Elf64_Rela *Rel = _RelaDyn + i;
|
||||
// Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset + BaseAddress);
|
||||
// Elf64_Xword RelType = ELF64_R_TYPE(Rel->r_info);
|
||||
// switch (RelType)
|
||||
// {
|
||||
// case R_X86_64_RELATIVE:
|
||||
// {
|
||||
// *GOTEntry = (Elf64_Addr)(BaseAddress + Rel->r_addend);
|
||||
// debug("GOT[%ld](%#lx): %#lx (R_X86_64_RELATIVE)",
|
||||
// i, uintptr_t(GOTEntry) - BaseAddress,
|
||||
// *GOTEntry);
|
||||
// break;
|
||||
// }
|
||||
// case R_X86_64_GLOB_DAT:
|
||||
// {
|
||||
// Elf64_Xword SymIndex = ELF64_R_SYM(Rel->r_info);
|
||||
// Elf64_Sym *Sym = _SymTab + SymIndex;
|
||||
// if (Sym->st_name)
|
||||
// {
|
||||
// char *SymName = _DynStr + Sym->st_name;
|
||||
// debug("SymName: %s", SymName);
|
||||
// Elf64_Sym LibSym = ELFLookupSymbol(fd, SymName);
|
||||
// if (LibSym.st_value)
|
||||
// {
|
||||
// *GOTEntry = (Elf64_Addr)(BaseAddress + LibSym.st_value);
|
||||
// debug("GOT[%ld](%#lx): %#lx (R_X86_64_GLOB_DAT)",
|
||||
// i, uintptr_t(GOTEntry) - BaseAddress,
|
||||
// *GOTEntry);
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// {
|
||||
// fixme("Unhandled relocation type: %#lx", RelType);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (strcmp(sectionName, ".dynsym") == 0)
|
||||
// {
|
||||
// // .dynsym
|
||||
// // STT_OBJECT
|
||||
// Elf64_Sym *SymArray = (Elf64_Sym *)(shdr.sh_addr + BaseAddress);
|
||||
// Elf64_Xword numEntries = shdr.sh_size / shdr.sh_entsize;
|
||||
// debug("start %#lx (off %#lx), entries %ld",
|
||||
// SymArray, shdr.sh_addr, numEntries);
|
||||
// for (Elf64_Xword j = 0; j < numEntries; j++)
|
||||
// {
|
||||
// Elf64_Sym Sym = SymArray[j];
|
||||
// if (Sym.st_shndx == SHN_UNDEF)
|
||||
// continue;
|
||||
// if (Sym.st_value == 0)
|
||||
// continue;
|
||||
// unsigned char SymType = ELF64_ST_TYPE(Sym.st_info);
|
||||
// if (SymType == STT_OBJECT)
|
||||
// {
|
||||
// Elf64_Addr *GOTEntry = (Elf64_Addr *)(Sym.st_value + BaseAddress);
|
||||
// *GOTEntry = (Elf64_Addr)(BaseAddress + Sym.st_value);
|
||||
// debug("%ld: \"%s\" %#lx -> %#lx", j,
|
||||
// _DynStr + Sym.st_name,
|
||||
// uintptr_t(GOTEntry) - BaseAddress,
|
||||
// *GOTEntry);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (strcmp(sectionName, ".symtab") == 0)
|
||||
// {
|
||||
// // .symtab
|
||||
// // STT_OBJECT
|
||||
// Elf64_Xword numEntries = shdr.sh_size / shdr.sh_entsize;
|
||||
// Elf64_Sym *SymArray = new Elf64_Sym[numEntries];
|
||||
// lseek(fd, shdr.sh_offset, SEEK_SET);
|
||||
// fread(fd, (uint8_t *)SymArray, shdr.sh_size);
|
||||
// debug("start %#lx (off %#lx), entries %ld",
|
||||
// SymArray, shdr.sh_addr, numEntries);
|
||||
// for (Elf64_Xword j = 0; j < numEntries; j++)
|
||||
// {
|
||||
// Elf64_Sym Sym = SymArray[j];
|
||||
// if (Sym.st_shndx == SHN_UNDEF)
|
||||
// continue;
|
||||
// if (Sym.st_value == 0)
|
||||
// continue;
|
||||
// unsigned char SymType = ELF64_ST_TYPE(Sym.st_info);
|
||||
// if (SymType == STT_OBJECT)
|
||||
// {
|
||||
// Elf64_Addr *GOTEntry = (Elf64_Addr *)(Sym.st_value + BaseAddress);
|
||||
// *GOTEntry = (Elf64_Addr)(BaseAddress + Sym.st_value);
|
||||
// debug("%ld: \"<fixme>\" %#lx -> %#lx", j,
|
||||
// /*_DynStr + Sym.st_name,*/
|
||||
// uintptr_t(GOTEntry) - BaseAddress,
|
||||
// *GOTEntry);
|
||||
// }
|
||||
// }
|
||||
// delete[] SymArray;
|
||||
// }
|
||||
// // if (shdr.sh_type == SHT_PROGBITS &&
|
||||
// // (shdr.sh_flags & SHF_WRITE) &&
|
||||
// // (shdr.sh_flags & SHF_ALLOC))
|
||||
// }
|
||||
// }
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
@ -661,6 +747,11 @@ namespace Execute
|
||||
fread(fd, sh, statbuf.st_size);
|
||||
TargetProcess->ELFSymbolTable->AppendSymbols(uintptr_t(sh.Get()), BaseAddress);
|
||||
|
||||
if (!TargetProcess->ELFSymbolTable->SymTableExists)
|
||||
{
|
||||
debug("NO SYMBOL TABLE FOUND?");
|
||||
}
|
||||
|
||||
debug("Entry Point: %#lx", EntryPoint);
|
||||
|
||||
this->GenerateAuxiliaryVector_x86_64(vma, fd, ELFHeader,
|
||||
@ -759,6 +850,7 @@ namespace Execute
|
||||
error("Failed to open %s, errno: %d", AbsolutePath, fd);
|
||||
return;
|
||||
}
|
||||
debug("Opened %s", AbsolutePath);
|
||||
|
||||
int argc = 0;
|
||||
int envc = 0;
|
||||
@ -769,23 +861,23 @@ namespace Execute
|
||||
envc++;
|
||||
|
||||
// ELFargv = new const char *[argc + 2];
|
||||
size_t argv_size = TO_PAGES(argc + 2 * sizeof(char *));
|
||||
ELFargv = (const char **)TargetProcess->vma->RequestPages(argv_size);
|
||||
size_t argv_size = argc + 2 * sizeof(char *);
|
||||
ELFargv = (const char **)TargetProcess->vma->RequestPages(TO_PAGES(argv_size));
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
size_t arg_size = TO_PAGES(strlen(argv[i]) + 1);
|
||||
ELFargv[i] = (const char *)TargetProcess->vma->RequestPages(arg_size);
|
||||
size_t arg_size = strlen(argv[i]) + 1;
|
||||
ELFargv[i] = (const char *)TargetProcess->vma->RequestPages(TO_PAGES(arg_size));
|
||||
strcpy((char *)ELFargv[i], argv[i]);
|
||||
}
|
||||
ELFargv[argc] = nullptr;
|
||||
|
||||
// ELFenvp = new const char *[envc + 1];
|
||||
size_t envp_size = TO_PAGES(envc + 1 * sizeof(char *));
|
||||
ELFenvp = (const char **)TargetProcess->vma->RequestPages(envp_size);
|
||||
size_t envp_size = envc + 1 * sizeof(char *);
|
||||
ELFenvp = (const char **)TargetProcess->vma->RequestPages(TO_PAGES(envp_size));
|
||||
for (int i = 0; i < envc; i++)
|
||||
{
|
||||
size_t env_size = TO_PAGES(strlen(envp[i]) + 1);
|
||||
ELFenvp[i] = (const char *)TargetProcess->vma->RequestPages(env_size);
|
||||
size_t env_size = strlen(envp[i]) + 1;
|
||||
ELFenvp[i] = (const char *)TargetProcess->vma->RequestPages(TO_PAGES(env_size));
|
||||
strcpy((char *)ELFenvp[i], envp[i]);
|
||||
}
|
||||
ELFenvp[envc] = nullptr;
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <msexec.h>
|
||||
|
||||
#include "../../kernel.h"
|
||||
#include "../../Fex.hpp"
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
|
@ -20,83 +20,82 @@
|
||||
#include <msexec.h>
|
||||
|
||||
#include "../../kernel.h"
|
||||
#include "../../Fex.hpp"
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
/* Originally from https://wiki.osdev.org/ELF_Tutorial */
|
||||
/* Originally from https://wiki.osdev.org/ELF_Tutorial */
|
||||
|
||||
void ELFLoadRel(void *BaseImage,
|
||||
const char *Name,
|
||||
Tasking::PCB *Process)
|
||||
{
|
||||
void ELFLoadRel(void *BaseImage,
|
||||
const char *Name,
|
||||
Tasking::PCB *Process)
|
||||
{
|
||||
#if defined(a64)
|
||||
UNUSED(Name);
|
||||
debug("Relocatable");
|
||||
/* TODO: I have to fully implement this, but for now I will leave it as it is now. */
|
||||
warn("Relocatable ELF is not fully supported yet");
|
||||
Elf64_Shdr *shdr = GetELFSheader(((Elf64_Ehdr *)BaseImage));
|
||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)BaseImage)->e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr *Section = &shdr[i];
|
||||
if (Section->sh_type == SHT_NOBITS)
|
||||
{
|
||||
if (!Section->sh_size)
|
||||
continue;
|
||||
if (Section->sh_flags & SHF_ALLOC)
|
||||
{
|
||||
void *Buffer = KernelAllocator.RequestPages(TO_PAGES(Section->sh_size + 1));
|
||||
memset(Buffer, 0, Section->sh_size);
|
||||
UNUSED(Name);
|
||||
debug("Relocatable");
|
||||
/* TODO: I have to fully implement this, but for now I will leave it as it is now. */
|
||||
warn("Relocatable ELF is not fully supported yet");
|
||||
Elf64_Shdr *shdr = GetELFSheader(((Elf64_Ehdr *)BaseImage));
|
||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)BaseImage)->e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr *Section = &shdr[i];
|
||||
if (Section->sh_type == SHT_NOBITS)
|
||||
{
|
||||
if (!Section->sh_size)
|
||||
continue;
|
||||
if (Section->sh_flags & SHF_ALLOC)
|
||||
{
|
||||
void *Buffer = KernelAllocator.RequestPages(TO_PAGES(Section->sh_size + 1));
|
||||
memset(Buffer, 0, Section->sh_size);
|
||||
|
||||
Memory::Virtual(Process->PageTable).Map((void *)Buffer, (void *)Buffer, Section->sh_size, Memory::PTFlag::RW | Memory::PTFlag::US);
|
||||
Memory::Virtual(Process->PageTable).Map((void *)Buffer, (void *)Buffer, Section->sh_size, Memory::PTFlag::RW | Memory::PTFlag::US);
|
||||
|
||||
Section->sh_offset = (uintptr_t)Buffer - (uintptr_t)BaseImage;
|
||||
debug("Section %ld", Section->sh_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
Section->sh_offset = (uintptr_t)Buffer - (uintptr_t)BaseImage;
|
||||
debug("Section %ld", Section->sh_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)BaseImage)->e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr *Section = &shdr[i];
|
||||
if (Section->sh_type == SHT_REL)
|
||||
{
|
||||
for (size_t Index = 0; Index < Section->sh_size / Section->sh_entsize; Index++)
|
||||
{
|
||||
Elf64_Rel *RelTable = &((Elf64_Rel *)((uintptr_t)BaseImage + Section->sh_offset))[Index];
|
||||
Elf64_Shdr *Target = GetELFSection(((Elf64_Ehdr *)BaseImage), Section->sh_info);
|
||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)BaseImage)->e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr *Section = &shdr[i];
|
||||
if (Section->sh_type == SHT_REL)
|
||||
{
|
||||
for (size_t Index = 0; Index < Section->sh_size / Section->sh_entsize; Index++)
|
||||
{
|
||||
Elf64_Rel *RelTable = &((Elf64_Rel *)((uintptr_t)BaseImage + Section->sh_offset))[Index];
|
||||
Elf64_Shdr *Target = GetELFSection(((Elf64_Ehdr *)BaseImage), Section->sh_info);
|
||||
|
||||
uintptr_t *RelAddress = (uintptr_t *)(((uintptr_t)BaseImage + Target->sh_offset) + RelTable->r_offset);
|
||||
uint64_t SymbolValue = 0;
|
||||
uintptr_t *RelAddress = (uintptr_t *)(((uintptr_t)BaseImage + Target->sh_offset) + RelTable->r_offset);
|
||||
uint64_t SymbolValue = 0;
|
||||
|
||||
if (ELF64_R_SYM(RelTable->r_info) != SHN_UNDEF)
|
||||
{
|
||||
SymbolValue = ELFGetSymbolValue(((Elf64_Ehdr *)BaseImage), Section->sh_link, ELF64_R_SYM(RelTable->r_info));
|
||||
if (SymbolValue == 0xdead)
|
||||
return;
|
||||
}
|
||||
if (ELF64_R_SYM(RelTable->r_info) != SHN_UNDEF)
|
||||
{
|
||||
SymbolValue = ELFGetSymbolValue(((Elf64_Ehdr *)BaseImage), Section->sh_link, ELF64_R_SYM(RelTable->r_info));
|
||||
if (SymbolValue == 0xdead)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ELF64_R_TYPE(RelTable->r_info))
|
||||
{
|
||||
case R_386_NONE:
|
||||
break;
|
||||
case R_386_32:
|
||||
*RelAddress = DO_64_64(SymbolValue, *RelAddress);
|
||||
break;
|
||||
case R_386_PC32:
|
||||
*RelAddress = DO_64_PC32(SymbolValue, *RelAddress, (uintptr_t)RelAddress);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
error("Unsupported relocation type: %d", ELF64_R_TYPE(RelTable->r_info));
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug("Symbol value: %#lx", SymbolValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (ELF64_R_TYPE(RelTable->r_info))
|
||||
{
|
||||
case R_386_NONE:
|
||||
break;
|
||||
case R_386_32:
|
||||
*RelAddress = DO_64_64(SymbolValue, *RelAddress);
|
||||
break;
|
||||
case R_386_PC32:
|
||||
*RelAddress = DO_64_PC32(SymbolValue, *RelAddress, (uintptr_t)RelAddress);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
error("Unsupported relocation type: %d", ELF64_R_TYPE(RelTable->r_info));
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug("Symbol value: %#lx", SymbolValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(a32)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
100
exec/spawn.cpp
100
exec/spawn.cpp
@ -25,14 +25,13 @@
|
||||
#include <abi.h>
|
||||
|
||||
#include "../kernel.h"
|
||||
#include "../Fex.hpp"
|
||||
|
||||
using namespace Tasking;
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
int Spawn(char *Path, const char **argv, const char **envp,
|
||||
Tasking::PCB *Parent,
|
||||
Tasking::PCB *Parent, bool Fork,
|
||||
Tasking::TaskCompatibility Compatibility,
|
||||
bool Critical)
|
||||
{
|
||||
@ -50,19 +49,6 @@ namespace Execute
|
||||
|
||||
switch (GetBinaryType(Path))
|
||||
{
|
||||
case BinaryType::BinTypeFex:
|
||||
{
|
||||
Fex FexHdr;
|
||||
fread(fd, (uint8_t *)&FexHdr, sizeof(Fex));
|
||||
if (FexHdr.Type == FexFormatType::FexFormatType_Executable)
|
||||
{
|
||||
stub;
|
||||
assert(false);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
case BinaryType::BinTypeELF:
|
||||
{
|
||||
TaskArchitecture Arch = TaskArchitecture::UnknownArchitecture;
|
||||
@ -118,20 +104,44 @@ namespace Execute
|
||||
debug("Loaded elf %s at %#lx with the length of %ld",
|
||||
Path, ElfFile, statbuf.st_size);
|
||||
|
||||
if (Parent == nullptr)
|
||||
Parent = thisProcess;
|
||||
PCB *Process;
|
||||
if (Fork)
|
||||
{
|
||||
assert(Parent != nullptr);
|
||||
CriticalSection cs;
|
||||
|
||||
PCB *Process = TaskManager->CreateProcess(Parent,
|
||||
BaseName,
|
||||
TaskExecutionMode::User,
|
||||
ElfFile, false,
|
||||
0, 0);
|
||||
Process = Parent;
|
||||
foreach (auto tcb in Process->Threads)
|
||||
{
|
||||
debug("Deleting thread %d", tcb->ID);
|
||||
// delete tcb;
|
||||
tcb->SetState(Tasking::Terminated);
|
||||
}
|
||||
|
||||
KernelAllocator.FreePages(ElfFile, TO_PAGES(statbuf.st_size + 1));
|
||||
fixme("free allocated memory");
|
||||
fixme("change symbol table");
|
||||
// Process->vma->FreeAllPages();
|
||||
delete Process->ELFSymbolTable;
|
||||
Process->ELFSymbolTable = new SymbolResolver::Symbols((uintptr_t)ElfFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Parent == nullptr)
|
||||
Parent = thisProcess;
|
||||
|
||||
Process = TaskManager->CreateProcess(Parent,
|
||||
BaseName,
|
||||
TaskExecutionMode::User,
|
||||
ElfFile, false,
|
||||
0, 0);
|
||||
Process->Info.Compatibility = Compatibility;
|
||||
Process->Info.Architecture = Arch;
|
||||
}
|
||||
|
||||
Process->SetWorkingDirectory(fs->GetNodeFromPath(Path)->Parent);
|
||||
Process->Info.Compatibility = TaskCompatibility::Native;
|
||||
Process->Info.Architecture = TaskArchitecture::x64;
|
||||
Process->SetExe(Path);
|
||||
|
||||
KernelAllocator.FreePages(ElfFile, TO_PAGES(statbuf.st_size + 1));
|
||||
|
||||
ELFObject *obj = new ELFObject(Path, Process, argv, envp);
|
||||
if (!obj->IsValid)
|
||||
@ -142,14 +152,40 @@ namespace Execute
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
/* FIXME: implement stdio fildes */
|
||||
vfs::FileDescriptorTable *pfdt = Parent->FileDescriptors;
|
||||
vfs::FileDescriptorTable *fdt = Process->FileDescriptors;
|
||||
// stdin
|
||||
fdt->_open("/dev/tty", O_RDWR, 0666);
|
||||
// stdout
|
||||
fdt->_open("/dev/tty", O_RDWR, 0666);
|
||||
// stderr
|
||||
fdt->_open("/dev/tty", O_RDWR, 0666);
|
||||
|
||||
auto ForkStdio = [pfdt, fdt](Node *SearchNode)
|
||||
{
|
||||
if (unlikely(SearchNode == nullptr))
|
||||
return false;
|
||||
|
||||
std::vector<FileDescriptorTable::Fildes>
|
||||
pfds = pfdt->GetFileDescriptors();
|
||||
|
||||
foreach (auto ffd in pfds)
|
||||
{
|
||||
if (ffd.Flags & O_CLOEXEC)
|
||||
continue;
|
||||
|
||||
if (ffd.Handle->node == SearchNode)
|
||||
{
|
||||
fdt->_open(ffd.Handle->node->FullPath,
|
||||
ffd.Flags, ffd.Mode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (!ForkStdio(Parent->stdin))
|
||||
fdt->_open("/dev/kcon", O_RDWR, 0666);
|
||||
|
||||
if (!ForkStdio(Parent->stdout))
|
||||
fdt->_open("/dev/kcon", O_RDWR, 0666);
|
||||
|
||||
if (!ForkStdio(Parent->stderr))
|
||||
fdt->_open("/dev/kcon", O_RDWR, 0666);
|
||||
|
||||
TCB *Thread = nullptr;
|
||||
{
|
||||
|
Reference in New Issue
Block a user