diff options
| author | Amlal EL Mahrouss <amlalelmahrouss@icloud.com> | 2024-08-15 18:35:34 +0200 |
|---|---|---|
| committer | Amlal EL Mahrouss <amlalelmahrouss@icloud.com> | 2024-08-15 18:35:34 +0200 |
| commit | f3d931aa7cfaf96baef8383b59a8938779541ee7 (patch) | |
| tree | fdb9fc51badb3dbd03e46ab0766a49d9522e13e2 /dev/Kernel/Sources/Heap.cxx | |
| parent | 86640816e8b1d3595365f1fcc8a2a9e61fb40ff1 (diff) | |
[IMP] Moved source code into dev/ folder.
Signed-off-by: Amlal EL Mahrouss <amlalelmahrouss@icloud.com>
Diffstat (limited to 'dev/Kernel/Sources/Heap.cxx')
| -rw-r--r-- | dev/Kernel/Sources/Heap.cxx | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/dev/Kernel/Sources/Heap.cxx b/dev/Kernel/Sources/Heap.cxx new file mode 100644 index 00000000..de0c8a5c --- /dev/null +++ b/dev/Kernel/Sources/Heap.cxx @@ -0,0 +1,246 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include <KernelKit/DebugOutput.hxx> +#include <KernelKit/LPC.hxx> +#include <KernelKit/Heap.hxx> +#include <NewKit/Crc32.hxx> +#include <NewKit/PageManager.hxx> + +//! @file KernelHeap.cxx +//! @brief Kernel heap allocator. + +#define kKernelHeapMagic (0xD4D7D5) +#define kKernelHeapHeaderPaddingSz (16U) + +namespace Kernel +{ + SizeT kHeapCount = 0UL; + PageManager kHeapPageManager; + Bool kOperationInProgress = No; + + namespace Detail + { + /// @brief Kernel heap information block. + /// Located before the address bytes. + /// | HIB | ADDRESS | + struct PACKED HEAP_INFORMATION_BLOCK final + { + ///! @brief 32-bit value which contains the magic number of the heap. + UInt32 fMagic; + ///! @brief Boolean value which tells if the heap is allocated. + Boolean fPresent; + ///! @brief 32-bit CRC checksum. + UInt32 fCRC32; + /// @brief 64-bit pointer size. + SizeT fTargetPtrSize; + /// @brief 64-bit target pointer. + UIntPtr fTargetPtr; + /// @brief Is this a page pointer? + Boolean fPagePtr; + /// @brief Padding bytes for header. + UInt8 fPadding[kKernelHeapHeaderPaddingSz]; + }; + + typedef HEAP_INFORMATION_BLOCK* HEAP_INFORMATION_BLOCK_PTR; + + Void mm_alloc_init_timeout(Void) noexcept + { + kOperationInProgress = Yes; + } + + Void mm_alloc_fini_timeout(Void) noexcept + { + kOperationInProgress = No; + } + } // namespace Detail + + /// @brief Declare a new size for allocatedPtr. + /// @param allocatedPtr the pointer. + /// @return + voidPtr mm_realloc_ke_heap(voidPtr allocatedPtr, SizeT newSz) + { + if (!allocatedPtr || newSz < 1) + return nullptr; + + Detail::HEAP_INFORMATION_BLOCK_PTR heapInfoBlk = + reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>( + (UIntPtr)allocatedPtr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + heapInfoBlk->fTargetPtrSize = newSz; + + if (heapInfoBlk->fCRC32 > 0) + { + MUST_PASS(mm_protect_ke_heap(allocatedPtr)); + } + + return allocatedPtr; + } + + /// @brief allocate chunk of memory. + /// @param sz size of pointer + /// @param rw read write (true to enable it) + /// @param user is it accesible by user processes? + /// @return The newly allocated pointer. + VoidPtr mm_new_ke_heap(const SizeT sz, const bool rw, const bool user) + { + Detail::mm_alloc_init_timeout(); + + auto szFix = sz; + + if (szFix == 0) + ++szFix; + + kcout << "newoskrnl: allocating VMH page...\r"; + + auto wrapper = kHeapPageManager.Request(rw, user, false, szFix); + + Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr = + reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>( + wrapper.VirtualAddress()); + + heap_info_ptr->fTargetPtrSize = szFix; + heap_info_ptr->fMagic = kKernelHeapMagic; + heap_info_ptr->fCRC32 = 0; // dont fill it for now. + heap_info_ptr->fTargetPtr = wrapper.VirtualAddress(); + heap_info_ptr->fPagePtr = 0; + + ++kHeapCount; + + Detail::mm_alloc_fini_timeout(); + + return reinterpret_cast<VoidPtr>(wrapper.VirtualAddress() + + sizeof(Detail::HEAP_INFORMATION_BLOCK)); + } + + /// @brief Makes a page heap. + /// @param heap_ptr + /// @return + Int32 mm_make_ke_page(VoidPtr heap_ptr) + { + if (kHeapCount < 1) + return -kErrorInternal; + if (((IntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)) <= 0) + return -kErrorInternal; + if (((IntPtr)heap_ptr - kBadPtr) < 0) + return -kErrorInternal; + + Detail::mm_alloc_init_timeout(); + + Detail::HEAP_INFORMATION_BLOCK_PTR heapInfoBlk = + reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + heapInfoBlk->fPagePtr = 1; + + Detail::mm_alloc_fini_timeout(); + + return 0; + } + + /// @brief Declare pointer as free. + /// @param heap_ptr the pointer. + /// @return + Int32 mm_delete_ke_heap(VoidPtr heap_ptr) + { + if (kHeapCount < 1) + return -kErrorInternal; + if (((IntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)) <= 0) + return -kErrorInternal; + if (((IntPtr)heap_ptr - kBadPtr) < 0) + return -kErrorInternal; + + Detail::mm_alloc_init_timeout(); + + Detail::HEAP_INFORMATION_BLOCK_PTR heapInfoBlk = + reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (heapInfoBlk && heapInfoBlk->fMagic == kKernelHeapMagic) + { + if (!heapInfoBlk->fPresent) + { + Detail::mm_alloc_fini_timeout(); + return -kErrorHeapNotPresent; + } + + if (heapInfoBlk->fCRC32 != 0) + { + if (heapInfoBlk->fCRC32 != + ke_calculate_crc32((Char*)heapInfoBlk->fTargetPtr, + heapInfoBlk->fTargetPtrSize)) + { + ke_stop(RUNTIME_CHECK_POINTER); + } + } + + heapInfoBlk->fTargetPtrSize = 0UL; + heapInfoBlk->fPresent = false; + heapInfoBlk->fTargetPtr = 0; + heapInfoBlk->fCRC32 = 0; + heapInfoBlk->fMagic = 0; + + PTEWrapper pageWrapper(false, false, false, reinterpret_cast<UIntPtr>(heapInfoBlk)); + Ref<PTEWrapper*> pteAddress{&pageWrapper}; + + kHeapPageManager.Free(pteAddress); + + --kHeapCount; + + Detail::mm_alloc_fini_timeout(); + + return 0; + } + + return -kErrorInternal; + } + + /// @brief Check if pointer is a valid kernel pointer. + /// @param heap_ptr the pointer + /// @return if it exists. + Boolean mm_is_valid_heap(VoidPtr heap_ptr) + { + if (kHeapCount < 1) + return false; + + if (heap_ptr) + { + Detail::HEAP_INFORMATION_BLOCK_PTR virtualAddress = + reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (virtualAddress->fPresent && virtualAddress->fMagic == kKernelHeapMagic) + { + return true; + } + } + + return false; + } + + /// @brief Protect the heap with a CRC value. + /// @param heap_ptr HIB pointer. + /// @return if it valid: point has crc now., otherwise fail. + Boolean mm_protect_ke_heap(VoidPtr heap_ptr) + { + if (heap_ptr) + { + Detail::HEAP_INFORMATION_BLOCK_PTR heapInfoBlk = + reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>( + (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK)); + + if (heapInfoBlk->fPresent && kKernelHeapMagic == heapInfoBlk->fMagic) + { + heapInfoBlk->fCRC32 = + ke_calculate_crc32((Char*)heapInfoBlk->fTargetPtr, heapInfoBlk->fTargetPtrSize); + + return true; + } + } + + return false; + } +} // namespace Kernel |
