mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-18 13:21:09 +00:00
PPU: Fix thread entry detection false positives
This commit is contained in:
parent
6aff2803e5
commit
c87a7cb2c0
@ -2121,7 +2121,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar)
|
||||
}
|
||||
|
||||
// Program entry
|
||||
u32 entry = 0;
|
||||
u32 entry = static_cast<u32>(elf.header.e_entry); // Run entry from elf (HLE)
|
||||
|
||||
// Set path (TODO)
|
||||
_main.name.clear();
|
||||
@ -2264,6 +2264,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar)
|
||||
ppu_thread_params p{};
|
||||
p.stack_addr = vm::cast(vm::alloc(primary_stacksize, vm::stack, 4096));
|
||||
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);
|
||||
|
||||
@ -2278,7 +2279,7 @@ bool ppu_load_exec(const ppu_exec_object& elf, utils::serial* ar)
|
||||
|
||||
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
|
||||
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
|
||||
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_gpr, 11 }, u64{elf.header.e_entry},
|
||||
{ ppu_cmd::set_gpr, 12 }, u64{malloc_pagesize},
|
||||
{ ppu_cmd::lle_call, entry },
|
||||
{ ppu_cmd::entry_call, 0 },
|
||||
});
|
||||
|
||||
// Set actual memory protection (experimental)
|
||||
|
@ -1480,6 +1480,14 @@ void ppu_thread::cpu_task()
|
||||
cmd_pop(), fast_call(opd[0], opd[1]);
|
||||
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:
|
||||
{
|
||||
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:
|
||||
{
|
||||
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;
|
||||
}
|
||||
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)));
|
||||
}
|
||||
|
||||
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_rtoc = gpr[2];
|
||||
@ -2066,7 +2074,7 @@ void ppu_thread::fast_call(u32 addr, u64 rtoc)
|
||||
gpr[2] = old_rtoc;
|
||||
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;
|
||||
dump_all(ret);
|
||||
@ -2076,7 +2084,9 @@ void ppu_thread::fast_call(u32 addr, u64 rtoc)
|
||||
|
||||
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;
|
||||
|
@ -22,6 +22,7 @@ enum class ppu_cmd : u32
|
||||
ptr_call, // Execute function by pointer
|
||||
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
|
||||
entry_call, // Load addr and rtoc from entry_func
|
||||
initialize, // ppu_initialize()
|
||||
sleep,
|
||||
reset_stack, // resets stack address
|
||||
@ -339,7 +340,7 @@ public:
|
||||
|
||||
be_t<u64>* get_stack_arg(s32 i, u64 align = alignof(u64));
|
||||
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 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::set_args, 2 }, arg1, arg2,
|
||||
{ ppu_cmd::opd_call, 0 }, thread->entry_func,
|
||||
{ ppu_cmd::entry_call, 0 },
|
||||
{ ppu_cmd::sleep, 0 },
|
||||
{ ppu_cmd::ptr_call, 0 },
|
||||
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
|
||||
({
|
||||
{ppu_cmd::opd_call, 0}, thread.entry_func
|
||||
{ppu_cmd::entry_call, 0},
|
||||
});
|
||||
|
||||
return {};
|
||||
|
Loading…
x
Reference in New Issue
Block a user