2020-12-05 13:08:24 +01:00
|
|
|
#include "stdafx.h"
|
2016-03-21 20:42:14 +01:00
|
|
|
#include "Emu/Cell/PPUModule.h"
|
2015-08-02 04:15:49 +02:00
|
|
|
|
2025-10-04 15:46:36 +02:00
|
|
|
#include "cellos/sys_lwmutex.h"
|
|
|
|
|
#include "cellos/sys_prx.h"
|
2015-08-02 04:15:49 +02:00
|
|
|
#include "sysPrxForUser.h"
|
|
|
|
|
|
2020-01-31 10:01:17 +01:00
|
|
|
LOG_CHANNEL(sysPrxForUser);
|
2015-08-02 04:15:49 +02:00
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
extern vm::gvar<sys_lwmutex_t> g_ppu_prx_lwm;
|
|
|
|
|
|
2017-04-13 01:58:33 +02:00
|
|
|
// Convert the array of 32-bit pointers to 64-bit pointers using stack allocation
|
|
|
|
|
static auto convert_path_list(vm::cpptr<char> path_list, s32 count)
|
2015-08-02 04:15:49 +02:00
|
|
|
{
|
2018-09-03 14:09:09 +02:00
|
|
|
return vm::var<vm::cptr<char, u64>[]>(count, path_list.get_ptr());
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Execute start or stop module function
|
|
|
|
|
static void entryx(ppu_thread& ppu, vm::ptr<sys_prx_start_stop_module_option_t> opt, u32 args, vm::ptr<void> argp, vm::ptr<s32> res)
|
|
|
|
|
{
|
2020-02-19 16:26:41 +01:00
|
|
|
if (opt->entry2.addr() != umax)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
*res = opt->entry2(ppu, opt->entry, args, argp);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-19 16:26:41 +01:00
|
|
|
if (opt->entry.addr() != umax)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
*res = opt->entry(ppu, args, argp);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2020-03-26 15:40:22 +01:00
|
|
|
|
|
|
|
|
*res = 0;
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_load_module(ppu_thread& ppu, vm::cptr<char> path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.warning("sys_prx_load_module(path=%s, flags=0x%x, pOpt=*0x%x)", path, flags, pOpt);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_load_module(ppu, path, flags, pOpt);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_load_module_by_fd(ppu_thread& ppu, s32 fd, u64 offset, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.warning("sys_prx_load_module_by_fd(fd=%d, offset=0x%x, flags=0x%x, pOpt=*0x%x)", fd, offset, flags, pOpt);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_load_module_by_fd(ppu, fd, offset, flags, pOpt);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_load_module_on_memcontainer(ppu_thread& ppu, vm::cptr<char> path, u32 mem_ct, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.warning("sys_prx_load_module_on_memcontainer(path=%s, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x)", path, mem_ct, flags, pOpt);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_load_module_on_memcontainer(ppu, path, mem_ct, flags, pOpt);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_load_module_on_memcontainer_by_fd(ppu_thread& ppu, s32 fd, u64 offset, u32 mem_ct, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.warning("sys_prx_load_module_on_memcontainer_by_fd(fd=%d, offset=0x%x, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x)", fd, offset, mem_ct, flags, pOpt);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_load_module_on_memcontainer_by_fd(ppu, fd, offset, mem_ct, flags, pOpt);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_load_module_list(ppu_thread& ppu, s32 count, vm::cpptr<char> path_list, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt, vm::ptr<u32> id_list)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.todo("sys_prx_load_module_list(count=%d, path_list=**0x%x, flags=0x%x, pOpt=*0x%x, id_list=*0x%x)", count, path_list, flags, pOpt, id_list);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_load_module_list(ppu, count, convert_path_list(path_list, count), flags, pOpt, id_list);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_load_module_list_on_memcontainer(ppu_thread& ppu, s32 count, vm::cpptr<char> path_list, u32 mem_ct, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt, vm::ptr<u32> id_list)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.todo("sys_prx_load_module_list_on_memcontainer(count=%d, path_list=**0x%x, mem_ct=0x%x, flags=0x%x, pOpt=*0x%x, id_list=*0x%x)", count, path_list, mem_ct, flags, pOpt, id_list);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_load_module_list_on_memcontainer(ppu, count, convert_path_list(path_list, count), mem_ct, flags, pOpt, id_list);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error_code sys_prx_start_module(ppu_thread& ppu, u32 id, u32 args, vm::ptr<void> argp, vm::ptr<s32> result, u64 flags, vm::ptr<void> pOpt)
|
|
|
|
|
{
|
|
|
|
|
sysPrxForUser.warning("sys_prx_start_module(id=0x%x, args=%u, argp=*0x%x, result=*0x%x, flags=0x%x, pOpt=*0x%x)", id, args, argp, result, flags, pOpt);
|
|
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
|
{
|
|
|
|
|
return CELL_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-04-13 01:58:33 +02:00
|
|
|
|
|
|
|
|
vm::var<sys_prx_start_stop_module_option_t> opt;
|
|
|
|
|
opt->size = opt.size();
|
2025-04-05 21:50:45 +02:00
|
|
|
opt->cmd = 1;
|
2017-04-13 01:58:33 +02:00
|
|
|
opt->entry2.set(-1);
|
|
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
const error_code res = _sys_prx_start_module(ppu, id, flags, opt);
|
2017-04-13 01:58:33 +02:00
|
|
|
|
|
|
|
|
if (res < 0)
|
|
|
|
|
{
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entryx(ppu, opt, args, argp, result);
|
|
|
|
|
|
|
|
|
|
opt->cmd = 2;
|
|
|
|
|
opt->res = *result;
|
|
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
_sys_prx_start_module(ppu, id, flags, opt);
|
2017-04-13 01:58:33 +02:00
|
|
|
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error_code sys_prx_stop_module(ppu_thread& ppu, u32 id, u32 args, vm::ptr<void> argp, vm::ptr<s32> result, u64 flags, vm::ptr<void> pOpt)
|
|
|
|
|
{
|
|
|
|
|
sysPrxForUser.warning("sys_prx_stop_module(id=0x%x, args=%u, argp=*0x%x, result=*0x%x, flags=0x%x, pOpt=*0x%x)", id, args, argp, result, flags, pOpt);
|
|
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
|
{
|
|
|
|
|
return CELL_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-04-13 01:58:33 +02:00
|
|
|
|
|
|
|
|
vm::var<sys_prx_start_stop_module_option_t> opt;
|
|
|
|
|
opt->size = opt.size();
|
2025-04-05 21:50:45 +02:00
|
|
|
opt->cmd = 1;
|
2017-04-13 01:58:33 +02:00
|
|
|
opt->entry2.set(-1);
|
|
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
const error_code res = _sys_prx_stop_module(ppu, id, flags, opt);
|
2017-04-13 01:58:33 +02:00
|
|
|
|
|
|
|
|
if (res < 0)
|
|
|
|
|
{
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entryx(ppu, opt, args, argp, result);
|
|
|
|
|
|
|
|
|
|
opt->cmd = 2;
|
|
|
|
|
opt->res = *result;
|
|
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
_sys_prx_stop_module(ppu, id, flags, opt);
|
2017-04-13 01:58:33 +02:00
|
|
|
|
2015-08-02 04:15:49 +02:00
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_unload_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<sys_prx_unload_module_option_t> pOpt)
|
2015-08-02 04:15:49 +02:00
|
|
|
{
|
2017-04-13 01:58:33 +02:00
|
|
|
sysPrxForUser.warning("sys_prx_unload_module(id=0x%x, flags=0x%x, pOpt=*0x%x)", id, flags, pOpt);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_unload_module(ppu, id, flags, pOpt);
|
2015-08-02 04:15:49 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_register_library(ppu_thread& ppu, vm::ptr<void> lib_entry)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.warning("sys_prx_register_library(lib_entry=*0x%x)", lib_entry);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_register_library(ppu, lib_entry);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2017-07-12 18:10:56 +02:00
|
|
|
error_code sys_prx_unregister_library(ppu_thread& ppu, vm::ptr<void> lib_entry)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.warning("sys_prx_unregister_library(lib_entry=*0x%x)", lib_entry);
|
|
|
|
|
|
2020-02-26 21:23:06 +01:00
|
|
|
sys_lwmutex_locker lock(ppu, g_ppu_prx_lwm);
|
2017-07-12 18:10:56 +02:00
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_unregister_library(ppu, lib_entry);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error_code sys_prx_get_module_list(ppu_thread& ppu, u64 flags, vm::ptr<sys_prx_get_module_list_t> info)
|
|
|
|
|
{
|
|
|
|
|
sysPrxForUser.trace("sys_prx_get_module_list(flags=0x%x, info=*0x%x)", flags, info);
|
|
|
|
|
|
|
|
|
|
if (!info || !info->idlist)
|
|
|
|
|
{
|
|
|
|
|
return CELL_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialize params
|
|
|
|
|
vm::var<sys_prx_get_module_list_option_t> opt;
|
2025-04-05 21:50:45 +02:00
|
|
|
opt->size = opt.size();
|
|
|
|
|
opt->max = info->max;
|
|
|
|
|
opt->count = 0;
|
2017-04-13 01:58:33 +02:00
|
|
|
opt->idlist = info->idlist;
|
2025-04-05 21:50:45 +02:00
|
|
|
opt->unk = 0;
|
2017-04-13 01:58:33 +02:00
|
|
|
|
|
|
|
|
// Call the syscall
|
2020-11-03 13:05:13 +01:00
|
|
|
const s32 res = _sys_prx_get_module_list(ppu, 2, opt);
|
2017-04-13 01:58:33 +02:00
|
|
|
|
2025-04-05 21:50:45 +02:00
|
|
|
info->max = opt->max;
|
2017-04-13 01:58:33 +02:00
|
|
|
info->count = opt->count;
|
|
|
|
|
|
|
|
|
|
return not_an_error(res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error_code sys_prx_get_module_info(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<sys_prx_module_info_t> info)
|
|
|
|
|
{
|
|
|
|
|
sysPrxForUser.trace("sys_prx_get_module_info(id=0x%x, flags=0x%x, info=*0x%x)", id, flags, info);
|
|
|
|
|
|
|
|
|
|
if (!info)
|
|
|
|
|
{
|
|
|
|
|
return CELL_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialize params
|
|
|
|
|
vm::var<sys_prx_module_info_option_t> opt;
|
|
|
|
|
opt->size = opt.size();
|
|
|
|
|
opt->info = info;
|
|
|
|
|
|
|
|
|
|
// Call the syscall
|
2025-01-18 14:16:38 +01:00
|
|
|
return _sys_prx_get_module_info(ppu, id, flags, opt);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
error_code sys_prx_get_module_id_by_name(ppu_thread& ppu, vm::cptr<char> name, u64 flags, vm::ptr<sys_prx_get_module_id_by_name_option_t> pOpt)
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.trace("sys_prx_get_module_id_by_name(name=%s, flags=0x%x, pOpt=*0x%x)", name, flags, pOpt);
|
|
|
|
|
|
|
|
|
|
if (flags || pOpt)
|
|
|
|
|
{
|
|
|
|
|
return CELL_EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Call the syscall
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_get_module_id_by_name(ppu, name, u64{0}, vm::null);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-03 13:05:13 +01:00
|
|
|
error_code sys_prx_get_module_id_by_address(ppu_thread& ppu, u32 addr)
|
2015-08-02 04:15:49 +02:00
|
|
|
{
|
2017-04-13 01:58:33 +02:00
|
|
|
sysPrxForUser.trace("sys_prx_get_module_id_by_address()");
|
2015-08-02 04:15:49 +02:00
|
|
|
|
2017-04-13 01:58:33 +02:00
|
|
|
// Call the syscall
|
2020-11-03 13:05:13 +01:00
|
|
|
return _sys_prx_get_module_id_by_address(ppu, addr);
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error_code sys_prx_exitspawn_with_level()
|
|
|
|
|
{
|
|
|
|
|
sysPrxForUser.todo("sys_prx_exitspawn_with_level()");
|
|
|
|
|
return CELL_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-05 20:05:37 +01:00
|
|
|
error_code sys_prx_get_my_module_id(ppu_thread& ppu_do_not_call, ppu_thread&, ppu_thread&, ppu_thread&) // Do not call directly
|
2017-04-13 01:58:33 +02:00
|
|
|
{
|
|
|
|
|
sysPrxForUser.trace("sys_prx_get_my_module_id()");
|
|
|
|
|
|
|
|
|
|
// Call the syscall using the LR
|
2021-03-05 20:05:37 +01:00
|
|
|
return _sys_prx_get_module_id_by_address(ppu_do_not_call, static_cast<u32>(ppu_do_not_call.lr));
|
2017-04-13 01:58:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void sysPrxForUser_sys_prx_init()
|
|
|
|
|
{
|
2015-08-02 04:15:49 +02:00
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_load_module);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_load_module_by_fd);
|
2015-08-01 09:52:44 +02:00
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_load_module_on_memcontainer);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_load_module_on_memcontainer_by_fd);
|
2015-08-02 04:15:49 +02:00
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_load_module_list);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_load_module_list_on_memcontainer);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_start_module);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_stop_module);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_unload_module);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_register_library);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_unregister_library);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_get_module_list);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_get_module_info);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_get_module_id_by_name);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_get_module_id_by_address);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_exitspawn_with_level);
|
|
|
|
|
REG_FUNC(sysPrxForUser, sys_prx_get_my_module_id);
|
|
|
|
|
}
|