diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index 9d6fb2e700..f9fd58be5f 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -50,6 +50,7 @@ struct ppu_segment u32 size; u32 type; u32 flags; + u32 filesz; }; // PPU Module Information diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 9a76ec76b5..d691eb2756 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Utilities/VirtualMemory.h" #include "Utilities/bin_patch.h" #include "Crypto/sha1.h" @@ -732,6 +732,7 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, const std::stri ppu_segment _seg; _seg.addr = addr; _seg.size = mem_size; + _seg.filesz = file_size; _seg.type = p_type; _seg.flags = prog.p_flags; prx->segs.emplace_back(_seg); @@ -766,6 +767,7 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, const std::stri _sec.size = size; _sec.type = s.sh_type; _sec.flags = s.sh_flags & 7; + _sec.filesz = 0; prx->secs.emplace_back(_sec); break; } @@ -885,7 +887,7 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, const std::stri struct ppu_prx_library_info { be_t attributes; - be_t version; + u8 version[2]; char name[28]; be_t toc; be_t exports_start; @@ -898,6 +900,11 @@ std::shared_ptr ppu_load_prx(const ppu_prx_object& elf, const std::stri const auto& lib_info = vm::cptr(vm::cast(prx->segs[0].addr + elf.progs[0].p_paddr - elf.progs[0].p_offset, HERE)); const auto& lib_name = std::string(lib_info->name); + std::memcpy(prx->module_info_name, lib_info->name, sizeof(prx->module_info_name)); + prx->module_info_version[0] = lib_info->version[0]; + prx->module_info_version[1] = lib_info->version[1]; + prx->module_info_attributes = lib_info->attributes; + LOG_WARNING(LOADER, "Library %s (rtoc=0x%x):", lib_name, lib_info->toc); prx->specials = ppu_load_exports(link, lib_info->exports_start, lib_info->exports_end); @@ -979,6 +986,7 @@ void ppu_load_exec(const ppu_exec_object& elf) const u32 size = _seg.size = ::narrow(prog.p_memsz, "p_memsz" HERE); const u32 type = _seg.type = prog.p_type; const u32 flag = _seg.flags = prog.p_flags; + _seg.filesz = ::narrow(prog.p_filesz, "p_filesz" HERE); // Hash big-endian values sha1_update(&sha, (uchar*)&prog.p_type, sizeof(prog.p_type)); @@ -1019,6 +1027,7 @@ void ppu_load_exec(const ppu_exec_object& elf) const u32 size = _sec.size = vm::cast(s.sh_size); const u32 type = _sec.type = s.sh_type; const u32 flag = _sec.flags = s.sh_flags & 7; + _sec.filesz = 0; if (s.sh_type == 1 && addr && size) { diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index c6c160e4e1..925c433504 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -306,7 +306,43 @@ error_code _sys_prx_get_module_list(u64 flags, vm::ptr pOpt) { - sys_prx.todo("_sys_prx_get_module_info(id=0x%x, flags=%d, pOpt=*0x%x)", id, flags, pOpt); + sys_prx.warning("_sys_prx_get_module_info(id=0x%x, flags=%d, pOpt=*0x%x)", id, flags, pOpt); + + const auto prx = idm::get(id); + + if (!pOpt || !pOpt->info || !prx) + { + return CELL_EINVAL; + } + + std::memset(pOpt->info->name, 0, 30); + std::memcpy(pOpt->info->name, prx->module_info_name, 28); + pOpt->info->version[0] = prx->module_info_version[0]; + pOpt->info->version[1] = prx->module_info_version[1]; + pOpt->info->modattribute = prx->module_info_attributes; + pOpt->info->start_entry = prx->start.addr(); + pOpt->info->stop_entry = prx->stop.addr(); + pOpt->info->all_segments_num = prx->segs.size(); + if (pOpt->info->filename) + { + std::strncpy(pOpt->info->filename.get_ptr(), prx->name.c_str(), pOpt->info->filename_size); + pOpt->info->filename[pOpt->info->filename_size - 1] = 0; + } + + if (pOpt->info->segments) + { + u32 i = 0; + for (; i < prx->segs.size() && i < pOpt->info->segments_num; i++) + { + pOpt->info->segments[i].index = i; + pOpt->info->segments[i].base = prx->segs[i].addr; + pOpt->info->segments[i].filesz = prx->segs[i].filesz; + pOpt->info->segments[i].memsz = prx->segs[i].size; + pOpt->info->segments[i].type = prx->segs[i].type; + } + pOpt->info->segments_num = i; + } + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.h b/rpcs3/Emu/Cell/lv2/sys_prx.h index 4c1d836631..6496e5ea90 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.h +++ b/rpcs3/Emu/Cell/lv2/sys_prx.h @@ -129,6 +129,10 @@ struct lv2_prx final : lv2_obj, ppu_module vm::ps3::ptr argv)> prologue = vm::null; vm::ps3::ptr argv)> epilogue = vm::null; vm::ps3::ptr exit = vm::null; + + char module_info_name[28]; + u8 module_info_version[2]; + be_t module_info_attributes; }; // SysCalls