From 01035d35bd3e7b7da95e856ec44a36a30dbd844d Mon Sep 17 00:00:00 2001 From: Eladash Date: Tue, 14 Jan 2020 20:32:41 +0200 Subject: [PATCH] sys_process: Fix sys_process_get_id, add error_code (#7246) --- rpcs3/Emu/Cell/Modules/cellSpurs.cpp | 2 +- rpcs3/Emu/Cell/PPUFunction.cpp | 2 +- rpcs3/Emu/Cell/lv2/lv2.cpp | 2 +- rpcs3/Emu/Cell/lv2/sys_process.cpp | 60 +++++++++++++++++++--------- rpcs3/Emu/Cell/lv2/sys_process.h | 23 ++++++----- 5 files changed, 57 insertions(+), 32 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp index 5b834d413f..7724a6155c 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp @@ -949,7 +949,7 @@ s32 _spurs::initialize(ppu_thread& ppu, vm::ptr spurs, u32 revision, return CELL_SPURS_CORE_ERROR_INVAL; } - if (sys_process_is_spu_lock_line_reservation_address(spurs.addr(), SYS_MEMORY_ACCESS_RIGHT_SPU_THR) != CELL_OK) + if (process_is_spu_lock_line_reservation_address(spurs.addr(), SYS_MEMORY_ACCESS_RIGHT_SPU_THR) != CELL_OK) { return CELL_SPURS_CORE_ERROR_PERM; } diff --git a/rpcs3/Emu/Cell/PPUFunction.cpp b/rpcs3/Emu/Cell/PPUFunction.cpp index 5c9b3bffdb..cb61ef586f 100644 --- a/rpcs3/Emu/Cell/PPUFunction.cpp +++ b/rpcs3/Emu/Cell/PPUFunction.cpp @@ -22,7 +22,7 @@ extern std::string ppu_get_syscall_name(u64 code) case 25: return "sys_process_get_sdk_version"; case 26: return "_sys_process_exit2"; case 28: return "_sys_process_get_number_of_object"; - case 29: return "sys_process_get_id"; + case 29: return "sys_process_get_id2"; case 30: return "_sys_process_get_paramsfo"; case 31: return "sys_process_get_ppu_guid"; case 41: return "_sys_ppu_thread_exit"; diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 4757b89f4f..e17c3005eb 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -97,7 +97,7 @@ const std::array s_ppu_syscall_table BIND_FUNC(_sys_process_exit2), //26 (0x01A) null_func,//BIND_FUNC(), //27 (0x01B) DBG null_func,//BIND_FUNC(_sys_process_get_number_of_object)//28 (0x01C) ROOT - BIND_FUNC(sys_process_get_id), //29 (0x01D) ROOT + BIND_FUNC(sys_process_get_id2), //29 (0x01D) ROOT BIND_FUNC(_sys_process_get_paramsfo), //30 (0x01E) null_func,//BIND_FUNC(sys_process_get_ppu_guid), //31 (0x01F) diff --git a/rpcs3/Emu/Cell/lv2/sys_process.cpp b/rpcs3/Emu/Cell/lv2/sys_process.cpp index c3589b83a9..90141001cf 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_process.cpp @@ -71,7 +71,7 @@ u32 idm_get_count() return idm::select([&](u32, Get&) {}); } -s32 sys_process_get_number_of_object(u32 object, vm::ptr nump) +error_code sys_process_get_number_of_object(u32 object, vm::ptr nump) { sys_process.error("sys_process_get_number_of_object(object=0x%x, nump=*0x%x)", object, nump); @@ -117,10 +117,8 @@ void idm_get_set(std::set& out) }); } -s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size) +static error_code process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size) { - sys_process.error("sys_process_get_id(object=0x%x, buffer=*0x%x, size=%d, set_size=*0x%x)", object, buffer, size, set_size); - std::set objects; switch (object) @@ -143,8 +141,7 @@ s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr s case SYS_FS_FD_OBJECT: idm_get_set(objects); break; case SYS_LWCOND_OBJECT: idm_get_set(objects); break; case SYS_EVENT_FLAG_OBJECT: idm_get_set(objects); break; - - case SYS_SPUPORT_OBJECT: // Unallowed + case SYS_SPUPORT_OBJECT: fmt::throw_exception("SYS_SPUPORT_OBJECT" HERE); default: { return CELL_EINVAL; @@ -153,7 +150,8 @@ s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr s u32 i = 0; - for (auto id = objects.begin(); i < size && id != objects.end(); id++, i++) + // NOTE: Treats negative and 0 values as 1 due to signed checks and "do-while" behavior of fw + for (auto id = objects.begin(); i < std::max(size, 1) + 0u && id != objects.end(); id++, i++) { buffer[i] = *id; } @@ -163,7 +161,33 @@ s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr s return CELL_OK; } -s32 process_is_spu_lock_line_reservation_address(u32 addr, u64 flags) +error_code sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size) +{ + sys_process.error("sys_process_get_id(object=0x%x, buffer=*0x%x, size=%d, set_size=*0x%x)", object, buffer, size, set_size); + + if (object == SYS_SPUPORT_OBJECT) + { + // Unallowed for this syscall + return CELL_EINVAL; + } + + return process_get_id(object, buffer, size, set_size); +} + +error_code sys_process_get_id2(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size) +{ + sys_process.error("sys_process_get_id2(object=0x%x, buffer=*0x%x, size=%d, set_size=*0x%x)", object, buffer, size, set_size); + + if (!g_ps3_process_info.has_root_perm()) + { + // This syscall is more capable than sys_process_get_id but also needs a root perm check + return CELL_ENOSYS; + } + + return process_get_id(object, buffer, size, set_size); +} + +error_code process_is_spu_lock_line_reservation_address(u32 addr, u64 flags) { if (!flags || flags & ~(SYS_MEMORY_ACCESS_RIGHT_SPU_THR | SYS_MEMORY_ACCESS_RIGHT_RAW_SPU)) { @@ -174,14 +198,14 @@ s32 process_is_spu_lock_line_reservation_address(u32 addr, u64 flags) return CELL_OK; } -s32 sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags) +error_code sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags) { sys_process.warning("sys_process_is_spu_lock_line_reservation_address(addr=0x%x, flags=0x%llx)", addr, flags); return process_is_spu_lock_line_reservation_address(addr, flags); } -s32 _sys_process_get_paramsfo(vm::ptr buffer) +error_code _sys_process_get_paramsfo(vm::ptr buffer) { sys_process.warning("_sys_process_get_paramsfo(buffer=0x%x)", buffer); @@ -204,15 +228,15 @@ s32 process_get_sdk_version(u32 pid, s32& ver) return CELL_OK; } -s32 sys_process_get_sdk_version(u32 pid, vm::ptr version) +error_code sys_process_get_sdk_version(u32 pid, vm::ptr version) { sys_process.warning("sys_process_get_sdk_version(pid=0x%x, version=*0x%x)", pid, version); s32 sdk_ver; - s32 ret = process_get_sdk_version(pid, sdk_ver); + const s32 ret = process_get_sdk_version(pid, sdk_ver); if (ret != CELL_OK) { - return ret; // error code + return CellError{ret + 0u}; // error code } else { @@ -221,34 +245,34 @@ s32 sys_process_get_sdk_version(u32 pid, vm::ptr version) } } -s32 sys_process_kill(u32 pid) +error_code sys_process_kill(u32 pid) { sys_process.todo("sys_process_kill(pid=0x%x)", pid); return CELL_OK; } -s32 sys_process_wait_for_child(u32 pid, vm::ptr status, u64 unk) +error_code sys_process_wait_for_child(u32 pid, vm::ptr status, u64 unk) { sys_process.todo("sys_process_wait_for_child(pid=0x%x, status=*0x%x, unk=0x%llx", pid, status, unk); return CELL_OK; } -s32 sys_process_wait_for_child2(u64 unk1, u64 unk2, u64 unk3, u64 unk4, u64 unk5, u64 unk6) +error_code sys_process_wait_for_child2(u64 unk1, u64 unk2, u64 unk3, u64 unk4, u64 unk5, u64 unk6) { sys_process.todo("sys_process_wait_for_child2(unk1=0x%llx, unk2=0x%llx, unk3=0x%llx, unk4=0x%llx, unk5=0x%llx, unk6=0x%llx)", unk1, unk2, unk3, unk4, unk5, unk6); return CELL_OK; } -s32 sys_process_get_status(u64 unk) +error_code sys_process_get_status(u64 unk) { sys_process.todo("sys_process_get_status(unk=0x%llx)", unk); //vm::write32(CPU.gpr[4], GetPPUThreadStatus(CPU)); return CELL_OK; } -s32 sys_process_detach_child(u64 unk) +error_code sys_process_detach_child(u64 unk) { sys_process.todo("sys_process_detach_child(unk=0x%llx)", unk); return CELL_OK; diff --git a/rpcs3/Emu/Cell/lv2/sys_process.h b/rpcs3/Emu/Cell/lv2/sys_process.h index cf6ec469fb..f65d4a4be5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.h +++ b/rpcs3/Emu/Cell/lv2/sys_process.h @@ -54,20 +54,21 @@ extern ps3_process_info_t g_ps3_process_info; // Auxiliary functions s32 process_getpid(); s32 process_get_sdk_version(u32 pid, s32& ver); -s32 process_is_spu_lock_line_reservation_address(u32 addr, u64 flags); +error_code process_is_spu_lock_line_reservation_address(u32 addr, u64 flags); // SysCalls s32 sys_process_getpid(); s32 sys_process_getppid(); -s32 sys_process_get_number_of_object(u32 object, vm::ptr nump); -s32 sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size); -s32 _sys_process_get_paramsfo(vm::ptr buffer); -s32 sys_process_get_sdk_version(u32 pid, vm::ptr version); -s32 sys_process_get_status(u64 unk); -s32 sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags); -s32 sys_process_kill(u32 pid); -s32 sys_process_wait_for_child(u32 pid, vm::ptr status, u64 unk); -s32 sys_process_wait_for_child2(u64 unk1, u64 unk2, u64 unk3, u64 unk4, u64 unk5, u64 unk6); -s32 sys_process_detach_child(u64 unk); +error_code sys_process_get_number_of_object(u32 object, vm::ptr nump); +error_code sys_process_get_id(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size); +error_code sys_process_get_id2(u32 object, vm::ptr buffer, u32 size, vm::ptr set_size); +error_code _sys_process_get_paramsfo(vm::ptr buffer); +error_code sys_process_get_sdk_version(u32 pid, vm::ptr version); +error_code sys_process_get_status(u64 unk); +error_code sys_process_is_spu_lock_line_reservation_address(u32 addr, u64 flags); +error_code sys_process_kill(u32 pid); +error_code sys_process_wait_for_child(u32 pid, vm::ptr status, u64 unk); +error_code sys_process_wait_for_child2(u64 unk1, u64 unk2, u64 unk3, u64 unk4, u64 unk5, u64 unk6); +error_code sys_process_detach_child(u64 unk); void _sys_process_exit(ppu_thread& ppu, s32 status, u32 arg2, u32 arg3); void _sys_process_exit2(ppu_thread& ppu, s32 status, vm::ptr arg, u32 arg_size, u32 arg4);