From 5339d016c07bf717ee388f4feb73544087324af0 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sat, 6 Jan 2024 09:14:11 +0100 Subject: git: port from mercurial repo. Signed-off-by: Amlal El Mahrouss --- Source/CodeManager.cxx | 144 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 Source/CodeManager.cxx (limited to 'Source/CodeManager.cxx') diff --git a/Source/CodeManager.cxx b/Source/CodeManager.cxx new file mode 100644 index 00000000..47c7bd1b --- /dev/null +++ b/Source/CodeManager.cxx @@ -0,0 +1,144 @@ +/* + * ======================================================== + * + * hCore + * Copyright Mahrouss Logic, all rights reserved. + * + * ======================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace hCore +{ + namespace Detail + { + UInt32 rt_get_pef_platform(void) + { +#ifdef __powerpc + return kPefArchPower; +#elif defined(__arc__) + return kPefArchARC; +#elif defined(__x86_64__) + return kPefArchAMD64; +#else + return kPefArchInvalid; +#endif // __POWER || __x86_64__ + } + } + + PEFLoader::PEFLoader(const char* path) + : fCachedBlob(nullptr), fBad(false) + { + OwnPtr> file; + + file.New(const_cast(path)); + + if (StringBuilder::Equals(file->MIME(), this->MIME())) + { + fPath = StringBuilder::Construct(path).Leak(); + + fCachedBlob = file->ReadAll(); + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + auto fFree = [&]() -> void { + kcout << "CodeManager: Warning: Bad executable, program will not be started!\n"; + fBad = true; + + kernel_delete_ptr(fCachedBlob); + + fCachedBlob = nullptr; + }; + + if (container->Cpu == Detail::rt_get_pef_platform() && + container->Magic[0] == kPefMagic[0] && + container->Magic[1] == kPefMagic[1] && + container->Magic[2] == kPefMagic[2] && + container->Abi == kPefAbi) + { + if (container->Kind != kPefKindObject && + container->Kind != kPefKindDebug) + { + kcout << "CodeManager: Info: Good executable. can proceed.\n"; + return; + } + } + + fFree(); + } + } + + PEFLoader::~PEFLoader() + { + if (fCachedBlob) + kernel_delete_ptr(fCachedBlob); + } + + VoidPtr PEFLoader::FindSymbol(const char* name, Int32 kind) + { + if (!fCachedBlob || + fBad) + return nullptr; + + PEFContainer* container = reinterpret_cast(fCachedBlob); + + PEFCommandHeader* container_header = reinterpret_cast((UIntPtr)fCachedBlob + sizeof(PEFContainer)); + + for (SizeT index = 0; index < container->Count; ++index) + { + kcout << "Iterating over container at index: " << StringBuilder::FromInt("%", index) << ", name: " << container_header->Name << "\n"; + + if (StringBuilder::Equals(container_header->Name, name)) + { + kcout << "Found potential container, checking for validity.\n"; + + if (container_header->Kind == kind) + return static_cast(fCachedBlob) + container_header->Offset; + + continue; + } + } + + return nullptr; + } + + ErrorOr PEFLoader::LoadStart() + { + if (auto sym = this->FindSymbol("__start", kPefCode); sym) + return ErrorOr(sym); + + return ErrorOr(ME_EXEC_ERROR); + } + + bool PEFLoader::IsLoaded() noexcept { return !fBad && fCachedBlob; } + + namespace Utils + { + bool execute_from_image(PEFLoader& exec) + { + auto errOrStart = exec.LoadStart(); + + if (errOrStart.Error() != 0) + return false; + + Process proc(errOrStart.Leak().Leak()); + Ref refProc = proc; + + return ProcessManager::Shared().Leak().Add(refProc); + } + } + + const char* PEFLoader::Path() { return fPath.Leak().CData(); } + + const char* PEFLoader::Format() { return "PEF"; } + + const char* PEFLoader::MIME() { return "application/x-exec"; } +} // namespace hCore -- cgit v1.2.3