mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
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:
parent
b84d831d8f
commit
39e679806b
@ -874,7 +874,7 @@ template<typename T, typename T1, T1 value> struct _se<be_t<T>, T1, value> : pub
|
||||
template<typename Tto, typename Tfrom>
|
||||
struct convert_le_be_t
|
||||
{
|
||||
static Tto func(Tfrom&& value)
|
||||
static Tto func(Tfrom value)
|
||||
{
|
||||
return (Tto)value;
|
||||
}
|
||||
@ -883,7 +883,7 @@ struct convert_le_be_t
|
||||
template<typename Tt, typename Tt1, typename 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);
|
||||
}
|
||||
@ -892,7 +892,7 @@ struct convert_le_be_t<be_t<Tt, Tt1>, Tfrom>
|
||||
template<typename Tt, typename Tt1, typename Tf, typename 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;
|
||||
}
|
||||
@ -901,20 +901,20 @@ struct convert_le_be_t<be_t<Tt, Tt1>, be_t<Tf, Tf1>>
|
||||
template<typename Tto, typename Tf, typename 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();
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -208,49 +208,6 @@ std::vector<std::string> fmt::split(const std::string& source, std::initializer_
|
||||
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::transform(source.begin(), source.end(), source.begin(), ::tolower);
|
||||
|
@ -289,8 +289,54 @@ namespace fmt
|
||||
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::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 toupper(std::string source);
|
||||
std::string escape(std::string source);
|
||||
|
@ -298,10 +298,16 @@ namespace vm
|
||||
u32 alloc_offset;
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
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];
|
||||
|
@ -66,14 +66,16 @@ namespace vm
|
||||
force_inline bool operator !=(const nullptr_t& right) 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>
|
||||
@ -88,14 +90,15 @@ namespace vm
|
||||
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)
|
||||
{
|
||||
return reinterpret_cast<_ptr_base&>(addr);
|
||||
return reinterpret_cast<const _ptr_base&>(addr);
|
||||
}
|
||||
|
||||
_ptr_base& operator = (const _ptr_base& right) = default;
|
||||
@ -112,7 +115,7 @@ namespace vm
|
||||
|
||||
force_inline static const u32 data_size()
|
||||
{
|
||||
return sizeof(T);
|
||||
return convert_le_be<AT>(sizeof(T));
|
||||
}
|
||||
|
||||
force_inline T* const operator -> () const
|
||||
@ -158,10 +161,10 @@ namespace vm
|
||||
return *this;
|
||||
}
|
||||
|
||||
_ptr_base operator + (typename remove_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(m_addr + 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 to_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(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(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(convert_le_be<AT>(convert_le_be<decltype(count)>(m_addr) - count * convert_le_be<decltype(count)>(data_size()))); }
|
||||
|
||||
force_inline T& operator *() const
|
||||
{
|
||||
@ -235,9 +238,10 @@ namespace vm
|
||||
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
|
||||
@ -297,9 +301,10 @@ namespace vm
|
||||
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
|
||||
@ -349,20 +354,24 @@ namespace vm
|
||||
|
||||
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
|
||||
{
|
||||
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; }
|
||||
|
@ -595,6 +595,7 @@ bool patch_ppu_import(u32 addr, u32 index)
|
||||
return true;
|
||||
}
|
||||
|
||||
//vm::write32(addr, HACK(imm));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -422,7 +422,7 @@ const ppu_func_caller sc_table[1024] =
|
||||
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_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_get_ppu_guid) //467 (0x1D3)
|
||||
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,//bind_func(sys_prx_load_module), //480 (0x1E0)
|
||||
null_func,//bind_func(sys_prx_start_module), //481 (0x1E1)
|
||||
null_func,//bind_func(sys_prx_stop_module), //482 (0x1E2)
|
||||
null_func,//bind_func(sys_prx_unload_module), //483 (0x1E3)
|
||||
null_func,//bind_func(sys_prx_register_module), //484 (0x1E4)
|
||||
bind_func(sys_prx_load_module), //480 (0x1E0)
|
||||
bind_func(sys_prx_start_module), //481 (0x1E1)
|
||||
bind_func(sys_prx_stop_module), //482 (0x1E2)
|
||||
bind_func(sys_prx_unload_module), //483 (0x1E3)
|
||||
bind_func(sys_prx_register_module), //484 (0x1E4)
|
||||
bind_func(sys_prx_query_module), //485 (0x1E5)
|
||||
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_unlink_library), //489 (0x1E9)
|
||||
bind_func(sys_prx_query_library), //490 (0x1EA)
|
||||
|
@ -3,46 +3,162 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.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/vfsFile.h"
|
||||
#include "Crypto/unself.h"
|
||||
#include "Loader/ELF64.h"
|
||||
#include "sys_prx.h"
|
||||
|
||||
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();
|
||||
// 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";
|
||||
}
|
||||
loader::handlers::elf64 loader;
|
||||
|
||||
vfsFile f(_path);
|
||||
if (!f.IsOpened()) {
|
||||
vfsFile f(path);
|
||||
if (!f.IsOpened())
|
||||
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
|
||||
std::shared_ptr<lv2_prx_t> prx = std::make_shared<lv2_prx_t>();
|
||||
prx->size = (u32)f.GetSize();
|
||||
prx->address = (u32)Memory.Alloc(prx->size, 4);
|
||||
prx->path = (const char*)path;
|
||||
|
||||
// Load the PRX into memory
|
||||
f.Read(vm::get_ptr(prx->address), prx->size);
|
||||
for (auto& seg : info.segments)
|
||||
{
|
||||
const u32 addr = seg.begin.addr();
|
||||
const u32 size = align(seg.size, 4096);
|
||||
|
||||
if (vm::check_addr(addr, 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));
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)",
|
||||
id, args, argp_addr, modres.addr(), flags, pOpt.addr());
|
||||
sys_prx.Warning("sys_prx_start_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (prx->isStarted)
|
||||
return CELL_PRX_ERROR_ALREADY_STARTED;
|
||||
//if (prx->is_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;
|
||||
}
|
||||
|
||||
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)",
|
||||
id, args, argp_addr, modres.addr(), flags, pOpt.addr());
|
||||
sys_prx.Warning("sys_prx_stop_module(id=0x%x, flags=0x%llx, pOpt=*0x%x)", id, flags, pOpt);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!prx->isStarted)
|
||||
return CELL_PRX_ERROR_ALREADY_STOPPED;
|
||||
//if (!prx->is_started)
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
Memory.Free(prx->address);
|
||||
//Memory.Free(prx->address);
|
||||
|
||||
//s32 result = prx->exit ? prx->exit() : CELL_OK;
|
||||
Emu.GetIdManager().remove<lv2_prx_t>(id);
|
||||
|
||||
return CELL_OK;
|
||||
@ -145,15 +267,15 @@ s32 sys_prx_get_module_info()
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -101,11 +101,15 @@ struct sys_prx_load_module_option_t
|
||||
struct sys_prx_start_module_option_t
|
||||
{
|
||||
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
|
||||
{
|
||||
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
|
||||
@ -116,13 +120,13 @@ struct sys_prx_unload_module_option_t
|
||||
// Auxiliary data types
|
||||
struct lv2_prx_t
|
||||
{
|
||||
u32 size;
|
||||
u32 address;
|
||||
std::string path;
|
||||
bool isStarted;
|
||||
bool is_started = false;
|
||||
|
||||
vm::ptr<s32(int argc, vm::ptr<void> argv)> start = vm::null;
|
||||
vm::ptr<s32(int argc, vm::ptr<void> argv)> stop = vm::null;
|
||||
vm::ptr<s32()> exit = vm::null;
|
||||
|
||||
lv2_prx_t()
|
||||
: isStarted(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -131,19 +135,20 @@ REG_ID_TYPE(lv2_prx_t, 0x23); // SYS_PRX_OBJECT
|
||||
|
||||
// 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_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_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_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_start_module(s32 id, u64 flags, vm::ptr<sys_prx_start_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_get_module_list();
|
||||
s32 sys_prx_get_my_module_id();
|
||||
s32 sys_prx_get_module_id_by_address();
|
||||
s32 sys_prx_get_module_id_by_name();
|
||||
s32 sys_prx_get_module_info();
|
||||
s32 sys_prx_register_library(u32 lib_addr);
|
||||
s32 sys_prx_unregister_library();
|
||||
s32 sys_prx_register_library(vm::ptr<void> library);
|
||||
s32 sys_prx_unregister_library(vm::ptr<void> library);
|
||||
s32 sys_prx_get_ppu_guid();
|
||||
s32 sys_prx_register_module();
|
||||
s32 sys_prx_query_module();
|
||||
|
@ -673,26 +673,6 @@ namespace loader
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
//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]);
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user