Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vm/sys_overlay Improvements #6102

Merged
merged 1 commit into from Jul 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Utilities/Thread.cpp
Expand Up @@ -1420,7 +1420,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
if (cpu->check_state())
{
// Hack: allocate memory in case the emulator is stopping
auto area = vm::get(vm::any, addr & -0x10000, 0x10000);
auto area = vm::reserve_map(vm::any, addr & -0x10000, 0x10000);

if (area->flags & 0x100)
{
Expand Down
6 changes: 2 additions & 4 deletions rpcs3/Emu/Cell/Modules/cellSaveData.cpp
Expand Up @@ -16,8 +16,6 @@

LOG_CHANNEL(cellSaveData);

extern u32 g_ps3_sdk_version;

template<>
void fmt_class_string<CellSaveDataError>::format(std::string& out, u64 arg)
{
Expand Down Expand Up @@ -140,7 +138,7 @@ static bool savedata_check_args(u32 operation, u32 version, vm::cptr<char> dirNa
}

if (!memchr(setList->dirNamePrefix.get_ptr(), '\0', CELL_SAVEDATA_PREFIX_SIZE)
|| (g_ps3_sdk_version > 0x3FFFFF && !setList->dirNamePrefix[0]))
|| (g_ps3_process_info.sdk_ver > 0x3FFFFF && !setList->dirNamePrefix[0]))
{
// ****** sysutil savedata parameter error : 17 ******
return false;
Expand Down Expand Up @@ -803,7 +801,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
return CELL_SAVEDATA_ERROR_PARAM;
}

if (g_ps3_sdk_version > 0x36FFFF)
if (g_ps3_process_info.sdk_ver > 0x36FFFF)
{
for (u8 resv : statSet->setParam->reserved2)
{
Expand Down
24 changes: 21 additions & 3 deletions rpcs3/Emu/Cell/PPUModule.cpp
Expand Up @@ -12,6 +12,7 @@
#include "Emu/Cell/PPUOpcodes.h"
#include "Emu/Cell/PPUAnalyser.h"

#include "Emu/Cell/lv2/sys_process.h"
#include "Emu/Cell/lv2/sys_prx.h"
#include "Emu/Cell/lv2/sys_memory.h"
#include "Emu/Cell/lv2/sys_overlay.h"
Expand All @@ -34,8 +35,6 @@ extern void ppu_initialize();

extern void sys_initialize_tls(ppu_thread&, u64, u32, u32, u32);

extern u32 g_ps3_sdk_version;

// HLE function name cache
std::vector<std::string> g_ppu_function_names;

Expand Down Expand Up @@ -1064,6 +1063,7 @@ void ppu_load_exec(const ppu_exec_object& elf)
s32 primary_prio = 1001;
u32 primary_stacksize = 0x100000;
u32 malloc_pagesize = 0x100000;
u32 ppc_seg = 0;

// Executable hash
sha1_context sha;
Expand Down Expand Up @@ -1219,6 +1219,7 @@ void ppu_load_exec(const ppu_exec_object& elf)

primary_stacksize = info.primary_stacksize;
malloc_pagesize = info.malloc_pagesize;
ppc_seg = info.ppc_seg;

LOG_NOTICE(LOADER, "*** sdk version: 0x%x", info.sdk_version);
LOG_NOTICE(LOADER, "*** primary prio: %d", info.primary_prio);
Expand Down Expand Up @@ -1472,7 +1473,24 @@ void ppu_load_exec(const ppu_exec_object& elf)
_main->validate(0);

// Set SDK version
g_ps3_sdk_version = sdk_version;
g_ps3_process_info.sdk_ver = sdk_version;

// Set ppc fixed allocations segment permission
g_ps3_process_info.ppc_seg = ppc_seg;

if (ppc_seg != 0x0)
{
if (ppc_seg != 0x1)
{
LOG_TODO(LOADER, "Unknown ppc_seg flag value = 0x%x", ppc_seg);
}

// Additional segment for fixed allocations
if (!vm::map(0x30000000, 0x10000000, 0x200))
{
fmt::throw_exception("Failed to map ppc_seg's segment!" HERE);
}
}

// Initialize process arguments
auto args = vm::ptr<u64>::make(vm::alloc(u32{sizeof(u64)} * (::size32(Emu.argv) + ::size32(Emu.envp) + 2), vm::main));
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/lv2/lv2.cpp
Expand Up @@ -429,7 +429,7 @@ const std::array<ppu_function_t, 1024> s_ppu_syscall_table
BIND_FUNC(sys_overlay_unload_module), //451 (0x1C3)
null_func,//BIND_FUNC(sys_overlay_get_module_list) //452 (0x1C4)
null_func,//BIND_FUNC(sys_overlay_get_module_info) //453 (0x1C5)
null_func,//BIND_FUNC(sys_overlay_load_module_by_fd) //454 (0x1C6)
BIND_FUNC(sys_overlay_load_module_by_fd), //454 (0x1C6)
null_func,//BIND_FUNC(sys_overlay_get_module_info2) //455 (0x1C7)
null_func,//BIND_FUNC(sys_overlay_get_sdk_version) //456 (0x1C8)
null_func,//BIND_FUNC(sys_overlay_get_module_dbg_info) //457 (0x1C9)
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_memory.cpp
Expand Up @@ -52,7 +52,7 @@ error_code sys_memory_allocate(u32 size, u64 flags, vm::ptr<u32> alloc_addr)
return CELL_ENOMEM;
}

if (const auto area = vm::get(align == 0x10000 ? vm::user64k : vm::user1m, 0, ::align(size, 0x10000000)))
if (const auto area = vm::reserve_map(align == 0x10000 ? vm::user64k : vm::user1m, 0, ::align(size, 0x10000000), 0x401))
{
if (u32 addr = area->alloc(size, align))
{
Expand Down Expand Up @@ -118,7 +118,7 @@ error_code sys_memory_allocate_from_container(u32 size, u32 cid, u64 flags, vm::
// Create phantom memory object
const auto mem = idm::make_ptr<lv2_memory_alloca>(size, align, flags, ct.ptr);

if (const auto area = vm::get(align == 0x10000 ? vm::user64k : vm::user1m, 0, ::align(size, 0x10000000)))
if (const auto area = vm::reserve_map(align == 0x10000 ? vm::user64k : vm::user1m, 0, ::align(size, 0x10000000), 0x401))
{
if (u32 addr = area->alloc(size, mem->align, &mem->shm))
{
Expand Down
59 changes: 53 additions & 6 deletions rpcs3/Emu/Cell/lv2/sys_overlay.cpp
Expand Up @@ -7,22 +7,26 @@
#include "Crypto/unedat.h"
#include "Loader/ELF.h"

#include "sys_process.h"
#include "sys_overlay.h"
#include "sys_fs.h"

extern std::shared_ptr<lv2_overlay> ppu_load_overlay(const ppu_exec_object&, const std::string& path);

extern void ppu_initialize(const ppu_module&);

LOG_CHANNEL(sys_overlay);

error_code sys_overlay_load_module(vm::ptr<u32> ovlmid, vm::cptr<char> path2, u64 flags, vm::ptr<u32> entry)
static error_code overlay_load_module(vm::ptr<u32> ovlmid, const std::string& vpath, u64 flags, vm::ptr<u32> entry, fs::file src = {})
{
sys_overlay.warning("sys_overlay_load_module(ovlmid=*0x%x, path=%s, flags=0x%x, entry=*0x%x)", ovlmid, path2, flags, entry);
const std::string path = vfs::get(vpath);

const std::string path = path2.get_ptr();
const auto name = path.substr(path.find_last_of('/') + 1);
if (!src)
{
src.open(path);
}

const ppu_exec_object obj = decrypt_self(fs::file(vfs::get(path)), fxm::get_always<LoadedNpdrmKeys_t>()->devKlic.data());
const ppu_exec_object obj = decrypt_self(std::move(src), fxm::get_always<LoadedNpdrmKeys_t>()->devKlic.data());

if (obj != elf_error::ok)
{
Expand All @@ -33,14 +37,57 @@ error_code sys_overlay_load_module(vm::ptr<u32> ovlmid, vm::cptr<char> path2, u6

ppu_initialize(*ovlm);

sys_overlay.success("Loaded overlay: %s", path);
sys_overlay.success("Loaded overlay: %s", vpath);

*ovlmid = idm::last_id();
*entry = ovlm->entry;

return CELL_OK;
}

error_code sys_overlay_load_module(vm::ptr<u32> ovlmid, vm::cptr<char> path, u64 flags, vm::ptr<u32> entry)
{
sys_overlay.warning("sys_overlay_load_module(ovlmid=*0x%x, path=%s, flags=0x%x, entry=*0x%x)", ovlmid, path, flags, entry);

if (!g_ps3_process_info.ppc_seg)
{
// Process not permitted
return CELL_ENOSYS;
}

if (!path)
{
return CELL_EFAULT;
}

return overlay_load_module(ovlmid, path.get_ptr(), flags, entry);
}

error_code sys_overlay_load_module_by_fd(vm::ptr<u32> ovlmid, u32 fd, u64 offset, u64 flags, vm::ptr<u32> entry)
{
sys_overlay.warning("sys_overlay_load_module_by_fd(ovlmid=*0x%x, fd=%d, offset=0x%llx, flags=0x%x, entry=*0x%x)", ovlmid, fd, offset, flags, entry);

if (!g_ps3_process_info.ppc_seg)
{
// Process not permitted
return CELL_ENOSYS;
}

if ((s64)offset < 0)
{
return CELL_EINVAL;
}

const auto file = idm::get<lv2_fs_object, lv2_file>(fd);

if (!file)
{
return CELL_EBADF;
}

return overlay_load_module(ovlmid, fmt::format("%s_x%x", file->name.data(), offset), flags, entry, lv2_file::make_view(file, offset));
}

error_code sys_overlay_unload_module(u32 ovlmid)
{
sys_overlay.warning("sys_overlay_unload_module(ovlmid=0x%x)", ovlmid);
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/lv2/sys_overlay.h
Expand Up @@ -12,10 +12,10 @@ struct lv2_overlay final : lv2_obj, ppu_module
};

error_code sys_overlay_load_module(vm::ptr<u32> ovlmid, vm::cptr<char> path, u64 flags, vm::ptr<u32> entry);
error_code sys_overlay_load_module_by_fd(vm::ptr<u32> ovlmid, u32 fd, u64 offset, u64 flags, vm::ptr<u32> entry);
error_code sys_overlay_unload_module(u32 ovlmid);
//error_code sys_overlay_get_module_list(sys_pid_t pid, size_t ovlmids_num, sys_overlay_t * ovlmids, size_t * num_of_modules);
//error_code sys_overlay_get_module_info(sys_pid_t pid, sys_overlay_t ovlmid, sys_overlay_module_info_t * info);
//error_code sys_overlay_load_module_by_fd(sys_overlay_t * ovlmid, int fd, u64 offset, uint64_t flags, sys_addr_t * entry);
//error_code sys_overlay_get_module_info2(sys_pid_t pid, sys_overlay_t ovlmid, sys_overlay_module_info2_t * info);//
//error_code sys_overlay_get_sdk_version(); //2 params
//error_code sys_overlay_get_module_dbg_info(); //3 params?
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/Cell/lv2/sys_process.cpp
Expand Up @@ -28,7 +28,7 @@

LOG_CHANNEL(sys_process);

u32 g_ps3_sdk_version;
ps3_process_info_t g_ps3_process_info;

s32 process_getpid()
{
Expand Down Expand Up @@ -182,7 +182,7 @@ s32 _sys_process_get_paramsfo(vm::ptr<char> buffer)
s32 process_get_sdk_version(u32 pid, s32& ver)
{
// get correct SDK version for selected pid
ver = g_ps3_sdk_version;
ver = g_ps3_process_info.sdk_ver;

return CELL_OK;
}
Expand Down
8 changes: 8 additions & 0 deletions rpcs3/Emu/Cell/lv2/sys_process.h
Expand Up @@ -36,6 +36,14 @@ struct sys_exit2_param
vm::bpptr<char, u64, u64> args;
};

struct ps3_process_info_t
{
u32 sdk_ver;
u32 ppc_seg;
};

extern ps3_process_info_t g_ps3_process_info;

// Auxiliary functions
s32 process_getpid();
s32 process_get_sdk_version(u32 pid, s32& ver);
Expand Down
16 changes: 16 additions & 0 deletions rpcs3/Emu/Cell/lv2/sys_prx.cpp
Expand Up @@ -9,6 +9,7 @@
#include "Emu/Cell/ErrorCodes.h"
#include "Crypto/unedat.h"
#include "sys_fs.h"
#include "sys_process.h"



Expand Down Expand Up @@ -83,6 +84,21 @@ static const std::unordered_map<std::string, int> s_prx_ignore

static error_code prx_load_module(const std::string& vpath, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt, fs::file src = {})
{
if (flags != 0)
{
if (flags & SYS_PRX_LOAD_MODULE_FLAGS_INVALIDMASK)
{
return CELL_EINVAL;
}

if (flags & SYS_PRX_LOAD_MODULE_FLAGS_FIXEDADDR && !g_ps3_process_info.ppc_seg)
{
return CELL_ENOSYS;
}

fmt::throw_exception("sys_prx: Unimplemented fixed address allocations" HERE);
}

std::string name = vpath.substr(vpath.find_last_of('/') + 1);
std::string path = vfs::get(vpath);

Expand Down
6 changes: 6 additions & 0 deletions rpcs3/Emu/Cell/lv2/sys_prx.h
Expand Up @@ -137,6 +137,12 @@ struct lv2_prx final : lv2_obj, ppu_module
be_t<u16> module_info_attributes;
};

enum : u64
{
SYS_PRX_LOAD_MODULE_FLAGS_FIXEDADDR = 0x1ull,
SYS_PRX_LOAD_MODULE_FLAGS_INVALIDMASK = ~SYS_PRX_LOAD_MODULE_FLAGS_FIXEDADDR,
};

// SysCalls

error_code sys_prx_get_ppu_guid();
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/lv2/sys_rsx.cpp
@@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "sys_rsx.h"

#include "Emu/System.h"
Expand Down