mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-30 12:32:43 +00:00
PRX: Implement multi-referenced library management
This commit is contained in:
parent
5b95cfda40
commit
820e692e57
@ -22,6 +22,7 @@
|
|||||||
#include "Emu/Cell/Modules/StaticHLE.h"
|
#include "Emu/Cell/Modules/StaticHLE.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <span>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
@ -154,6 +155,7 @@ struct ppu_linkage_info
|
|||||||
// Module map
|
// Module map
|
||||||
std::map<std::string, module_data> modules{};
|
std::map<std::string, module_data> modules{};
|
||||||
std::map<std::string, atomic_t<bool>, std::less<>> lib_lock;
|
std::map<std::string, atomic_t<bool>, std::less<>> lib_lock;
|
||||||
|
shared_mutex lib_lock_mutex;
|
||||||
shared_mutex mutex;
|
shared_mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -601,6 +603,12 @@ static void ppu_patch_refs(std::vector<ppu_reloc>* out_relocs, u32 fref, u32 fad
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PRX_EXPORT_ATTRIBUTES : u16
|
||||||
|
{
|
||||||
|
PRX_EXPORT_LIBRARY_FLAG = 1,
|
||||||
|
PRX_EXPORT_PRX_MANAGEMENT_FUNCTIONS_FLAG = 0x8000,
|
||||||
|
};
|
||||||
|
|
||||||
// Export or import module struct
|
// Export or import module struct
|
||||||
struct ppu_prx_module_info
|
struct ppu_prx_module_info
|
||||||
{
|
{
|
||||||
@ -639,7 +647,7 @@ extern bool ppu_register_library_lock(std::string_view libname, bool lock_lib)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
reader_lock lock(link->mutex);
|
reader_lock lock(link->lib_lock_mutex);
|
||||||
|
|
||||||
if (auto it = link->lib_lock.find(libname); it != link->lib_lock.cend())
|
if (auto it = link->lib_lock.find(libname); it != link->lib_lock.cend())
|
||||||
{
|
{
|
||||||
@ -660,17 +668,31 @@ extern bool ppu_register_library_lock(std::string_view libname, bool lock_lib)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load and register exports; return special exports found (nameless module)
|
// Load and register exports; return special exports found (nameless module)
|
||||||
static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 exports_end, bool for_observing_callbacks = false)
|
static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 exports_end, bool for_observing_callbacks = false, std::basic_string<bool>* loaded_flags = nullptr)
|
||||||
{
|
{
|
||||||
std::unordered_map<u32, u32> result;
|
std::unordered_map<u32, u32> result;
|
||||||
|
|
||||||
|
// Flags were already provided meaning it's an unload operation
|
||||||
|
const bool unload_exports = loaded_flags && !loaded_flags->empty();
|
||||||
|
|
||||||
std::lock_guard lock(link->mutex);
|
std::lock_guard lock(link->mutex);
|
||||||
|
|
||||||
for (u32 addr = exports_start; addr < exports_end;)
|
usz unload_index = 0;
|
||||||
{
|
|
||||||
const auto& lib = vm::_ref<const ppu_prx_module_info>(addr);
|
|
||||||
|
|
||||||
if (!lib.name)
|
for (u32 addr = exports_start; addr < exports_end; unload_index++)
|
||||||
|
{
|
||||||
|
ppu_prx_module_info lib{};
|
||||||
|
std::memcpy(&lib, vm::base(addr), sizeof(lib));
|
||||||
|
|
||||||
|
const bool is_library = !!(lib.attributes & PRX_EXPORT_LIBRARY_FLAG);
|
||||||
|
const bool is_management = !is_library && !!(lib.attributes & PRX_EXPORT_PRX_MANAGEMENT_FUNCTIONS_FLAG);
|
||||||
|
|
||||||
|
if (loaded_flags && !unload_exports)
|
||||||
|
{
|
||||||
|
loaded_flags->push_back(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_management)
|
||||||
{
|
{
|
||||||
// Set special exports
|
// Set special exports
|
||||||
for (u32 i = 0, end = lib.num_func + lib.num_var; i < end; i++)
|
for (u32 i = 0, end = lib.num_func + lib.num_var; i < end; i++)
|
||||||
@ -694,6 +716,13 @@ static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 expo
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_library)
|
||||||
|
{
|
||||||
|
// Skipped if none of the flags is set
|
||||||
|
addr += lib.size ? lib.size : sizeof(ppu_prx_module_info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (for_observing_callbacks)
|
if (for_observing_callbacks)
|
||||||
{
|
{
|
||||||
addr += lib.size ? lib.size : sizeof(ppu_prx_module_info);
|
addr += lib.size ? lib.size : sizeof(ppu_prx_module_info);
|
||||||
@ -702,13 +731,38 @@ static auto ppu_load_exports(ppu_linkage_info* link, u32 exports_start, u32 expo
|
|||||||
|
|
||||||
const std::string module_name(lib.name.get_ptr());
|
const std::string module_name(lib.name.get_ptr());
|
||||||
|
|
||||||
ppu_loader.notice("** Exported module '%s' (0x%x, 0x%x, 0x%x, 0x%x)", module_name, lib.vnids, lib.vstubs, lib.unk4, lib.unk5);
|
if (unload_exports)
|
||||||
|
{
|
||||||
|
if (::at32(*loaded_flags, unload_index))
|
||||||
|
{
|
||||||
|
ppu_register_library_lock(module_name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
addr += lib.size ? lib.size : sizeof(ppu_prx_module_info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppu_loader.notice("** Exported module '%s' (vnids=0x%x, vstubs=0x%x, version=0x%x, attributes=0x%x, unk4=0x%x, unk5=0x%x)", module_name, lib.vnids, lib.vstubs, lib.version, lib.attributes, lib.unk4, lib.unk5);
|
||||||
|
|
||||||
if (lib.num_tlsvar)
|
if (lib.num_tlsvar)
|
||||||
{
|
{
|
||||||
ppu_loader.fatal("Unexpected num_tlsvar (%u)!", lib.num_tlsvar);
|
ppu_loader.fatal("Unexpected num_tlsvar (%u)!", lib.num_tlsvar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool should_load = ppu_register_library_lock(module_name, true);
|
||||||
|
|
||||||
|
if (loaded_flags)
|
||||||
|
{
|
||||||
|
loaded_flags->back() = should_load;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!should_load)
|
||||||
|
{
|
||||||
|
ppu_loader.notice("** Skipped module '%s' (already loaded)", module_name);
|
||||||
|
addr += lib.size ? lib.size : sizeof(ppu_prx_module_info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Static module
|
// Static module
|
||||||
const auto _sm = ppu_module_manager::get_module(module_name);
|
const auto _sm = ppu_module_manager::get_module(module_name);
|
||||||
|
|
||||||
@ -904,12 +958,12 @@ static auto ppu_load_imports(std::vector<ppu_reloc>& relocs, ppu_linkage_info* l
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For _sys_prx_register_module
|
// For _sys_prx_register_module
|
||||||
void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size)
|
void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<bool>& loaded_flags)
|
||||||
{
|
{
|
||||||
auto& _main = g_fxo->get<ppu_module>();
|
auto& _main = g_fxo->get<ppu_module>();
|
||||||
auto& link = g_fxo->get<ppu_linkage_info>();
|
auto& link = g_fxo->get<ppu_linkage_info>();
|
||||||
|
|
||||||
ppu_load_exports(&link, exports_start, exports_start + exports_size);
|
ppu_load_exports(&link, exports_start, exports_start + exports_size, false, &loaded_flags);
|
||||||
|
|
||||||
if (!imports_size)
|
if (!imports_size)
|
||||||
{
|
{
|
||||||
|
@ -307,6 +307,13 @@ std::shared_ptr<void> lv2_prx::load(utils::serial& ar)
|
|||||||
|
|
||||||
if (seg_count)
|
if (seg_count)
|
||||||
{
|
{
|
||||||
|
std::basic_string<bool> loaded_flags;
|
||||||
|
|
||||||
|
if (version >= 3)
|
||||||
|
{
|
||||||
|
ar(loaded_flags);
|
||||||
|
}
|
||||||
|
|
||||||
fs::file file{path.substr(0, path.size() - (offset ? fmt::format("_x%x", offset).size() : 0))};
|
fs::file file{path.substr(0, path.size() - (offset ? fmt::format("_x%x", offset).size() : 0))};
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
@ -314,13 +321,18 @@ std::shared_ptr<void> lv2_prx::load(utils::serial& ar)
|
|||||||
u128 klic = g_fxo->get<loaded_npdrm_keys>().last_key();
|
u128 klic = g_fxo->get<loaded_npdrm_keys>().last_key();
|
||||||
file = make_file_view(std::move(file), offset);
|
file = make_file_view(std::move(file), offset);
|
||||||
prx = ppu_load_prx(ppu_prx_object{ decrypt_self(std::move(file), reinterpret_cast<u8*>(&klic)) }, path, 0, &ar);
|
prx = ppu_load_prx(ppu_prx_object{ decrypt_self(std::move(file), reinterpret_cast<u8*>(&klic)) }, path, 0, &ar);
|
||||||
|
prx->m_loaded_flags = std::move(loaded_flags);
|
||||||
|
|
||||||
if (version >= 2 && state == PRX_STATE_STARTED)
|
if (version == 2 && state == PRX_STATE_STARTED)
|
||||||
{
|
{
|
||||||
ensure(ppu_register_library_lock(prx->module_info_name, true));
|
|
||||||
prx->load_exports();
|
prx->load_exports();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version == 3 && state == PRX_STATE_STARTED)
|
||||||
|
{
|
||||||
|
prx->restore_exports();
|
||||||
|
}
|
||||||
|
|
||||||
if (version == 1)
|
if (version == 1)
|
||||||
{
|
{
|
||||||
prx->load_exports();
|
prx->load_exports();
|
||||||
@ -361,6 +373,11 @@ void lv2_prx::save(utils::serial& ar)
|
|||||||
// Save segments count
|
// Save segments count
|
||||||
ar.serialize_vle(segs.size());
|
ar.serialize_vle(segs.size());
|
||||||
|
|
||||||
|
if (!segs.empty())
|
||||||
|
{
|
||||||
|
ar(m_loaded_flags);
|
||||||
|
}
|
||||||
|
|
||||||
for (const ppu_segment& seg : segs)
|
for (const ppu_segment& seg : segs)
|
||||||
{
|
{
|
||||||
if (seg.type == 0x1u && seg.size) ar(seg.addr);
|
if (seg.type == 0x1u && seg.size) ar(seg.addr);
|
||||||
@ -506,7 +523,7 @@ error_code _sys_prx_start_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<sys
|
|||||||
{
|
{
|
||||||
std::lock_guard lock(prx->mutex);
|
std::lock_guard lock(prx->mutex);
|
||||||
|
|
||||||
if (prx->state != PRX_STATE_INITIALIZED)
|
if (!prx->state.compare_and_swap_test(PRX_STATE_INITIALIZED, PRX_STATE_STARTING))
|
||||||
{
|
{
|
||||||
if (prx->state == PRX_STATE_DESTROYED)
|
if (prx->state == PRX_STATE_DESTROYED)
|
||||||
{
|
{
|
||||||
@ -516,26 +533,7 @@ error_code _sys_prx_start_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<sys
|
|||||||
return CELL_PRX_ERROR_ERROR;
|
return CELL_PRX_ERROR_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prx->exports_end > prx->exports_start && !ppu_register_library_lock(prx->module_info_name, true))
|
|
||||||
{
|
|
||||||
return {CELL_PRX_ERROR_LIBRARY_FOUND, +prx->module_info_name};
|
|
||||||
}
|
|
||||||
|
|
||||||
prx->load_exports();
|
prx->load_exports();
|
||||||
|
|
||||||
if (!prx->state.compare_and_swap_test(PRX_STATE_INITIALIZED, PRX_STATE_STARTING))
|
|
||||||
{
|
|
||||||
// The only error code here
|
|
||||||
ensure(prx->exports_end <= prx->exports_start || ppu_register_library_lock(prx->module_info_name, false));
|
|
||||||
|
|
||||||
if (prx->state == PRX_STATE_DESTROYED)
|
|
||||||
{
|
|
||||||
return CELL_ESRCH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return CELL_PRX_ERROR_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
@ -557,6 +555,7 @@ error_code _sys_prx_start_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<sys
|
|||||||
|
|
||||||
// Thread-safe if called from liblv2.sprx, due to internal lwmutex lock before it
|
// Thread-safe if called from liblv2.sprx, due to internal lwmutex lock before it
|
||||||
prx->state = PRX_STATE_STOPPED;
|
prx->state = PRX_STATE_STOPPED;
|
||||||
|
prx->unload_exports();
|
||||||
_sys_prx_unload_module(ppu, id, 0, vm::null);
|
_sys_prx_unload_module(ppu, id, 0, vm::null);
|
||||||
|
|
||||||
// Return the exact value returned by the start function (as an error)
|
// Return the exact value returned by the start function (as an error)
|
||||||
@ -641,7 +640,10 @@ error_code _sys_prx_stop_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<sys_
|
|||||||
{
|
{
|
||||||
// No error code on invalid state, so throw on unexpected state
|
// No error code on invalid state, so throw on unexpected state
|
||||||
std::lock_guard lock(prx->mutex);
|
std::lock_guard lock(prx->mutex);
|
||||||
ensure(prx->exports_end <= prx->exports_start || (prx->state == PRX_STATE_STOPPING && ppu_register_library_lock(prx->module_info_name, false)));
|
ensure(prx->exports_end <= prx->exports_start || (prx->state == PRX_STATE_STOPPING));
|
||||||
|
|
||||||
|
prx->unload_exports();
|
||||||
|
|
||||||
ensure(prx->state.compare_and_swap_test(PRX_STATE_STOPPING, PRX_STATE_STOPPED));
|
ensure(prx->state.compare_and_swap_test(PRX_STATE_STOPPING, PRX_STATE_STOPPED));
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -739,7 +741,7 @@ error_code _sys_prx_unload_module(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<sy
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size);
|
void ppu_manual_load_imports_exports(u32 imports_start, u32 imports_size, u32 exports_start, u32 exports_size, std::basic_string<bool>& loaded_flags);
|
||||||
|
|
||||||
void lv2_prx::load_exports()
|
void lv2_prx::load_exports()
|
||||||
{
|
{
|
||||||
@ -749,7 +751,40 @@ void lv2_prx::load_exports()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ppu_manual_load_imports_exports(0, 0, exports_start, exports_end - exports_start);
|
if (!m_loaded_flags.empty())
|
||||||
|
{
|
||||||
|
// Already loaded
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppu_manual_load_imports_exports(0, 0, exports_start, exports_end - exports_start, m_loaded_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv2_prx::restore_exports()
|
||||||
|
{
|
||||||
|
constexpr usz sizeof_export_data = 0x1C;
|
||||||
|
|
||||||
|
std::basic_string<bool> loaded_flags_empty;
|
||||||
|
|
||||||
|
for (usz start = exports_start, i = 0; start < exports_end; i++, start += sizeof_export_data)
|
||||||
|
{
|
||||||
|
if (::at32(m_loaded_flags, i))
|
||||||
|
{
|
||||||
|
loaded_flags_empty.clear();
|
||||||
|
ppu_manual_load_imports_exports(0, 0, start, sizeof_export_data, loaded_flags_empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv2_prx::unload_exports()
|
||||||
|
{
|
||||||
|
if (m_loaded_flags.empty())
|
||||||
|
{
|
||||||
|
// Not loaded
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppu_manual_load_imports_exports(0, 0, exports_start, exports_end - exports_start, m_loaded_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_code _sys_prx_register_module(ppu_thread& ppu, vm::cptr<char> name, vm::ptr<void> opt)
|
error_code _sys_prx_register_module(ppu_thread& ppu, vm::cptr<char> name, vm::ptr<void> opt)
|
||||||
@ -799,7 +834,7 @@ error_code _sys_prx_register_module(ppu_thread& ppu, vm::cptr<char> name, vm::pt
|
|||||||
{
|
{
|
||||||
if (g_ps3_process_info.get_cellos_appname() == "vsh.self"sv)
|
if (g_ps3_process_info.get_cellos_appname() == "vsh.self"sv)
|
||||||
{
|
{
|
||||||
ppu_manual_load_imports_exports(info.lib_stub_ea.addr(), info.lib_stub_size, info.lib_entries_ea.addr(), info.lib_entries_size);
|
ppu_manual_load_imports_exports(info.lib_stub_ea.addr(), info.lib_stub_size, info.lib_entries_ea.addr(), info.lib_entries_size, *std::make_unique<std::basic_string<bool>>());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -63,17 +63,17 @@ struct sys_prx_segment_info_t
|
|||||||
|
|
||||||
struct sys_prx_module_info_t
|
struct sys_prx_module_info_t
|
||||||
{
|
{
|
||||||
be_t<u64> size;
|
be_t<u64> size; // 0
|
||||||
char name[30];
|
char name[30]; // 8
|
||||||
char version[2];
|
char version[2]; // 0x26
|
||||||
be_t<u32> modattribute;
|
be_t<u32> modattribute; // 0x28
|
||||||
be_t<u32> start_entry;
|
be_t<u32> start_entry; // 0x2c
|
||||||
be_t<u32> stop_entry;
|
be_t<u32> stop_entry; // 0x30
|
||||||
be_t<u32> all_segments_num;
|
be_t<u32> all_segments_num; // 0x34
|
||||||
vm::bptr<char> filename;
|
vm::bptr<char> filename; // 0x38
|
||||||
be_t<u32> filename_size;
|
be_t<u32> filename_size; // 0x3c
|
||||||
vm::bptr<sys_prx_segment_info_t> segments;
|
vm::bptr<sys_prx_segment_info_t> segments; // 0x40
|
||||||
be_t<u32> segments_num;
|
be_t<u32> segments_num; // 0x44
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sys_prx_module_info_option_t
|
struct sys_prx_module_info_option_t
|
||||||
@ -188,14 +188,18 @@ struct lv2_prx final : lv2_obj, ppu_module
|
|||||||
vm::ptr<s32(u64 callback, u64 argc, vm::ptr<void, u64> argv)> epilogue = vm::null;
|
vm::ptr<s32(u64 callback, u64 argc, vm::ptr<void, u64> argv)> epilogue = vm::null;
|
||||||
vm::ptr<s32()> exit = vm::null;
|
vm::ptr<s32()> exit = vm::null;
|
||||||
|
|
||||||
char module_info_name[28];
|
char module_info_name[28]{};
|
||||||
u8 module_info_version[2];
|
u8 module_info_version[2]{};
|
||||||
be_t<u16> module_info_attributes;
|
be_t<u16> module_info_attributes{};
|
||||||
|
|
||||||
u32 exports_start = umax;
|
u32 exports_start = umax;
|
||||||
u32 exports_end = 0;
|
u32 exports_end = 0;
|
||||||
|
|
||||||
|
std::basic_string<bool> m_loaded_flags;
|
||||||
|
|
||||||
void load_exports(); // (Re)load exports
|
void load_exports(); // (Re)load exports
|
||||||
|
void restore_exports(); // For savestates
|
||||||
|
void unload_exports();
|
||||||
|
|
||||||
lv2_prx() noexcept = default;
|
lv2_prx() noexcept = default;
|
||||||
lv2_prx(utils::serial&) {}
|
lv2_prx(utils::serial&) {}
|
||||||
|
@ -396,7 +396,7 @@ error_code sys_timer_sleep(ppu_thread& ppu, u32 sleep_time)
|
|||||||
{
|
{
|
||||||
ppu.state += cpu_flag::wait;
|
ppu.state += cpu_flag::wait;
|
||||||
|
|
||||||
sys_timer.warning("sys_timer_sleep(sleep_time=%d)", sleep_time);
|
sys_timer.trace("sys_timer_sleep(sleep_time=%d)", sleep_time);
|
||||||
|
|
||||||
return sys_timer_usleep(ppu, sleep_time * u64{1000000});
|
return sys_timer_usleep(ppu, sleep_time * u64{1000000});
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ SERIALIZATION_VER(lv2_sync, 3, 1)
|
|||||||
SERIALIZATION_VER(lv2_vm, 4, 1)
|
SERIALIZATION_VER(lv2_vm, 4, 1)
|
||||||
SERIALIZATION_VER(lv2_net, 5, 1)
|
SERIALIZATION_VER(lv2_net, 5, 1)
|
||||||
SERIALIZATION_VER(lv2_fs, 6, 1)
|
SERIALIZATION_VER(lv2_fs, 6, 1)
|
||||||
SERIALIZATION_VER(lv2_prx_overlay, 7, 1, 2/*PRX dynamic exports*/)
|
SERIALIZATION_VER(lv2_prx_overlay, 7, 1, 2/*PRX dynamic exports*/, 3/*Conditionally Loaded Local Exports*/)
|
||||||
SERIALIZATION_VER(lv2_memory, 8, 1)
|
SERIALIZATION_VER(lv2_memory, 8, 1)
|
||||||
SERIALIZATION_VER(lv2_config, 9, 1)
|
SERIALIZATION_VER(lv2_config, 9, 1)
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ namespace np
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// Compiler bug, lambda function body does seem to inherit used namespace atleast for function decleration
|
// Compiler bug, lambda function body does seem to inherit used namespace atleast for function declaration
|
||||||
SERIALIZATION_VER(rsx, 10)
|
SERIALIZATION_VER(rsx, 10)
|
||||||
SERIALIZATION_VER(sceNp, 11)
|
SERIALIZATION_VER(sceNp, 11)
|
||||||
#endif
|
#endif
|
||||||
|
@ -466,7 +466,7 @@ void kernel_explorer::update()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString text = qstr(fmt::format("PRX 0x%08x: '%s'", id, prx.name));
|
const QString text = qstr(fmt::format("PRX 0x%08x: '%s', attr=0x%x, lib=%s", id, prx.name, prx.module_info_attributes, prx.module_info_name));
|
||||||
QTreeWidgetItem* prx_tree = add_solid_node(node, text, text);
|
QTreeWidgetItem* prx_tree = add_solid_node(node, text, text);
|
||||||
display_program_segments(prx_tree, prx);
|
display_program_segments(prx_tree, prx);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user