diff --git a/src/core/libraries/kernel/event_flag/event_flag.cpp b/src/core/libraries/kernel/event_flag/event_flag.cpp index b8cac4f3..8afd139c 100644 --- a/src/core/libraries/kernel/event_flag/event_flag.cpp +++ b/src/core/libraries/kernel/event_flag/event_flag.cpp @@ -54,14 +54,19 @@ int PS4_SYSV_ABI sceKernelCreateEventFlag(OrbisKernelEventFlag* ef, const char* UNREACHABLE(); } - ASSERT_MSG(queue_mode == EventFlagInternal::QueueMode::Fifo, - "ThreadPriority attr is not supported!"); + if (queue_mode == EventFlagInternal::QueueMode::ThreadPrio) { + LOG_ERROR(Kernel_Event, "ThreadPriority attr is not supported!"); + } *ef = new EventFlagInternal(std::string(pName), thread_mode, queue_mode, initPattern); return ORBIS_OK; } int PS4_SYSV_ABI sceKernelDeleteEventFlag(OrbisKernelEventFlag ef) { - LOG_ERROR(Kernel_Event, "(STUBBED) called"); + if (ef == nullptr) { + return ORBIS_KERNEL_ERROR_ESRCH; + } + + delete ef; return ORBIS_OK; } int PS4_SYSV_ABI sceKernelOpenEventFlag() { diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index 0adb058e..c3b6c3ae 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -9,6 +9,7 @@ #include "core/libraries/error_codes.h" #include "core/libraries/kernel/file_system.h" #include "core/libraries/libs.h" +#include "libkernel.h" namespace Libraries::Kernel { @@ -59,7 +60,8 @@ int PS4_SYSV_ABI sceKernelOpen(const char* path, int flags, u16 mode) { file->m_guest_name = path; file->m_host_name = mnt->GetHostDirectory(file->m_guest_name); if (!std::filesystem::is_directory(file->m_host_name)) { // directory doesn't exist - UNREACHABLE(); // not supported yet + h->DeleteHandle(handle); + return ORBIS_KERNEL_ERROR_ENOTDIR; } else { if (create) { return handle; // dir already exists @@ -99,7 +101,10 @@ int PS4_SYSV_ABI posix_open(const char* path, int flags, /* SceKernelMode*/ u16 LOG_INFO(Kernel_Fs, "posix open redirect to sceKernelOpen"); int result = sceKernelOpen(path, flags, mode); // Posix calls different only for their return values - ASSERT(result >= 0); + if (result < 0) { + ErrSceToPosix(result); + return -1; + } return result; } @@ -122,7 +127,13 @@ int PS4_SYSV_ABI sceKernelClose(int d) { } int PS4_SYSV_ABI posix_close(int d) { - ASSERT(sceKernelClose(d) == 0); + int result = sceKernelClose(d); + if (result < 0) { + LOG_ERROR(Kernel_Pthread, "posix_close: error = {}", result); + ErrSceToPosix(result); + return -1; + } + return result; return ORBIS_OK; } @@ -175,7 +186,13 @@ s64 PS4_SYSV_ABI sceKernelLseek(int d, s64 offset, int whence) { } s64 PS4_SYSV_ABI posix_lseek(int d, s64 offset, int whence) { - return sceKernelLseek(d, offset, whence); + int result = sceKernelLseek(d, offset, whence); + if (result < 0) { + LOG_ERROR(Kernel_Pthread, "posix_lseek: error = {}", result); + ErrSceToPosix(result); + return -1; + } + return result; } s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) { @@ -190,7 +207,13 @@ s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) { } int PS4_SYSV_ABI posix_read(int d, void* buf, size_t nbytes) { - return sceKernelRead(d, buf, nbytes); + int result = sceKernelRead(d, buf, nbytes); + if (result < 0) { + LOG_ERROR(Kernel_Pthread, "posix_read: error = {}", result); + ErrSceToPosix(result); + return -1; + } + return result; } int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) { @@ -215,7 +238,13 @@ int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) { } int PS4_SYSV_ABI posix_mkdir(const char* path, u16 mode) { - return sceKernelMkdir(path, mode); + int result = sceKernelMkdir(path, mode); + if (result < 0) { + LOG_ERROR(Kernel_Pthread, "posix_mkdir: error = {}", result); + ErrSceToPosix(result); + return -1; + } + return result; } int PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) { @@ -246,9 +275,10 @@ int PS4_SYSV_ABI sceKernelStat(const char* path, OrbisKernelStat* sb) { int PS4_SYSV_ABI posix_stat(const char* path, OrbisKernelStat* sb) { int result = sceKernelStat(path, sb); - if (result != 0) { + if (result < 0) { LOG_ERROR(Kernel_Pthread, "posix_stat: error = {}", result); - result += ORBIS_KERNEL_ERROR_UNKNOWN; + ErrSceToPosix(result); + return -1; } return result; } @@ -308,7 +338,13 @@ int PS4_SYSV_ABI sceKernelFStat(int fd, OrbisKernelStat* sb) { } int PS4_SYSV_ABI posix_fstat(int fd, OrbisKernelStat* sb) { - return sceKernelFStat(fd, sb); + int result = sceKernelFStat(fd, sb); + if (result < 0) { + LOG_ERROR(Kernel_Pthread, "posix_fstat: error = {}", result); + ErrSceToPosix(result); + return -1; + } + return result; } s32 PS4_SYSV_ABI sceKernelFsync(int fd) { diff --git a/src/core/libraries/kernel/libkernel.cpp b/src/core/libraries/kernel/libkernel.cpp index e7e7d11d..74a1ab7a 100644 --- a/src/core/libraries/kernel/libkernel.cpp +++ b/src/core/libraries/kernel/libkernel.cpp @@ -63,9 +63,16 @@ 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 g_posix_errno = 0; int* PS4_SYSV_ABI __Error() { - return &libc_error; + return &g_posix_errno; +} + +void ErrSceToPosix(int result) { + int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP + ? result + -SCE_KERNEL_ERROR_UNKNOWN + : POSIX_EOTHER; + g_posix_errno = rt; } int PS4_SYSV_ABI sceKernelMmap(void* addr, u64 len, int prot, int flags, int fd, size_t offset, diff --git a/src/core/libraries/kernel/libkernel.h b/src/core/libraries/kernel/libkernel.h index 0cc6b0b2..04dc8ba5 100644 --- a/src/core/libraries/kernel/libkernel.h +++ b/src/core/libraries/kernel/libkernel.h @@ -12,6 +12,8 @@ class SymbolsResolver; namespace Libraries::Kernel { +void ErrSceToPosix(int result); + struct OrbisTimesec { time_t t; u32 west_sec; diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 6ea85a1d..1569a51c 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -1,6 +1,16 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#ifdef WIN32 +#define _WINSOCK_DEPRECATED_NO_WARNINGS +#include +#include +#include +#else +#include +#endif + +#include #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" @@ -48,7 +58,7 @@ int PS4_SYSV_ABI sce_net_in6addr_nodelocal_allnodes() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetAccept() { +OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } @@ -108,7 +118,7 @@ int PS4_SYSV_ABI sceNetBandwidthControlSetPolicy() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetBind() { +int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } @@ -668,12 +678,12 @@ int PS4_SYSV_ABI sceNetGetSockInfo6() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetGetsockname() { +int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sceNetGetsockopt() { +int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } @@ -693,24 +703,28 @@ int PS4_SYSV_ABI sceNetGetSystemTime() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetHtonl() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +u32 PS4_SYSV_ABI sceNetHtonl(u32 host32) { + return htonl(host32); } -int PS4_SYSV_ABI sceNetHtonll() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +u64 PS4_SYSV_ABI sceNetHtonll(u64 host64) { + return HTONLL(host64); } -int PS4_SYSV_ABI sceNetHtons() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +u16 PS4_SYSV_ABI sceNetHtons(u16 host16) { + return htons(host16); } -int PS4_SYSV_ABI sceNetInetNtop() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32 size) { +#ifdef WIN32 + const char* res = InetNtopA(af, src, dst, size); +#else + const char* res = inet_ntop(af, src, dst, size); +#endif + if (res == nullptr) { + UNREACHABLE(); + } + return dst; } int PS4_SYSV_ABI sceNetInetNtopWithScopeId() { @@ -773,9 +787,8 @@ int PS4_SYSV_ABI sceNetMemoryFree() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetNtohl() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +u32 PS4_SYSV_ABI sceNetNtohl(u32 net32) { + return ntohl(net32); } int PS4_SYSV_ABI sceNetNtohll() { @@ -783,9 +796,8 @@ int PS4_SYSV_ABI sceNetNtohll() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetNtohs() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +u16 PS4_SYSV_ABI sceNetNtohs(u16 net16) { + return ntohs(net16); } int PS4_SYSV_ABI sceNetPoolCreate(const char* name, int size, int flags) { @@ -813,7 +825,8 @@ int PS4_SYSV_ABI sceNetRecv() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetRecvfrom() { +int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags, + OrbisNetSockaddr* addr, u32* paddrlen) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } @@ -1018,7 +1031,7 @@ int PS4_SYSV_ABI sceNetShutdown() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetSocket() { +int PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol) { LOG_ERROR(Lib_Net, "(STUBBED) called"); return ORBIS_OK; } diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index e4244f45..965b7680 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -9,8 +9,20 @@ namespace Core::Loader { class SymbolsResolver; } +// Define our own htonll and ntohll because its not available in some systems/platforms +#define HTONLL(x) (((uint64_t)htonl((x) & 0xFFFFFFFFUL)) << 32) | htonl((uint32_t)((x) >> 32)) +#define NTOHLL(x) (((uint64_t)ntohl((x) & 0xFFFFFFFFUL)) << 32) | ntohl((uint32_t)((x) >> 32)) + namespace Libraries::Net { +using OrbisNetId = s32; + +struct OrbisNetSockaddr { + u8 sa_len; + u8 sa_family; + char sa_data[14]; +}; + int PS4_SYSV_ABI in6addr_any(); int PS4_SYSV_ABI in6addr_loopback(); int PS4_SYSV_ABI sce_net_dummy(); @@ -19,7 +31,7 @@ int PS4_SYSV_ABI sce_net_in6addr_linklocal_allnodes(); int PS4_SYSV_ABI sce_net_in6addr_linklocal_allrouters(); int PS4_SYSV_ABI sce_net_in6addr_loopback(); int PS4_SYSV_ABI sce_net_in6addr_nodelocal_allnodes(); -int PS4_SYSV_ABI sceNetAccept(); +OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen); int PS4_SYSV_ABI sceNetAddrConfig6GetInfo(); int PS4_SYSV_ABI sceNetAddrConfig6Start(); int PS4_SYSV_ABI sceNetAddrConfig6Stop(); @@ -31,7 +43,7 @@ int PS4_SYSV_ABI sceNetBandwidthControlGetPolicy(); int PS4_SYSV_ABI sceNetBandwidthControlSetDefaultParam(); int PS4_SYSV_ABI sceNetBandwidthControlSetIfParam(); int PS4_SYSV_ABI sceNetBandwidthControlSetPolicy(); -int PS4_SYSV_ABI sceNetBind(); +int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen); int PS4_SYSV_ABI sceNetClearDnsCache(); int PS4_SYSV_ABI sceNetConfigAddArp(); int PS4_SYSV_ABI sceNetConfigAddArpWithInterface(); @@ -143,15 +155,15 @@ int PS4_SYSV_ABI sceNetGetRandom(); int PS4_SYSV_ABI sceNetGetRouteInfo(); int PS4_SYSV_ABI sceNetGetSockInfo(); int PS4_SYSV_ABI sceNetGetSockInfo6(); -int PS4_SYSV_ABI sceNetGetsockname(); -int PS4_SYSV_ABI sceNetGetsockopt(); +int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen); +int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen); int PS4_SYSV_ABI sceNetGetStatisticsInfo(); int PS4_SYSV_ABI sceNetGetStatisticsInfoInternal(); int PS4_SYSV_ABI sceNetGetSystemTime(); -int PS4_SYSV_ABI sceNetHtonl(); -int PS4_SYSV_ABI sceNetHtonll(); -int PS4_SYSV_ABI sceNetHtons(); -int PS4_SYSV_ABI sceNetInetNtop(); +u32 PS4_SYSV_ABI sceNetHtonl(u32 host32); +u64 PS4_SYSV_ABI sceNetHtonll(u64 host64); +u16 PS4_SYSV_ABI sceNetHtons(u16 host16); +const char* PS4_SYSV_ABI sceNetInetNtop(int af, const void* src, char* dst, u32 size); int PS4_SYSV_ABI sceNetInetNtopWithScopeId(); int PS4_SYSV_ABI sceNetInetPton(); int PS4_SYSV_ABI sceNetInetPtonEx(); @@ -164,15 +176,16 @@ int PS4_SYSV_ABI sceNetIoctl(); int PS4_SYSV_ABI sceNetListen(); int PS4_SYSV_ABI sceNetMemoryAllocate(); int PS4_SYSV_ABI sceNetMemoryFree(); -int PS4_SYSV_ABI sceNetNtohl(); +u32 PS4_SYSV_ABI sceNetNtohl(u32 net32); int PS4_SYSV_ABI sceNetNtohll(); -int PS4_SYSV_ABI sceNetNtohs(); +u16 PS4_SYSV_ABI sceNetNtohs(u16 net16); int PS4_SYSV_ABI sceNetPoolCreate(const char* name, int size, int flags); int PS4_SYSV_ABI sceNetPoolDestroy(); int PS4_SYSV_ABI sceNetPppoeStart(); int PS4_SYSV_ABI sceNetPppoeStop(); int PS4_SYSV_ABI sceNetRecv(); -int PS4_SYSV_ABI sceNetRecvfrom(); +int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags, + OrbisNetSockaddr* addr, u32* paddrlen); int PS4_SYSV_ABI sceNetRecvmsg(); int PS4_SYSV_ABI sceNetResolverAbort(); int PS4_SYSV_ABI sceNetResolverConnect(); @@ -213,7 +226,7 @@ int PS4_SYSV_ABI sceNetShowRoute6WithMemory(); int PS4_SYSV_ABI sceNetShowRouteForBuffer(); int PS4_SYSV_ABI sceNetShowRouteWithMemory(); int PS4_SYSV_ABI sceNetShutdown(); -int PS4_SYSV_ABI sceNetSocket(); +int PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol); int PS4_SYSV_ABI sceNetSocketAbort(); int PS4_SYSV_ABI sceNetSocketClose(); int PS4_SYSV_ABI sceNetSyncCreate(); diff --git a/src/core/libraries/save_data/savedata.cpp b/src/core/libraries/save_data/savedata.cpp index a2086af2..d4f04a25 100644 --- a/src/core/libraries/save_data/savedata.cpp +++ b/src/core/libraries/save_data/savedata.cpp @@ -351,6 +351,7 @@ s32 saveDataMount(u32 user_id, std::string dir_name, u32 mount_mode, mount_result->mount_status = 0; strncpy(mount_result->mount_point.data, g_mount_point.c_str(), 16); } break; + case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE: case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDONLY: case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR: case ORBIS_SAVE_DATA_MOUNT_MODE_CREATE | ORBIS_SAVE_DATA_MOUNT_MODE_RDWR | diff --git a/src/emulator.cpp b/src/emulator.cpp index 77ba91f0..11b506c5 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -140,11 +140,13 @@ void Emulator::Run(const std::filesystem::path& file) { void Emulator::LoadSystemModules(const std::filesystem::path& file) { - constexpr std::array ModulesToLoad{ + constexpr std::array ModulesToLoad{ {{"libSceNgs2.sprx", nullptr}, {"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterlibSceLibcInternal}, {"libSceDiscMap.sprx", &Libraries::DiscMap::RegisterlibSceDiscMap}, - {"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc}}}; + {"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc}, + {"libSceJpegEnc.sprx", nullptr}, + {"libSceJson2.sprx", nullptr}}}; std::vector found_modules; const auto& sys_module_path = Common::FS::GetUserPath(Common::FS::PathType::SysModuleDir);