diff --git a/core/libs/CMakeLists.txt b/core/libs/CMakeLists.txt index 68e441814..97021bfbf 100644 --- a/core/libs/CMakeLists.txt +++ b/core/libs/CMakeLists.txt @@ -314,6 +314,16 @@ if(BUILD_TESTING) set_tests_properties(guest_signals PROPERTIES ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$") endif() + add_executable(guest_kernel_error_tests tests/GuestKernelErrors.cpp) + target_include_directories(guest_kernel_error_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_link_libraries(guest_kernel_error_tests PRIVATE libkernel libc) + configure_windows_unwind(guest_kernel_error_tests) + add_test(NAME guest_kernel_errors COMMAND guest_kernel_error_tests) + set_tests_properties(guest_kernel_errors PROPERTIES TIMEOUT 20) + if(WIN32) + set_tests_properties(guest_kernel_errors PROPERTIES ENVIRONMENT_MODIFICATION + "PATH=path_list_prepend:$") + endif() add_executable(guest_system_configuration_tests tests/GuestSystemConfiguration.cpp) target_include_directories(guest_system_configuration_tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(guest_system_configuration_tests PRIVATE libkernel libc) diff --git a/core/libs/prx/libkernel/DirectMemory/DirectMemory.hpp b/core/libs/prx/libkernel/DirectMemory/DirectMemory.hpp index c53b17f05..ff97aaeb1 100644 --- a/core/libs/prx/libkernel/DirectMemory/DirectMemory.hpp +++ b/core/libs/prx/libkernel/DirectMemory/DirectMemory.hpp @@ -7,11 +7,11 @@ static constexpr size_t DIRECT_MEMORY_SIZE = 13824ULL * 1024 * 1024; static constexpr size_t PS5_PAGE_SIZE = 0x4000; -static constexpr int SCE_KERNEL_ERROR_EINVAL = -2147418107; -static constexpr int SCE_KERNEL_ERROR_EAGAIN = -2147418110; -static constexpr int SCE_KERNEL_ERROR_ENOMEM = -2147418105; -static constexpr int SCE_KERNEL_ERROR_EACCES = -2147418108; -static constexpr int SCE_KERNEL_ERROR_EFAULT = -2147418103; +static constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016; +static constexpr int SCE_KERNEL_ERROR_EAGAIN = 0x80020023; +static constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000C; +static constexpr int SCE_KERNEL_ERROR_EACCES = 0x8002000D; +static constexpr int SCE_KERNEL_ERROR_EFAULT = 0x8002000E; int DirectMemoryAlloc(int64_t searchStart, int64_t searchEnd, size_t len, size_t alignment, int64_t* physOut); void DirectMemoryFree(int64_t start, size_t len); diff --git a/core/libs/prx/libkernel/Equeue/Equeue.hpp b/core/libs/prx/libkernel/Equeue/Equeue.hpp index cae407344..d5bcf3910 100644 --- a/core/libs/prx/libkernel/Equeue/Equeue.hpp +++ b/core/libs/prx/libkernel/Equeue/Equeue.hpp @@ -23,11 +23,11 @@ static constexpr uint16_t EV_CLEAR = 0x0020; static constexpr uint16_t EV_ERROR = 0x4000; static constexpr int EQUEUE_OK = 0; -static constexpr int EQUEUE_ERROR_EBADF = -2147418090; -static constexpr int EQUEUE_ERROR_EFAULT = -2147418103; -static constexpr int EQUEUE_ERROR_EINVAL = -2147418107; -static constexpr int EQUEUE_ERROR_ENOENT = -2147418095; -static constexpr int EQUEUE_ERROR_ETIMEDOUT = -2147418077; +static constexpr int EQUEUE_ERROR_EBADF = 0x80020009; +static constexpr int EQUEUE_ERROR_EFAULT = 0x8002000E; +static constexpr int EQUEUE_ERROR_EINVAL = 0x80020016; +static constexpr int EQUEUE_ERROR_ENOENT = 0x80020002; +static constexpr int EQUEUE_ERROR_ETIMEDOUT = 0x8002003C; struct KernelEqueueEvent; diff --git a/core/libs/tests/GuestKernelErrors.cpp b/core/libs/tests/GuestKernelErrors.cpp new file mode 100644 index 000000000..96997af26 --- /dev/null +++ b/core/libs/tests/GuestKernelErrors.cpp @@ -0,0 +1,56 @@ +#include "SceTypes.hpp" +#include +#include + +extern "C" { +int APS5_VABI sceKernelCreateEqueue(KernelEqueue* eq, const char* name); +int APS5_VABI sceKernelDeleteEqueue(KernelEqueue eq); +int APS5_VABI sceKernelWaitEqueue(KernelEqueue eq, KernelEvent* ev, int num, int* out, const KernelUseconds* timo); +int APS5_VABI sceKernelDeleteUserEvent(KernelEqueue eq, int id); +int APS5_VABI scePthreadMutexattrInit(PthreadMutexattr* attr); +int APS5_VABI scePthreadMutexattrDestroy(PthreadMutexattr* attr); +int APS5_VABI scePthreadMutexattrSettype(PthreadMutexattr* attr, int type); +int APS5_VABI scePthreadMutexInit(PthreadMutex* mutex, const PthreadMutexattr* attr, const char* name); +int APS5_VABI scePthreadMutexDestroy(PthreadMutex* mutex); +int APS5_VABI scePthreadMutexLock(PthreadMutex* mutex); +int APS5_VABI scePthreadMutexUnlock(PthreadMutex* mutex); +} + +static constexpr int SCE_OK = 0; +static constexpr int SCE_KERNEL_ERROR_ENOENT = static_cast(0x80020002); +static constexpr int SCE_KERNEL_ERROR_EBADF = static_cast(0x80020009); +static constexpr int SCE_KERNEL_ERROR_EDEADLK = static_cast(0x8002000B); +static constexpr int SCE_KERNEL_ERROR_EFAULT = static_cast(0x8002000E); +static constexpr int SCE_KERNEL_ERROR_EINVAL = static_cast(0x80020016); +static constexpr int SCE_KERNEL_ERROR_ETIMEDOUT = static_cast(0x8002003C); +static constexpr int MUTEX_TYPE_ERRORCHECK = 1; + +static void Require(bool value) { if (!value) std::abort(); } + +int main() { + KernelEqueue eq = 0; + Require(sceKernelCreateEqueue(&eq, "errors") == SCE_OK); + KernelEvent event{}; + int count = -1; + const KernelUseconds timeout = 1000; + Require(sceKernelWaitEqueue(eq, &event, 1, &count, &timeout) == SCE_KERNEL_ERROR_ETIMEDOUT); + Require(count == 0); + Require(sceKernelWaitEqueue(eq, nullptr, 1, &count, &timeout) == SCE_KERNEL_ERROR_EFAULT); + Require(sceKernelWaitEqueue(eq, &event, 0, &count, &timeout) == SCE_KERNEL_ERROR_EINVAL); + Require(sceKernelDeleteUserEvent(eq, 7) == SCE_KERNEL_ERROR_ENOENT); + Require(sceKernelDeleteEqueue(eq) == SCE_OK); + Require(sceKernelDeleteEqueue(eq) == SCE_KERNEL_ERROR_EBADF); + Require(sceKernelWaitEqueue(eq, &event, 1, &count, &timeout) == SCE_KERNEL_ERROR_EBADF); + Require(sceKernelCreateEqueue(nullptr, "errors") == SCE_KERNEL_ERROR_EINVAL); + + PthreadMutexattr attr = nullptr; + Require(scePthreadMutexattrInit(&attr) == SCE_OK); + Require(scePthreadMutexattrSettype(&attr, MUTEX_TYPE_ERRORCHECK) == SCE_OK); + PthreadMutex mutex = nullptr; + Require(scePthreadMutexInit(&mutex, &attr, nullptr) == SCE_OK); + Require(scePthreadMutexattrDestroy(&attr) == SCE_OK); + Require(scePthreadMutexLock(&mutex) == SCE_OK); + Require(scePthreadMutexLock(&mutex) == SCE_KERNEL_ERROR_EDEADLK); + Require(scePthreadMutexUnlock(&mutex) == SCE_OK); + Require(scePthreadMutexDestroy(&mutex) == SCE_OK); +}