Implemented some sys_prx syscalls

Fixed vm::ptr

Conflicts:
	Utilities/BEType.h
	Utilities/StrFmt.cpp
	rpcs3/Emu/Memory/vm_ptr.h
	rpcs3/Emu/SysCalls/lv2/sys_prx.cpp
	rpcs3/Emu/SysCalls/lv2/sys_prx.h

Cherry-picked commit "Implemented some sys_prx syscalls"
This commit is contained in:
DHrpcs3 2015-04-01 02:49:39 +03:00 committed by Nekotekina
parent b84d831d8f
commit 39e679806b
10 changed files with 273 additions and 172 deletions

View File

@ -874,7 +874,7 @@ template<typename T, typename T1, T1 value> struct _se<be_t<T>, T1, value> : pub
template<typename Tto, typename Tfrom> template<typename Tto, typename Tfrom>
struct convert_le_be_t struct convert_le_be_t
{ {
static Tto func(Tfrom&& value) static Tto func(Tfrom value)
{ {
return (Tto)value; return (Tto)value;
} }
@ -883,7 +883,7 @@ struct convert_le_be_t
template<typename Tt, typename Tt1, typename Tfrom> template<typename Tt, typename Tt1, typename Tfrom>
struct convert_le_be_t<be_t<Tt, Tt1>, Tfrom> struct convert_le_be_t<be_t<Tt, Tt1>, Tfrom>
{ {
static be_t<Tt, Tt1> func(Tfrom&& value) static be_t<Tt, Tt1> func(Tfrom value)
{ {
return be_t<Tt, Tt1>::make(value); return be_t<Tt, Tt1>::make(value);
} }
@ -892,7 +892,7 @@ struct convert_le_be_t<be_t<Tt, Tt1>, Tfrom>
template<typename Tt, typename Tt1, typename Tf, typename Tf1> template<typename Tt, typename Tt1, typename Tf, typename Tf1>
struct convert_le_be_t<be_t<Tt, Tt1>, be_t<Tf, Tf1>> struct convert_le_be_t<be_t<Tt, Tt1>, be_t<Tf, Tf1>>
{ {
static be_t<Tt, Tt1> func(be_t<Tf, Tf1>&& value) static be_t<Tt, Tt1> func(be_t<Tf, Tf1> value)
{ {
return value; return value;
} }
@ -901,20 +901,20 @@ struct convert_le_be_t<be_t<Tt, Tt1>, be_t<Tf, Tf1>>
template<typename Tto, typename Tf, typename Tf1> template<typename Tto, typename Tf, typename Tf1>
struct convert_le_be_t<Tto, be_t<Tf, Tf1>> struct convert_le_be_t<Tto, be_t<Tf, Tf1>>
{ {
static Tto func(be_t<Tf, Tf1>&& value) static Tto func(be_t<Tf, Tf1> value)
{ {
return value.value(); return value.value();
} }
}; };
template<typename Tto, typename Tfrom> template<typename Tto, typename Tfrom>
force_inline Tto convert_le_be(Tfrom&& value) force_inline Tto convert_le_be(Tfrom value)
{ {
return convert_le_be_t<Tto, Tfrom>::func(value); return convert_le_be_t<Tto, Tfrom>::func(value);
} }
template<typename Tto, typename Tfrom> template<typename Tto, typename Tfrom>
force_inline void convert_le_be(Tto& dst, Tfrom&& src) force_inline void convert_le_be(Tto& dst, Tfrom src)
{ {
dst = convert_le_be_t<Tto, Tfrom>::func(src); dst = convert_le_be_t<Tto, Tfrom>::func(src);
} }

View File

@ -208,49 +208,6 @@ std::vector<std::string> fmt::split(const std::string& source, std::initializer_
return std::move(result); return std::move(result);
} }
std::string fmt::merge(std::vector<std::string> source, const std::string& separator)
{
if (!source.size())
{
return "";
}
std::string result;
for (int i = 0; i < source.size() - 1; ++i)
{
result += source[i] + separator;
}
return result + source.back();
}
std::string fmt::merge(std::initializer_list<std::vector<std::string>> sources, const std::string& separator)
{
if (!sources.size())
{
return "";
}
std::string result;
bool first = true;
for (auto &v : sources)
{
if (first)
{
result = fmt::merge(v, separator);
first = false;
}
else
{
result += separator + fmt::merge(v, separator);
}
}
return result;
}
std::string fmt::tolower(std::string source) std::string fmt::tolower(std::string source)
{ {
std::transform(source.begin(), source.end(), source.begin(), ::tolower); std::transform(source.begin(), source.end(), source.begin(), ::tolower);

View File

@ -289,8 +289,54 @@ namespace fmt
std::vector<std::string> rSplit(const std::string& source, const std::string& delim); std::vector<std::string> rSplit(const std::string& source, const std::string& delim);
std::vector<std::string> split(const std::string& source, std::initializer_list<std::string> separators, bool is_skip_empty = true); std::vector<std::string> split(const std::string& source, std::initializer_list<std::string> separators, bool is_skip_empty = true);
std::string merge(std::vector<std::string> source, const std::string& separator);
std::string merge(std::initializer_list<std::vector<std::string>> sources, const std::string& separator); template<typename T>
std::string merge(const T& source, const std::string& separator)
{
if (!source.size())
{
return{};
}
std::string result;
auto it = source.begin();
auto end = source.end();
for (--end; it != end; ++it)
{
result += *it + separator;
}
return result + source.back();
}
template<typename T>
std::string merge(std::initializer_list<T> sources, const std::string& separator)
{
if (!sources.size())
{
return{};
}
std::string result;
bool first = true;
for (auto &v : sources)
{
if (first)
{
result = fmt::merge(v, separator);
first = false;
}
else
{
result += separator + fmt::merge(v, separator);
}
}
return result;
}
std::string tolower(std::string source); std::string tolower(std::string source);
std::string toupper(std::string source); std::string toupper(std::string source);
std::string escape(std::string source); std::string escape(std::string source);

View File

@ -298,10 +298,16 @@ namespace vm
u32 alloc_offset; u32 alloc_offset;
template<typename T = char> template<typename T = char>
ptr<T> alloc(u32 count) const ptr<T> alloc(u32 count = 1) const
{ {
return ptr<T>::make(allocator(count * sizeof(T))); return ptr<T>::make(allocator(count * sizeof(T)));
} }
template<typename T = char>
ptr<T> fixed_alloc(u32 addr, u32 count = 1) const
{
return ptr<T>::make(fixed_allocator(addr, count * sizeof(T)));
}
}; };
extern location_info g_locations[memory_location_count]; extern location_info g_locations[memory_location_count];

View File

@ -66,14 +66,16 @@ namespace vm
force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; } force_inline bool operator !=(const nullptr_t& right) const { return m_addr != 0; }
explicit operator bool() const { return m_addr != 0; } explicit operator bool() const { return m_addr != 0; }
force_inline _ptr_base<T, lvl - 1, std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>>& operator *() const force_inline _ptr_base<T, lvl - 1, typename std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>::type> operator *() const
{ {
return vm::get_ref<_ptr_base<T, lvl - 1, std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>>>(vm::cast(m_addr)); AT addr = convert_le_be<AT>(read64(convert_le_be<u32>(m_addr)));
return (_ptr_base<T, lvl - 1, typename std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>::type>&)addr;
} }
force_inline _ptr_base<T, lvl - 1, std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>>& operator [](AT index) const force_inline _ptr_base<T, lvl - 1, typename std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>::type> operator [](AT index) const
{ {
return vm::get_ref<_ptr_base<T, lvl - 1, std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>>>(vm::cast(m_addr + sizeof(AT)* index)); AT addr = convert_le_be<AT>(read64(convert_le_be<u32>(m_addr + 8 * index)));
return (_ptr_base<T, lvl - 1, typename std::conditional<is_be_t<T>::value, typename to_be_t<AT>::type, AT>::type>&)addr;
} }
template<typename AT2> template<typename AT2>
@ -88,14 +90,15 @@ namespace vm
return m_addr; return m_addr;
} }
void set(const AT value) template<typename U>
void set(U&& value)
{ {
m_addr = value; m_addr = convert_le_be<AT>(value);
} }
static _ptr_base make(const AT& addr) static _ptr_base make(const AT& addr)
{ {
return reinterpret_cast<_ptr_base&>(addr); return reinterpret_cast<const _ptr_base&>(addr);
} }
_ptr_base& operator = (const _ptr_base& right) = default; _ptr_base& operator = (const _ptr_base& right) = default;
@ -112,7 +115,7 @@ namespace vm
force_inline static const u32 data_size() force_inline static const u32 data_size()
{ {
return sizeof(T); return convert_le_be<AT>(sizeof(T));
} }
force_inline T* const operator -> () const force_inline T* const operator -> () const
@ -158,10 +161,10 @@ namespace vm
return *this; return *this;
} }
_ptr_base operator + (typename remove_be_t<AT>::type count) const { return make(m_addr + count * data_size()); } _ptr_base operator + (typename remove_be_t<AT>::type count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) + count * convert_le_be<decltype(count)>(data_size()))); }
_ptr_base operator + (typename to_be_t<AT>::type count) const { return make(m_addr + count * data_size()); } _ptr_base operator + (typename to_be_t<AT>::type count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) + count * convert_le_be<decltype(count)>(data_size()))); }
_ptr_base operator - (typename remove_be_t<AT>::type count) const { return make(m_addr - count * data_size()); } _ptr_base operator - (typename remove_be_t<AT>::type count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) - count * convert_le_be<decltype(count)>(data_size()))); }
_ptr_base operator - (typename to_be_t<AT>::type count) const { return make(m_addr - count * data_size()); } _ptr_base operator - (typename to_be_t<AT>::type count) const { return make(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) - count * convert_le_be<decltype(count)>(data_size()))); }
force_inline T& operator *() const force_inline T& operator *() const
{ {
@ -235,9 +238,10 @@ namespace vm
return m_addr; return m_addr;
} }
void set(const AT value) template<typename U>
void set(U&& value)
{ {
m_addr = value; m_addr = convert_le_be<AT>(value);
} }
void* get_ptr() const void* get_ptr() const
@ -297,9 +301,10 @@ namespace vm
return m_addr; return m_addr;
} }
void set(const AT value) template<typename U>
void set(U&& value)
{ {
m_addr = value; m_addr = convert_le_be<AT>(value);
} }
const void* get_ptr() const const void* get_ptr() const
@ -349,20 +354,24 @@ namespace vm
typedef RT(type)(T...); typedef RT(type)(T...);
RT operator()(PPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified PPU thread context // defined in CB_FUNC.h, call using specified PPU thread context
RT operator()(PPUThread& CPU, T... args) const;
RT operator()(ARMv7Context& context, T... args) const; // defined in ARMv7Callback.h, passing context is mandatory // defined in ARMv7Callback.h, passing context is mandatory
RT operator()(ARMv7Context& context, T... args) const;
RT operator()(T... args) const; // defined in CB_FUNC.h, call using current PPU thread context // defined in CB_FUNC.h, call using current PPU thread context
RT operator()(T... args) const;
AT addr() const AT addr() const
{ {
return m_addr; return m_addr;
} }
void set(const AT value) template<typename U>
void set(U&& value)
{ {
m_addr = value; m_addr = convert_le_be<AT>(value);
} }
force_inline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; } force_inline bool operator <(const _ptr_base& right) const { return m_addr < right.m_addr; }

View File

@ -595,6 +595,7 @@ bool patch_ppu_import(u32 addr, u32 index)
return true; return true;
} }
//vm::write32(addr, HACK(imm));
return false; return false;
} }

View File

@ -422,7 +422,7 @@ const ppu_func_caller sc_table[1024] =
null_func, //462 (0x1CE) UNS null_func, //462 (0x1CE) UNS
null_func,//bind_func(sys_prx_load_module_by_fd) //463 (0x1CF) null_func,//bind_func(sys_prx_load_module_by_fd) //463 (0x1CF)
null_func,//bind_func(sys_prx_load_module_on_memcontainer_by_fd) //464 (0x1D0) null_func,//bind_func(sys_prx_load_module_on_memcontainer_by_fd) //464 (0x1D0)
null_func,//bind_func(sys_prx_load_module_list) //465 (0x1D1) bind_func(sys_prx_load_module_list), //465 (0x1D1)
null_func,//bind_func(sys_prx_load_module_list_on_memcontainer) //466 (0x1D2) null_func,//bind_func(sys_prx_load_module_list_on_memcontainer) //466 (0x1D2)
null_func,//bind_func(sys_prx_get_ppu_guid) //467 (0x1D3) null_func,//bind_func(sys_prx_get_ppu_guid) //467 (0x1D3)
null_func,//bind_func(sys_...) //468 (0x1D4) ROOT null_func,//bind_func(sys_...) //468 (0x1D4) ROOT
@ -437,14 +437,14 @@ const ppu_func_caller sc_table[1024] =
null_func, null_func, null_func, //477-479 UNS null_func, null_func, null_func, //477-479 UNS
null_func,//bind_func(sys_prx_load_module), //480 (0x1E0) bind_func(sys_prx_load_module), //480 (0x1E0)
null_func,//bind_func(sys_prx_start_module), //481 (0x1E1) bind_func(sys_prx_start_module), //481 (0x1E1)
null_func,//bind_func(sys_prx_stop_module), //482 (0x1E2) bind_func(sys_prx_stop_module), //482 (0x1E2)
null_func,//bind_func(sys_prx_unload_module), //483 (0x1E3) bind_func(sys_prx_unload_module), //483 (0x1E3)
null_func,//bind_func(sys_prx_register_module), //484 (0x1E4) bind_func(sys_prx_register_module), //484 (0x1E4)
bind_func(sys_prx_query_module), //485 (0x1E5) bind_func(sys_prx_query_module), //485 (0x1E5)
bind_func(sys_prx_register_library), //486 (0x1E6) bind_func(sys_prx_register_library), //486 (0x1E6)
null_func,//bind_func(sys_prx_unregister_library), //487 (0x1E7) bind_func(sys_prx_unregister_library), //487 (0x1E7)
bind_func(sys_prx_link_library), //488 (0x1E8) bind_func(sys_prx_link_library), //488 (0x1E8)
bind_func(sys_prx_unlink_library), //489 (0x1E9) bind_func(sys_prx_unlink_library), //489 (0x1E9)
bind_func(sys_prx_query_library), //490 (0x1EA) bind_func(sys_prx_query_library), //490 (0x1EA)

View File

@ -3,46 +3,162 @@
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/IdManager.h" #include "Emu/IdManager.h"
#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SysCalls.h"
#include "Emu/SysCalls/CB_FUNC.h"
#include "Emu/SysCalls/Modules.h"
#include "Emu/SysCalls/ModuleManager.h"
#include "Emu/Cell/PPUInstrTable.h"
#include "Emu/FS/VFS.h" #include "Emu/FS/VFS.h"
#include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsFile.h"
#include "Crypto/unself.h" #include "Crypto/unself.h"
#include "Loader/ELF64.h"
#include "sys_prx.h" #include "sys_prx.h"
SysCallBase sys_prx("sys_prx"); SysCallBase sys_prx("sys_prx");
s32 sys_prx_load_module(vm::ptr<const char> path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt) extern void fill_ppu_exec_map(u32 addr, u32 size);
s32 prx_load_module(std::string path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt)
{ {
sys_prx.Todo("sys_prx_load_module(path=\"%s\", flags=0x%llx, pOpt=0x%x)", path.get_ptr(), flags, pOpt.addr()); sys_prx.Warning("prx_load_module(path='%s', flags=0x%llx, pOpt=*0x%x)", path.c_str(), flags, pOpt);
std::string _path = path.get_ptr(); loader::handlers::elf64 loader;
// Check if the file is SPRX
std::string local_path;
Emu.GetVFS().GetDevice(_path, local_path);
if (IsSelf(local_path)) {
if (!DecryptSelf(local_path+".prx", local_path)) {
return CELL_PRX_ERROR_ILLEGAL_LIBRARY;
}
_path += ".prx";
}
vfsFile f(_path); vfsFile f(path);
if (!f.IsOpened()) { if (!f.IsOpened())
return CELL_PRX_ERROR_UNKNOWN_MODULE; return CELL_PRX_ERROR_UNKNOWN_MODULE;
if (loader.init(f) != loader::handler::error_code::ok || !loader.is_sprx())
return CELL_PRX_ERROR_ILLEGAL_LIBRARY;
loader::handlers::elf64::sprx_info info;
loader.load_sprx(info);
auto prx = std::make_shared<lv2_prx_t>();
auto meta = info.modules[""];
prx->start.set(meta.exports[0xBC9A0086]);
prx->stop.set(meta.exports[0xAB779874]);
prx->exit.set(meta.exports[0x3AB9A95E]);
for (auto &module_ : info.modules)
{
if (module_.first == "")
continue;
Module* module = Emu.GetModuleManager().GetModuleByName(module_.first.c_str());
if (!module)
{
sys_prx.Error("Unknown module '%s'", module_.first.c_str());
}
for (auto& f : module_.second.exports)
{
const u32 nid = f.first;
const u32 addr = f.second;
u32 index;
auto func = get_ppu_func_by_nid(nid, &index);
if (!func)
{
index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr, vm::ptr<void()>::make(addr)));
}
else
{
func->lle_func.set(addr);
if (func->flags & MFF_FORCED_HLE)
{
u32 i_addr = 0;
if (!vm::check_addr(addr, 8) || !vm::check_addr(i_addr = vm::read32(addr), 4))
{
sys_prx.Error("Failed to inject code for exported function '%s' (opd=0x%x, 0x%x)", SysCalls::GetFuncName(nid), addr, i_addr);
}
else
{
vm::write32(i_addr, PPU_instr::HACK(index | EIF_PERFORM_BLR));
}
}
}
}
for (auto &import : module_.second.imports)
{
u32 nid = import.first;
u32 addr = import.second;
u32 index;
auto func = get_ppu_func_by_nid(nid, &index);
if (!func)
{
sys_prx.Error("Unimplemented function '%s' in '%s' module (0x%x)", SysCalls::GetFuncName(nid), module_.first);
index = add_ppu_func(ModuleFunc(nid, 0, module, nullptr, nullptr));
}
else
{
const bool is_lle = func->lle_func && !(func->flags & MFF_FORCED_HLE);
sys_prx.Error("Imported %sfunction '%s' in '%s' module (0x%x)", (is_lle ? "LLE " : ""), SysCalls::GetFuncName(nid), module_.first, addr);
}
if (!patch_ppu_import(addr, index))
{
sys_prx.Error("Failed to inject code at address 0x%x", addr);
}
}
} }
// Create the PRX object and return its id for (auto& seg : info.segments)
std::shared_ptr<lv2_prx_t> prx = std::make_shared<lv2_prx_t>(); {
prx->size = (u32)f.GetSize(); const u32 addr = seg.begin.addr();
prx->address = (u32)Memory.Alloc(prx->size, 4); const u32 size = align(seg.size, 4096);
prx->path = (const char*)path;
if (vm::check_addr(addr, size))
// Load the PRX into memory {
f.Read(vm::get_ptr(prx->address), prx->size); fill_ppu_exec_map(addr, size);
}
else
{
sys_prx.Error("Failed to process executable area (addr=0x%x, size=0x%x)", addr, size);
}
}
return Emu.GetIdManager().add(std::move(prx)); return Emu.GetIdManager().add(std::move(prx));
} }
s32 sys_prx_load_module(vm::ptr<const char> path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt)
{
sys_prx.Warning("sys_prx_load_module(path=*0x%x, flags=0x%llx, pOpt=*0x%x)", path, flags, pOpt);
return prx_load_module(path.get_ptr(), flags, pOpt);
}
s32 sys_prx_load_module_list(s32 count, vm::ptr<const char, 2> path_list, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt, vm::ptr<u32> id_list)
{
sys_prx.Warning("sys_prx_load_module_list(count=%d, path_list=*0x%x, flags=0x%llx, pOpt=*0x%x, id_list=*0x%x)", count, path_list, flags, pOpt, id_list);
for (s32 i = 0; i < count; ++i)
{
auto path = path_list[i];
std::string name = path.get_ptr();
s32 result = prx_load_module(name, flags, pOpt);
if (result < 0)
return result;
id_list[i] = result;
}
return CELL_OK;
}
s32 sys_prx_load_module_on_memcontainer() s32 sys_prx_load_module_on_memcontainer()
{ {
sys_prx.Todo("sys_prx_load_module_on_memcontainer()"); sys_prx.Todo("sys_prx_load_module_on_memcontainer()");
@ -61,10 +177,9 @@ s32 sys_prx_load_module_on_memcontainer_by_fd()
return CELL_OK; return CELL_OK;
} }
s32 sys_prx_start_module(s32 id, u32 args, u32 argp_addr, vm::ptr<u32> modres, u64 flags, vm::ptr<sys_prx_start_module_option_t> pOpt) s32 sys_prx_start_module(s32 id, u64 flags, vm::ptr<sys_prx_start_module_option_t> pOpt)
{ {
sys_prx.Todo("sys_prx_start_module(id=0x%x, args=%d, argp_addr=0x%x, modres_addr=0x%x, flags=0x%llx, pOpt=0x%x)", sys_prx.Warning("sys_prx_start_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt);
id, args, argp_addr, modres.addr(), flags, pOpt.addr());
const auto prx = Emu.GetIdManager().get<lv2_prx_t>(id); const auto prx = Emu.GetIdManager().get<lv2_prx_t>(id);
@ -73,16 +188,18 @@ s32 sys_prx_start_module(s32 id, u32 args, u32 argp_addr, vm::ptr<u32> modres, u
return CELL_ESRCH; return CELL_ESRCH;
} }
if (prx->isStarted) //if (prx->is_started)
return CELL_PRX_ERROR_ALREADY_STARTED; // return CELL_PRX_ERROR_ALREADY_STARTED;
//prx->is_started = true;
pOpt->entry_point.set(be_t<u64>::make(prx->start ? prx->start.addr() : ~0ull));
return CELL_OK; return CELL_OK;
} }
s32 sys_prx_stop_module(s32 id, u32 args, u32 argp_addr, vm::ptr<u32> modres, u64 flags, vm::ptr<sys_prx_stop_module_option_t> pOpt) s32 sys_prx_stop_module(s32 id, u64 flags, vm::ptr<sys_prx_stop_module_option_t> pOpt)
{ {
sys_prx.Todo("sys_prx_stop_module(id=0x%x, args=%d, argp_addr=0x%x, modres_addr=0x%x, flags=0x%llx, pOpt=0x%x)", sys_prx.Warning("sys_prx_stop_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt);
id, args, argp_addr, modres.addr(), flags, pOpt.addr());
const auto prx = Emu.GetIdManager().get<lv2_prx_t>(id); const auto prx = Emu.GetIdManager().get<lv2_prx_t>(id);
@ -91,15 +208,18 @@ s32 sys_prx_stop_module(s32 id, u32 args, u32 argp_addr, vm::ptr<u32> modres, u6
return CELL_ESRCH; return CELL_ESRCH;
} }
if (!prx->isStarted) //if (!prx->is_started)
return CELL_PRX_ERROR_ALREADY_STOPPED; // return CELL_PRX_ERROR_ALREADY_STOPPED;
//prx->is_started = false;
pOpt->entry_point.set(be_t<u64>::make(prx->stop ? prx->stop.addr() : -1));
return CELL_OK; return CELL_OK;
} }
s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr<sys_prx_unload_module_option_t> pOpt) s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr<sys_prx_unload_module_option_t> pOpt)
{ {
sys_prx.Todo("sys_prx_unload_module(id=0x%x, flags=0x%llx, pOpt=0x%x)", id, flags, pOpt.addr()); sys_prx.Warning("sys_prx_unload_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt);
// Get the PRX, free the used memory and delete the object and its ID // Get the PRX, free the used memory and delete the object and its ID
const auto prx = Emu.GetIdManager().get<lv2_prx_t>(id); const auto prx = Emu.GetIdManager().get<lv2_prx_t>(id);
@ -109,7 +229,9 @@ s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr<sys_prx_unload_module_optio
return CELL_ESRCH; return CELL_ESRCH;
} }
Memory.Free(prx->address); //Memory.Free(prx->address);
//s32 result = prx->exit ? prx->exit() : CELL_OK;
Emu.GetIdManager().remove<lv2_prx_t>(id); Emu.GetIdManager().remove<lv2_prx_t>(id);
return CELL_OK; return CELL_OK;
@ -145,15 +267,15 @@ s32 sys_prx_get_module_info()
return CELL_OK; return CELL_OK;
} }
s32 sys_prx_register_library(u32 lib_addr) s32 sys_prx_register_library(vm::ptr<void> library)
{ {
sys_prx.Todo("sys_prx_register_library(lib_addr=0x%x)", lib_addr); sys_prx.Todo("sys_prx_register_library(library=*0x%x)", library);
return CELL_OK; return CELL_OK;
} }
s32 sys_prx_unregister_library() s32 sys_prx_unregister_library(vm::ptr<void> library)
{ {
sys_prx.Todo("sys_prx_unregister_library()"); sys_prx.Todo("sys_prx_unregister_library(library=*0x%x)", library);
return CELL_OK; return CELL_OK;
} }

View File

@ -101,11 +101,15 @@ struct sys_prx_load_module_option_t
struct sys_prx_start_module_option_t struct sys_prx_start_module_option_t
{ {
be_t<u64> size; be_t<u64> size;
be_t<u64> put;
vm::bptr<s32(int argc, vm::ptr<void> argv), 1, u64> entry_point;
}; };
struct sys_prx_stop_module_option_t struct sys_prx_stop_module_option_t
{ {
be_t<u64> size; be_t<u64> size;
be_t<u64> put;
vm::bptr<s32(int argc, vm::ptr<void> argv), 1, u64> entry_point;
}; };
struct sys_prx_unload_module_option_t struct sys_prx_unload_module_option_t
@ -116,13 +120,13 @@ struct sys_prx_unload_module_option_t
// Auxiliary data types // Auxiliary data types
struct lv2_prx_t struct lv2_prx_t
{ {
u32 size; bool is_started = false;
u32 address;
std::string path; vm::ptr<s32(int argc, vm::ptr<void> argv)> start = vm::null;
bool isStarted; vm::ptr<s32(int argc, vm::ptr<void> argv)> stop = vm::null;
vm::ptr<s32()> exit = vm::null;
lv2_prx_t() lv2_prx_t()
: isStarted(false)
{ {
} }
}; };
@ -131,19 +135,20 @@ REG_ID_TYPE(lv2_prx_t, 0x23); // SYS_PRX_OBJECT
// SysCalls // SysCalls
s32 sys_prx_load_module(vm::ptr<const char> path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt); s32 sys_prx_load_module(vm::ptr<const char> path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt);
s32 sys_prx_load_module_list(s32 count, vm::ptr<const char, 2> path_list, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt, vm::ptr<u32> id_list);
s32 sys_prx_load_module_on_memcontainer(); s32 sys_prx_load_module_on_memcontainer();
s32 sys_prx_load_module_by_fd(); s32 sys_prx_load_module_by_fd();
s32 sys_prx_load_module_on_memcontainer_by_fd(); s32 sys_prx_load_module_on_memcontainer_by_fd();
s32 sys_prx_start_module(s32 id, u32 args, u32 argp_addr, vm::ptr<u32> modres, u64 flags, vm::ptr<sys_prx_start_module_option_t> pOpt); s32 sys_prx_start_module(s32 id, u64 flags, vm::ptr<sys_prx_start_module_option_t> pOpt);
s32 sys_prx_stop_module(s32 id, u32 args, u32 argp_addr, vm::ptr<u32> modres, u64 flags, vm::ptr<sys_prx_stop_module_option_t> pOpt); s32 sys_prx_stop_module(s32 id, u64 flags, vm::ptr<sys_prx_stop_module_option_t> pOpt);
s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr<sys_prx_unload_module_option_t> pOpt); s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr<sys_prx_unload_module_option_t> pOpt);
s32 sys_prx_get_module_list(); s32 sys_prx_get_module_list();
s32 sys_prx_get_my_module_id(); s32 sys_prx_get_my_module_id();
s32 sys_prx_get_module_id_by_address(); s32 sys_prx_get_module_id_by_address();
s32 sys_prx_get_module_id_by_name(); s32 sys_prx_get_module_id_by_name();
s32 sys_prx_get_module_info(); s32 sys_prx_get_module_info();
s32 sys_prx_register_library(u32 lib_addr); s32 sys_prx_register_library(vm::ptr<void> library);
s32 sys_prx_unregister_library(); s32 sys_prx_unregister_library(vm::ptr<void> library);
s32 sys_prx_get_ppu_guid(); s32 sys_prx_get_ppu_guid();
s32 sys_prx_register_module(); s32 sys_prx_register_module();
s32 sys_prx_query_module(); s32 sys_prx_query_module();

View File

@ -673,26 +673,6 @@ namespace loader
LOG_WARNING(LOADER, "Unknown module '%s'", module_name.c_str()); LOG_WARNING(LOADER, "Unknown module '%s'", module_name.c_str());
} }
//struct tbl_item
//{
// be_t<u32> stub;
// be_t<u32> rtoc;
//};
//struct stub_data_t
//{
// be_t<u32> data[3];
//}
//static const stub_data =
//{
// be_t<u32>::make(MR(11, 2)),
// be_t<u32>::make(SC(0)),
// be_t<u32>::make(BLR())
//};
//const auto& tbl = vm::get().alloc<tbl_item>(stub->s_imports);
//const auto& dst = vm::get().alloc<stub_data_t>(stub->s_imports);
for (u32 i = 0; i < stub->s_imports; ++i) for (u32 i = 0; i < stub->s_imports; ++i)
{ {
const u32 nid = stub->s_nid[i]; const u32 nid = stub->s_nid[i];
@ -719,31 +699,6 @@ namespace loader
{ {
LOG_ERROR(LOADER, "Failed to inject code at address 0x%x", addr); LOG_ERROR(LOADER, "Failed to inject code at address 0x%x", addr);
} }
//if (!func || !func->lle_func)
//{
// dst[i] = stub_data;
// tbl[i].stub = (dst + i).addr();
// tbl[i].rtoc = stub->s_nid[i];
// stub->s_text[i] = (tbl + i).addr();
// if (!func)
// {
//
// }
// else //if (Ini.HLELogging.GetValue())
// {
// LOG_NOTICE(LOADER, "Imported function '%s' in '%s' module (HLE)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str());
// }
//}
//else
//{
// stub->s_text[i] = func->lle_func.addr();
// //Is function auto exported, than we can use it
// LOG_NOTICE(LOADER, "Imported function '%s' in '%s' module (LLE: 0x%x)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str(), (u32)stub->s_text[i]);
//}
} }
} }
} }