RSX-Debugger: Implement backwards scrolling

* Use 2 points of known true RSX code roots and follow them in order to peek at the current section of valid RSX code:
These roots are: current RSX instruction address and the last targeted address by a branch instruction.
This commit is contained in:
Eladash 2022-03-25 18:17:25 +03:00 committed by Ivan
parent 26d8120168
commit 1d51f3af0c
10 changed files with 108 additions and 34 deletions

View file

@ -12,6 +12,7 @@
#include "Capture/rsx_capture.h"
#include "rsx_methods.h"
#include "gcm_printing.h"
#include "RSXDisAsm.h"
#include "Emu/Cell/lv2/sys_event.h"
#include "Emu/Cell/lv2/sys_time.h"
#include "Emu/Cell/Modules/cellGcmSys.h"
@ -2640,6 +2641,63 @@ namespace rsx
fifo_ctrl->sync_get();
}
std::pair<u32, u32> thread::try_get_pc_of_x_cmds_backwards(u32 count, u32 get) const
{
if (!ctrl)
{
return {0, umax};
}
if (!count)
{
return {0, get};
}
u32 true_get = ctrl->get;
u32 start = last_known_code_start;
RSXDisAsm disasm(cpu_disasm_mode::survey_cmd_size, vm::g_sudo_addr, 0, this);
std::vector<u32> pcs_of_valid_cmds;
pcs_of_valid_cmds.reserve(std::min<u32>((get - start) / 16, 0x4000)); // Rough estimation of final array size
auto probe_code_region = [&](u32 probe_start) -> std::pair<u32, u32>
{
pcs_of_valid_cmds.clear();
pcs_of_valid_cmds.push_back(probe_start);
while (pcs_of_valid_cmds.back() < get)
{
if (u32 advance = disasm.disasm(pcs_of_valid_cmds.back()))
{
pcs_of_valid_cmds.push_back(pcs_of_valid_cmds.back() + advance);
}
else
{
return {0, umax};
}
}
if (pcs_of_valid_cmds.size() == 1u || pcs_of_valid_cmds.back() != get)
{
return {0, umax};
}
u32 found_cmds_count = std::min(count, ::size32(pcs_of_valid_cmds) - 1);
return {found_cmds_count, *(pcs_of_valid_cmds.end() - 1 - found_cmds_count)};
};
auto pair = probe_code_region(start);
if (!pair.first)
{
pair = probe_code_region(true_get);
}
return pair;
}
void thread::recover_fifo(u32 line, u32 col, const char* file, const char* func)
{
const u64 current_time = rsx::uclock();