/*
This file is part of Fennix Kernel.
Fennix Kernel is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Kernel is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Kernel. If not, see .
*/
#ifndef __FENNIX_KERNEL_FILE_EXECUTE_H__
#define __FENNIX_KERNEL_FILE_EXECUTE_H__
#include
#include
#include
#include
#include
#include
namespace Execute
{
enum BinaryType
{
BinTypeInvalid,
BinTypeFex,
BinTypeELF,
BinTypePE,
BinTypeNE,
BinTypeMZ,
BinTypeUnknown
};
enum ExStatus
{
Unknown,
OK,
Unsupported,
GenericError,
LoadingProcedureFailed,
InvalidFile,
InvalidFileFormat,
InvalidFileHeader,
InvalidFileData,
InvalidFileEntryPoint,
InvalidFilePath
};
struct SpawnData
{
ExStatus Status;
Tasking::PCB *Process;
Tasking::TCB *Thread;
};
struct SharedLibrary
{
char Identifier[64];
char Path[256];
uint64_t Timeout;
int RefCount;
uintptr_t MemoryImage;
size_t Length;
};
struct ELFBaseLoad
{
bool Success;
bool Interpreter;
SpawnData sd;
Tasking::IP InstructionPointer;
std::vector NeededLibraries;
void *MemoryImage;
void *VirtualMemoryImage;
/* This should be deleted after copying the allocated pages to the thread
Intended to be used only inside BaseLoad.cpp */
Memory::MemMgr *TmpMem;
/* Same as above, for BaseLoad.cpp only */
std::vector auxv;
};
struct MmImage
{
void *Physical;
void *Virtual;
};
class ELFObject
{
private:
ELFBaseLoad BaseLoadInfo{};
ELFBaseLoad LoadExec_x86_32(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess);
ELFBaseLoad LoadExec_x86_64(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess);
ELFBaseLoad LoadDyn_x86_32(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess,
bool IsLibrary);
ELFBaseLoad LoadDyn_x86_64(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess,
bool IsLibrary);
public:
ELFBaseLoad GetBaseLoadInfo() { return BaseLoadInfo; }
bool IsValid() { return BaseLoadInfo.Success; }
ELFObject(char *AbsolutePath,
Tasking::PCB *TargetProcess,
bool IsLibrary = false);
~ELFObject();
};
/* Full binary size. */
BinaryType GetBinaryType(void *Image);
BinaryType GetBinaryType(char *Path);
SpawnData Spawn(char *Path, const char **argv, const char **envp);
ELFBaseLoad ELFLoad(char *Path, const char **argv, const char **envp,
Tasking::TaskCompatibility Compatibility = Tasking::TaskCompatibility::Native);
void ELFInterpreterIPCThread(Tasking::PCB *TargetProcess,
std::string *TargetPath,
void *MemoryImage,
std::vector *NeededLibraries);
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, const char *Name);
Elf64_Sym ELFLookupSymbol(VirtualFileSystem::File &ElfFile, const char *Name);
uintptr_t ELFGetSymbolValue(Elf64_Ehdr *Header, uint64_t Table, uint64_t Index);
std::vector ELFGetSymbolType_x86_64(VirtualFileSystem::File &ElfFile, SegmentTypes Tag);
std::vector ELFGetSymbolType_x86_32(VirtualFileSystem::File &ElfFile, SegmentTypes Tag);
std::vector ELFGetSections_x86_64(VirtualFileSystem::File &ElfFile, const char *SectionName);
std::vector ELFGetSections_x86_32(VirtualFileSystem::File &ElfFile, const char *SectionName);
std::vector ELFGetDynamicTag_x86_64(VirtualFileSystem::File &ElfFile, DynamicArrayTags Tag);
std::vector ELFGetDynamicTag_x86_32(VirtualFileSystem::File &ElfFile, DynamicArrayTags Tag);
void CopyLOADSegments(VirtualFileSystem::File &ElfFile, uintptr_t HdrsBase, uintptr_t PhysicalBase);
void GetBaseAndSize(VirtualFileSystem::File &ElfFile, uintptr_t &Base, size_t &Size);
/**
* @brief Create a ELF Memory Image
*
* @param mem The memory manager to use
* @param vmm Memory::Virtual object to use
* @param ElfFile The ELF File
* @param Length Length of @p ElfFile
* @return The Memory Image (Physical and Virtual)
*/
MmImage ELFCreateMemoryImage(Memory::MemMgr *mem,
Memory::Virtual &vmm,
VirtualFileSystem::File &ElfFile,
size_t Length);
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem,
Memory::Virtual &vmm,
const char *Interpreter);
void LibraryManagerService();
bool AddLibrary(char *Identifier,
VirtualFileSystem::File &ExFile,
const Memory::Virtual &vmm = Memory::Virtual());
SharedLibrary GetLibrary(char *Identifier);
}
#endif // !__FENNIX_KERNEL_FILE_EXECUTE_H__