#include "prx/libc/include/Api.hpp" #include "prx/libSceJxr/include/Api.hpp" #include "prx/libc/include/ApplicationHeap.hpp" #include "prx/libc/include/general/VabiMacros.hpp" #include #include #include #include #include namespace { void Require(bool value) { if (!value) std::abort(); } void* lastFreed = nullptr; int frees = 0; void* APS5_VABI Allocate(std::size_t size) { return std::malloc(size); } void APS5_VABI Free(void* pointer) { if (pointer != nullptr) { lastFreed = pointer; ++frees; } std::free(pointer); } void* APS5_VABI Reallocate(void* pointer, std::size_t size) { return std::realloc(pointer, size); } void* APS5_VABI Calloc(std::size_t count, std::size_t size) { return std::calloc(count, size); } void* APS5_VABI Align(std::size_t, std::size_t size) { return std::malloc(size); } void* APS5_VABI Realign(void* pointer, std::size_t size, std::size_t) { return std::realloc(pointer, size); } int APS5_VABI PosixAlign(void** pointer, std::size_t, std::size_t size) { *pointer = std::malloc(size); return *pointer ? 0 : 12; } void InitializeHeap() { alignas(16) static std::array process{}; alignas(16) static std::array libc{}; alignas(16) static std::array replacement{}; const auto write = [](auto& data, std::size_t offset, auto value) { std::memcpy(data.data() + offset, &value, sizeof(value)); }; write(process, 0, std::uint64_t{0x40}); write(process, 8, std::uint32_t{0x4942524f}); write(process, 0x38, libc.data()); write(libc, 0, std::uint64_t{0x38}); write(libc, 0x30, replacement.data()); write(replacement, 0, std::uint64_t{0x78}); write(replacement, 8, std::uint64_t{2}); write(replacement, 0x20, reinterpret_cast(&Allocate)); write(replacement, 0x28, reinterpret_cast(&Free)); write(replacement, 0x30, reinterpret_cast(&Calloc)); write(replacement, 0x38, reinterpret_cast(&Reallocate)); write(replacement, 0x40, reinterpret_cast(&Align)); write(replacement, 0x48, reinterpret_cast(&Realign)); write(replacement, 0x50, reinterpret_cast(&PosixAlign)); ApplicationHeapInitialize_nid_no_patch(process.data()); } } int main() { InitializeHeap(); void* memory = malloc_nid_postfix(64); Require(memory != nullptr); void* const allocated = memory; Require(PKFree_nid_postfix(&memory) == 0); Require(memory == nullptr); Require(frees == 1 && lastFreed == allocated); Require(PKFree_nid_postfix(&memory) == 0); Require(memory == nullptr); Require(frees == 1); Require(PKFree_nid_postfix(nullptr) == 0); Require(frees == 1); return 0; }