From f143b3d9bca3e8d948619b129971728df9c295cb Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 16 Nov 2023 13:57:40 +0200 Subject: [PATCH] sceKernelMmap, posix_mmap implementation --- .../hle/libraries/libkernel/libkernel.cpp | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/core/hle/libraries/libkernel/libkernel.cpp b/src/core/hle/libraries/libkernel/libkernel.cpp index 52e1a8e6c..8435ce5d6 100644 --- a/src/core/hle/libraries/libkernel/libkernel.cpp +++ b/src/core/hle/libraries/libkernel/libkernel.cpp @@ -14,11 +14,15 @@ #ifdef _WIN64 #include +#include #endif #include "thread_management.h" +#include namespace Core::Libraries::LibKernel { +constexpr bool log_libkernel_file = true; // disable it to disable logging + static u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; // dummy return int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len) { @@ -28,11 +32,61 @@ int32_t PS4_SYSV_ABI sceKernelReleaseDirectMemory(off_t start, size_t len) { static PS4_SYSV_ABI void stack_chk_fail() { BREAKPOINT(); } -int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { BREAKPOINT(); } +int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { + BREAKPOINT(); + return SCE_OK; +} static thread_local int libc_error; int* PS4_SYSV_ABI __Error() { return &libc_error; } +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 + +int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, off_t offset, void** res) { + PRINT_FUNCTION_NAME(); + if (prot > 3)// READ,WRITE or bitwise READ | WRITE supported + { + LOG_ERROR_IF(log_libkernel_file, "sceKernelMmap prot ={} not supported\n",prot); + } + DWORD flProtect; + if (prot & PROT_WRITE) { + flProtect = PAGE_READWRITE; + } + off_t end = len + offset; + HANDLE mmap_fd, h; + if (fd == -1) + mmap_fd = INVALID_HANDLE_VALUE; + else + mmap_fd = (HANDLE)_get_osfhandle(fd); + h = CreateFileMapping(mmap_fd, NULL, flProtect, 0, end, NULL); + int k = GetLastError(); + if (NULL == h) return -1; + DWORD dwDesiredAccess; + if (prot & PROT_WRITE) + dwDesiredAccess = FILE_MAP_WRITE; + else + dwDesiredAccess = FILE_MAP_READ; + void* ret = MapViewOfFile(h, dwDesiredAccess, 0, offset, len); + if (ret == NULL) { + CloseHandle(h); + ret = nullptr; + } + *res = ret; + return 0; +} + +PS4_SYSV_ABI void* posix_mmap(void* addr, u64 len, int prot, int flags, int fd, u64 offset) { + void* ptr; + LOG_INFO_IF(log_libkernel_file, "posix mmap redirect to sceKernelMmap\n"); + // posix call the difference is that there is a different behaviour when it doesn't return 0 or SCE_OK + int result = sceKernelMmap(addr, len, prot, flags, fd, offset, &ptr); + if (result != 0) { + BREAKPOINT(); + } + return ptr; +} + void LibKernel_Register(Loader::SymbolsResolver* sym) { // obj LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard); @@ -42,6 +96,7 @@ void LibKernel_Register(Loader::SymbolsResolver* sym) { LIB_FUNCTION("L-Q3LEjIbgA", "libkernel", 1, "libkernel", 1, 1, Kernel::sceKernelMapDirectMemory); LIB_FUNCTION("MBuItvba6z8", "libkernel", 1, "libkernel", 1, 1, sceKernelReleaseDirectMemory); LIB_FUNCTION("cQke9UuBQOk", "libkernel", 1, "libkernel", 1, 1, sceKernelMunmap); + LIB_FUNCTION("PGhQHd-dzv8", "libkernel", 1, "libkernel", 1, 1, sceKernelMmap); // equeue LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", 1, 1, Kernel::sceKernelCreateEqueue); LIB_FUNCTION("fzyMKs9kim0", "libkernel", 1, "libkernel", 1, 1, Kernel::sceKernelWaitEqueue); @@ -49,6 +104,7 @@ void LibKernel_Register(Loader::SymbolsResolver* sym) { LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, Kernel::sceKernelIsNeoMode); LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail); LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error); + LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", 1, 1, posix_mmap); Core::Libraries::LibKernel::fileSystemSymbolsRegister(sym); Core::Libraries::LibKernel::timeSymbolsRegister(sym);