mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-19 18:04:56 +00:00
core: Many things (#194)
* video_core: Add a few missed things * libkernel: More proper memory mapped files * memory: Fix tessellation buffer mapping * Cuphead work * sceKernelPollSema fix * clang format * fixed ngs2 lle loading and rtc lib * draft pthreads keys implementation * fixed return codes * return error code if sceKernelLoadStartModule module is invalid * re-enabled system modules and disable debug in libs.h * Improve linux support * fix windows build * kernel: Rework keys --------- Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
parent
6a47f8ae50
commit
c5d1d579b1
67 changed files with 1406 additions and 307 deletions
|
@ -62,62 +62,35 @@ size_t PS4_SYSV_ABI _writev(int fd, const struct iovec* iov, int iovcn) {
|
|||
return total_written;
|
||||
}
|
||||
|
||||
static thread_local int libc_error;
|
||||
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,
|
||||
int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, size_t offset,
|
||||
void** res) {
|
||||
#ifdef _WIN64
|
||||
LOG_INFO(Kernel_Vmm, "called");
|
||||
if (prot > 3) {
|
||||
LOG_ERROR(Kernel_Vmm, "prot = {} not supported", prot);
|
||||
LOG_INFO(Kernel_Vmm, "called addr = {}, len = {}, prot = {}, flags = {}, fd = {}, offset = {}",
|
||||
fmt::ptr(addr), len, prot, flags, fd, offset);
|
||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||
auto* memory = Core::Memory::Instance();
|
||||
const auto mem_prot = static_cast<Core::MemoryProt>(prot);
|
||||
const auto mem_flags = static_cast<Core::MemoryMapFlags>(flags);
|
||||
if (fd == -1) {
|
||||
return memory->MapMemory(res, std::bit_cast<VAddr>(addr), len, mem_prot, mem_flags,
|
||||
Core::VMAType::Flexible);
|
||||
} else {
|
||||
const uintptr_t handle = h->GetFile(fd)->f.GetFileMapping();
|
||||
return memory->MapFile(res, std::bit_cast<VAddr>(addr), len, mem_prot, mem_flags, handle,
|
||||
offset);
|
||||
}
|
||||
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;
|
||||
#else
|
||||
void* result = mmap(addr, len, prot, flags, fd, offset);
|
||||
if (result != MAP_FAILED) {
|
||||
*res = result;
|
||||
return 0;
|
||||
}
|
||||
std::abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
PS4_SYSV_ABI void* posix_mmap(void* addr, u64 len, int prot, int flags, int fd, u64 offset) {
|
||||
void* PS4_SYSV_ABI posix_mmap(void* addr, u64 len, int prot, int flags, int fd, u64 offset) {
|
||||
void* ptr;
|
||||
LOG_INFO(Kernel_Vmm, "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
|
||||
const VAddr ret_addr = (VAddr)__builtin_return_address(0);
|
||||
int result = sceKernelMmap(addr, len, prot, flags, fd, offset, &ptr);
|
||||
ASSERT(result == 0);
|
||||
return ptr;
|
||||
|
@ -201,11 +174,19 @@ s32 PS4_SYSV_ABI sceKernelLoadStartModule(const char* moduleFileName, size_t arg
|
|||
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||
const auto path = mnt->GetHostFile(moduleFileName);
|
||||
|
||||
// Load PRX module.
|
||||
// Load PRX module and relocate any modules that import it.
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
u32 handle = linker->LoadModule(path);
|
||||
if (handle == -1) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
auto* module = linker->GetModule(handle);
|
||||
linker->Relocate(module);
|
||||
linker->RelocateAnyImports(module);
|
||||
|
||||
// If the new module has a TLS image, trigger its load when TlsGetAddr is called.
|
||||
if (module->tls.image_size != 0) {
|
||||
linker->AdvanceGenerationCounter();
|
||||
}
|
||||
|
||||
// Retrieve and verify proc param according to libkernel.
|
||||
u64* param = module->GetProcParam<u64*>();
|
||||
|
@ -225,10 +206,84 @@ s32 PS4_SYSV_ABI sceKernelDlsym(s32 handle, const char* symbol, void** addrp) {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
static constexpr size_t ORBIS_DBG_MAX_NAME_LENGTH = 256;
|
||||
|
||||
struct OrbisModuleInfoForUnwind {
|
||||
u64 st_size;
|
||||
std::array<char, ORBIS_DBG_MAX_NAME_LENGTH> name;
|
||||
VAddr eh_frame_hdr_addr;
|
||||
VAddr eh_frame_addr;
|
||||
u64 eh_frame_size;
|
||||
VAddr seg0_addr;
|
||||
u64 seg0_size;
|
||||
};
|
||||
|
||||
s32 PS4_SYSV_ABI sceKernelGetModuleInfoForUnwind(VAddr addr, int flags,
|
||||
OrbisModuleInfoForUnwind* info) {
|
||||
if (flags >= 3) {
|
||||
std::memset(info, 0, sizeof(OrbisModuleInfoForUnwind));
|
||||
return SCE_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (!info) {
|
||||
return ORBIS_KERNEL_ERROR_EFAULT;
|
||||
}
|
||||
if (info->st_size <= sizeof(OrbisModuleInfoForUnwind)) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
// Find module that contains specified address.
|
||||
LOG_INFO(Lib_Kernel, "called addr = {:#x}, flags = {:#x}", addr, flags);
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
auto* module = linker->FindByAddress(addr);
|
||||
const auto mod_info = module->GetModuleInfoEx();
|
||||
|
||||
// Fill in module info.
|
||||
info->name = mod_info.name;
|
||||
info->eh_frame_hdr_addr = mod_info.eh_frame_hdr_addr;
|
||||
info->eh_frame_addr = mod_info.eh_frame_addr;
|
||||
info->eh_frame_size = mod_info.eh_frame_size;
|
||||
info->seg0_addr = mod_info.segments[0].address;
|
||||
info->seg0_size = mod_info.segments[0].size;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelGetModuleInfoFromAddr(VAddr addr, int flags,
|
||||
Core::OrbisKernelModuleInfoEx* info) {
|
||||
LOG_INFO(Lib_Kernel, "called addr = {:#x}, flags = {:#x}", addr, flags);
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
auto* module = linker->FindByAddress(addr);
|
||||
*info = module->GetModuleInfoEx();
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelDebugRaiseException() {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
char PS4_SYSV_ABI _is_signal_return(s64* param_1) {
|
||||
char cVar1;
|
||||
|
||||
if (((*param_1 != 0x48006a40247c8d48ULL) || (param_1[1] != 0x50f000001a1c0c7ULL)) ||
|
||||
(cVar1 = '\x01', (param_1[2] & 0xffffffU) != 0xfdebf4)) {
|
||||
cVar1 = ((*(u64*)((s64)param_1 + -5) & 0xffffffffff) == 0x50fca8949) * '\x02';
|
||||
}
|
||||
return cVar1;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceKernelGetCpumode() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
void PS4_SYSV_ABI sched_yield() {
|
||||
return std::this_thread::yield();
|
||||
}
|
||||
|
||||
void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
||||
// obj
|
||||
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
||||
// memory
|
||||
LIB_FUNCTION("OMDRKKAZ8I4", "libkernel", 1, "libkernel", 1, 1, sceKernelDebugRaiseException);
|
||||
LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateDirectMemory);
|
||||
LIB_FUNCTION("B+vc2AO2Zrc", "libkernel", 1, "libkernel", 1, 1,
|
||||
sceKernelAllocateMainDirectMemory);
|
||||
|
@ -248,6 +303,9 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
|||
_sceKernelRtldSetApplicationHeapAPI);
|
||||
LIB_FUNCTION("wzvqT4UqKX8", "libkernel", 1, "libkernel", 1, 1, sceKernelLoadStartModule);
|
||||
LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym);
|
||||
LIB_FUNCTION("RpQJJVKTiFM", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoForUnwind);
|
||||
LIB_FUNCTION("f7KBOafysXo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoFromAddr);
|
||||
LIB_FUNCTION("VOx8NGmHXTs", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCpumode);
|
||||
|
||||
// equeue
|
||||
LIB_FUNCTION("D0OdFMjp46I", "libkernel", 1, "libkernel", 1, 1, sceKernelCreateEqueue);
|
||||
|
@ -255,6 +313,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("fzyMKs9kim0", "libkernel", 1, "libkernel", 1, 1, sceKernelWaitEqueue);
|
||||
LIB_FUNCTION("vz+pg2zdopI", "libkernel", 1, "libkernel", 1, 1, sceKernelGetEventUserData);
|
||||
LIB_FUNCTION("4R6-OvI2cEA", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEvent);
|
||||
LIB_FUNCTION("WDszmSbWuDk", "libkernel", 1, "libkernel", 1, 1, sceKernelAddUserEventEdge);
|
||||
LIB_FUNCTION("F6e0kwo4cnk", "libkernel", 1, "libkernel", 1, 1, sceKernelTriggerUserEvent);
|
||||
LIB_FUNCTION("LJDwdSNTnDg", "libkernel", 1, "libkernel", 1, 1, sceKernelDeleteUserEvent);
|
||||
|
||||
|
@ -263,11 +322,13 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
|||
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("BPE9s9vQQXo", "libScePosix", 1, "libkernel", 1, 1, posix_mmap);
|
||||
LIB_FUNCTION("YSHRBRLn2pI", "libkernel", 1, "libkernel", 1, 1, _writev);
|
||||
LIB_FUNCTION("959qrazPIrg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetProcParam);
|
||||
LIB_FUNCTION("-o5uEDpN+oY", "libkernel", 1, "libkernel", 1, 1, sceKernelConvertUtcToLocaltime);
|
||||
LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCompiledSdkVersion);
|
||||
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
|
||||
LIB_FUNCTION("crb5j7mkk1c", "libkernel", 1, "libkernel", 1, 1, _is_signal_return);
|
||||
|
||||
Libraries::Kernel::fileSystemSymbolsRegister(sym);
|
||||
Libraries::Kernel::timeSymbolsRegister(sym);
|
||||
|
@ -278,6 +339,7 @@ void LibKernel_Register(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1,
|
||||
sceLibcHeapGetTraceInfo);
|
||||
LIB_FUNCTION("FxVZqBAA7ks", "libkernel", 1, "libkernel", 1, 1, ps4__write);
|
||||
LIB_FUNCTION("6XG4B33N09g", "libScePosix", 1, "libkernel", 1, 1, sched_yield);
|
||||
}
|
||||
|
||||
} // namespace Libraries::Kernel
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue