mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-10-02 06:10:00 +00:00
PPU: Fix thread entry detection false positives
This commit is contained in:
parent
6aff2803e5
commit
c87a7cb2c0
5 changed files with 22 additions and 15 deletions
|
@ -2121,7 +2121,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Program entry
|
// Program entry
|
||||||
u32 entry = 0;
|
u32 entry = static_cast<u32>(elf.header.e_entry); // Run entry from elf (HLE)
|
||||||
|
|
||||||
// Set path (TODO)
|
// Set path (TODO)
|
||||||
_main.name.clear();
|
_main.name.clear();
|
||||||
|
@ -2264,6 +2264,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar)
|
||||||
ppu_thread_params p{};
|
ppu_thread_params p{};
|
||||||
p.stack_addr = vm::cast(vm::alloc(primary_stacksize, vm::stack, 4096));
|
p.stack_addr = vm::cast(vm::alloc(primary_stacksize, vm::stack, 4096));
|
||||||
p.stack_size = primary_stacksize;
|
p.stack_size = primary_stacksize;
|
||||||
|
p.entry = vm::_ref<ppu_func_opd_t>(entry);
|
||||||
|
|
||||||
auto ppu = idm::make_ptr<named_thread<ppu_thread>>(p, "main_thread", primary_prio, 1);
|
auto ppu = idm::make_ptr<named_thread<ppu_thread>>(p, "main_thread", primary_prio, 1);
|
||||||
|
|
||||||
|
@ -2278,7 +2279,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar)
|
||||||
|
|
||||||
ppu->cmd_push({ppu_cmd::initialize, 0});
|
ppu->cmd_push({ppu_cmd::initialize, 0});
|
||||||
|
|
||||||
if (!entry && !Emu.IsVsh())
|
if (entry == static_cast<u32>(elf.header.e_entry) && !Emu.IsVsh())
|
||||||
{
|
{
|
||||||
// Set TLS args, call sys_initialize_tls
|
// Set TLS args, call sys_initialize_tls
|
||||||
ppu->cmd_list
|
ppu->cmd_list
|
||||||
|
@ -2288,11 +2289,6 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!entry)
|
|
||||||
{
|
|
||||||
entry = static_cast<u32>(elf.header.e_entry); // Run entry from elf
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run start functions
|
// Run start functions
|
||||||
for (const auto& prx : loaded_modules)
|
for (const auto& prx : loaded_modules)
|
||||||
{
|
{
|
||||||
|
@ -2315,7 +2311,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar)
|
||||||
{ ppu_cmd::set_args, 8 }, u64{Emu.argv.size()}, u64{argv.addr()}, u64{envp.addr()}, u64{0}, u64{ppu->id}, u64{tls_vaddr}, u64{tls_fsize}, u64{tls_vsize},
|
{ ppu_cmd::set_args, 8 }, u64{Emu.argv.size()}, u64{argv.addr()}, u64{envp.addr()}, u64{0}, u64{ppu->id}, u64{tls_vaddr}, u64{tls_fsize}, u64{tls_vsize},
|
||||||
{ ppu_cmd::set_gpr, 11 }, u64{elf.header.e_entry},
|
{ ppu_cmd::set_gpr, 11 }, u64{elf.header.e_entry},
|
||||||
{ ppu_cmd::set_gpr, 12 }, u64{malloc_pagesize},
|
{ ppu_cmd::set_gpr, 12 }, u64{malloc_pagesize},
|
||||||
{ ppu_cmd::lle_call, entry },
|
{ ppu_cmd::entry_call, 0 },
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set actual memory protection (experimental)
|
// Set actual memory protection (experimental)
|
||||||
|
|
|
@ -1480,6 +1480,14 @@ void ppu_thread::cpu_task()
|
||||||
cmd_pop(), fast_call(opd[0], opd[1]);
|
cmd_pop(), fast_call(opd[0], opd[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ppu_cmd::entry_call:
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
pthread_jit_write_protect_np(true);
|
||||||
|
#endif
|
||||||
|
cmd_pop(), fast_call(entry_func.addr, entry_func.rtoc, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ppu_cmd::hle_call:
|
case ppu_cmd::hle_call:
|
||||||
{
|
{
|
||||||
cmd_pop(), ::at32(ppu_function_manager::get(), arg)(*this, {arg}, vm::_ptr<u32>(cia - 4), &ppu_ret);
|
cmd_pop(), ::at32(ppu_function_manager::get(), arg)(*this, {arg}, vm::_ptr<u32>(cia - 4), &ppu_ret);
|
||||||
|
@ -1503,7 +1511,7 @@ void ppu_thread::cpu_task()
|
||||||
case ppu_cmd::cia_call:
|
case ppu_cmd::cia_call:
|
||||||
{
|
{
|
||||||
loaded_from_savestate = true;
|
loaded_from_savestate = true;
|
||||||
cmd_pop(), fast_call(std::exchange(cia, 0), gpr[2]);
|
cmd_pop(), fast_call(std::exchange(cia, 0), gpr[2], true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ppu_cmd::initialize:
|
case ppu_cmd::initialize:
|
||||||
|
@ -2000,7 +2008,7 @@ be_t<u64>* ppu_thread::get_stack_arg(s32 i, u64 align)
|
||||||
return vm::_ptr<u64>(vm::cast((gpr[1] + 0x30 + 0x8 * (i - 1)) & (0 - align)));
|
return vm::_ptr<u64>(vm::cast((gpr[1] + 0x30 + 0x8 * (i - 1)) & (0 - align)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ppu_thread::fast_call(u32 addr, u64 rtoc)
|
void ppu_thread::fast_call(u32 addr, u64 rtoc, bool is_thread_entry)
|
||||||
{
|
{
|
||||||
const auto old_cia = cia;
|
const auto old_cia = cia;
|
||||||
const auto old_rtoc = gpr[2];
|
const auto old_rtoc = gpr[2];
|
||||||
|
@ -2066,7 +2074,7 @@ void ppu_thread::fast_call(u32 addr, u64 rtoc)
|
||||||
gpr[2] = old_rtoc;
|
gpr[2] = old_rtoc;
|
||||||
lr = old_lr;
|
lr = old_lr;
|
||||||
}
|
}
|
||||||
else if (state & cpu_flag::ret && cia == g_fxo->get<ppu_function_manager>().func_addr(1, true) + 4)
|
else if (state & cpu_flag::ret && cia == g_fxo->get<ppu_function_manager>().func_addr(1, true) + 4 && is_thread_entry)
|
||||||
{
|
{
|
||||||
std::string ret;
|
std::string ret;
|
||||||
dump_all(ret);
|
dump_all(ret);
|
||||||
|
@ -2076,7 +2084,9 @@ void ppu_thread::fast_call(u32 addr, u64 rtoc)
|
||||||
|
|
||||||
lv2_obj::sleep(*this);
|
lv2_obj::sleep(*this);
|
||||||
|
|
||||||
state += cpu_flag::again; // For savestates
|
// For savestates
|
||||||
|
state += cpu_flag::again;
|
||||||
|
std::memcpy(syscall_args, &gpr[3], sizeof(syscall_args));
|
||||||
}
|
}
|
||||||
|
|
||||||
current_function = old_func;
|
current_function = old_func;
|
||||||
|
|
|
@ -22,6 +22,7 @@ enum class ppu_cmd : u32
|
||||||
ptr_call, // Execute function by pointer
|
ptr_call, // Execute function by pointer
|
||||||
opd_call, // Execute function by provided rtoc and address (unlike lle_call, does not read memory)
|
opd_call, // Execute function by provided rtoc and address (unlike lle_call, does not read memory)
|
||||||
cia_call, // Execute from current CIA, mo GPR modification applied
|
cia_call, // Execute from current CIA, mo GPR modification applied
|
||||||
|
entry_call, // Load addr and rtoc from entry_func
|
||||||
initialize, // ppu_initialize()
|
initialize, // ppu_initialize()
|
||||||
sleep,
|
sleep,
|
||||||
reset_stack, // resets stack address
|
reset_stack, // resets stack address
|
||||||
|
@ -339,7 +340,7 @@ public:
|
||||||
|
|
||||||
be_t<u64>* get_stack_arg(s32 i, u64 align = alignof(u64));
|
be_t<u64>* get_stack_arg(s32 i, u64 align = alignof(u64));
|
||||||
void exec_task();
|
void exec_task();
|
||||||
void fast_call(u32 addr, u64 rtoc);
|
void fast_call(u32 addr, u64 rtoc, bool is_thread_entry = false);
|
||||||
|
|
||||||
static std::pair<vm::addr_t, u32> stack_push(u32 size, u32 align_v);
|
static std::pair<vm::addr_t, u32> stack_push(u32 size, u32 align_v);
|
||||||
static void stack_pop_verbose(u32 addr, u32 size) noexcept;
|
static void stack_pop_verbose(u32 addr, u32 size) noexcept;
|
||||||
|
|
|
@ -75,7 +75,7 @@ void lv2_int_serv::exec() const
|
||||||
({
|
({
|
||||||
{ ppu_cmd::reset_stack, 0 },
|
{ ppu_cmd::reset_stack, 0 },
|
||||||
{ ppu_cmd::set_args, 2 }, arg1, arg2,
|
{ ppu_cmd::set_args, 2 }, arg1, arg2,
|
||||||
{ ppu_cmd::opd_call, 0 }, thread->entry_func,
|
{ ppu_cmd::entry_call, 0 },
|
||||||
{ ppu_cmd::sleep, 0 },
|
{ ppu_cmd::sleep, 0 },
|
||||||
{ ppu_cmd::ptr_call, 0 },
|
{ ppu_cmd::ptr_call, 0 },
|
||||||
std::bit_cast<u64>(&ppu_interrupt_thread_entry)
|
std::bit_cast<u64>(&ppu_interrupt_thread_entry)
|
||||||
|
|
|
@ -563,7 +563,7 @@ error_code sys_ppu_thread_start(ppu_thread& ppu, u32 thread_id)
|
||||||
|
|
||||||
thread.cmd_list
|
thread.cmd_list
|
||||||
({
|
({
|
||||||
{ppu_cmd::opd_call, 0}, thread.entry_func
|
{ppu_cmd::entry_call, 0},
|
||||||
});
|
});
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue