Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PPU debugger: report functions on registers display #8055

Merged
merged 7 commits into from Apr 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/PPUAnalyser.cpp
Expand Up @@ -664,7 +664,7 @@ void ppu_module::analyse(u32 lib_toc, u32 entry)
const u32 _toc_end = _toc + 0x8000;

// TODO: improve TOC constraints
if (_toc % 4 || _toc == 0 || _toc >= 0x40000000 || (_toc >= start && _toc < end))
if (_toc % 4 || !vm::check_addr(_toc) || _toc >= 0x40000000 || (_toc >= start && _toc < end))
{
sec_end.set(0);
break;
Expand Down
37 changes: 32 additions & 5 deletions rpcs3/Emu/Cell/PPUThread.cpp
Expand Up @@ -381,20 +381,47 @@ std::string ppu_thread::dump_regs() const
const u32 max_str_len = 32;
const u32 hex_count = 8;

if (reg <= UINT32_MAX && vm::check_addr(static_cast<u32>(reg), max_str_len, vm::page_readable))
if (reg <= UINT32_MAX && vm::check_addr(static_cast<u32>(reg), max_str_len))
{
const u64 reg_ptr = vm::read64(reg);
bool is_function = false;
u32 toc = 0;

if (reg_ptr <= UINT32_MAX && vm::check_addr(static_cast<u32>(reg_ptr), max_str_len, vm::page_readable))
if (const u32 reg_ptr = *vm::get_super_ptr<u32>(static_cast<u32>(reg));
vm::check_addr(reg_ptr, max_str_len))
{
if ((reg | reg_ptr) % 4 == 0 && vm::check_addr(reg_ptr, 4, vm::page_executable))
{
toc = *vm::get_super_ptr<u32>(static_cast<u32>(reg + 4));

if (toc % 4 == 0 && vm::check_addr(toc))
{
is_function = true;
}
}

reg = reg_ptr;
}
else if (reg % 4 == 0 && vm::check_addr(reg, 4, vm::page_executable))
{
is_function = true;
}

const auto gpr_buf = vm::get_super_ptr<u8>(reg);

std::string buf_tmp(gpr_buf, gpr_buf + max_str_len);

if (std::isprint(static_cast<u8>(buf_tmp[0])) && std::isprint(static_cast<u8>(buf_tmp[1])) && std::isprint(static_cast<u8>(buf_tmp[2])))
if (is_function)
{
if (toc)
{
fmt::append(ret, " -> func(at=0x%x, toc=0x%x)", reg, toc);
}
else
{
fmt::append(ret, " -> function-code");
}
}
else if (std::isprint(static_cast<u8>(buf_tmp[0])) && std::isprint(static_cast<u8>(buf_tmp[1])) && std::isprint(static_cast<u8>(buf_tmp[2])))
{
fmt::append(ret, " -> \"%s\"", buf_tmp.c_str());
}
Expand Down Expand Up @@ -504,7 +531,7 @@ std::string ppu_thread::dump_misc() const

if (_func)
{
ret += "Current function: ";
ret += "In function: ";
ret += _func;
ret += '\n';

Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/SPUThread.cpp
Expand Up @@ -1056,7 +1056,7 @@ std::string spu_thread::dump_misc() const
{
if (const auto func = current_func)
{
ret += "\nCurrent function: ";
ret += "\nIn function: ";
ret += func;
}
else
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/Emu/Cell/lv2/lv2.cpp
Expand Up @@ -56,7 +56,7 @@ void fmt_class_string<ppu_syscall_code>::format(std::string& out, u64 arg)

static bool null_func(ppu_thread& ppu)
{
ppu_log.todo("Unimplemented syscall %s -> CELL_OK (r3=0x%llx, r4=0x%x, r5=0x%llx, r6=0x%llx, r7=0x%llx, r8=0x%llx, r9=0x%llx, r10=0x%llx)", ppu_syscall_code(ppu.gpr[11]),
ppu_log.todo("Unimplemented syscall %s -> CELL_OK (r3=0x%llx, r4=0x%llx, r5=0x%llx, r6=0x%llx, r7=0x%llx, r8=0x%llx, r9=0x%llx, r10=0x%llx)", ppu_syscall_code(ppu.gpr[11]),
ppu.gpr[3], ppu.gpr[4], ppu.gpr[5], ppu.gpr[6], ppu.gpr[7], ppu.gpr[8], ppu.gpr[9], ppu.gpr[10]);

ppu.gpr[3] = 0;
Expand Down