From 22c6d41b25faac172bf290dc06e75ca1ea60470b Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 7 Jan 2026 21:32:05 +0100 Subject: feat: kernel: Loader, IPC, and Linker improvements. Signed-off-by: Amlal El Mahrouss --- src/kernel/HALKit/AMD64/HalKernelMain.cc | 7 ++-- src/kernel/KernelKit/PEFCodeMgr.h | 5 +-- src/kernel/NeKit/ErrorOr.h | 4 +- src/kernel/NeKit/Ref.h | 6 +-- src/kernel/NetworkKit/IPC.h | 2 +- src/kernel/src/Network/IPCMessage.cc | 6 +-- src/kernel/src/PE32CodeMgr.cc | 17 +++++--- src/kernel/src/PEFCodeMgr.cc | 72 +++++++++++++++++--------------- 8 files changed, 62 insertions(+), 57 deletions(-) (limited to 'src/kernel') diff --git a/src/kernel/HALKit/AMD64/HalKernelMain.cc b/src/kernel/HALKit/AMD64/HalKernelMain.cc index ed82b60f..f8d0ca4b 100644 --- a/src/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/src/kernel/HALKit/AMD64/HalKernelMain.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -145,11 +146,9 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) { UserProcessScheduler::The().SwitchTeam(kRTUserTeam); - // TODO: Prosan, Process sanitizer. - rtl_create_user_process([]() -> void { while (YES); }, "ProSan"); + PEFLoader ldr("/system/init.out"); - // TODO: Vet sanitizer. - rtl_create_user_process([]() -> void { while (YES); }, "VetSan"); + if (ldr.IsLoaded()) rtl_create_user_process(ldr, UserProcess::ExecutableKind::kExecutableKind); HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); diff --git a/src/kernel/KernelKit/PEFCodeMgr.h b/src/kernel/KernelKit/PEFCodeMgr.h index e5daa4f5..7bdf4d2d 100644 --- a/src/kernel/KernelKit/PEFCodeMgr.h +++ b/src/kernel/KernelKit/PEFCodeMgr.h @@ -65,9 +65,8 @@ class PEFLoader : public ILoader { BOOL fBad{}; }; -namespace Utils { - ProcessID rtl_create_user_process(PEFLoader& exec, const UserProcess::ExecutableKind& procKind); -} // namespace Utils +ProcessID rtl_create_user_process(PEFLoader& exec, const UserProcess::ExecutableKind& procKind); + } // namespace Kernel #endif // ifndef _INC_CODE_MANAGER_PEF_H_ diff --git a/src/kernel/NeKit/ErrorOr.h b/src/kernel/NeKit/ErrorOr.h index 722d8f84..4289a890 100644 --- a/src/kernel/NeKit/ErrorOr.h +++ b/src/kernel/NeKit/ErrorOr.h @@ -15,8 +15,8 @@ namespace Kernel { template class ErrorOr final { public: - explicit ErrorOr() = default; - ~ErrorOr() = default; + ErrorOr() = default; + ~ErrorOr() = default; public: using RefType = Ref; diff --git a/src/kernel/NeKit/Ref.h b/src/kernel/NeKit/Ref.h index 267fc217..2c669611 100644 --- a/src/kernel/NeKit/Ref.h +++ b/src/kernel/NeKit/Ref.h @@ -19,8 +19,8 @@ namespace Kernel { template class Ref final { public: - explicit Ref() = default; - ~Ref() = default; + Ref() = default; + ~Ref() = default; public: using Type = T; @@ -76,9 +76,7 @@ class NonNullRef final { NonNullRef() = delete; NonNullRef(Type* ref) : fRef(ref) {} - NonNullRef(nullPtr ref) = delete; - NonNullRef(RefType ref) : fRef(ref) {} Ref& operator->() { diff --git a/src/kernel/NetworkKit/IPC.h b/src/kernel/NetworkKit/IPC.h index 27f39079..8da5fc69 100644 --- a/src/kernel/NetworkKit/IPC.h +++ b/src/kernel/NetworkKit/IPC.h @@ -53,7 +53,6 @@ enum { kIPCLockUsed = 2, }; -/// @brief IPC connection header, message cannot be greater than 6K. typedef struct IPC_MSG final { UInt32 IpcHeaderMagic; // cRemoteHeaderMagic UInt8 IpcEndianess; // 0 : LE, 1 : BE @@ -64,6 +63,7 @@ typedef struct IPC_MSG final { UInt32 IpcMsg; UInt32 IpcMsgSz; UInt32 IpcLock; + SizeT IpcSize; UInt8* IpcData; /// @brief Passes the message to target, could be anything, HTTP packet, JSON or whatever. static Bool Pass(IPC_MSG* self, IPC_MSG* target); diff --git a/src/kernel/src/Network/IPCMessage.cc b/src/kernel/src/Network/IPCMessage.cc index 7db9f022..3773ac46 100644 --- a/src/kernel/src/Network/IPCMessage.cc +++ b/src/kernel/src/Network/IPCMessage.cc @@ -100,8 +100,8 @@ Bool ipc_construct_packet(_Output IPC_MSG** pckt_in) { /***********************************************************************************/ Bool IPC_MSG::Pass(IPC_MSG* src, IPC_MSG* target) { if (src && target && (target != src)) { - if (src->IpcMsgSz > target->IpcMsgSz) return No; - if (target->IpcMsgSz > src->IpcMsgSz) return No; + if (src->IpcSize > target->IpcSize) return No; + if (target->IpcSize > src->IpcSize) return No; auto timeout = 0U; @@ -115,7 +115,7 @@ Bool IPC_MSG::Pass(IPC_MSG* src, IPC_MSG* target) { ++target->IpcLock; - rt_copy_memory_safe(src->IpcData, target->IpcData, src->IpcMsgSz, target->IpcMsgSz); + rt_copy_memory_safe(src->IpcData, target->IpcData, src->IpcSize, target->IpcSize); --target->IpcLock; diff --git a/src/kernel/src/PE32CodeMgr.cc b/src/kernel/src/PE32CodeMgr.cc index a7b1057e..517900c4 100644 --- a/src/kernel/src/PE32CodeMgr.cc +++ b/src/kernel/src/PE32CodeMgr.cc @@ -54,7 +54,7 @@ PE32Loader::PE32Loader(const Char* path) : fCachedBlob(static_cast(null auto kPefHeader = "PE32_BLOB"; fCachedBlob = fFile->Read(kPefHeader, 0); - if (fCachedBlob.HasError()) fBad = YES; + if (fCachedBlob.HasError() || !fCachedBlob.Leak().Leak()) fBad = YES; } /***********************************************************************************/ @@ -62,9 +62,10 @@ PE32Loader::PE32Loader(const Char* path) : fCachedBlob(static_cast(null /***********************************************************************************/ PE32Loader::~PE32Loader() { - if (fCachedBlob) mm_free_ptr(fCachedBlob.Leak().Leak()); - - fFile.Reset(); + if (fCachedBlob) { + mm_free_ptr(fCachedBlob.Leak().Leak()); + fFile.Reset(); + } } /***********************************************************************************/ @@ -118,7 +119,7 @@ ErrorOr PE32Loader::FindSectionByName(const Char* name) { /***********************************************************************************/ ErrorOr PE32Loader::FindSymbol(const Char* name, Int32 kind) { - if (!name || *name == 0) return ErrorOr{kErrorInvalidData}; + if (!fCachedBlob || fBad || !name) return ErrorOr{kErrorInvalidData}; auto section_name = "\0"; @@ -193,7 +194,7 @@ ErrorOr PE32Loader::FindStart() { /// @brief Tells if the executable is loaded or not. /// @return Whether it's not bad and is cached. bool PE32Loader::IsLoaded() { - return !fBad && fCachedBlob; + return !fBad; } const Char* PE32Loader::Path() { @@ -237,6 +238,10 @@ namespace Utils { symname = ErrorOr{(VoidPtr) rt_alloc_string("USER_PROCESS_PE32+")}; } + if (!symname) { + return -1; + } + ProcessID id = UserProcessScheduler::The().Spawn(reinterpret_cast(symname.Leak().Leak()), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); diff --git a/src/kernel/src/PEFCodeMgr.cc b/src/kernel/src/PEFCodeMgr.cc index 7585b553..79ec97e0 100644 --- a/src/kernel/src/PEFCodeMgr.cc +++ b/src/kernel/src/PEFCodeMgr.cc @@ -49,7 +49,7 @@ namespace Detail { /// @param blob file blob. /***********************************************************************************/ PEFLoader::PEFLoader(const VoidPtr blob) : fCachedBlob(blob) { - if (fCachedBlob.HasError()) { + if (fCachedBlob.Leak().Leak()) { this->fBad = YES; return; } @@ -94,7 +94,7 @@ PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false) /// @note zero here means that the FileMgr will read every container header inside the file. fCachedBlob = fFile->Read(kPefHeader, 0UL); - if (!fCachedBlob) { + if (!fCachedBlob.Leak().Leak()) { this->fBad = YES; return; } @@ -130,8 +130,10 @@ PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false) /// @brief PEF destructor. /***********************************************************************************/ PEFLoader::~PEFLoader() { - if (fCachedBlob) mm_free_ptr(fCachedBlob.Leak().Leak()); - fFile.Reset(); + if (fCachedBlob) { + mm_free_ptr(fCachedBlob.Leak().Leak()); + fFile.Reset(); + } } /***********************************************************************************/ @@ -140,7 +142,7 @@ PEFLoader::~PEFLoader() { /// @param kind kind of symbol we want. /***********************************************************************************/ ErrorOr PEFLoader::FindSymbol(const Char* name, Int32 kind) { - if (!fCachedBlob || fBad || !name) return ErrorOr{kErrorInvalidData}; + if (!fCachedBlob.Leak().Leak() || fBad || !name) return ErrorOr{kErrorInvalidData}; auto blob = fFile->Read(name, sizeof(PEFCommandHeader)); @@ -255,7 +257,7 @@ ErrorOr PEFLoader::FindStart() { /// @brief Tells if the executable is loaded or not. /// @return Whether it's not bad and is cached. bool PEFLoader::IsLoaded() { - return !fBad && fCachedBlob; + return !fBad; } const Char* PEFLoader::Path() { @@ -286,44 +288,46 @@ ErrorOr PEFLoader::GetBlob() { return ErrorOr{this->fCachedBlob}; } -namespace Utils { - ProcessID rtl_create_user_process(PEFLoader& exec, - const UserProcess::ExecutableKind& process_kind) { - auto errOrStart = exec.FindStart(); +ProcessID rtl_create_user_process(PEFLoader& exec, + const UserProcess::ExecutableKind& process_kind) { + auto errOrStart = exec.FindStart(); - if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID; + if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID; - auto symname = exec.FindSymbol(kPefNameSymbol, kPefData); + auto symname = exec.FindSymbol(kPefNameSymbol, kPefData); - if (!symname) { - symname = ErrorOr{(VoidPtr) rt_alloc_string("USER_PROCESS_PEF")}; - } + if (!symname) { + symname = ErrorOr{(VoidPtr) rt_alloc_string("USER_PROCESS_PEF")}; + } - ProcessID id = - UserProcessScheduler::The().Spawn(reinterpret_cast(symname.Leak().Leak()), - errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); + if (!symname) { + return -1; + } - mm_free_ptr(symname.Leak().Leak()); + ProcessID id = + UserProcessScheduler::The().Spawn(reinterpret_cast(symname.Leak().Leak()), + errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); - if (id != kSchedInvalidPID) { - auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData); + mm_free_ptr(symname.Leak().Leak()); - if (!stacksym) { - stacksym = ErrorOr{(VoidPtr) new UIntPtr(kSchedMaxStackSz)}; - } + if (id != kSchedInvalidPID) { + auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData); - if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) { - *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz; - } - - UserProcessScheduler::The().TheCurrentTeam().Leak().AsArray()[id].Kind = process_kind; - UserProcessScheduler::The().TheCurrentTeam().Leak().AsArray()[id].StackSize = - *(UIntPtr*) stacksym.Leak().Leak(); + if (!stacksym) { + stacksym = ErrorOr{(VoidPtr) new UIntPtr(kSchedMaxStackSz)}; + } - mm_free_ptr(stacksym.Leak().Leak()); + if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) { + *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz; } - return id; + UserProcessScheduler::The().TheCurrentTeam().Leak().AsArray()[id].Kind = process_kind; + UserProcessScheduler::The().TheCurrentTeam().Leak().AsArray()[id].StackSize = + *(UIntPtr*) stacksym.Leak().Leak(); + + mm_free_ptr(stacksym.Leak().Leak()); } -} // namespace Utils + + return id; +} } // namespace Kernel -- cgit v1.2.3