Fix elf loading

This commit is contained in:
Alex 2023-04-21 17:47:09 +03:00
parent 96a27f7bc8
commit f2eab6c64f
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
5 changed files with 119 additions and 24 deletions

View File

@ -32,9 +32,10 @@ namespace Memory
memset(AllocatedStack, 0, USER_STACK_SIZE);
debug("AllocatedStack: %p", AllocatedStack);
Virtual va = Virtual(Table);
for (size_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++)
{
Virtual(Table).Map((void *)(USER_STACK_BASE + (i * PAGE_SIZE)),
va.Map((void *)(USER_STACK_BASE + (i * PAGE_SIZE)),
(void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)),
PTFlag::RW | PTFlag::US);
@ -88,9 +89,10 @@ namespace Memory
void *AllocatedStack = KernelAllocator.RequestPages(TO_PAGES(USER_STACK_SIZE + 1));
debug("AllocatedStack: %p", AllocatedStack);
memset(AllocatedStack, 0, USER_STACK_SIZE);
Virtual va = Virtual(this->Table);
for (uintptr_t i = 0; i < TO_PAGES(USER_STACK_SIZE); i++)
{
Virtual(this->Table).Map((void *)((uintptr_t)this->StackBottom - (i * PAGE_SIZE)), (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)), PTFlag::RW | PTFlag::US);
va.Map((void *)((uintptr_t)this->StackBottom - (i * PAGE_SIZE)), (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)), PTFlag::RW | PTFlag::US);
debug("Mapped %p to %p", (void *)((uintptr_t)this->StackBottom - (i * PAGE_SIZE)), (void *)((uintptr_t)AllocatedStack + (i * PAGE_SIZE)));
}
this->StackBottom = (void *)((uintptr_t)this->StackBottom - USER_STACK_SIZE);

View File

@ -51,7 +51,7 @@ namespace Execute
return StringTable + Offset;
}
void *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name)
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name)
{
Elf64_Shdr *SymbolTable = nullptr;
Elf64_Shdr *StringTable = nullptr;
@ -82,7 +82,7 @@ namespace Execute
Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
if (strcmp(String, Name) == 0)
return (void *)Symbol->st_value;
return Symbol;
}
return nullptr;
}
@ -108,7 +108,7 @@ namespace Execute
Elf64_Shdr *StringTable = GetELFSection(Header, SymbolTable->sh_link);
const char *Name = (const char *)Header + StringTable->sh_offset + Symbol->st_name;
void *Target = ELFLookupSymbol(Header, Name);
void *Target = (void *)ELFLookupSymbol(Header, Name)->st_value;
if (Target == nullptr)
{
if (ELF64_ST_BIND(Symbol->st_info) & STB_WEAK)
@ -165,6 +165,8 @@ namespace Execute
{
void *MemoryImage = nullptr;
Elf64_Ehdr *ELFHeader = (Elf64_Ehdr *)ElfFile;
bool IsPIC = ELFHeader->e_type == ET_DYN;
debug("Elf %s PIC", IsPIC ? "is" : "is not");
/* TODO: Not sure what I am supposed to do with this.
* It is supposed to detect if it's PIC or not but I
@ -195,15 +197,17 @@ namespace Execute
if (ItrPhdr.p_type == PT_LOAD && ItrPhdr.p_vaddr == 0)
{
debug("p_vaddr is 0, allocating %ld pages for image", TO_PAGES(Length));
MemoryImage = mem->RequestPages(TO_PAGES(Length + 1), true);
debug("p_vaddr is 0, allocating %ld pages for image (size: %#lx)", TO_PAGES(Length), Length);
MemoryImage = mem->RequestPages(TO_PAGES(Length), true);
debug("MemoryImage: %#lx-%#lx", MemoryImage, (uintptr_t)MemoryImage + Length);
memset(MemoryImage, 0, Length);
return {MemoryImage, (void *)FirstProgramHeaderVirtualAddress};
}
}
debug("Allocating %ld pages for image", TO_PAGES(Length));
MemoryImage = mem->RequestPages(TO_PAGES(Length + 1));
debug("Allocating %ld pages for image (size: %#lx)", TO_PAGES(Length), Length);
MemoryImage = mem->RequestPages(TO_PAGES(Length));
debug("MemoryImage: %#lx-%#lx", MemoryImage, (uintptr_t)MemoryImage + Length);
memset(MemoryImage, 0, Length);
if (FirstProgramHeaderVirtualAddress != 0)

View File

@ -127,6 +127,95 @@ namespace Execute
debug("memcpy: %#lx => %#lx (%ld bytes)", (uint8_t *)LibFile + ItrProgramHeader.p_offset, (uintptr_t)MAddr, ItrProgramHeader.p_filesz);
break;
}
struct Elf64_Dyn *JmpRel = ELFGetDynamicTag((void *)LibFile, DT_JMPREL);
struct Elf64_Dyn *SymTab = ELFGetDynamicTag((void *)LibFile, DT_SYMTAB);
struct Elf64_Dyn *StrTab = ELFGetDynamicTag((void *)LibFile, DT_STRTAB);
if (!JmpRel)
{
debug("No DT_JMPREL");
}
if (!SymTab)
{
debug("No DT_SYMTAB");
}
if (!StrTab)
{
debug("No DT_STRTAB");
}
if (JmpRel && SymTab && StrTab)
{
debug("JmpRel: %#lx, SymTab: %#lx, StrTab: %#lx", JmpRel->d_un.d_ptr, SymTab->d_un.d_ptr, StrTab->d_un.d_ptr);
Elf64_Rela *_JmpRel = (Elf64_Rela *)(sl.MemoryImage + (JmpRel->d_un.d_ptr - BaseAddress));
Elf64_Sym *_SymTab = (Elf64_Sym *)(sl.MemoryImage + (SymTab->d_un.d_ptr - BaseAddress));
char *_DynStr = (char *)(sl.MemoryImage + (StrTab->d_un.d_ptr - BaseAddress));
Elf64_Shdr *gotSection = nullptr;
for (Elf64_Half i = 0; i < ((Elf64_Ehdr *)LibFile)->e_shnum; i++)
{
Elf64_Shdr *shdr = (Elf64_Shdr *)((uint8_t *)LibFile + ((Elf64_Ehdr *)LibFile)->e_shoff + i * sizeof(Elf64_Shdr));
if (shdr->sh_type == SHT_PROGBITS && (shdr->sh_flags & SHF_WRITE) && (shdr->sh_flags & SHF_ALLOC))
{
gotSection = shdr;
break;
}
}
debug("LIB_DBG");
if (gotSection)
{
Elf64_Xword numEntries = gotSection->sh_size / sizeof(Elf64_Addr);
for (Elf64_Xword i = 0; i < numEntries - 3; i++)
{
Elf64_Rela *Rel = _JmpRel + i;
Elf64_Addr *GOTEntry = (Elf64_Addr *)(Rel->r_offset + sl.MemoryImage);
Elf64_Xword RelType = ELF64_R_TYPE(Rel->r_info);
debug("r_offset: %#lx RelType: %d", Rel->r_offset, RelType);
switch (RelType)
{
case R_X86_64_NONE:
break;
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((Elf64_Ehdr *)LibFile, SymName);
if (LibSym)
{
*GOTEntry = (Elf64_Addr)(sl.MemoryImage + LibSym->st_value);
debug("GOT[%ld]: %#lx + %#lx = %#lx", i, sl.MemoryImage, LibSym->st_value, *GOTEntry);
}
}
break;
}
default:
{
fixme("RelType %d not supported", RelType);
break;
}
}
debug("GOT[%ld](%#lx): %#lx", i, GOTEntry, *GOTEntry);
}
}
else
debug("GOT section not found");
}
}
sl.Address = r_cst(uint64_t, LibFile);

View File

@ -188,7 +188,7 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
if (!lib.Address)
debug("Failed to get library address %#lx", (uintptr_t)lib.Address);
debug("Returning library address %#lx", (uintptr_t)lib.Address);
debug("Returning library address %#lx (%s)", (uintptr_t)lib.Address, Identifier);
return (uintptr_t)lib.Address;
}
case KCTL_GET_ELF_LIB_MEMORY_IMAGE:
@ -202,7 +202,7 @@ static uintptr_t sys_kernelctl(SyscallsFrame *Frame, enum KCtl Command, uint64_t
if (!lib.MemoryImage)
debug("Failed to get library memory image %#lx", (uintptr_t)lib.MemoryImage);
debug("Returning memory image %#lx", (uintptr_t)lib.MemoryImage);
debug("Returning memory image %#lx (%s)", (uintptr_t)lib.MemoryImage, Identifier);
return (uintptr_t)lib.MemoryImage;
}
default:
@ -228,28 +228,28 @@ static int sys_ipc(SyscallsFrame *Frame, enum IPCCommand Command, enum IPCType T
return TaskManager->GetCurrentProcess()->IPC->HandleSyscall(Command, Type, ID, Flags, Buffer, Size);
}
static int sys_file_open(SyscallsFrame *Frame)
static uint64_t sys_file_open(SyscallsFrame *Frame, const char *Path, uint64_t Flags)
{
fixme("sys_file_open: %#lx", Frame);
return SYSCALL_NOT_IMPLEMENTED;
fixme("%s, %#lx", Path, Flags);
return 0;
}
static int sys_file_close(SyscallsFrame *Frame)
static int sys_file_close(SyscallsFrame *Frame, void *KernelPrivate)
{
fixme("sys_file_close: %#lx", Frame);
return SYSCALL_NOT_IMPLEMENTED;
fixme("%#lx", KernelPrivate);
return SYSCALL_OK;
}
static int sys_file_read(SyscallsFrame *Frame)
static uint64_t sys_file_read(SyscallsFrame *Frame, void *KernelPrivate, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
{
fixme("sys_file_read: %#lx", Frame);
return SYSCALL_NOT_IMPLEMENTED;
fixme("%#lx, %#lx, %#lx, %#lx, %#lx", Frame, KernelPrivate, Offset, Buffer, Size);
return 0;
}
static int sys_file_write(SyscallsFrame *Frame)
static uint64_t sys_file_write(SyscallsFrame *Frame, void *KernelPrivate, uint64_t Offset, uint8_t *Buffer, uint64_t Size)
{
fixme("sys_file_write: %#lx", Frame);
return SYSCALL_NOT_IMPLEMENTED;
fixme("%#lx, %#lx, %#lx, %#lx, %#lx", Frame, KernelPrivate, Offset, Buffer, Size);
return 0;
}
static int sys_file_seek(SyscallsFrame *Frame)

View File

@ -107,7 +107,7 @@ namespace Execute
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index);
char *GetELFStringTable(Elf64_Ehdr *Header);
char *ELFLookupString(Elf64_Ehdr *Header, uintptr_t Offset);
void *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name);
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name);
uintptr_t ELFGetSymbolValue(Elf64_Ehdr *Header, uint64_t Table, uint64_t Index);
Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicArrayTags Tag);