mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-07-09 22:39:24 +00:00
Updated kernel (tl;dr: improved filesystem, tasking, loading files, etc..)
This commit is contained in:
@ -26,7 +26,7 @@ namespace Execute
|
||||
void StartExecuteService()
|
||||
{
|
||||
mem = new Memory::MemMgr;
|
||||
return;
|
||||
// return;
|
||||
|
||||
while (true)
|
||||
{
|
||||
@ -53,7 +53,7 @@ namespace Execute
|
||||
}
|
||||
}
|
||||
|
||||
SharedLibraries *AddLibrary(char *Identifier, void *LibraryImage, size_t Length)
|
||||
SharedLibraries *AddLibrary(char *Identifier, void *ElfImage, size_t Length, const Memory::Virtual &pV)
|
||||
{
|
||||
SmartLock(ExecuteServiceLock);
|
||||
SharedLibraries sl;
|
||||
@ -62,12 +62,47 @@ namespace Execute
|
||||
sl.Timeout = TimeManager->CalculateTarget(600000); /* 10 minutes */
|
||||
sl.RefCount = 0;
|
||||
|
||||
void *BaseLibImage = mem->RequestPages(TO_PAGES(Length));
|
||||
memcpy(BaseLibImage, (void *)LibraryImage, Length);
|
||||
sl.Address = BaseLibImage;
|
||||
void *LibFile = mem->RequestPages(TO_PAGES(Length), true);
|
||||
memcpy(LibFile, (void *)ElfImage, Length);
|
||||
|
||||
Memory::Virtual ncpV = pV;
|
||||
sl.MemoryImage = ELFCreateMemoryImage(mem, ncpV, LibFile, Length);
|
||||
|
||||
{
|
||||
uintptr_t BaseAddress = UINTPTR_MAX;
|
||||
Elf64_Phdr ItrProgramHeader;
|
||||
|
||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)LibFile)->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrProgramHeader, (uint8_t *)LibFile + ((Elf64_Ehdr *)LibFile)->e_phoff + ((Elf64_Ehdr *)LibFile)->e_phentsize * i, sizeof(Elf64_Phdr));
|
||||
BaseAddress = MIN(BaseAddress, ItrProgramHeader.p_vaddr);
|
||||
}
|
||||
|
||||
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)LibFile)->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrProgramHeader, (uint8_t *)LibFile + ((Elf64_Ehdr *)LibFile)->e_phoff + ((Elf64_Ehdr *)LibFile)->e_phentsize * i, sizeof(Elf64_Phdr));
|
||||
if (ItrProgramHeader.p_type != PT_LOAD)
|
||||
continue;
|
||||
|
||||
debug("PT_LOAD - Offset: %#lx, VirtAddr: %#lx, FileSiz: %ld, MemSiz: %ld, Align: %#lx",
|
||||
ItrProgramHeader.p_offset, ItrProgramHeader.p_vaddr,
|
||||
ItrProgramHeader.p_filesz, ItrProgramHeader.p_memsz, ItrProgramHeader.p_align);
|
||||
uintptr_t MAddr = (ItrProgramHeader.p_vaddr - BaseAddress) + (uintptr_t)sl.MemoryImage;
|
||||
fixme("Address: %#lx %s%s%s", MAddr,
|
||||
(ItrProgramHeader.p_flags & PF_R) ? "R" : "",
|
||||
(ItrProgramHeader.p_flags & PF_W) ? "W" : "",
|
||||
(ItrProgramHeader.p_flags & PF_X) ? "X" : "");
|
||||
|
||||
memcpy((void *)MAddr, (uint8_t *)LibFile + ItrProgramHeader.p_offset, ItrProgramHeader.p_filesz);
|
||||
debug("memcpy: %#lx => %#lx (%ld bytes)", (uint8_t *)LibFile + ItrProgramHeader.p_offset, (uintptr_t)MAddr, ItrProgramHeader.p_filesz);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sl.Address = LibFile;
|
||||
sl.Length = Length;
|
||||
|
||||
debug("Library %s loaded at %#lx", Identifier, BaseLibImage);
|
||||
debug("Library %s loaded at %#lx (full file: %#lx)", Identifier, sl.MemoryImage, LibFile);
|
||||
|
||||
Libs.push_back(sl);
|
||||
return &Libs[Libs.size() - 1];
|
||||
@ -77,262 +112,4 @@ namespace Execute
|
||||
{
|
||||
SmartLock(ExecuteServiceLock);
|
||||
}
|
||||
|
||||
void AttachLibrary(SharedLibraries *Lib, void *BaseImage)
|
||||
{
|
||||
SmartLock(ExecuteServiceLock);
|
||||
|
||||
BinaryType Type = GetBinaryType(BaseImage);
|
||||
switch (Type)
|
||||
{
|
||||
case BinaryType::BinTypeFex:
|
||||
{
|
||||
fixme("Fex is not supported yet");
|
||||
return;
|
||||
}
|
||||
case BinaryType::BinTypeELF:
|
||||
{
|
||||
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)BaseImage;
|
||||
uintptr_t BaseAddress = UINTPTR_MAX;
|
||||
size_t ElfAppSize = 0;
|
||||
Elf64_Phdr ItrProgramHeader;
|
||||
|
||||
Elf64_Shdr *ElfSections = (Elf64_Shdr *)((uintptr_t)BaseImage + ELFHeader->e_shoff);
|
||||
Elf64_Shdr *Dynamic = nullptr;
|
||||
Elf64_Shdr *DynamicSymbol = nullptr;
|
||||
Elf64_Shdr *DynamicString = nullptr;
|
||||
Elf64_Shdr *SymbolTable = nullptr;
|
||||
Elf64_Shdr *StringTable = nullptr;
|
||||
Elf64_Shdr *RelaPlt = nullptr;
|
||||
Elf64_Shdr *GotPlt = nullptr;
|
||||
size_t SymbolCount = 0;
|
||||
|
||||
size_t GOTSize = 0;
|
||||
Elf64_Addr *GOTEntry = 0;
|
||||
|
||||
uintptr_t RelaOffset = 0;
|
||||
uint64_t RelaEnt = 0;
|
||||
size_t RelaSize = 0;
|
||||
|
||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrProgramHeader, (uint8_t *)BaseImage + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, sizeof(Elf64_Phdr));
|
||||
BaseAddress = MIN(BaseAddress, ItrProgramHeader.p_vaddr);
|
||||
}
|
||||
|
||||
for (Elf64_Half i = 0; i < ELFHeader->e_phnum; i++)
|
||||
{
|
||||
memcpy(&ItrProgramHeader, (uint8_t *)BaseImage + ELFHeader->e_phoff + ELFHeader->e_phentsize * i, sizeof(Elf64_Phdr));
|
||||
uintptr_t SegmentEnd;
|
||||
SegmentEnd = ItrProgramHeader.p_vaddr - BaseAddress + ItrProgramHeader.p_memsz;
|
||||
ElfAppSize = MAX(ElfAppSize, SegmentEnd);
|
||||
|
||||
for (Elf64_Half i = 0; i < ELFHeader->e_shnum; i++)
|
||||
{
|
||||
char *DynamicStringTable = (char *)((uintptr_t)BaseImage + ElfSections[ELFHeader->e_shstrndx].sh_offset + ElfSections[i].sh_name);
|
||||
|
||||
if (strcmp(DynamicStringTable, ".dynamic") == 0)
|
||||
{
|
||||
Dynamic = &ElfSections[i];
|
||||
}
|
||||
else if (strcmp(DynamicStringTable, ".dynsym") == 0)
|
||||
{
|
||||
DynamicSymbol = &ElfSections[i];
|
||||
}
|
||||
else if (strcmp(DynamicStringTable, ".dynstr") == 0)
|
||||
{
|
||||
DynamicString = &ElfSections[i];
|
||||
}
|
||||
else if (strcmp(DynamicStringTable, ".strtab") == 0)
|
||||
{
|
||||
StringTable = &ElfSections[i];
|
||||
}
|
||||
else if (strcmp(DynamicStringTable, ".rela.plt") == 0)
|
||||
{
|
||||
RelaPlt = &ElfSections[i];
|
||||
}
|
||||
else if (strcmp(DynamicStringTable, ".got.plt") == 0)
|
||||
{
|
||||
GotPlt = &ElfSections[i];
|
||||
}
|
||||
else if (strcmp(DynamicStringTable, ".symtab") == 0)
|
||||
{
|
||||
SymbolTable = &ElfSections[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (ItrProgramHeader.p_type == PT_DYNAMIC)
|
||||
{
|
||||
Elf64_Dyn *Dynamic = (Elf64_Dyn *)((uint8_t *)BaseImage + ItrProgramHeader.p_offset);
|
||||
|
||||
for (uint64_t i = 0; i < ItrProgramHeader.p_filesz / sizeof(Elf64_Dyn); i++)
|
||||
{
|
||||
switch (Dynamic[i].d_tag)
|
||||
{
|
||||
case DT_PLTRELSZ:
|
||||
{
|
||||
GOTSize = Dynamic[i].d_un.d_val;
|
||||
break;
|
||||
}
|
||||
case DT_PLTGOT:
|
||||
{
|
||||
GOTEntry = (Elf64_Addr *)Dynamic[i].d_un.d_ptr;
|
||||
break;
|
||||
}
|
||||
case DT_RELA:
|
||||
{
|
||||
RelaOffset = Dynamic[i].d_un.d_ptr;
|
||||
break;
|
||||
}
|
||||
case DT_RELASZ:
|
||||
{
|
||||
RelaSize = Dynamic[i].d_un.d_val;
|
||||
break;
|
||||
}
|
||||
case DT_RELAENT:
|
||||
{
|
||||
RelaEnt = Dynamic[i].d_un.d_val;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (Dynamic[i].d_tag == DT_NULL)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
debug("BaseAddress: %#lx Size: %ld", BaseAddress, ElfAppSize);
|
||||
|
||||
if (RelaOffset != 0)
|
||||
{
|
||||
if (RelaEnt != sizeof(Elf64_Rela))
|
||||
{
|
||||
error("RelaEnt != sizeof(Elf64_Rela)");
|
||||
/* I should exit here I guess... */
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t RelaOffsetItr = 0; RelaOffsetItr < RelaSize; RelaOffsetItr += RelaEnt)
|
||||
{
|
||||
Elf64_Rela *Rela = (Elf64_Rela *)(((char *)BaseImage) + RelaOffset + RelaOffsetItr);
|
||||
|
||||
switch (Rela->r_info)
|
||||
{
|
||||
case R_X86_64_RELATIVE:
|
||||
{
|
||||
uintptr_t *Ptr = (uintptr_t *)((uintptr_t)BaseImage + Rela->r_offset);
|
||||
*Ptr = (uintptr_t)Lib->Address + Rela->r_addend;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fixme("Rela: %ld", Rela->r_info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
debug("No Rela");
|
||||
|
||||
if (DynamicSymbol != nullptr)
|
||||
SymbolCount = DynamicSymbol->sh_size / sizeof(Elf64_Sym);
|
||||
else if (SymbolTable != nullptr)
|
||||
SymbolCount = SymbolTable->sh_size / sizeof(Elf64_Sym);
|
||||
|
||||
debug("GOT Address %#lx Size %#lx Entry %#lx",
|
||||
GOTEntry, GOTSize, GOTEntry ? GOTEntry : 0);
|
||||
|
||||
#ifdef DEBUG
|
||||
DumpData("Old GOT", (void *)GOTEntry, GOTSize);
|
||||
|
||||
if (DynamicSymbol && DynamicString)
|
||||
for (size_t i = 0; i < SymbolCount; i++)
|
||||
{
|
||||
Elf64_Sym *Symbol = (Elf64_Sym *)((uintptr_t)BaseImage + DynamicSymbol->sh_offset + i * sizeof(Elf64_Sym));
|
||||
char *SymbolName = (char *)((uintptr_t)BaseImage + DynamicString->sh_offset + Symbol->st_name);
|
||||
if (GOTEntry)
|
||||
if (GOTEntry[i])
|
||||
{
|
||||
uintptr_t SymbolAddress = GOTEntry[i];
|
||||
debug("New GOTEntry[%d] - Symbol %s Address %#lx", i, SymbolName, SymbolAddress);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < GOTSize; i++)
|
||||
if (GOTEntry)
|
||||
if (GOTEntry[i])
|
||||
debug("GOTEntry[%d] = %#lx", i, GOTEntry[i]);
|
||||
#endif
|
||||
|
||||
GOTEntry[1] = (uintptr_t)BaseImage;
|
||||
GOTEntry[2] = (uintptr_t)ElfLazyResolver;
|
||||
|
||||
if (DynamicSymbol && DynamicString && GOTEntry)
|
||||
for (size_t i = 0; i < SymbolCount; i++)
|
||||
{
|
||||
Elf64_Sym *Symbol = (Elf64_Sym *)((uintptr_t)BaseImage + DynamicSymbol->sh_offset + i * sizeof(Elf64_Sym));
|
||||
char *SymbolName = (char *)((uintptr_t)BaseImage + DynamicString->sh_offset + Symbol->st_name);
|
||||
|
||||
switch (ELF64_ST_TYPE(Symbol->st_info))
|
||||
{
|
||||
case STT_OBJECT:
|
||||
fixme("STT_OBJECT");
|
||||
case STT_FUNC:
|
||||
{
|
||||
uintptr_t SymbolAddress = (uintptr_t)ELFLookupSymbol((Elf64_Ehdr *)Lib->Address, SymbolName);
|
||||
if (SymbolAddress == 0)
|
||||
{
|
||||
error("Symbol %s not found", SymbolName);
|
||||
continue;
|
||||
}
|
||||
GOTEntry[i] = (uintptr_t)Lib->Address + SymbolAddress;
|
||||
debug("%d %#lx Symbol %s at %#lx (%#lx)", i, &GOTEntry[i], SymbolName, SymbolAddress, (uintptr_t)Lib->Address + SymbolAddress);
|
||||
break;
|
||||
}
|
||||
case STT_NOTYPE:
|
||||
break;
|
||||
default:
|
||||
error("Unsupported symbol type %d", ELF64_ST_TYPE(Symbol->st_info));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
DumpData("New GOT", (void *)GOTEntry, GOTSize);
|
||||
|
||||
if (DynamicSymbol && DynamicString)
|
||||
for (size_t i = 0; i < SymbolCount; i++)
|
||||
{
|
||||
Elf64_Sym *Symbol = (Elf64_Sym *)((uintptr_t)BaseImage + DynamicSymbol->sh_offset + i * sizeof(Elf64_Sym));
|
||||
char *SymbolName = (char *)((uintptr_t)BaseImage + DynamicString->sh_offset + Symbol->st_name);
|
||||
if (GOTEntry)
|
||||
if (GOTEntry[i])
|
||||
{
|
||||
uintptr_t SymbolAddress = GOTEntry[i];
|
||||
debug("New GOTEntry[%d] - Symbol %s Address %#lx", i, SymbolName, SymbolAddress);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < GOTSize; i++)
|
||||
if (GOTEntry)
|
||||
if (GOTEntry[i])
|
||||
debug("GOTEntry[%d] = %#lx", i, GOTEntry[i]);
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fixme("Unsupported binary type %d", Type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Lib->RefCount++;
|
||||
debug("Attached library %s", Lib->Identifier);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user