summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/src/PEFCodeMgr.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-11-24 03:02:43 +0100
committerAmlal El Mahrouss <amlal@nekernel.org>2025-11-24 03:02:43 +0100
commit83d870e58457a1d335a1d9b9966a6a1887cc297b (patch)
tree72888f88c7728c82f3f6df1f4f70591de15eab36 /dev/kernel/src/PEFCodeMgr.cc
parentab37adbacf0f33845804c788b39680cd754752a8 (diff)
feat! breaking changes on kernel sources.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/src/PEFCodeMgr.cc')
-rw-r--r--dev/kernel/src/PEFCodeMgr.cc335
1 files changed, 0 insertions, 335 deletions
diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc
deleted file mode 100644
index c0a79c32..00000000
--- a/dev/kernel/src/PEFCodeMgr.cc
+++ /dev/null
@@ -1,335 +0,0 @@
-/* ========================================
-
- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.
- Copyright (C) 2025, Amlal El Mahrouss & NeKernel contributors, licensed under the Apache 2.0
-license.
-
-======================================== */
-
-#include <ArchKit/ArchKit.h>
-#include <KernelKit/DebugOutput.h>
-#include <KernelKit/HeapMgr.h>
-#include <KernelKit/PEFCodeMgr.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <NeKit/Defines.h>
-#include <NeKit/KString.h>
-#include <NeKit/KernelPanic.h>
-#include <NeKit/OwnPtr.h>
-#include <NeKit/Utils.h>
-
-/// @author Amlal El Mahrouss (amlal@nekernel.org)
-/// @brief PEF backend for the Code Manager.
-/// @file PEFCodeMgr.cc
-
-/// @brief PEF stack size symbol.
-#define kPefStackSizeSymbol "__PEFSizeOfReserveStack"
-#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap"
-#define kPefNameSymbol "__PEFProgramName"
-
-namespace Kernel {
-namespace Detail {
- /***********************************************************************************/
- /// @brief Get the PEF platform signature according to the compiled architecture.
- /***********************************************************************************/
- static UInt32 ldr_get_platform(void) noexcept {
-#if defined(__NE_32X0__)
- return kPefArch32x0;
-#elif defined(__NE_64X0__)
- return kPefArch64x0;
-#elif defined(__NE_AMD64__)
- return kPefArchAMD64;
-#elif defined(__NE_PPC64__)
- return kPefArchPowerPC;
-#elif defined(__NE_ARM64__)
- return kPefArchARM64;
-#else
- return kPefArchInvalid;
-#endif // __32x0__ || __64x0__ || __x86_64__
- }
-} // namespace Detail
-
-/***********************************************************************************/
-/// @brief PEF loader constructor w/ blob.
-/// @param blob file blob.
-/***********************************************************************************/
-PEFLoader::PEFLoader(const VoidPtr blob) : fCachedBlob(blob) {
- MUST_PASS(fCachedBlob);
-
- if (!fCachedBlob) {
- this->fBad = YES;
- return;
- }
-
- PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
-
- if (container->Abi == kPefAbi &&
- container->Count >=
- 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */
- if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] &&
- container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] &&
- container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4]) {
- return;
- } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] &&
- container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] &&
- container->Magic[4] == kPefMagicFat[4]) {
- /// This is a fat binary. Treat it as such.
- this->fFatBinary = YES;
- return;
- }
- }
-
- kout << "PEFLoader: warning: Binary format error!\r";
-
- this->fFatBinary = NO;
- this->fBad = YES;
-
- if (this->fCachedBlob) mm_free_ptr(this->fCachedBlob);
- this->fCachedBlob = nullptr;
-}
-
-/***********************************************************************************/
-/// @brief PEF loader constructor.
-/// @param path the filesystem path.
-/***********************************************************************************/
-PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false), fBad(false) {
- fFile.New(const_cast<Char*>(path), kRestrictRB);
- fPath = KStringBuilder::Construct(path).Leak();
-
- constexpr auto kPefHeader = "PEF_CONTAINER";
-
- /// @note zero here means that the FileMgr will read every container header inside the file.
- fCachedBlob = fFile->Read(kPefHeader, 0UL);
-
- if (!fCachedBlob) {
- this->fBad = YES;
- return;
- }
-
- PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
-
- if (container->Abi == kPefAbi &&
- container->Count >=
- 3) { /* if same ABI, AND: .text, .bss, .data (or at least similar) exists */
- if (container->Cpu == Detail::ldr_get_platform() && container->Magic[0] == kPefMagic[0] &&
- container->Magic[1] == kPefMagic[1] && container->Magic[2] == kPefMagic[2] &&
- container->Magic[3] == kPefMagic[3] && container->Magic[4] == kPefMagic[4]) {
- return;
- } else if (container->Magic[0] == kPefMagicFat[0] && container->Magic[1] == kPefMagicFat[1] &&
- container->Magic[2] == kPefMagicFat[2] && container->Magic[3] == kPefMagicFat[3] &&
- container->Magic[4] == kPefMagicFat[4]) {
- /// This is a fat binary, treat it as such.
- this->fFatBinary = YES;
- return;
- }
- }
-
- kout << "PEFLoader: warning: Binary format error!\r";
-
- this->fFatBinary = NO;
- this->fBad = YES;
-
- if (this->fCachedBlob) mm_free_ptr(this->fCachedBlob);
- this->fCachedBlob = nullptr;
-}
-
-/***********************************************************************************/
-/// @brief PEF destructor.
-/***********************************************************************************/
-PEFLoader::~PEFLoader() {
- if (fCachedBlob) mm_free_ptr(fCachedBlob);
-
- fFile.Delete();
-}
-
-/***********************************************************************************/
-/// @brief Finds the symbol according to it's name.
-/// @param name name of symbol.
-/// @param kind kind of symbol we want.
-/***********************************************************************************/
-ErrorOr<VoidPtr> PEFLoader::FindSymbol(const Char* name, Int32 kind) {
- if (!fCachedBlob || fBad || !name) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- auto blob = fFile->Read(name, sizeof(PEFCommandHeader));
-
- if (!blob) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
-
- if (!container) return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- PEFCommandHeader* command_header = reinterpret_cast<PEFCommandHeader*>(blob);
-
- if (command_header->VMSize < 1 || command_header->VMAddress == 0)
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- /// fat binary check.
- if (command_header->Cpu != container->Cpu && !this->fFatBinary)
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-
- const auto kMangleCharacter = '$';
- const Char* kContainerKinds[] = {".code64", ".data64", ".zero64", nullptr};
-
- ErrorOr<KString> error_or_symbol;
-
- switch (kind) {
- case kPefCode: {
- error_or_symbol = KStringBuilder::Construct(kContainerKinds[0]); // code symbol.
- break;
- }
- case kPefData: {
- error_or_symbol = KStringBuilder::Construct(kContainerKinds[1]); // data symbol.
- break;
- }
- case kPefZero: {
- error_or_symbol = KStringBuilder::Construct(kContainerKinds[2]); // block starting symbol.
- break;
- }
- default:
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- // prevent that from the kernel's mode perspective, let that happen if it
- // were a user process.
- }
-
- Char* unconst_symbol = const_cast<Char*>(name);
-
- for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i) {
- if (rt_is_space(unconst_symbol[i])) {
- unconst_symbol[i] = kMangleCharacter;
- }
- }
-
- error_or_symbol.Leak().Leak() += name;
-
- if (KStringBuilder::Equals(command_header->Name, error_or_symbol.Leak().Leak().CData())) {
- if (command_header->Kind == kind) {
- if (command_header->Cpu != Detail::ldr_get_platform()) {
- if (!this->fFatBinary) {
- mm_free_ptr(blob);
- blob = nullptr;
-
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- }
- }
-
- Char* container_blob_value = new Char[command_header->VMSize];
-
- rt_copy_memory_safe((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value,
- command_header->VMSize, command_header->VMSize);
-
- mm_free_ptr(blob);
-
- kout << "PEFLoader: info: Load stub: " << command_header->Name << "!\r";
-
- Int32 ret = 0;
- SizeT pages_count = (command_header->VMSize + kPageSize - 1) / kPageSize;
-
- for (SizeT i_vm{}; i_vm < pages_count; ++i_vm) {
- ret = HAL::mm_map_page(
- (VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)),
- (VoidPtr) (HAL::mm_get_page_addr(container_blob_value) + (i_vm * kPageSize)),
- HAL::kMMFlagsPresent | HAL::kMMFlagsUser);
-
- if (ret != kErrorSuccess) {
- /// We set the VMAddress to nullptr, if the mapping fail here.
- for (SizeT i_vm_unmap{}; i_vm_unmap < i_vm; ++i_vm_unmap) {
- ret = HAL::mm_map_page((VoidPtr) (command_header->VMAddress + (i_vm * kPageSize)),
- nullptr, HAL::kMMFlagsPresent | HAL::kMMFlagsUser);
- }
-
- delete[] container_blob_value;
- container_blob_value = nullptr;
-
- return ErrorOr<VoidPtr>{kErrorInvalidData};
- }
- }
-
- return ErrorOr<VoidPtr>{container_blob_value};
- }
- }
-
- mm_free_ptr(blob);
- return ErrorOr<VoidPtr>{kErrorInvalidData};
-}
-
-/// @brief Finds the executable entrypoint.
-/// @return
-ErrorOr<VoidPtr> PEFLoader::FindStart() {
- if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym) return sym;
-
- return ErrorOr<VoidPtr>(kErrorExecutable);
-}
-
-/// @brief Tells if the executable is loaded or not.
-/// @return Whether it's not bad and is cached.
-bool PEFLoader::IsLoaded() noexcept {
- return !fBad && fCachedBlob;
-}
-
-const Char* PEFLoader::Path() {
- return fPath.Leak().CData();
-}
-
-const Char* PEFLoader::AsString() {
-#ifdef __32x0__
- return "32x0 PEF";
-#elif defined(__64x0__)
- return "64x0 PEF";
-#elif defined(__x86_64__)
- return "x86_64 PEF";
-#elif defined(__aarch64__)
- return "AARCH64 PEF";
-#elif defined(__powerpc64__)
- return "POWER64 PEF";
-#else
- return "???? PEF";
-#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__
-}
-
-const Char* PEFLoader::MIME() {
- return kPefApplicationMime;
-}
-
-ErrorOr<VoidPtr> PEFLoader::GetBlob() {
- return ErrorOr<VoidPtr>{this->fCachedBlob};
-}
-
-namespace Utils {
- ProcessID rtl_create_user_process(PEFLoader& exec, const Int32& process_kind) noexcept {
- auto errOrStart = exec.FindStart();
-
- if (errOrStart.Error() != kErrorSuccess) return kSchedInvalidPID;
-
- auto symname = exec.FindSymbol(kPefNameSymbol, kPefData);
-
- if (!symname) {
- symname = ErrorOr<VoidPtr>{(VoidPtr) rt_alloc_string("USER_PROCESS_PEF")};
- }
-
- ProcessID id =
- UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(symname.Leak().Leak()),
- errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
-
- mm_free_ptr(symname.Leak().Leak());
-
- if (id != kSchedInvalidPID) {
- auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData);
-
- if (!stacksym) {
- stacksym = ErrorOr<VoidPtr>{(VoidPtr) new UIntPtr(kSchedMaxStackSz)};
- }
-
- if ((*(volatile UIntPtr*) stacksym.Leak().Leak()) > kSchedMaxStackSz) {
- *(volatile UIntPtr*) stacksym.Leak().Leak() = kSchedMaxStackSz;
- }
-
- UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].Kind = process_kind;
- UserProcessScheduler::The().TheCurrentTeam().AsArray()[id].StackSize =
- *(UIntPtr*) stacksym.Leak().Leak();
-
- mm_free_ptr(stacksym.Leak().Leak());
- }
-
- return id;
- }
-} // namespace Utils
-} // namespace Kernel