diff --git a/src/core/PS4/HLE/LibKernel.cpp b/src/core/PS4/HLE/LibKernel.cpp index a7599afad..4e7eee753 100644 --- a/src/core/PS4/HLE/LibKernel.cpp +++ b/src/core/PS4/HLE/LibKernel.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "Emulator/Util/singleton.h" #include "../Loader/Elf.h" @@ -26,6 +27,51 @@ 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(); } + +static thread_local int libc_error; +PS4_SYSV_ABI int* __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) { + 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* mmap(void* addr, u64 len, int prot, int flags, int fd, u64 offset) { + void* ptr; + // 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(SymbolsResolver* sym) { // obj LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &HLE::Libs::LibKernel::g_stack_chk_guard); @@ -41,6 +87,10 @@ void LibKernel_Register(SymbolsResolver* sym) { // misc LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, CPUManagement::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, mmap); Core::Libraries::LibKernel::fileSystemSymbolsRegister(sym); Core::Libraries::LibKernel::timeSymbolsRegister(sym);