PPU: Fix thread entry detection false positives

This commit is contained in:
Eladash 2023-06-07 14:34:39 +03:00 committed by Ivan
parent 6aff2803e5
commit c87a7cb2c0
5 changed files with 22 additions and 15 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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 {};