mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
style(kernel/elf): change code style
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
fe6d7f4b08
commit
0041300a00
@ -517,11 +517,11 @@ namespace Driver
|
||||
{
|
||||
AssertReturnError(pltrelSize != nullptr, -ENOEXEC);
|
||||
|
||||
std::vector<Elf64_Dyn> symtab = Execute::ELFGetDynamicTag_x86_64(File, DT_SYMTAB);
|
||||
std::vector<Elf64_Dyn> symtab = Execute::ELFGetDynamicTag(File, DT_SYMTAB);
|
||||
Elf64_Sym *symbols = (Elf64_Sym *)((uintptr_t)Drv.BaseAddress + symtab[0].d_un.d_ptr);
|
||||
|
||||
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag_x86_64(File, DT_STRTAB);
|
||||
char *DynStr = (char *)((uintptr_t)Drv.BaseAddress + StrTab[0].d_un.d_ptr);
|
||||
std::vector<Elf64_Dyn> StrTab = Execute::ELFGetDynamicTag(File, DT_STRTAB);
|
||||
char *dynStr = (char *)((uintptr_t)Drv.BaseAddress + StrTab[0].d_un.d_ptr);
|
||||
|
||||
Elf64_Rela *rela = (Elf64_Rela *)(Drv.BaseAddress + dyn->d_un.d_ptr);
|
||||
for (size_t i = 0; i < (pltrelSize->d_un.d_val / sizeof(Elf64_Rela)); i++)
|
||||
@ -536,7 +536,7 @@ namespace Driver
|
||||
Elf64_Xword symIndex = ELF64_R_SYM(r->r_info);
|
||||
Elf64_Sym *sym = symbols + symIndex;
|
||||
|
||||
const char *symName = DynStr + sym->st_name;
|
||||
const char *symName = dynStr + sym->st_name;
|
||||
debug("Resolving symbol %s", symName);
|
||||
|
||||
*reloc = (uintptr_t)GetSymbolByName(symName, driverInfo.Version.APIVersion);
|
||||
|
@ -28,73 +28,73 @@ namespace Execute
|
||||
BinaryType GetBinaryType(FileNode *Node)
|
||||
{
|
||||
debug("Checking binary type of %s", Node->Path.c_str());
|
||||
BinaryType Type;
|
||||
BinaryType type;
|
||||
|
||||
if (Node == nullptr)
|
||||
ReturnLogError((BinaryType)-ENOENT, "Node is null");
|
||||
|
||||
Elf32_Ehdr ELFHeader;
|
||||
Node->Read(&ELFHeader, sizeof(Elf32_Ehdr), 0);
|
||||
Elf_Ehdr ehdr;
|
||||
Node->Read(&ehdr, sizeof(Elf_Ehdr), 0);
|
||||
|
||||
mach_header MachHeader;
|
||||
Node->Read(&MachHeader, sizeof(mach_header), 0);
|
||||
mach_header mach;
|
||||
Node->Read(&mach, sizeof(mach_header), 0);
|
||||
|
||||
IMAGE_DOS_HEADER MZHeader;
|
||||
Node->Read(&MZHeader, sizeof(IMAGE_DOS_HEADER), 0);
|
||||
IMAGE_DOS_HEADER mz;
|
||||
Node->Read(&mz, 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 (ehdr.e_ident[EI_MAG0] == ELFMAG0 &&
|
||||
ehdr.e_ident[EI_MAG1] == ELFMAG1 &&
|
||||
ehdr.e_ident[EI_MAG2] == ELFMAG2 &&
|
||||
ehdr.e_ident[EI_MAG3] == ELFMAG3)
|
||||
{
|
||||
debug("Image - ELF");
|
||||
Type = BinaryType::BinTypeELF;
|
||||
type = BinaryType::BinTypeELF;
|
||||
goto Success;
|
||||
}
|
||||
|
||||
if (MachHeader.magic == MH_MAGIC || MachHeader.magic == MH_CIGAM)
|
||||
if (mach.magic == MH_MAGIC || mach.magic == MH_CIGAM)
|
||||
{
|
||||
debug("Image - Mach-O");
|
||||
Type = BinaryType::BinTypeMachO;
|
||||
type = BinaryType::BinTypeMachO;
|
||||
goto Success;
|
||||
}
|
||||
|
||||
/* Check MZ header. */
|
||||
else if (MZHeader.e_magic == IMAGE_DOS_SIGNATURE)
|
||||
else if (mz.e_magic == IMAGE_DOS_SIGNATURE)
|
||||
{
|
||||
IMAGE_NT_HEADERS PEHeader;
|
||||
Node->Read(&PEHeader, sizeof(IMAGE_NT_HEADERS), MZHeader.e_lfanew);
|
||||
IMAGE_NT_HEADERS pe;
|
||||
Node->Read(&pe, sizeof(IMAGE_NT_HEADERS), mz.e_lfanew);
|
||||
|
||||
IMAGE_OS2_HEADER NEHeader;
|
||||
Node->Read(&NEHeader, sizeof(IMAGE_OS2_HEADER), MZHeader.e_lfanew);
|
||||
IMAGE_OS2_HEADER ne;
|
||||
Node->Read(&ne, sizeof(IMAGE_OS2_HEADER), mz.e_lfanew);
|
||||
|
||||
/* TODO: LE, EDOS */
|
||||
if (PEHeader.Signature == IMAGE_NT_SIGNATURE)
|
||||
if (pe.Signature == IMAGE_NT_SIGNATURE)
|
||||
{
|
||||
debug("Image - PE");
|
||||
Type = BinaryType::BinTypePE;
|
||||
type = BinaryType::BinTypePE;
|
||||
goto Success;
|
||||
}
|
||||
else if (NEHeader.ne_magic == IMAGE_OS2_SIGNATURE)
|
||||
else if (ne.ne_magic == IMAGE_OS2_SIGNATURE)
|
||||
{
|
||||
debug("Image - NE");
|
||||
Type = BinaryType::BinTypeNE;
|
||||
type = BinaryType::BinTypeNE;
|
||||
goto Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("Image - MZ");
|
||||
Type = BinaryType::BinTypeMZ;
|
||||
type = BinaryType::BinTypeMZ;
|
||||
goto Success;
|
||||
}
|
||||
}
|
||||
|
||||
/* ... */
|
||||
|
||||
Type = BinaryType::BinTypeUnknown;
|
||||
type = BinaryType::BinTypeUnknown;
|
||||
Success:
|
||||
return Type;
|
||||
return type;
|
||||
}
|
||||
|
||||
BinaryType GetBinaryType(std::string Path)
|
||||
|
@ -32,7 +32,7 @@ using namespace vfs;
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
void ELFObject::GenerateAuxiliaryVector(Memory::VirtualMemoryArea *vma, FileNode *fd, Elf64_Ehdr ELFHeader, uintptr_t EntryPoint, uintptr_t BaseAddress)
|
||||
void ELFObject::GenerateAuxiliaryVector(Memory::VirtualMemoryArea *vma, FileNode *fd, Elf_Ehdr ELFHeader, uintptr_t EntryPoint, uintptr_t BaseAddress)
|
||||
{
|
||||
char *aux_platform = (char *)vma->RequestPages(1, true); /* TODO: 4KiB is too much for this */
|
||||
strcpy(aux_platform, "x86_64");
|
||||
@ -393,109 +393,100 @@ namespace Execute
|
||||
|
||||
void ELFObject::LoadExec(FileNode *fd, PCB *TargetProcess)
|
||||
{
|
||||
Elf_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf_Ehdr), 0);
|
||||
uintptr_t EntryPoint = ELFHeader.e_entry;
|
||||
debug("Entry point is %#lx", EntryPoint);
|
||||
Elf_Ehdr ehdr{};
|
||||
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
|
||||
uintptr_t entry = ehdr.e_entry;
|
||||
debug("Entry point is %#lx", entry);
|
||||
|
||||
Memory::Virtual vmm(TargetProcess->PageTable);
|
||||
Memory::VirtualMemoryArea *vma = TargetProcess->vma;
|
||||
debug("Target process page table is %#lx", TargetProcess->PageTable);
|
||||
|
||||
uintptr_t BaseAddress = 0;
|
||||
this->LoadSegments(fd, TargetProcess, ELFHeader, BaseAddress);
|
||||
uintptr_t base = 0;
|
||||
this->LoadSegments(fd, TargetProcess, ehdr, base);
|
||||
|
||||
debug("Entry Point: %#lx", EntryPoint);
|
||||
debug("Entry Point: %#lx", entry);
|
||||
|
||||
this->GenerateAuxiliaryVector(vma, fd, ELFHeader, EntryPoint, 0);
|
||||
this->GenerateAuxiliaryVector(vma, fd, ehdr, entry, 0);
|
||||
|
||||
this->ip = EntryPoint;
|
||||
this->ip = entry;
|
||||
this->IsElfValid = true;
|
||||
}
|
||||
|
||||
void ELFObject::LoadDyn(FileNode *fd, PCB *TargetProcess)
|
||||
{
|
||||
Elf_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf_Ehdr), 0);
|
||||
uintptr_t EntryPoint = ELFHeader.e_entry;
|
||||
debug("Entry point is %#lx", EntryPoint);
|
||||
Elf_Ehdr ehdr{};
|
||||
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
|
||||
uintptr_t entry = ehdr.e_entry;
|
||||
debug("Entry point is %#lx", entry);
|
||||
|
||||
Memory::Virtual vmm(TargetProcess->PageTable);
|
||||
Memory::VirtualMemoryArea *vma = TargetProcess->vma;
|
||||
uintptr_t BaseAddress = 0;
|
||||
this->LoadSegments(fd, TargetProcess, ELFHeader, BaseAddress);
|
||||
EntryPoint += BaseAddress;
|
||||
debug("The new ep is %#lx", EntryPoint);
|
||||
uintptr_t base = 0;
|
||||
this->LoadSegments(fd, TargetProcess, ehdr, base);
|
||||
entry += base;
|
||||
debug("The new ep is %#lx", entry);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
debug("Entry Point: %#lx", EntryPoint);
|
||||
debug("Entry Point: %#lx", entry);
|
||||
|
||||
this->GenerateAuxiliaryVector(vma, fd, ELFHeader, EntryPoint, BaseAddress);
|
||||
this->GenerateAuxiliaryVector(vma, fd, ehdr, entry, base);
|
||||
|
||||
this->ip = EntryPoint;
|
||||
this->ip = entry;
|
||||
this->IsElfValid = true;
|
||||
|
||||
std::vector<Elf64_Phdr> PhdrINTERP = ELFGetSymbolType_x86_64(fd, PT_INTERP);
|
||||
for (auto Interp : PhdrINTERP)
|
||||
Elf_Phdr interp = ELFGetSymbolType(fd, PT_INTERP).front();
|
||||
std::string interpreterPath;
|
||||
interpreterPath.resize(256);
|
||||
fd->Read(interpreterPath.data(), 256, interp.p_offset);
|
||||
debug("Interpreter: %s", interpreterPath.c_str());
|
||||
|
||||
FileNode *ifd = fs->GetByPath(interpreterPath.c_str(), TargetProcess->Info.RootNode);
|
||||
if (ifd == nullptr)
|
||||
{
|
||||
std::string interpreterPath;
|
||||
interpreterPath.resize(256);
|
||||
fd->Read(interpreterPath.data(), 256, Interp.p_offset);
|
||||
debug("Interpreter: %s", (const char *)interpreterPath.c_str());
|
||||
|
||||
FileNode *ifd = fs->GetByPath(interpreterPath.c_str(), TargetProcess->Info.RootNode);
|
||||
if (ifd == nullptr)
|
||||
{
|
||||
warn("Failed to open interpreter file: %s", interpreterPath.c_str());
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ifd->IsSymbolicLink())
|
||||
{
|
||||
char buffer[512];
|
||||
ifd->ReadLink(buffer, sizeof(buffer));
|
||||
ifd = fs->GetByPath(buffer, ifd->Parent);
|
||||
}
|
||||
|
||||
debug("ifd: %p, interpreter: %s", ifd, interpreterPath.c_str());
|
||||
if (GetBinaryType(interpreterPath) != BinTypeELF)
|
||||
{
|
||||
warn("Interpreter %s is not an ELF file", interpreterPath.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LoadInterpreter(ifd, TargetProcess))
|
||||
{
|
||||
debug("Interpreter loaded successfully");
|
||||
return;
|
||||
}
|
||||
}
|
||||
warn("Failed to open interpreter file: %s", interpreterPath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (ifd->IsSymbolicLink())
|
||||
{
|
||||
char buffer[512];
|
||||
ifd->ReadLink(buffer, sizeof(buffer));
|
||||
ifd = fs->GetByPath(buffer, ifd->Parent);
|
||||
}
|
||||
|
||||
debug("ifd: %p, interpreter: %s", ifd, interpreterPath.c_str());
|
||||
if (GetBinaryType(interpreterPath) != BinTypeELF)
|
||||
{
|
||||
warn("Interpreter %s is not an ELF file", interpreterPath.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
LoadInterpreter(ifd, TargetProcess);
|
||||
}
|
||||
|
||||
bool ELFObject::LoadInterpreter(FileNode *fd, PCB *TargetProcess)
|
||||
{
|
||||
Elf_Ehdr ELFHeader;
|
||||
fd->Read(&ELFHeader, sizeof(Elf_Ehdr), 0);
|
||||
Elf_Ehdr ehdr;
|
||||
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
|
||||
|
||||
switch (ELFHeader.e_type)
|
||||
switch (ehdr.e_type)
|
||||
{
|
||||
case ET_EXEC:
|
||||
assert(ELFHeader.e_type != ET_EXEC);
|
||||
assert(ehdr.e_type != ET_EXEC);
|
||||
break;
|
||||
case ET_DYN:
|
||||
{
|
||||
uintptr_t BaseAddress = 0;
|
||||
this->LoadSegments(fd, TargetProcess, ELFHeader, BaseAddress);
|
||||
this->ip = BaseAddress + ELFHeader.e_entry;
|
||||
uintptr_t base = 0;
|
||||
this->LoadSegments(fd, TargetProcess, ehdr, base);
|
||||
this->ip = base + ehdr.e_entry;
|
||||
for (auto &&aux : Elfauxv)
|
||||
{
|
||||
if (aux.archaux.a_type != AT_BASE)
|
||||
continue;
|
||||
|
||||
aux.archaux.a_un.a_val = BaseAddress;
|
||||
aux.archaux.a_un.a_val = base;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -505,12 +496,12 @@ namespace Execute
|
||||
case ET_REL:
|
||||
case ET_NONE:
|
||||
{
|
||||
warn("Ignoring interpreter: %s (reason: ET_ is %#lx)", fd->Path.c_str(), ELFHeader.e_type);
|
||||
warn("Ignoring interpreter: %s (reason: ET_ is %#lx)", fd->Path.c_str(), ehdr.e_type);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
error("Unknown ELF Type: %d", ELFHeader.e_type);
|
||||
error("Unknown ELF Type: %d", ehdr.e_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -549,8 +540,8 @@ namespace Execute
|
||||
while (envp[envc] != nullptr)
|
||||
envc++;
|
||||
|
||||
Elf_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf_Ehdr), 0);
|
||||
Elf_Ehdr ehdr{};
|
||||
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
|
||||
|
||||
// ELFargv = new const char *[argc + 2];
|
||||
size_t argv_size = argc + 2 * sizeof(char *);
|
||||
@ -576,7 +567,7 @@ namespace Execute
|
||||
}
|
||||
ELFenvp[envc] = nullptr;
|
||||
|
||||
switch (ELFHeader.e_type)
|
||||
switch (ehdr.e_type)
|
||||
{
|
||||
case ET_REL:
|
||||
{
|
||||
@ -585,7 +576,7 @@ namespace Execute
|
||||
}
|
||||
case ET_EXEC:
|
||||
{
|
||||
switch (ELFHeader.e_machine)
|
||||
switch (ehdr.e_machine)
|
||||
{
|
||||
case EM_386:
|
||||
case EM_X86_64:
|
||||
@ -594,14 +585,14 @@ namespace Execute
|
||||
this->LoadExec(fd, TargetProcess);
|
||||
break;
|
||||
default:
|
||||
error("Unknown architecture: %d", ELFHeader.e_machine);
|
||||
error("Unknown architecture: %d", ehdr.e_machine);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ET_DYN:
|
||||
{
|
||||
switch (ELFHeader.e_machine)
|
||||
switch (ehdr.e_machine)
|
||||
{
|
||||
case EM_386:
|
||||
case EM_X86_64:
|
||||
@ -610,7 +601,7 @@ namespace Execute
|
||||
this->LoadDyn(fd, TargetProcess);
|
||||
break;
|
||||
default:
|
||||
error("Unknown architecture: %d", ELFHeader.e_machine);
|
||||
error("Unknown architecture: %d", ehdr.e_machine);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -623,7 +614,7 @@ namespace Execute
|
||||
case ET_NONE:
|
||||
default:
|
||||
{
|
||||
error("Unknown ELF Type: %d", ELFHeader.e_type);
|
||||
error("Unknown ELF Type: %d", ehdr.e_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -25,52 +25,52 @@ namespace Execute
|
||||
{
|
||||
bool ELFIs64(void *Header)
|
||||
{
|
||||
Elf32_Ehdr *ELFHeader = (Elf32_Ehdr *)Header;
|
||||
if (ELFHeader->e_ident[EI_CLASS] == ELFCLASS64)
|
||||
Elf_Ehdr *ehdr = (Elf_Ehdr *)Header;
|
||||
if (ehdr->e_ident[EI_CLASS] == ELFCLASS64)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Originally from https://wiki.osdev.org/ELF_Tutorial */
|
||||
|
||||
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header)
|
||||
Elf_Shdr *GetELFSheader(Elf_Ehdr *Header)
|
||||
{
|
||||
return (Elf64_Shdr *)((uintptr_t)Header + Header->e_shoff);
|
||||
return (Elf_Shdr *)((uintptr_t)Header + Header->e_shoff);
|
||||
}
|
||||
|
||||
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index)
|
||||
Elf_Shdr *GetELFSection(Elf_Ehdr *Header, uintptr_t Index)
|
||||
{
|
||||
return &GetELFSheader(Header)[Index];
|
||||
}
|
||||
|
||||
char *GetELFStringTable(Elf64_Ehdr *Header)
|
||||
char *GetELFStringTable(Elf_Ehdr *Header)
|
||||
{
|
||||
if (Header->e_shstrndx == SHN_UNDEF)
|
||||
return nullptr;
|
||||
return (char *)Header + GetELFSection(Header, Header->e_shstrndx)->sh_offset;
|
||||
}
|
||||
|
||||
char *ELFLookupString(Elf64_Ehdr *Header, uintptr_t Offset)
|
||||
char *ELFLookupString(Elf_Ehdr *Header, uintptr_t Offset)
|
||||
{
|
||||
char *StringTable = GetELFStringTable(Header);
|
||||
if (StringTable == nullptr)
|
||||
char *table = GetELFStringTable(Header);
|
||||
if (table == nullptr)
|
||||
return nullptr;
|
||||
return StringTable + Offset;
|
||||
return table + Offset;
|
||||
}
|
||||
|
||||
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, std::string Name)
|
||||
Elf_Sym *ELFLookupSymbol(Elf_Ehdr *Header, std::string Name)
|
||||
{
|
||||
Elf64_Shdr *SymbolTable = nullptr;
|
||||
Elf64_Shdr *StringTable = nullptr;
|
||||
Elf_Shdr *symTable = nullptr;
|
||||
Elf_Shdr *stringTable = nullptr;
|
||||
|
||||
for (Elf64_Half i = 0; i < Header->e_shnum; i++)
|
||||
for (Elf_Half i = 0; i < Header->e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr *shdr = GetELFSection(Header, i);
|
||||
Elf_Shdr *shdr = GetELFSection(Header, i);
|
||||
switch (shdr->sh_type)
|
||||
{
|
||||
case SHT_SYMTAB:
|
||||
SymbolTable = shdr;
|
||||
StringTable = GetELFSection(Header, shdr->sh_link);
|
||||
symTable = shdr;
|
||||
stringTable = GetELFSection(Header, shdr->sh_link);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
@ -79,117 +79,108 @@ namespace Execute
|
||||
}
|
||||
}
|
||||
|
||||
if (SymbolTable == nullptr || StringTable == nullptr)
|
||||
if (symTable == nullptr || stringTable == nullptr)
|
||||
return nullptr;
|
||||
|
||||
for (size_t i = 0; i < (SymbolTable->sh_size / sizeof(Elf64_Sym)); i++)
|
||||
for (size_t i = 0; i < (symTable->sh_size / sizeof(Elf_Sym)); i++)
|
||||
{
|
||||
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);
|
||||
Elf_Sym *sym = (Elf_Sym *)((uintptr_t)Header + symTable->sh_offset + (i * sizeof(Elf_Sym)));
|
||||
char *String = (char *)((uintptr_t)Header + stringTable->sh_offset + sym->st_name);
|
||||
if (strcmp(String, Name.c_str()) == 0)
|
||||
return Symbol;
|
||||
return sym;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Elf64_Sym ELFLookupSymbol(FileNode *fd, std::string Name)
|
||||
Elf_Sym ELFLookupSymbol(FileNode *fd, std::string Name)
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
Elf64_Ehdr Header{};
|
||||
fd->Read(&Header, sizeof(Elf64_Ehdr), 0);
|
||||
Elf_Ehdr ehdr{};
|
||||
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
|
||||
|
||||
Elf64_Shdr SymbolTable{};
|
||||
Elf64_Shdr StringTable{};
|
||||
Elf_Shdr symTable{};
|
||||
Elf_Shdr stringTable{};
|
||||
|
||||
for (Elf64_Half i = 0; i < Header.e_shnum; i++)
|
||||
for (Elf64_Half i = 0; i < ehdr.e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr shdr;
|
||||
fd->Read(&shdr, sizeof(Elf64_Shdr), Header.e_shoff + (i * sizeof(Elf64_Shdr)));
|
||||
Elf_Shdr shdr;
|
||||
fd->Read(&shdr, sizeof(Elf_Shdr), ehdr.e_shoff + (i * sizeof(Elf_Shdr)));
|
||||
|
||||
switch (shdr.sh_type)
|
||||
{
|
||||
case SHT_SYMTAB:
|
||||
SymbolTable = shdr;
|
||||
fd->Read(&StringTable, sizeof(Elf64_Shdr), Header.e_shoff + (shdr.sh_link * sizeof(Elf64_Shdr)));
|
||||
symTable = shdr;
|
||||
fd->Read(&stringTable, sizeof(Elf_Shdr), ehdr.e_shoff + (shdr.sh_link * sizeof(Elf_Shdr)));
|
||||
break;
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (SymbolTable.sh_name == 0 || StringTable.sh_name == 0)
|
||||
if (symTable.sh_name == 0 || stringTable.sh_name == 0)
|
||||
{
|
||||
error("Symbol table not found.");
|
||||
return {};
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < (SymbolTable.sh_size / sizeof(Elf64_Sym)); i++)
|
||||
for (size_t i = 0; i < (symTable.sh_size / sizeof(Elf_Sym)); i++)
|
||||
{
|
||||
// Elf64_Sym *Symbol = (Elf64_Sym *)((uintptr_t)Header + SymbolTable->sh_offset + (i * sizeof(Elf64_Sym)));
|
||||
Elf64_Sym Symbol;
|
||||
fd->Read(&Symbol, sizeof(Elf64_Sym), SymbolTable.sh_offset + (i * sizeof(Elf64_Sym)));
|
||||
// Elf_Sym *sym = (Elf_Sym *)((uintptr_t)Header + symTable->sh_offset + (i * sizeof(Elf_Sym)));
|
||||
Elf_Sym sym;
|
||||
fd->Read(&sym, sizeof(Elf_Sym), symTable.sh_offset + (i * sizeof(Elf_Sym)));
|
||||
|
||||
// char *String = (char *)((uintptr_t)Header + StringTable->sh_offset + Symbol->st_name);
|
||||
char String[256];
|
||||
fd->Read(&String, sizeof(String), StringTable.sh_offset + Symbol.st_name);
|
||||
// char *str = (char *)((uintptr_t)Header + stringTable->sh_offset + sym->st_name);
|
||||
char str[256];
|
||||
fd->Read(&str, sizeof(str), stringTable.sh_offset + sym.st_name);
|
||||
|
||||
if (strcmp(String, Name.c_str()) == 0)
|
||||
return Symbol;
|
||||
if (strcmp(str, Name.c_str()) == 0)
|
||||
return sym;
|
||||
}
|
||||
error("Symbol not found.");
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
uintptr_t ELFGetSymbolValue(Elf64_Ehdr *Header, uint64_t Table, uint64_t Index)
|
||||
uintptr_t ELFGetSymbolValue(Elf_Ehdr *Header, uintptr_t Table, uintptr_t Index)
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
if (Table == SHN_UNDEF || Index == SHN_UNDEF)
|
||||
return 0;
|
||||
Elf64_Shdr *SymbolTable = GetELFSection(Header, Table);
|
||||
|
||||
uint64_t STEntries = SymbolTable->sh_size / SymbolTable->sh_entsize;
|
||||
if (Index >= STEntries)
|
||||
Elf_Shdr *symTable = GetELFSection(Header, Table);
|
||||
|
||||
uintptr_t entries = symTable->sh_size / symTable->sh_entsize;
|
||||
if (Index >= entries)
|
||||
{
|
||||
error("Symbol index out of range %d-%u.", Table, Index);
|
||||
return 0xdead;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t SymbolAddress = (uint64_t)Header + SymbolTable->sh_offset;
|
||||
Elf64_Sym *Symbol = &((Elf64_Sym *)SymbolAddress)[Index];
|
||||
uintptr_t symbolPtr = (uintptr_t)Header + symTable->sh_offset;
|
||||
Elf_Sym *sym = &((Elf_Sym *)symbolPtr)[Index];
|
||||
|
||||
if (Symbol->st_shndx == SHN_UNDEF)
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
{
|
||||
Elf64_Shdr *StringTable = GetELFSection(Header, SymbolTable->sh_link);
|
||||
const char *Name = (const char *)Header + StringTable->sh_offset + Symbol->st_name;
|
||||
Elf_Shdr *stringTable = GetELFSection(Header, symTable->sh_link);
|
||||
const char *name = (const char *)Header + stringTable->sh_offset + sym->st_name;
|
||||
|
||||
void *Target = (void *)ELFLookupSymbol(Header, Name)->st_value;
|
||||
if (Target == nullptr)
|
||||
void *target = (void *)ELFLookupSymbol(Header, name)->st_value;
|
||||
if (target == nullptr)
|
||||
{
|
||||
if (ELF64_ST_BIND(Symbol->st_info) & STB_WEAK)
|
||||
if (ELF64_ST_BIND(sym->st_info) & STB_WEAK)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
error("Undefined external symbol \"%s\".", Name);
|
||||
return 0xdead;
|
||||
error("Undefined external symbol \"%s\".", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
return (uintptr_t)Target;
|
||||
return (uintptr_t)target;
|
||||
}
|
||||
else if (Symbol->st_shndx == SHN_ABS)
|
||||
return Symbol->st_value;
|
||||
else if (sym->st_shndx == SHN_ABS)
|
||||
return sym->st_value;
|
||||
else
|
||||
{
|
||||
Elf64_Shdr *Target = GetELFSection(Header, Symbol->st_shndx);
|
||||
return (uintptr_t)Header + Symbol->st_value + Target->sh_offset;
|
||||
Elf_Shdr *shdr = GetELFSection(Header, sym->st_shndx);
|
||||
return (uintptr_t)Header + sym->st_value + shdr->sh_offset;
|
||||
}
|
||||
#elif defined(__i386__)
|
||||
return 0xdead;
|
||||
#elif defined(__aarch64__)
|
||||
return 0xdead;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -25,77 +25,72 @@ namespace Execute
|
||||
{
|
||||
/* 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(__amd64__)
|
||||
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++)
|
||||
Elf_Shdr *shdr = GetELFSheader(((Elf_Ehdr *)BaseImage));
|
||||
for (Elf_Half i = 0; i < ((Elf_Ehdr *)BaseImage)->e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr *Section = &shdr[i];
|
||||
if (Section->sh_type == SHT_NOBITS)
|
||||
Elf_Shdr *section = &shdr[i];
|
||||
if (section->sh_type == SHT_NOBITS)
|
||||
{
|
||||
if (!Section->sh_size)
|
||||
if (!section->sh_size)
|
||||
continue;
|
||||
if (Section->sh_flags & SHF_ALLOC)
|
||||
if (section->sh_flags & SHF_ALLOC)
|
||||
{
|
||||
void *Buffer = KernelAllocator.RequestPages(TO_PAGES(Section->sh_size + 1));
|
||||
memset(Buffer, 0, Section->sh_size);
|
||||
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++)
|
||||
for (Elf_Half i = 0; i < ((Elf_Ehdr *)BaseImage)->e_shnum; i++)
|
||||
{
|
||||
Elf64_Shdr *Section = &shdr[i];
|
||||
if (Section->sh_type == SHT_REL)
|
||||
Elf_Shdr *section = &shdr[i];
|
||||
if (section->sh_type == SHT_REL)
|
||||
{
|
||||
for (size_t Index = 0; Index < Section->sh_size / Section->sh_entsize; Index++)
|
||||
for (size_t i = 0; i < section->sh_size / section->sh_entsize; i++)
|
||||
{
|
||||
Elf64_Rel *RelTable = &((Elf64_Rel *)((uintptr_t)BaseImage + Section->sh_offset))[Index];
|
||||
Elf64_Shdr *Target = GetELFSection(((Elf64_Ehdr *)BaseImage), Section->sh_info);
|
||||
Elf_Rel *rel = &((Elf_Rel *)((uintptr_t)BaseImage + section->sh_offset))[i];
|
||||
Elf_Shdr *target = GetELFSection(((Elf_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 *relPtr = (uintptr_t *)(((uintptr_t)BaseImage + target->sh_offset) + rel->r_offset);
|
||||
uintptr_t value = 0;
|
||||
|
||||
if (ELF64_R_SYM(RelTable->r_info) != SHN_UNDEF)
|
||||
if (ELF64_R_SYM(rel->r_info) != SHN_UNDEF)
|
||||
{
|
||||
SymbolValue = ELFGetSymbolValue(((Elf64_Ehdr *)BaseImage), Section->sh_link, ELF64_R_SYM(RelTable->r_info));
|
||||
if (SymbolValue == 0xdead)
|
||||
value = ELFGetSymbolValue(((Elf_Ehdr *)BaseImage), section->sh_link, ELF64_R_SYM(rel->r_info));
|
||||
if (value == (uintptr_t)-1)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ELF64_R_TYPE(RelTable->r_info))
|
||||
switch (ELF64_R_TYPE(rel->r_info))
|
||||
{
|
||||
case R_386_NONE:
|
||||
break;
|
||||
case R_386_32:
|
||||
*RelAddress = DO_64_64(SymbolValue, *RelAddress);
|
||||
*relPtr = DO_64_64(value, *relPtr);
|
||||
break;
|
||||
case R_386_PC32:
|
||||
*RelAddress = DO_64_PC32(SymbolValue, *RelAddress, (uintptr_t)RelAddress);
|
||||
*relPtr = DO_64_PC32(value, *relPtr, (uintptr_t)relPtr);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
error("Unsupported relocation type: %d", ELF64_R_TYPE(RelTable->r_info));
|
||||
error("Unsupported relocation type: %d", ELF64_R_TYPE(rel->r_info));
|
||||
return;
|
||||
}
|
||||
}
|
||||
debug("Symbol value: %#lx", SymbolValue);
|
||||
debug("Symbol value: %#lx", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(__i386__)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -21,42 +21,31 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
std::vector<Elf64_Dyn> ELFGetDynamicTag_x86_64(FileNode *fd,
|
||||
DynamicArrayTags Tag)
|
||||
std::vector<Elf_Dyn> ELFGetDynamicTag(FileNode *fd, DynamicArrayTags Tag)
|
||||
{
|
||||
#if defined(__amd64__) || defined(__aarch64__)
|
||||
std::vector<Elf64_Dyn> Ret;
|
||||
std::vector<Elf_Dyn> ret;
|
||||
std::vector<Elf_Phdr> phdrs = ELFGetSymbolType(fd, PT_DYNAMIC);
|
||||
|
||||
Elf64_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
|
||||
|
||||
std::vector<Elf64_Phdr> DYNAMICPhdrs = ELFGetSymbolType_x86_64(fd, PT_DYNAMIC);
|
||||
|
||||
if (DYNAMICPhdrs.size() < 1)
|
||||
if (phdrs.size() < 1)
|
||||
{
|
||||
error("No dynamic phdrs found.");
|
||||
return Ret;
|
||||
debug("No dynamic phdrs found.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (auto Phdr : DYNAMICPhdrs)
|
||||
for (auto phdr : phdrs)
|
||||
{
|
||||
Elf64_Dyn Dynamic{};
|
||||
for (size_t i = 0; i < Phdr.p_filesz / sizeof(Elf64_Dyn); i++)
|
||||
Elf_Dyn dyn{};
|
||||
for (size_t i = 0; i < phdr.p_filesz / sizeof(Elf_Dyn); i++)
|
||||
{
|
||||
fd->Read(&Dynamic, sizeof(Elf64_Dyn), Phdr.p_offset + (i * sizeof(Elf64_Dyn)));
|
||||
|
||||
if (Dynamic.d_tag != Tag)
|
||||
fd->Read(&dyn, sizeof(Elf_Dyn), phdr.p_offset + (i * sizeof(Elf_Dyn)));
|
||||
if (dyn.d_tag != Tag)
|
||||
continue;
|
||||
|
||||
debug("Found dynamic tag %d at %#lx [d_val: %#lx]",
|
||||
Tag, &Dynamic, Dynamic.d_un.d_val);
|
||||
Ret.push_back(Dynamic);
|
||||
debug("Found dynamic tag %d at %#lx [d_val: %#lx]", Tag, &dyn, dyn.d_un.d_val);
|
||||
ret.push_back(dyn);
|
||||
}
|
||||
}
|
||||
|
||||
return Ret;
|
||||
#elif defined(__i386__)
|
||||
return {};
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -21,33 +21,28 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
std::vector<Elf64_Shdr> ELFGetSections_x86_64(FileNode *fd,
|
||||
const char *SectionName)
|
||||
std::vector<Elf_Shdr> ELFGetSections(FileNode *fd, const char *SectionName)
|
||||
{
|
||||
#if defined(__amd64__) || defined(__aarch64__)
|
||||
std::vector<Elf64_Shdr> Ret;
|
||||
std::vector<Elf_Shdr> ret;
|
||||
|
||||
Elf64_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
|
||||
Elf_Ehdr ehdr{};
|
||||
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
|
||||
|
||||
Elf64_Shdr *SectionHeaders = new Elf64_Shdr[ELFHeader.e_shnum];
|
||||
fd->Read(SectionHeaders, sizeof(Elf64_Shdr) * ELFHeader.e_shnum, ELFHeader.e_shoff);
|
||||
Elf_Shdr *sections = new Elf_Shdr[ehdr.e_shnum];
|
||||
fd->Read(sections, sizeof(Elf_Shdr) * ehdr.e_shnum, ehdr.e_shoff);
|
||||
|
||||
char *SectionNames = new char[SectionHeaders[ELFHeader.e_shstrndx].sh_size];
|
||||
fd->Read(SectionNames, SectionHeaders[ELFHeader.e_shstrndx].sh_size, SectionHeaders[ELFHeader.e_shstrndx].sh_offset);
|
||||
char *sectionNames = new char[sections[ehdr.e_shstrndx].sh_size];
|
||||
fd->Read(sectionNames, sections[ehdr.e_shstrndx].sh_size, sections[ehdr.e_shstrndx].sh_offset);
|
||||
|
||||
for (Elf64_Half i = 0; i < ELFHeader.e_shnum; ++i)
|
||||
for (Elf_Half i = 0; i < ehdr.e_shnum; ++i)
|
||||
{
|
||||
const char *Name = SectionNames + SectionHeaders[i].sh_name;
|
||||
const char *Name = sectionNames + sections[i].sh_name;
|
||||
if (strcmp(Name, SectionName) == 0)
|
||||
Ret.push_back(SectionHeaders[i]);
|
||||
ret.push_back(sections[i]);
|
||||
}
|
||||
|
||||
delete[] SectionHeaders;
|
||||
delete[] SectionNames;
|
||||
return Ret;
|
||||
#elif defined(__i386__)
|
||||
return {};
|
||||
#endif
|
||||
delete[] sections;
|
||||
delete[] sectionNames;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -21,31 +21,26 @@
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
std::vector<Elf64_Phdr> ELFGetSymbolType_x86_64(FileNode *fd,
|
||||
SegmentTypes Tag)
|
||||
std::vector<Elf_Phdr> ELFGetSymbolType(FileNode *fd, SegmentTypes Tag)
|
||||
{
|
||||
#if defined(__amd64__) || defined(__aarch64__)
|
||||
std::vector<Elf64_Phdr> Ret;
|
||||
std::vector<Elf_Phdr> ret;
|
||||
|
||||
Elf64_Ehdr ELFHeader{};
|
||||
fd->Read(&ELFHeader, sizeof(Elf64_Ehdr), 0);
|
||||
Elf_Ehdr ehdr{};
|
||||
fd->Read(&ehdr, sizeof(Elf_Ehdr), 0);
|
||||
|
||||
Elf64_Phdr ProgramHeaders{};
|
||||
fd->Read(&ProgramHeaders, sizeof(Elf64_Phdr), ELFHeader.e_phoff);
|
||||
Elf_Phdr phdr{};
|
||||
fd->Read(&phdr, sizeof(Elf_Phdr), ehdr.e_phoff);
|
||||
|
||||
off_t currentOffset = ELFHeader.e_phoff;
|
||||
for (Elf64_Half i = 0; i < ELFHeader.e_phnum; i++)
|
||||
off_t off = ehdr.e_phoff;
|
||||
for (Elf_Half i = 0; i < ehdr.e_phnum; i++)
|
||||
{
|
||||
if (ProgramHeaders.p_type == Tag)
|
||||
Ret.push_back(ProgramHeaders);
|
||||
if (phdr.p_type == Tag)
|
||||
ret.push_back(phdr);
|
||||
|
||||
currentOffset += sizeof(Elf64_Phdr);
|
||||
fd->Read(&ProgramHeaders, sizeof(Elf64_Phdr), currentOffset);
|
||||
off += sizeof(Elf_Phdr);
|
||||
fd->Read(&phdr, sizeof(Elf_Phdr), off);
|
||||
}
|
||||
|
||||
return Ret;
|
||||
#elif defined(__i386__)
|
||||
return {};
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -39,23 +39,6 @@ namespace Execute
|
||||
BinTypeUnknown
|
||||
};
|
||||
|
||||
struct SharedLibrary
|
||||
{
|
||||
char Identifier[64];
|
||||
char Path[256];
|
||||
uint64_t Timeout;
|
||||
int RefCount;
|
||||
|
||||
uintptr_t MemoryImage;
|
||||
size_t Length;
|
||||
};
|
||||
|
||||
struct MmImage
|
||||
{
|
||||
void *Physical;
|
||||
void *Virtual;
|
||||
};
|
||||
|
||||
class ELFObject
|
||||
{
|
||||
private:
|
||||
@ -67,7 +50,7 @@ namespace Execute
|
||||
void *ELFProgramHeaders;
|
||||
|
||||
void GenerateAuxiliaryVector(Memory::VirtualMemoryArea *vma,
|
||||
FileNode *fd, Elf64_Ehdr ELFHeader,
|
||||
FileNode *fd, Elf_Ehdr ELFHeader,
|
||||
uintptr_t EntryPoint,
|
||||
uintptr_t BaseAddress);
|
||||
|
||||
@ -100,22 +83,17 @@ namespace Execute
|
||||
bool Critical = false);
|
||||
|
||||
bool ELFIs64(void *Header);
|
||||
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header);
|
||||
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index);
|
||||
char *GetELFStringTable(Elf64_Ehdr *Header);
|
||||
char *ELFLookupString(Elf64_Ehdr *Header, uintptr_t Offset);
|
||||
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, std::string Name);
|
||||
Elf64_Sym ELFLookupSymbol(FileNode *fd, std::string Name);
|
||||
uintptr_t ELFGetSymbolValue(Elf64_Ehdr *Header, uint64_t Table, uint64_t Index);
|
||||
Elf_Shdr *GetELFSheader(Elf_Ehdr *Header);
|
||||
Elf_Shdr *GetELFSection(Elf_Ehdr *Header, uintptr_t Index);
|
||||
char *GetELFStringTable(Elf_Ehdr *Header);
|
||||
char *ELFLookupString(Elf_Ehdr *Header, uintptr_t Offset);
|
||||
Elf_Sym *ELFLookupSymbol(Elf_Ehdr *Header, std::string Name);
|
||||
Elf_Sym ELFLookupSymbol(FileNode *fd, std::string Name);
|
||||
uintptr_t ELFGetSymbolValue(Elf_Ehdr *Header, uintptr_t Table, uintptr_t Index);
|
||||
|
||||
std::vector<Elf64_Phdr> ELFGetSymbolType_x86_64(FileNode *fd, SegmentTypes Tag);
|
||||
std::vector<Elf32_Phdr> ELFGetSymbolType_x86_32(FileNode *fd, SegmentTypes Tag);
|
||||
|
||||
std::vector<Elf64_Shdr> ELFGetSections_x86_64(FileNode *fd, std::string SectionName);
|
||||
std::vector<Elf32_Shdr> ELFGetSections_x86_32(FileNode *fd, std::string SectionName);
|
||||
|
||||
std::vector<Elf64_Dyn> ELFGetDynamicTag_x86_64(FileNode *fd, DynamicArrayTags Tag);
|
||||
std::vector<Elf32_Dyn> ELFGetDynamicTag_x86_32(FileNode *fd, DynamicArrayTags Tag);
|
||||
std::vector<Elf_Phdr> ELFGetSymbolType(FileNode *fd, SegmentTypes Tag);
|
||||
std::vector<Elf_Shdr> ELFGetSections(FileNode *fd, std::string SectionName);
|
||||
std::vector<Elf_Dyn> ELFGetDynamicTag(FileNode *fd, DynamicArrayTags Tag);
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILE_EXECUTE_H__
|
||||
|
Loading…
x
Reference in New Issue
Block a user