From 4f6dc8fddbf2905aab0c22dbab4202d7ff83d94c Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sun, 19 Nov 2023 12:55:07 +0200 Subject: [PATCH] functions libkernel to get openrorbis working (without tls) --- .../hle/libraries/libkernel/libkernel.cpp | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/core/hle/libraries/libkernel/libkernel.cpp b/src/core/hle/libraries/libkernel/libkernel.cpp index 52e1a8e6..e0cb27bd 100644 --- a/src/core/hle/libraries/libkernel/libkernel.cpp +++ b/src/core/hle/libraries/libkernel/libkernel.cpp @@ -14,11 +14,14 @@ #ifdef _WIN64 #include +#include #endif #include "thread_management.h" 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) { @@ -30,9 +33,72 @@ static PS4_SYSV_ABI void stack_chk_fail() { BREAKPOINT(); } int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { BREAKPOINT(); } +void PS4_SYSV_ABI sceKernelUsleep(unsigned int microseconds) { std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); } + +struct iovec { + void* iov_base; /* Base address. */ + size_t iov_len; /* Length. */ +}; + +size_t PS4_SYSV_ABI _writev(int fd, const struct iovec* iov, int iovcn) { + // weird it gives fd ==0 and writes to stdout , i am not sure if it that is valid (found in openorbis) + size_t total_written = 0; + for (int i = 0; i < iovcn; i++) { + total_written += ::fwrite(iov[i].iov_base, 1, iov[i].iov_len, stdout); + } + return total_written; +} + 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); @@ -49,6 +115,9 @@ 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); + LIB_FUNCTION("1jfXLRVzisc", "libkernel", 1, "libkernel", 1, 1, sceKernelUsleep); + LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev); Core::Libraries::LibKernel::fileSystemSymbolsRegister(sym); Core::Libraries::LibKernel::timeSymbolsRegister(sym);