Update kernel

This commit is contained in:
Alex
2023-06-10 13:11:25 +03:00
parent dcdba03426
commit 41db477173
82 changed files with 6342 additions and 4079 deletions

View File

@ -289,45 +289,82 @@ namespace CPU
uint32_t ss; // Stack Segment
} TrapFrame;
// ! TODO: UNTESTED!
typedef union DR6
{
struct
{
/** @brief Breakpoint #0 Condition Detected */
uint64_t B0 : 1;
/** @brief Breakpoint #1 Condition Detected */
uint64_t B1 : 1;
/** @brief Breakpoint #2 Condition Detected */
uint64_t B2 : 1;
/** @brief Breakpoint #3 Condition Detected */
uint64_t B3 : 1;
/** @brief Reserved */
uint64_t Reserved0 : 8;
/** @brief Reserved */
uint64_t Reserved1 : 1;
/** @brief Breakpoint Debug Access Detected */
uint64_t BD : 1;
/** @brief Breakpoint Single Step */
uint64_t BS : 1;
/** @brief Breakpoint Task Switch */
uint64_t BT : 1;
/** @brief Reserved */
uint64_t Reserved2 : 15;
};
uint64_t raw;
} DR6;
typedef union DR7
{
struct
{
/** @brief Local DR0 Breakpoint (0) */
uint32_t LocalDR0 : 1;
/** @brief Global DR0 Breakpoint (1) */
uint32_t GlobalDR0 : 1;
/** @brief Local DR1 Breakpoint (2) */
uint32_t LocalDR1 : 1;
/** @brief Global DR1 Breakpoint (3) */
uint32_t GlobalDR1 : 1;
/** @brief Local DR2 Breakpoint (4) */
uint32_t LocalDR2 : 1;
/** @brief Global DR2 Breakpoint (5) */
uint32_t GlobalDR2 : 1;
/** @brief Local DR3 Breakpoint (6) */
uint32_t LocalDR3 : 1;
/** @brief Global DR3 Breakpoint (7) */
uint32_t GlobalDR3 : 1;
/** @brief Reserved [7 - (16-17)] */
uint32_t Reserved : 9;
/** @brief Conditions for DR0 (16-17) */
uint32_t ConditionsDR0 : 1;
/** @brief Size of DR0 Breakpoint (18-19) */
uint32_t SizeDR0 : 1;
/** @brief Conditions for DR1 (20-21) */
uint32_t ConditionsDR1 : 1;
/** @brief Size of DR1 Breakpoint (22-23) */
uint32_t SizeDR1 : 1;
/** @brief Conditions for DR2 (24-25) */
uint32_t ConditionsDR2 : 1;
/** @brief Size of DR2 Breakpoint (26-27) */
uint32_t SizeDR2 : 1;
/** @brief Conditions for DR3 (28-29) */
uint32_t ConditionsDR3 : 1;
/** @brief Size of DR3 Breakpoint (30-31) */
uint32_t SizeDR3 : 1;
/** @brief Local Exact Breakpoint #0 Enabled */
uint32_t L0 : 1;
/** @brief Global Exact Breakpoint #0 Enabled */
uint32_t G0 : 1;
/** @brief Local Exact Breakpoint #1 Enabled */
uint32_t L1 : 1;
/** @brief Global Exact Breakpoint #1 Enabled */
uint32_t G1 : 1;
/** @brief Local Exact Breakpoint #2 Enabled */
uint32_t L2 : 1;
/** @brief Global Exact Breakpoint #2 Enabled */
uint32_t G2 : 1;
/** @brief Local Exact Breakpoint #3 Enabled */
uint32_t L3 : 1;
/** @brief Global Exact Breakpoint #3 Enabled */
uint32_t G3 : 1;
/** @brief Local Exact Breakpoint Enabled */
uint32_t LE : 1;
/** @brief Global Exact Breakpoint Enabled */
uint32_t GE : 1;
/** @brief Reserved */
uint32_t Reserved0 : 1;
/** @brief Reserved */
uint32_t Reserved1 : 2;
/** @brief General Detect Enabled */
uint32_t GD : 1;
/** @brief Reserved */
uint32_t Reserved2 : 2;
/** @brief Type of Transaction(s) to Trap */
uint32_t RW0 : 2;
/** @brief Length of Breakpoint #0 */
uint32_t LEN0 : 2;
/** @brief Type of Transaction(s) to Trap */
uint32_t RW1 : 2;
/** @brief Length of Breakpoint #1 */
uint32_t LEN1 : 2;
/** @brief Type of Transaction(s) to Trap */
uint32_t RW2 : 2;
/** @brief Length of Breakpoint #2 */
uint32_t LEN2 : 2;
/** @brief Type of Transaction(s) to Trap */
uint32_t RW3 : 2;
/** @brief Length of Breakpoint #3 */
uint32_t LEN3 : 2;
};
uint32_t raw;
} DR7;
@ -590,45 +627,86 @@ namespace CPU
uint64_t raw;
} __packed EFER;
// ! TODO: UNTESTED!
typedef union DR6
{
struct
{
/** @brief Breakpoint #0 Condition Detected */
uint64_t B0 : 1;
/** @brief Breakpoint #1 Condition Detected */
uint64_t B1 : 1;
/** @brief Breakpoint #2 Condition Detected */
uint64_t B2 : 1;
/** @brief Breakpoint #3 Condition Detected */
uint64_t B3 : 1;
/** @brief Reserved */
uint64_t Reserved0 : 8;
/** @brief Reserved */
uint64_t Reserved1 : 1;
/** @brief Breakpoint Debug Access Detected */
uint64_t BD : 1;
/** @brief Breakpoint Single Step */
uint64_t BS : 1;
/** @brief Breakpoint Task Switch */
uint64_t BT : 1;
/** @brief Reserved */
uint64_t Reserved2 : 15;
/** @brief Reserved */
uint64_t Reserved3 : 32;
};
uint64_t raw;
} DR6;
typedef union DR7
{
struct
{
/** @brief Local DR0 Breakpoint (0) */
uint64_t LocalDR0 : 1;
/** @brief Global DR0 Breakpoint (1) */
uint64_t GlobalDR0 : 1;
/** @brief Local DR1 Breakpoint (2) */
uint64_t LocalDR1 : 1;
/** @brief Global DR1 Breakpoint (3) */
uint64_t GlobalDR1 : 1;
/** @brief Local DR2 Breakpoint (4) */
uint64_t LocalDR2 : 1;
/** @brief Global DR2 Breakpoint (5) */
uint64_t GlobalDR2 : 1;
/** @brief Local DR3 Breakpoint (6) */
uint64_t LocalDR3 : 1;
/** @brief Global DR3 Breakpoint (7) */
uint64_t GlobalDR3 : 1;
/** @brief Reserved [7 - (16-17)] */
uint64_t Reserved : 9;
/** @brief Conditions for DR0 (16-17) */
uint64_t ConditionsDR0 : 1;
/** @brief Size of DR0 Breakpoint (18-19) */
uint64_t SizeDR0 : 1;
/** @brief Conditions for DR1 (20-21) */
uint64_t ConditionsDR1 : 1;
/** @brief Size of DR1 Breakpoint (22-23) */
uint64_t SizeDR1 : 1;
/** @brief Conditions for DR2 (24-25) */
uint64_t ConditionsDR2 : 1;
/** @brief Size of DR2 Breakpoint (26-27) */
uint64_t SizeDR2 : 1;
/** @brief Conditions for DR3 (28-29) */
uint64_t ConditionsDR3 : 1;
/** @brief Size of DR3 Breakpoint (30-31) */
uint64_t SizeDR3 : 1;
/** @brief Local Exact Breakpoint #0 Enabled */
uint64_t L0 : 1;
/** @brief Global Exact Breakpoint #0 Enabled */
uint64_t G0 : 1;
/** @brief Local Exact Breakpoint #1 Enabled */
uint64_t L1 : 1;
/** @brief Global Exact Breakpoint #1 Enabled */
uint64_t G1 : 1;
/** @brief Local Exact Breakpoint #2 Enabled */
uint64_t L2 : 1;
/** @brief Global Exact Breakpoint #2 Enabled */
uint64_t G2 : 1;
/** @brief Local Exact Breakpoint #3 Enabled */
uint64_t L3 : 1;
/** @brief Global Exact Breakpoint #3 Enabled */
uint64_t G3 : 1;
/** @brief Local Exact Breakpoint Enabled */
uint64_t LE : 1;
/** @brief Global Exact Breakpoint Enabled */
uint64_t GE : 1;
/** @brief Reserved */
uint64_t Reserved0 : 1;
/** @brief Reserved */
uint64_t Reserved1 : 2;
/** @brief General Detect Enabled */
uint64_t GD : 1;
/** @brief Reserved */
uint64_t Reserved2 : 2;
/** @brief Type of Transaction(s) to Trap */
uint64_t RW0 : 2;
/** @brief Length of Breakpoint #0 */
uint64_t LEN0 : 2;
/** @brief Type of Transaction(s) to Trap */
uint64_t RW1 : 2;
/** @brief Length of Breakpoint #1 */
uint64_t LEN1 : 2;
/** @brief Type of Transaction(s) to Trap */
uint64_t RW2 : 2;
/** @brief Length of Breakpoint #2 */
uint64_t LEN2 : 2;
/** @brief Type of Transaction(s) to Trap */
uint64_t RW3 : 2;
/** @brief Length of Breakpoint #3 */
uint64_t LEN3 : 2;
/** @brief Reserved */
uint64_t Reserved3 : 32;
};
uint64_t raw;
} DR7;

View File

@ -23,13 +23,15 @@
enum DebugLevel
{
DebugLevelNone = 0,
DebugLevelError = 1,
DebugLevelWarning = 2,
DebugLevelInfo = 3,
DebugLevelDebug = 4,
DebugLevelTrace = 5,
DebugLevelFixme = 6,
DebugLevelUbsan = 7
DebugLevelError,
DebugLevelWarning,
DebugLevelInfo,
DebugLevelDebug,
DebugLevelTrace,
DebugLevelFixme,
DebugLevelUbsan,
DebugLevelStub,
DebugLevelFunction,
};
#ifdef __cplusplus
@ -48,12 +50,15 @@ namespace SysDbg
#ifdef DEBUG
#define debug(Format, ...) SysDbg::WriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define ubsan(Format, ...) SysDbg::WriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define function(Format, ...) SysDbg::WriteLine(DebugLevelFunction, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#else
#define debug(Format, ...)
#define ubsan(Format, ...)
#define function(Format, ...)
#endif
#define trace(Format, ...) SysDbg::WriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define fixme(Format, ...) SysDbg::WriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define stub SysDbg::WriteLine(DebugLevelStub, __FILE__, __LINE__, __FUNCTION__, "stub")
#define locked_error(Format, ...) SysDbg::LockedWriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_warn(Format, ...) SysDbg::LockedWriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
@ -61,12 +66,15 @@ namespace SysDbg
#ifdef DEBUG
#define locked_debug(Format, ...) SysDbg::LockedWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_ubsan(Format, ...) SysDbg::LockedWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_function(Format, ...) SysDbg::LockedWriteLine(DebugLevelFunction, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#else
#define locked_debug(Format, ...)
#define locked_ubsan(Format, ...)
#define locked_function(Format, ...)
#endif
#define locked_trace(Format, ...) SysDbg::LockedWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_fixme(Format, ...) SysDbg::LockedWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_stub SysDbg::LockedWriteLine(DebugLevelStub, __FILE__, __LINE__, __FUNCTION__, "stub")
#else
@ -81,12 +89,15 @@ void SysDbgLockedWriteLine(enum DebugLevel Level, const char *File, int Line, co
#ifdef DEBUG
#define debug(Format, ...) SysDbgWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define ubsan(Format, ...) SysDbgWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define function(Format, ...) SysDbgWriteLine(DebugLevelFunction, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#else
#define debug(Format, ...)
#define ubsan(Format, ...)
#define function(Format, ...)
#endif
#define trace(Format, ...) SysDbgWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define fixme(Format, ...) SysDbgWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define stub SysDbgWriteLine(DebugLevelStub, __FILE__, __LINE__, __FUNCTION__, "stub")
#define locked_error(Format, ...) SysDbgLockedWriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_warn(Format, ...) SysDbgLockedWriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
@ -94,15 +105,16 @@ void SysDbgLockedWriteLine(enum DebugLevel Level, const char *File, int Line, co
#ifdef DEBUG
#define locked_debug(Format, ...) SysDbgLockedWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_ubsan(Format, ...) SysDbgLockedWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_function(Format, ...) SysDbgLockedWriteLine(DebugLevelFunction, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#else
#define locked_debug(Format, ...)
#define locked_ubsan(Format, ...)
#define locked_function(Format, ...)
#endif
#define locked_trace(Format, ...) SysDbgLockedWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_fixme(Format, ...) SysDbgLockedWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define locked_stub SysDbgLockedWriteLine(DebugLevelStub, __FILE__, __LINE__, __FUNCTION__, "stub")
#endif // __cplusplus
#define stub fixme("stub")
#endif // !__FENNIX_KERNEL_DEBUGGER_H__

File diff suppressed because it is too large Load Diff

23
include/emmintrin.h Normal file
View File

@ -0,0 +1,23 @@
/*
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 <https://www.gnu.org/licenses/>.
*/
#ifndef __FENNIX_KERNEL_EMMINTRIN_H__
#define __FENNIX_KERNEL_EMMINTRIN_H__
/* stub header */
#endif // !__FENNIX_KERNEL_EMMINTRIN_H__

View File

@ -23,126 +23,168 @@
#include <filesystem.hpp>
#include <task.hpp>
#include <std.hpp>
#include <vector>
#include <elf.h>
namespace Execute
{
enum BinaryType
{
BinTypeInvalid,
BinTypeFex,
BinTypeELF,
BinTypePE,
BinTypeNE,
BinTypeMZ,
BinTypeUnknown
};
enum BinaryType
{
BinTypeInvalid,
BinTypeFex,
BinTypeELF,
BinTypePE,
BinTypeNE,
BinTypeMZ,
BinTypeUnknown
};
enum ExStatus
{
Unknown,
OK,
Unsupported,
GenericError,
InvalidFile,
InvalidFileFormat,
InvalidFileHeader,
InvalidFileData,
InvalidFileEntryPoint,
InvalidFilePath
};
enum ExStatus
{
Unknown,
OK,
Unsupported,
GenericError,
LoadingProcedureFailed,
InvalidFile,
InvalidFileFormat,
InvalidFileHeader,
InvalidFileData,
InvalidFileEntryPoint,
InvalidFilePath
};
struct SpawnData
{
ExStatus Status;
Tasking::PCB *Process;
Tasking::TCB *Thread;
};
struct SpawnData
{
ExStatus Status;
Tasking::PCB *Process;
Tasking::TCB *Thread;
};
struct SharedLibraries
{
char Identifier[64];
uint64_t Timeout;
int RefCount;
struct SharedLibrary
{
char Identifier[64];
char Path[256];
uint64_t Timeout;
int RefCount;
uintptr_t Address;
uintptr_t MemoryImage;
size_t Length;
};
uintptr_t MemoryImage;
size_t Length;
};
struct ELFBaseLoad
{
bool Success;
bool Interpreter;
SpawnData sd;
Tasking::IP InstructionPointer;
struct ELFBaseLoad
{
bool Success;
bool Interpreter;
SpawnData sd;
Tasking::IP InstructionPointer;
std::vector<const char *> NeededLibraries;
void *MemoryImage;
void *VirtualMemoryImage;
std::vector<const char *> 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;
/* 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<AuxiliaryVector> auxv;
};
/* Same as above, for BaseLoad.cpp only */
std::vector<AuxiliaryVector> auxv;
};
struct MmImage
{
void *Physical;
void *Virtual;
};
struct MmImage
{
void *Physical;
void *Virtual;
};
BinaryType GetBinaryType(void *Image);
BinaryType GetBinaryType(char *Path);
class ELFObject
{
private:
ELFBaseLoad BaseLoadInfo{};
SpawnData Spawn(char *Path, const char **argv, const char **envp);
ELFBaseLoad LoadExec_x86_32(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess);
ELFBaseLoad ELFLoad(char *Path, const char **argv, const char **envp,
Tasking::TaskCompatibility Compatibility = Tasking::TaskCompatibility::Native);
ELFBaseLoad LoadExec_x86_64(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess);
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);
uintptr_t ELFGetSymbolValue(Elf64_Ehdr *Header, uint64_t Table, uint64_t Index);
Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicArrayTags Tag);
ELFBaseLoad LoadDyn_x86_32(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess,
bool IsLibrary);
/**
* @brief Create a ELF Memory Image
*
* @param mem The memory manager to use
* @param pV Memory::Virtual object to use
* @param ElfFile ELF file loaded in memory (FULL FILE)
* @param Length Length of @p ElfFile
* @return The Memory Image (Physical and Virtual)
*/
MmImage ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length);
ELFBaseLoad LoadDyn_x86_64(VirtualFileSystem::File &ElfFile,
Tasking::PCB *TargetProcess,
bool IsLibrary);
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter);
public:
ELFBaseLoad GetBaseLoadInfo() { return BaseLoadInfo; }
bool IsValid() { return BaseLoadInfo.Success; }
ELFBaseLoad ELFLoadRel(void *ElfFile,
VirtualFileSystem::File &ExFile,
Tasking::PCB *Process);
ELFObject(char *AbsolutePath,
Tasking::PCB *TargetProcess,
bool IsLibrary = false);
~ELFObject();
};
ELFBaseLoad ELFLoadExec(void *ElfFile,
VirtualFileSystem::File &ExFile,
Tasking::PCB *Process);
/* Full binary size. */
BinaryType GetBinaryType(void *Image);
ELFBaseLoad ELFLoadDyn(void *ElfFile,
VirtualFileSystem::File &ExFile,
Tasking::PCB *Process);
BinaryType GetBinaryType(char *Path);
void StartExecuteService();
bool AddLibrary(char *Identifier,
void *ElfImage,
size_t Length,
const Memory::Virtual &pV = Memory::Virtual());
void SearchLibrary(char *Identifier);
SharedLibraries GetLibrary(char *Identifier);
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<const char *> *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<Elf64_Phdr> ELFGetSymbolType_x86_64(VirtualFileSystem::File &ElfFile, SegmentTypes Tag);
std::vector<Elf32_Phdr> ELFGetSymbolType_x86_32(VirtualFileSystem::File &ElfFile, SegmentTypes Tag);
std::vector<Elf64_Shdr> ELFGetSections_x86_64(VirtualFileSystem::File &ElfFile, const char *SectionName);
std::vector<Elf32_Shdr> ELFGetSections_x86_32(VirtualFileSystem::File &ElfFile, const char *SectionName);
std::vector<Elf64_Dyn> ELFGetDynamicTag_x86_64(VirtualFileSystem::File &ElfFile, DynamicArrayTags Tag);
std::vector<Elf32_Dyn> 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__

View File

@ -34,8 +34,8 @@ namespace VirtualFileSystem
typedef size_t (*OperationMount)(const char *, unsigned long, const void *);
typedef size_t (*OperationUmount)(int);
typedef size_t (*OperationRead)(Node *node, size_t Offset, size_t Size, uint8_t *Buffer);
typedef size_t (*OperationWrite)(Node *node, size_t Offset, size_t Size, uint8_t *Buffer);
typedef size_t (*OperationRead)(Node *node, size_t Size, uint8_t *Buffer);
typedef size_t (*OperationWrite)(Node *node, size_t Size, uint8_t *Buffer);
typedef void (*OperationOpen)(Node *node, uint8_t Mode, uint8_t Flags);
typedef void (*OperationClose)(Node *node);
typedef size_t (*OperationSync)(void);
@ -46,14 +46,14 @@ namespace VirtualFileSystem
#define MountFSFunction(name) size_t name(const char *unknown0, unsigned long unknown1, const uint8_t *unknown2)
#define UMountFSFunction(name) size_t name(int unknown0)
#define ReadFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Offset, size_t Size, uint8_t *Buffer)
#define WriteFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Offset, size_t Size, uint8_t *Buffer)
#define ReadFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Size, uint8_t *Buffer)
#define WriteFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Size, uint8_t *Buffer)
#define OpenFSFunction(name) void name(VirtualFileSystem::Node *node, uint8_t Mode, uint8_t Flags)
#define CloseFSFunction(name) void name(VirtualFileSystem::Node *node)
#define SyncFSFunction(name) size_t name(void)
#define CreateFSFunction(name) void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength)
#define MkdirFSFunction(name) void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength)
#define SeekFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Offset, uint8_t Whence)
#define SeekFSFunction(name) off_t name(VirtualFileSystem::Node *node, off_t Offset, uint8_t Whence)
enum FileStatus
{
@ -120,7 +120,7 @@ namespace VirtualFileSystem
uint64_t UserIdentifier = 0, GroupIdentifier = 0;
uintptr_t Address = 0;
size_t Length = 0;
size_t Offset = 0;
off_t Offset = 0;
Node *Parent = nullptr;
FileSystemOperations *Operator = nullptr;
/* For root node:
@ -135,9 +135,37 @@ namespace VirtualFileSystem
{
char Name[FILENAME_LENGTH];
FileStatus Status;
Node *node;
bool IsOK()
{
return Status == FileStatus::OK;
}
bool IsOK() { return Status == FileStatus::OK; }
size_t GetLength()
{
return node->Length;
}
std::vector<Node *> GetChildren()
{
return node->Children;
}
NodeFlags GetFlags()
{
return node->Flags;
}
/** @brief Special cases only. */
Node *GetNode()
{
return node;
}
private:
Node *node;
off_t ContextOffset;
friend class Virtual;
};
/* Manage / etc.. */
@ -178,8 +206,9 @@ namespace VirtualFileSystem
File Mount(const char *Path, FileSystemOperations *Operator);
FileStatus Unmount(File &File);
size_t Read(File &File, size_t Offset, uint8_t *Buffer, size_t Size);
size_t Write(File &File, size_t Offset, uint8_t *Buffer, size_t Size);
size_t Read(File &File, uint8_t *Buffer, size_t Size);
size_t Write(File &File, uint8_t *Buffer, size_t Size);
off_t Seek(File &File, off_t Offset, uint8_t Whence);
File Open(const char *Path, Node *Parent = nullptr);
FileStatus Close(File &File);

View File

@ -192,9 +192,17 @@ namespace Memory
uintptr_t Dirty : 1; // 6
uintptr_t PageAttributeTable : 1; // 7
uintptr_t Global : 1; // 8
uintptr_t Available0 : 3; // 9-11
uintptr_t Available0 : 1; // 9
uintptr_t Available1 : 1; // 10
uintptr_t Available2 : 1; // 11
uintptr_t Address : 40; // 12-51
uintptr_t Available1 : 7; // 52-58
uintptr_t Available3 : 1; // 52
uintptr_t Available4 : 1; // 53
uintptr_t Available5 : 1; // 54
uintptr_t Available6 : 1; // 55
uintptr_t Available7 : 1; // 56
uintptr_t Available8 : 1; // 57
uintptr_t Available9 : 1; // 58
uintptr_t ProtectionKey : 4; // 59-62
uintptr_t ExecuteDisable : 1; // 63
#elif defined(a32)
@ -207,7 +215,9 @@ namespace Memory
uintptr_t Dirty : 1; // 6
uintptr_t PageAttributeTable : 1; // 7
uintptr_t Global : 1; // 8
uintptr_t Available0 : 3; // 9-11
uintptr_t Available0 : 1; // 9
uintptr_t Available1 : 1; // 10
uintptr_t Available2 : 1; // 11
uintptr_t Address : 20; // 12-31
#elif defined(aa64)
#endif
@ -285,11 +295,19 @@ namespace Memory
uintptr_t Dirty : 1; // 6
uintptr_t PageSize : 1; // 7
uintptr_t Global : 1; // 8
uintptr_t Available0 : 3; // 9-11
uintptr_t Available0 : 1; // 9
uintptr_t Available1 : 1; // 10
uintptr_t Available2 : 1; // 11
uintptr_t PageAttributeTable : 1; // 12
uintptr_t Reserved0 : 8; // 13-20
uintptr_t Address : 31; // 21-51
uintptr_t Available1 : 7; // 52-58
uintptr_t Available3 : 1; // 52
uintptr_t Available4 : 1; // 53
uintptr_t Available5 : 1; // 54
uintptr_t Available6 : 1; // 55
uintptr_t Available7 : 1; // 56
uintptr_t Available8 : 1; // 57
uintptr_t Available9 : 1; // 58
uintptr_t ProtectionKey : 4; // 59-62
uintptr_t ExecuteDisable : 1; // 63
} TwoMB;
@ -319,7 +337,9 @@ namespace Memory
uintptr_t Dirty : 1; // 6
uintptr_t PageSize : 1; // 7
uintptr_t Global : 1; // 8
uintptr_t Available0 : 3; // 9-11
uintptr_t Available0 : 1; // 9
uintptr_t Available1 : 1; // 10
uintptr_t Available2 : 1; // 11
uintptr_t PageAttributeTable : 1; // 12
uintptr_t Address0 : 8; // 13-20
uintptr_t Reserved0 : 1; // 21
@ -395,11 +415,19 @@ namespace Memory
uintptr_t Dirty : 1; // 6
uintptr_t PageSize : 1; // 7
uintptr_t Global : 1; // 8
uintptr_t Available0 : 3; // 9-11
uintptr_t Available0 : 1; // 9
uintptr_t Available1 : 1; // 10
uintptr_t Available2 : 1; // 11
uintptr_t PageAttributeTable : 1; // 12
uintptr_t Reserved0 : 17; // 13-29
uintptr_t Address : 22; // 30-51
uintptr_t Available1 : 7; // 52-58
uintptr_t Available3 : 1; // 52
uintptr_t Available4 : 1; // 53
uintptr_t Available5 : 1; // 54
uintptr_t Available6 : 1; // 55
uintptr_t Available7 : 1; // 56
uintptr_t Available8 : 1; // 57
uintptr_t Available9 : 1; // 58
uintptr_t ProtectionKey : 4; // 59-62
uintptr_t ExecuteDisable : 1; // 63
} OneGB;
@ -754,6 +782,21 @@ namespace Memory
*/
void *GetPhysical(void *VirtualAddress);
/**
* @brief Get map type of the page.
* @param VirtualAddress Virtual address of the page.
* @return Map type of the page.
*/
MapType GetMapType(void *VirtualAddress);
#ifdef a64
PageMapLevel5 *GetPML5(void *VirtualAddress, MapType Type = MapType::FourKB);
PageMapLevel4 *GetPML4(void *VirtualAddress, MapType Type = MapType::FourKB);
PageDirectoryPointerTableEntry *GetPDPTE(void *VirtualAddress, MapType Type = MapType::FourKB);
#endif /* a64 */
PageDirectoryEntry *GetPDE(void *VirtualAddress, MapType Type = MapType::FourKB);
PageTableEntry *GetPTE(void *VirtualAddress, MapType Type = MapType::FourKB);
/**
* @brief Map page.
*

View File

@ -20,7 +20,7 @@
#include <types.h>
// some of the code is from: https://github.com/dotnet/llilc/blob/main/include/clr/ntimage.h
/* Some of the code is from: https://github.com/dotnet/llilc/blob/main/include/clr/ntimage.h */
#define near /* __near */
#define far /* __far */
@ -110,61 +110,61 @@ typedef double DOUBLE;
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
typedef struct _IMAGE_DOS_HEADER // DOS .EXE header
typedef struct _IMAGE_DOS_HEADER /* DOS .EXE header */
{
USHORT e_magic; // Magic number
USHORT e_cblp; // Bytes on last page of file
USHORT e_cp; // Pages in file
USHORT e_crlc; // Relocations
USHORT e_cparhdr; // Size of header in paragraphs
USHORT e_minalloc; // Minimum extra paragraphs needed
USHORT e_maxalloc; // Maximum extra paragraphs needed
USHORT e_ss; // Initial (relative) SS value
USHORT e_sp; // Initial SP value
USHORT e_csum; // Checksum
USHORT e_ip; // Initial IP value
USHORT e_cs; // Initial (relative) CS value
USHORT e_lfarlc; // File address of relocation table
USHORT e_ovno; // Overlay number
USHORT e_res[4]; // Reserved words
USHORT e_oemid; // OEM identifier (for e_oeminfo)
USHORT e_oeminfo; // OEM information; e_oemid specific
USHORT e_res2[10]; // Reserved words
USHORT e_lfanew; // File address of new exe header
USHORT e_magic; /* Magic number */
USHORT e_cblp; /* Bytes on last page of file */
USHORT e_cp; /* Pages in file */
USHORT e_crlc; /* Relocations */
USHORT e_cparhdr; /* Size of header in paragraphs */
USHORT e_minalloc; /* Minimum extra paragraphs needed */
USHORT e_maxalloc; /* Maximum extra paragraphs needed */
USHORT e_ss; /* Initial (relative) SS value */
USHORT e_sp; /* Initial SP value */
USHORT e_csum; /* Checksum */
USHORT e_ip; /* Initial IP value */
USHORT e_cs; /* Initial (relative) CS value */
USHORT e_lfarlc; /* File address of relocation table */
USHORT e_ovno; /* Overlay number */
USHORT e_res[4]; /* Reserved words */
USHORT e_oemid; /* OEM identifier (for e_oeminfo) */
USHORT e_oeminfo; /* OEM information; e_oemid specific */
USHORT e_res2[10]; /* Reserved words */
USHORT e_lfanew; /* File address of new exe header */
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
typedef struct _IMAGE_OS2_HEADER // OS/2 .EXE header
typedef struct _IMAGE_OS2_HEADER /* OS/2 .EXE header */
{
USHORT ne_magic; // Magic number
UCHAR ne_ver; // Version number
UCHAR ne_rev; // Revision number
USHORT ne_enttab; // Offset of Entry Table
USHORT ne_cbenttab; // Number of bytes in Entry Table
UINT ne_crc; // Checksum of whole file
USHORT ne_flags; // Flag word
USHORT ne_autodata; // Automatic data segment number
USHORT ne_heap; // Initial heap allocation
USHORT ne_stack; // Initial stack allocation
UINT ne_csip; // Initial CS:IP setting
UINT ne_sssp; // Initial SS:SP setting
USHORT ne_cseg; // Count of file segments
USHORT ne_cmod; // Entries in Module Reference Table
USHORT ne_cbnrestab; // Size of non-resident name table
USHORT ne_segtab; // Offset of Segment Table
USHORT ne_rsrctab; // Offset of Resource Table
USHORT ne_restab; // Offset of resident name table
USHORT ne_modtab; // Offset of Module Reference Table
USHORT ne_imptab; // Offset of Imported Names Table
UINT ne_nrestab; // Offset of Non-resident Names Table
USHORT ne_cmovent; // Count of movable entries
USHORT ne_align; // Segment alignment shift count
USHORT ne_cres; // Count of resource segments
UCHAR ne_exetyp; // Target Operating system
UCHAR ne_flagsothers; // Other .EXE flags
USHORT ne_pretthunks; // offset to return thunks
USHORT ne_psegrefbytes; // offset to segment ref. bytes
USHORT ne_swaparea; // Minimum code swap area size
USHORT ne_expver; // Expected Windows version number
USHORT ne_magic; /* Magic number */
UCHAR ne_ver; /* Version number */
UCHAR ne_rev; /* Revision number */
USHORT ne_enttab; /* Offset of Entry Table */
USHORT ne_cbenttab; /* Number of bytes in Entry Table */
UINT ne_crc; /* Checksum of whole file */
USHORT ne_flags; /* Flag word */
USHORT ne_autodata; /* Automatic data segment number */
USHORT ne_heap; /* Initial heap allocation */
USHORT ne_stack; /* Initial stack allocation */
UINT ne_csip; /* Initial CS:IP setting */
UINT ne_sssp; /* Initial SS:SP setting */
USHORT ne_cseg; /* Count of file segments */
USHORT ne_cmod; /* Entries in Module Reference Table */
USHORT ne_cbnrestab; /* Size of non-resident name table */
USHORT ne_segtab; /* Offset of Segment Table */
USHORT ne_rsrctab; /* Offset of Resource Table */
USHORT ne_restab; /* Offset of resident name table */
USHORT ne_modtab; /* Offset of Module Reference Table */
USHORT ne_imptab; /* Offset of Imported Names Table */
UINT ne_nrestab; /* Offset of Non-resident Names Table */
USHORT ne_cmovent; /* Count of movable entries */
USHORT ne_align; /* Segment alignment shift count */
USHORT ne_cres; /* Count of resource segments */
UCHAR ne_exetyp; /* Target Operating system */
UCHAR ne_flagsothers; /* Other .EXE flags */
USHORT ne_pretthunks; /* offset to return thunks */
USHORT ne_psegrefbytes; /* offset to segment ref. bytes */
USHORT ne_swaparea; /* Minimum code swap area size */
USHORT ne_expver; /* Expected Windows version number */
} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
typedef struct _IMAGE_SECTION_HEADER

View File

@ -19,6 +19,7 @@
#define __FENNIX_KERNEL_SMP_H__
#include <task.hpp>
#include <cxxabi.h>
#include <types.h>
#include <atomic>
@ -61,6 +62,9 @@ struct CPUData
/** @brief Current running thread */
std::atomic<Tasking::TCB *> CurrentThread;
/** @brief Unwind data */
__cxa_eh_globals EHGlobals;
/** @brief Architecture-specific data. */
CPUArchData Data;

View File

@ -32,10 +32,13 @@
namespace Tasking
{
typedef unsigned long IP;
typedef __UINTPTR_TYPE__ IPOffset;
typedef unsigned long UPID;
typedef unsigned long UTID;
/** @brief Instruction Pointer */
typedef __UINTPTR_TYPE__ IP;
/** @brief Process ID */
typedef int PID;
/** @brief Thread ID */
typedef int TID;
/* @brief Token */
typedef __UINTPTR_TYPE__ Token;
enum TaskArchitecture
@ -84,6 +87,16 @@ namespace Tasking
Critical = 10
};
enum KillErrorCodes : int
{
KILL_SCHEDULER_DESTRUCTION = -0xFFFF,
KILL_CXXABI_EXCEPTION = -0xECE97,
KILL_SYSCALL = -0xCA11,
KILL_OOM = -0x1008,
KILL_ERROR = -0x1,
KILL_SUCCESS = 0,
};
struct TaskSecurity
{
TaskTrustLevel TrustLevel;
@ -109,11 +122,10 @@ namespace Tasking
struct TCB
{
UTID ID;
TID ID;
char Name[256];
struct PCB *Parent;
IP EntryPoint;
IPOffset Offset;
int ExitCode;
Memory::StackGuard *Stack;
Memory::MemMgr *Memory;
@ -174,11 +186,34 @@ namespace Tasking
trace("Setting kernel debug mode of thread %s to %s", Name, Enable ? "true" : "false");
Security.IsKernelDebugEnabled = Enable;
}
void SYSV_ABI_Call(uintptr_t Arg1 = 0,
uintptr_t Arg2 = 0,
uintptr_t Arg3 = 0,
uintptr_t Arg4 = 0,
uintptr_t Arg5 = 0,
uintptr_t Arg6 = 0,
void *Function = nullptr)
{
CriticalSection cs;
#if defined(a64)
this->Registers.rdi = Arg1;
this->Registers.rsi = Arg2;
this->Registers.rdx = Arg3;
this->Registers.rcx = Arg4;
this->Registers.r8 = Arg5;
this->Registers.r9 = Arg6;
if (Function != nullptr)
this->Registers.rip = (uint64_t)Function;
#else
#warning "SYSV ABI not implemented for this architecture"
#endif
}
};
struct PCB
{
UPID ID;
PID ID;
char Name[256];
PCB *Parent;
int ExitCode;
@ -243,8 +278,8 @@ namespace Tasking
{
private:
Security SecurityManager;
UPID NextPID = 0;
UTID NextTID = 0;
PID NextPID = 0;
TID NextTID = 0;
std::vector<PCB *> ProcessList;
PCB *IdleProcess = nullptr;
@ -289,6 +324,7 @@ namespace Tasking
Security *GetSecurityManager() { return &SecurityManager; }
void CleanupProcessesThread();
void Panic() { StopScheduler = true; }
bool IsPanic() { return StopScheduler; }
__always_inline inline void Schedule()
{
#if defined(a86)
@ -301,16 +337,16 @@ namespace Tasking
void RevertProcessCreation(PCB *Process);
void RevertThreadCreation(TCB *Thread);
void KillThread(TCB *tcb, int Code)
void KillThread(TCB *tcb, enum KillErrorCodes Code)
{
tcb->Status = TaskStatus::Terminated;
tcb->ExitCode = Code;
tcb->ExitCode = (int)Code;
}
void KillProcess(PCB *pcb, int Code)
void KillProcess(PCB *pcb, enum KillErrorCodes Code)
{
pcb->Status = TaskStatus::Terminated;
pcb->ExitCode = Code;
pcb->ExitCode = (int)Code;
}
/**
@ -325,9 +361,9 @@ namespace Tasking
*/
TCB *GetCurrentThread();
PCB *GetProcessByID(UPID ID);
PCB *GetProcessByID(PID ID);
TCB *GetThreadByID(UTID ID);
TCB *GetThreadByID(TID ID);
/** @brief Wait for process to terminate */
void WaitForProcess(PCB *pcb);
@ -356,7 +392,6 @@ namespace Tasking
const char **argv = nullptr,
const char **envp = nullptr,
const std::vector<AuxiliaryVector> &auxv = std::vector<AuxiliaryVector>(),
IPOffset Offset = 0,
TaskArchitecture Architecture = TaskArchitecture::x64,
TaskCompatibility Compatibility = TaskCompatibility::Native,
bool ThreadNotReady = false);

View File

@ -78,8 +78,19 @@ typedef __builtin_va_list va_list;
#define offsetof(type, member) __builtin_offsetof(type, member)
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MAX(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
#define MIN(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})
#define ROUND_UP(x, y) (((x) + (y)-1) & ~((y)-1))
#define ROUND_DOWN(x, y) ((x) & ~((y)-1))
@ -183,6 +194,9 @@ typedef __SIG_ATOMIC_TYPE__ sig_atomic_t;
// TODO: ssize_t
typedef intptr_t ssize_t;
typedef long off_t;
typedef long long off64_t;
#define INT8_MAX __INT8_MAX__
#define INT8_MIN (-INT8_MAX - 1)
#define UINT8_MAX __UINT8_MAX__
@ -359,6 +373,9 @@ typedef uint48_t uint_fast48_t;
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define PUBLIC __visibility("default")
#define PRIVATE __visibility("hidden")
#define SafeFunction __no_stack_protector __no_sanitize_address __no_sanitize_undefined __no_address_safety_analysis __no_sanitize_thread
#define NIF __no_instrument_function