1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

Patches: Add savable breakpoints patch type

This commit is contained in:
Eladash 2023-09-25 18:32:50 +03:00 committed by Elad Ashkenazi
parent b2c6958750
commit e79fc867c5
12 changed files with 47 additions and 4 deletions

View File

@ -76,6 +76,7 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
case patch_type::bd64: return "bd64"; case patch_type::bd64: return "bd64";
case patch_type::lef32: return "lef32"; case patch_type::lef32: return "lef32";
case patch_type::lef64: return "lef64"; case patch_type::lef64: return "lef64";
case patch_type::bp_exec: return "bpex";
case patch_type::utf8: return "utf8"; case patch_type::utf8: return "utf8";
case patch_type::c_utf8: return "cutf8"; case patch_type::c_utf8: return "cutf8";
case patch_type::move_file: return "move_file"; case patch_type::move_file: return "move_file";
@ -755,6 +756,7 @@ bool patch_engine::add_patch_data(YAML::Node node, patch_info& info, u32 modifie
switch (p_data.type) switch (p_data.type)
{ {
case patch_type::bp_exec:
case patch_type::utf8: case patch_type::utf8:
case patch_type::jump_func: case patch_type::jump_func:
case patch_type::move_file: case patch_type::move_file:
@ -1008,6 +1010,7 @@ static usz apply_modification(std::basic_string<u32>& applied, patch_engine::pat
case patch_type::jump: case patch_type::jump:
case patch_type::jump_link: case patch_type::jump_link:
case patch_type::jump_func: case patch_type::jump_func:
case patch_type::bp_exec:
case patch_type::le32: case patch_type::le32:
case patch_type::lef32: case patch_type::lef32:
case patch_type::bd32: case patch_type::bd32:
@ -1316,6 +1319,17 @@ static usz apply_modification(std::basic_string<u32>& applied, patch_engine::pat
std::memcpy(ptr, &val, sizeof(val)); std::memcpy(ptr, &val, sizeof(val));
break; break;
} }
case patch_type::bp_exec:
{
const u32 exec_addr = vm::try_get_addr(relocate_instructions_at ? vm::get_super_ptr<u8>(offset & -4) : mem_translate(offset & -4, 4)).first;
if (exec_addr)
{
Emu.GetCallbacks().add_breakpoint(exec_addr);
}
break;
}
case patch_type::utf8: case patch_type::utf8:
{ {
std::memcpy(ptr, p.original_value.data(), p.original_value.size()); std::memcpy(ptr, p.original_value.data(), p.original_value.size());

View File

@ -52,6 +52,7 @@ enum class patch_type
bd64, // be64 with data hint (non-code) bd64, // be64 with data hint (non-code)
bef32, bef32,
bef64, bef64,
bp_exec, // Execution Breakpoint
utf8, // Text of string (not null-terminated automatically) utf8, // Text of string (not null-terminated automatically)
c_utf8, // Text of string (null-terminated automatically) c_utf8, // Text of string (null-terminated automatically)
move_file, // Move file move_file, // Move file

View File

@ -91,6 +91,7 @@ struct EmuCallbacks
std::string(*resolve_path)(std::string_view) = [](std::string_view arg){ return std::string{arg}; }; // Resolve path using Qt std::string(*resolve_path)(std::string_view) = [](std::string_view arg){ return std::string{arg}; }; // Resolve path using Qt
std::function<std::vector<std::string>()> get_font_dirs; std::function<std::vector<std::string>()> get_font_dirs;
std::function<bool(const std::vector<std::string>&)> on_install_pkgs; std::function<bool(const std::vector<std::string>&)> on_install_pkgs;
std::function<void(u32)> add_breakpoint;
}; };
namespace utils namespace utils

View File

@ -159,6 +159,7 @@ void headless_application::InitializeCallbacks()
callbacks.get_localized_u32string = [](localized_string_id, const char*) -> std::u32string { return {}; }; callbacks.get_localized_u32string = [](localized_string_id, const char*) -> std::u32string { return {}; };
callbacks.play_sound = [](const std::string&){}; callbacks.play_sound = [](const std::string&){};
callbacks.add_breakpoint = [](u32 /*addr*/){};
Emu.SetCallbacks(std::move(callbacks)); Emu.SetCallbacks(std::move(callbacks));
} }

View File

@ -100,7 +100,7 @@ bool breakpoint_list::AddBreakpoint(u32 pc)
/** /**
* If breakpoint exists, we remove it, else add new one. Yeah, it'd be nicer from a code logic to have it be set/reset. But, that logic has to happen somewhere anyhow. * If breakpoint exists, we remove it, else add new one. Yeah, it'd be nicer from a code logic to have it be set/reset. But, that logic has to happen somewhere anyhow.
*/ */
void breakpoint_list::HandleBreakpointRequest(u32 loc) void breakpoint_list::HandleBreakpointRequest(u32 loc, bool only_add)
{ {
if (!m_cpu || m_cpu->state & cpu_flag::exit) if (!m_cpu || m_cpu->state & cpu_flag::exit)
{ {
@ -167,7 +167,10 @@ void breakpoint_list::HandleBreakpointRequest(u32 loc)
if (m_ppu_breakpoint_handler->HasBreakpoint(loc)) if (m_ppu_breakpoint_handler->HasBreakpoint(loc))
{ {
RemoveBreakpoint(loc); if (!only_add)
{
RemoveBreakpoint(loc);
}
} }
else else
{ {

View File

@ -24,7 +24,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
void RequestShowAddress(u32 addr, bool select_addr = true, bool force = false); void RequestShowAddress(u32 addr, bool select_addr = true, bool force = false);
public Q_SLOTS: public Q_SLOTS:
void HandleBreakpointRequest(u32 loc); void HandleBreakpointRequest(u32 loc, bool add_only);
private Q_SLOTS: private Q_SLOTS:
void OnBreakpointListDoubleClicked(); void OnBreakpointListDoubleClicked();
void OnBreakpointListRightClicked(const QPoint &pos); void OnBreakpointListRightClicked(const QPoint &pos);

View File

@ -1250,6 +1250,11 @@ void debugger_frame::PerformGoToRequest(const QString& text_argument)
} }
} }
void debugger_frame::PerformAddBreakpointRequest(u32 addr)
{
m_debugger_list->BreakpointRequested(addr, true);
}
u64 debugger_frame::EvaluateExpression(const QString& expression) u64 debugger_frame::EvaluateExpression(const QString& expression)
{ {
bool ok = false; bool ok = false;

View File

@ -95,6 +95,7 @@ public:
void EnableButtons(bool enable); void EnableButtons(bool enable);
void ShowGotoAddressDialog(); void ShowGotoAddressDialog();
void PerformGoToRequest(const QString& text_argument); void PerformGoToRequest(const QString& text_argument);
void PerformAddBreakpointRequest(u32 addr);
u64 EvaluateExpression(const QString& expression); u64 EvaluateExpression(const QString& expression);
void ClearBreakpoints() const; // Fallthrough method into breakpoint_list. void ClearBreakpoints() const; // Fallthrough method into breakpoint_list.
void ClearCallStack(); void ClearCallStack();

View File

@ -30,7 +30,7 @@ public:
QColor m_text_color_pc; QColor m_text_color_pc;
Q_SIGNALS: Q_SIGNALS:
void BreakpointRequested(u32 loc); void BreakpointRequested(u32 loc, bool only_add = false);
public: public:
debugger_list(QWidget* parent, std::shared_ptr<gui_settings> settings, breakpoint_handler* handler); debugger_list(QWidget* parent, std::shared_ptr<gui_settings> settings, breakpoint_handler* handler);
void UpdateCPUData(cpu_thread* cpu, CPUDisAsm* disasm); void UpdateCPUData(cpu_thread* cpu, CPUDisAsm* disasm);

View File

@ -638,6 +638,14 @@ void gui_application::InitializeCallbacks()
}); });
}; };
callbacks.add_breakpoint = [this](u32 addr)
{
Emu.BlockingCallFromMainThread([this, addr]()
{
m_main_window->OnAddBreakpoint(addr);
});
};
Emu.SetCallbacks(std::move(callbacks)); Emu.SetCallbacks(std::move(callbacks));
} }

View File

@ -2007,6 +2007,14 @@ void main_window::EnableMenus(bool enabled) const
ui->actionCreate_Savestate->setEnabled(enabled); ui->actionCreate_Savestate->setEnabled(enabled);
} }
void main_window::OnAddBreakpoint(u32 addr) const
{
if (m_debugger_frame)
{
m_debugger_frame->PerformAddBreakpointRequest(addr);
}
}
void main_window::OnEnableDiscEject(bool enabled) const void main_window::OnEnableDiscEject(bool enabled) const
{ {
ui->ejectDiscAct->setEnabled(enabled); ui->ejectDiscAct->setEnabled(enabled);

View File

@ -106,6 +106,7 @@ public Q_SLOTS:
void OnEmuReady() const; void OnEmuReady() const;
void OnEnableDiscEject(bool enabled) const; void OnEnableDiscEject(bool enabled) const;
void OnEnableDiscInsert(bool enabled) const; void OnEnableDiscInsert(bool enabled) const;
void OnAddBreakpoint(u32 addr) const;
void RepaintGui(); void RepaintGui();
void RetranslateUI(const QStringList& language_codes, const QString& language); void RetranslateUI(const QStringList& language_codes, const QString& language);