mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-23 00:53:02 -05:00
The AMM ranges were reserved at the last 64 GiB of the guest arena and the reservation threw when that window was not free. On Windows the stacks of the threads that exist before the arena is reserved (the main thread and the loader's workers) are placed at random addresses and are left in the arena as host regions; when one fell in the last 64 GiB, the first AMM use threw "fixed guest mapping ... overlaps a host region in the guest arena". Reserve the highest free 64 GiB window instead: the last 64 GiB when it is free, and the window just below an occupied part of it otherwise.
73 lines
3.6 KiB
C++
73 lines
3.6 KiB
C++
#ifndef CORE_LIBS_PRX_LIBC_INCLUDE_GUESTARENA_HPP
|
|
#define CORE_LIBS_PRX_LIBC_INCLUDE_GUESTARENA_HPP
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
|
|
// Guest virtual memory is placed inside one reserved arena below the PS5 application map limit
|
|
// absolute address and breaks on host addresses outside that range.
|
|
namespace GuestArena {
|
|
|
|
#ifndef _WIN32
|
|
using SharedBackingResolver = bool (*)(std::uintptr_t address, std::size_t bytes, int* file, std::uint64_t* offset);
|
|
using SharedBackingWriter = bool (*)(std::uintptr_t address, const void* source, std::size_t bytes);
|
|
#endif
|
|
|
|
extern "C" {
|
|
|
|
bool GuestArenaAvailable_nid_postfix();
|
|
bool GuestArenaContains_nid_postfix(const void* pointer, std::size_t bytes);
|
|
void* GuestArenaAllocate_nid_postfix(std::size_t bytes, std::size_t alignment);
|
|
void* GuestArenaAllocateAtOrAbove_nid_postfix(std::uintptr_t hint, std::size_t bytes, std::size_t alignment);
|
|
std::uintptr_t GuestArenaHighestFree_nid_no_patch(std::size_t bytes, std::size_t alignment);
|
|
void GuestArenaMarkUsed_nid_postfix(const void* pointer, std::size_t bytes);
|
|
void GuestArenaRelease_nid_postfix(const void* pointer, std::size_t bytes);
|
|
// The reserved range, and whether it was reserved with page write watching (Windows MEM_WRITE_WATCH).
|
|
void GuestArenaRange_nid_postfix(std::uintptr_t* base, std::size_t* bytes);
|
|
bool GuestArenaWriteWatched_nid_postfix();
|
|
void GuestArenaSetProtection_nid_postfix(std::uintptr_t address, std::size_t bytes, std::uint32_t protection);
|
|
void GuestArenaCommit_nid_postfix(void* pointer, std::size_t bytes, std::uint32_t protection, std::size_t granule);
|
|
void GuestArenaReset_nid_postfix(void* pointer, std::size_t bytes);
|
|
#ifdef _WIN32
|
|
bool GuestArenaHandleWrite_nid_postfix(std::uintptr_t address);
|
|
void GuestArenaPinWritable_nid_postfix(const void* pointer, std::size_t bytes);
|
|
void GuestArenaUnpinWritable_nid_postfix(const void* pointer, std::size_t bytes);
|
|
bool GuestArenaProtection_nid_postfix(std::uintptr_t address, std::uint32_t* protection);
|
|
bool GuestArenaCollectWrites_nid_postfix(std::uintptr_t address, std::size_t bytes, void** pages, std::size_t* count, bool clear);
|
|
bool GuestArenaHostRegionOverlaps_nid_postfix(std::uintptr_t address, std::size_t bytes);
|
|
std::uint64_t GuestArenaCommitGeneration_nid_postfix();
|
|
void GuestArenaSetPrivateMappingObserver_nid_postfix(void (*callback)(std::uintptr_t address, std::size_t bytes, std::uint64_t generation));
|
|
void GuestArenaMap_nid_postfix(void* pointer, std::size_t bytes, void* section, std::uint64_t offset, std::uint32_t protection);
|
|
void* GuestArenaMapAlias_nid_postfix(std::uintptr_t address, std::size_t bytes);
|
|
void GuestArenaUnmapAlias_nid_postfix(void* alias);
|
|
#else
|
|
void GuestArenaSetSharedBacking_nid_postfix(SharedBackingResolver resolver);
|
|
void GuestArenaSetSharedBackingWriter_nid_no_patch(SharedBackingWriter writer);
|
|
bool GuestArenaWriteSharedBacking_nid_no_patch(std::uintptr_t address, const void* source, std::size_t bytes);
|
|
bool GuestArenaSharedBacking_nid_postfix(std::uintptr_t address, std::size_t bytes, int* file, std::uint64_t* offset);
|
|
#endif
|
|
bool GuestArenaBeginHostWrite_nid_postfix(void* pointer, std::size_t bytes);
|
|
void GuestArenaEndHostWrite_nid_postfix(void* pointer, std::size_t bytes);
|
|
|
|
}
|
|
|
|
class HostWrite {
|
|
public:
|
|
HostWrite(void* pointer, std::size_t bytes) : pointer(pointer), bytes(bytes), open(GuestArenaBeginHostWrite_nid_postfix(pointer, bytes)) {}
|
|
~HostWrite() {
|
|
if (open) GuestArenaEndHostWrite_nid_postfix(pointer, bytes);
|
|
}
|
|
HostWrite(const HostWrite&) = delete;
|
|
HostWrite& operator=(const HostWrite&) = delete;
|
|
bool Open() const { return open; }
|
|
|
|
private:
|
|
void* pointer;
|
|
std::size_t bytes;
|
|
bool open;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|