mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-29 22:20:48 +00:00
Debugger improved: Register editor added
How to use the register editor: 1. Load an .ELF file 2. Select any instruction from a thread. (This is a workaround to activate the appropriate event listener. This will be changed in the future). 3. Press 'R' key and modify any register you want. Note: The register editor only works with PPU and SPU threads. Additional changes: * Fixed the filesize problem caused by the instruction editor dialog. * Instruction Editor: Fixed small issue in SPU threads
This commit is contained in:
parent
bf293ebbfc
commit
9c6ae554fa
@ -159,6 +159,8 @@ public:
|
|||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
virtual wxString RegsToString() { return wxEmptyString; }
|
virtual wxString RegsToString() { return wxEmptyString; }
|
||||||
|
virtual wxString ReadRegString(wxString reg) { return wxEmptyString; }
|
||||||
|
virtual bool WriteRegString(wxString reg, wxString value) { return false; }
|
||||||
|
|
||||||
virtual void Exec();
|
virtual void Exec();
|
||||||
void ExecOnce();
|
void ExecOnce();
|
||||||
|
@ -753,6 +753,69 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual wxString ReadRegString(wxString reg)
|
||||||
|
{
|
||||||
|
if (reg.Contains("["))
|
||||||
|
{
|
||||||
|
long reg_index;
|
||||||
|
reg.AfterFirst('[').RemoveLast().ToLong(®_index);
|
||||||
|
if (reg.StartsWith("GPR")) return wxString::Format("%016x", GPR[reg_index]);
|
||||||
|
if (reg.StartsWith("FPR")) return wxString::Format("%016x", FPR[reg_index]);
|
||||||
|
if (reg.StartsWith("VPR")) return wxString::Format("%032x", VPR[reg_index]);
|
||||||
|
}
|
||||||
|
if (reg == "CR") return wxString::Format("%08x", CR);
|
||||||
|
if (reg == "LR") return wxString::Format("%016x", LR);
|
||||||
|
if (reg == "CTR") return wxString::Format("%016x", CTR);
|
||||||
|
if (reg == "XER") return wxString::Format("%016x", XER);
|
||||||
|
if (reg == "FPSCR") return wxString::Format("%08x", FPSCR);
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteRegString(wxString reg, wxString value) {
|
||||||
|
while (value.Len() < 32) value = "0"+value;
|
||||||
|
if (reg.Contains("["))
|
||||||
|
{
|
||||||
|
long reg_index;
|
||||||
|
reg.AfterFirst('[').RemoveLast().ToLong(®_index);
|
||||||
|
if (reg.StartsWith("GPR") || (reg.StartsWith("FPR")))
|
||||||
|
{
|
||||||
|
unsigned long long reg_value;
|
||||||
|
if (!value.SubString(16,32).ToULongLong(®_value, 16)) return false;
|
||||||
|
if (reg.StartsWith("GPR")) GPR[reg_index] = (u64)reg_value;
|
||||||
|
if (reg.StartsWith("FPR")) FPR[reg_index] = (u64)reg_value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (reg.StartsWith("VPR"))
|
||||||
|
{
|
||||||
|
unsigned long long reg_value0;
|
||||||
|
unsigned long long reg_value1;
|
||||||
|
if (!value.SubString(16,32).ToULongLong(®_value0, 16)) return false;
|
||||||
|
if (!value.SubString(0,16).ToULongLong(®_value1, 16)) return false;
|
||||||
|
VPR[reg_index]._u64[0] = (u64)reg_value0;
|
||||||
|
VPR[reg_index]._u64[1] = (u64)reg_value1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reg == "LR" || reg == "CTR" || reg == "XER")
|
||||||
|
{
|
||||||
|
unsigned long long reg_value;
|
||||||
|
if (!value.SubString(16,32).ToULongLong(®_value, 16)) return false;
|
||||||
|
if (reg == "LR") LR = (u64)reg_value;
|
||||||
|
if (reg == "CTR") CTR = (u64)reg_value;
|
||||||
|
if (reg == "XER") XER.XER = (u64)reg_value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (reg == "CR" || reg == "FPSCR")
|
||||||
|
{
|
||||||
|
unsigned long reg_value;
|
||||||
|
if (!value.SubString(24,32).ToULong(®_value, 16)) return false;
|
||||||
|
if (reg == "CR") CR.CR = (u32)reg_value;
|
||||||
|
if (reg == "FPSCR") FPSCR.FPSCR = (u32)reg_value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void AddArgv(const wxString& arg);
|
virtual void AddArgv(const wxString& arg);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -249,6 +249,37 @@ public:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual wxString ReadRegString(wxString reg)
|
||||||
|
{
|
||||||
|
if (reg.Contains("["))
|
||||||
|
{
|
||||||
|
long reg_index;
|
||||||
|
reg.AfterFirst('[').RemoveLast().ToLong(®_index);
|
||||||
|
if (reg.StartsWith("GPR")) return wxString::Format("%032x", GPR[reg_index]);
|
||||||
|
}
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteRegString(wxString reg, wxString value) {
|
||||||
|
while (value.Len() < 32) value = "0"+value;
|
||||||
|
if (reg.Contains("["))
|
||||||
|
{
|
||||||
|
long reg_index;
|
||||||
|
reg.AfterFirst('[').RemoveLast().ToLong(®_index);
|
||||||
|
if (reg.StartsWith("GPR"))
|
||||||
|
{
|
||||||
|
unsigned long long reg_value0;
|
||||||
|
unsigned long long reg_value1;
|
||||||
|
if (!value.SubString(16,32).ToULongLong(®_value0, 16)) return false;
|
||||||
|
if (!value.SubString(0,16).ToULongLong(®_value1, 16)) return false;
|
||||||
|
GPR[reg_index]._u64[0] = (u64)reg_value0;
|
||||||
|
GPR[reg_index]._u64[1] = (u64)reg_value1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual void InitRegs();
|
virtual void InitRegs();
|
||||||
virtual u64 GetFreeStackSize() const;
|
virtual u64 GetFreeStackSize() const;
|
||||||
|
@ -1,5 +1,20 @@
|
|||||||
#include "stdafx.h"
|
class InstructionEditorDialog
|
||||||
#include "InstructionEditor.h"
|
: public wxDialog
|
||||||
|
{
|
||||||
|
u64 pc;
|
||||||
|
PPC_DisAsm* disasm;
|
||||||
|
PPC_Decoder* decoder;
|
||||||
|
wxTextCtrl* t2_instr;
|
||||||
|
wxStaticText* t3_preview;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PPCThread* CPU;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm);
|
||||||
|
|
||||||
|
void updatePreview(wxCommandEvent& event);
|
||||||
|
};
|
||||||
|
|
||||||
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
|
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
|
||||||
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
|
: wxDialog(parent, wxID_ANY, "Edit instruction", wxDefaultPosition)
|
||||||
@ -56,7 +71,7 @@ InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCTh
|
|||||||
s_panel_margin_x->AddSpacer(12);
|
s_panel_margin_x->AddSpacer(12);
|
||||||
|
|
||||||
this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
|
this->Connect(wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
|
||||||
t2_instr->SetValue(wxString::Format("%08x", Memory.Read32(pc)));
|
t2_instr->SetValue(wxString::Format("%08x", Memory.Read32(CPU->GetOffset() + pc)));
|
||||||
|
|
||||||
this->SetSizerAndFit(s_panel_margin_x);
|
this->SetSizerAndFit(s_panel_margin_x);
|
||||||
|
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Emu/Cell/PPCThread.h"
|
|
||||||
#include "Emu/Cell/PPUDecoder.h"
|
|
||||||
#include "Emu/Cell/PPUDisAsm.h"
|
|
||||||
#include "Emu/Cell/SPUDecoder.h"
|
|
||||||
#include "Emu/Cell/SPUDisAsm.h"
|
|
||||||
|
|
||||||
class InstructionEditorDialog
|
|
||||||
: public wxDialog
|
|
||||||
{
|
|
||||||
u64 pc;
|
|
||||||
PPC_DisAsm* disasm;
|
|
||||||
PPC_Decoder* decoder;
|
|
||||||
wxTextCtrl* t2_instr;
|
|
||||||
wxStaticText* t3_preview;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PPCThread* CPU;
|
|
||||||
|
|
||||||
public:
|
|
||||||
InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm);
|
|
||||||
|
|
||||||
void updatePreview(wxCommandEvent& event);
|
|
||||||
};
|
|
@ -1,6 +1,8 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "InterpreterDisAsm.h"
|
#include "InterpreterDisAsm.h"
|
||||||
#include "InstructionEditor.h"
|
|
||||||
|
#include "InstructionEditor.cpp"
|
||||||
|
#include "RegisterEditor.cpp"
|
||||||
|
|
||||||
//static const int show_lines = 30;
|
//static const int show_lines = 30;
|
||||||
|
|
||||||
@ -458,6 +460,10 @@ void InterpreterDisAsmFrame::InstrKey(wxListEvent& event)
|
|||||||
InstructionEditorDialog(this, pc, CPU, decoder, disasm);
|
InstructionEditorDialog(this, pc, CPU, decoder, disasm);
|
||||||
DoUpdate();
|
DoUpdate();
|
||||||
return;
|
return;
|
||||||
|
case 'R':
|
||||||
|
RegisterEditorDialog(this, pc, CPU, decoder, disasm);
|
||||||
|
DoUpdate();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
105
rpcs3/Gui/RegisterEditor.cpp
Normal file
105
rpcs3/Gui/RegisterEditor.cpp
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
class RegisterEditorDialog
|
||||||
|
: public wxDialog
|
||||||
|
{
|
||||||
|
u64 pc;
|
||||||
|
PPC_DisAsm* disasm;
|
||||||
|
PPC_Decoder* decoder;
|
||||||
|
wxComboBox* t1_register;
|
||||||
|
wxTextCtrl* t2_value;
|
||||||
|
wxStaticText* t3_preview;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PPCThread* CPU;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm);
|
||||||
|
|
||||||
|
void updateRegister(wxCommandEvent& event);
|
||||||
|
void updatePreview(wxCommandEvent& event);
|
||||||
|
};
|
||||||
|
|
||||||
|
RegisterEditorDialog::RegisterEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
|
||||||
|
: wxDialog(parent, wxID_ANY, "Edit registers", wxDefaultPosition)
|
||||||
|
, pc(_pc)
|
||||||
|
, CPU(_CPU)
|
||||||
|
, decoder(_decoder)
|
||||||
|
, disasm(_disasm)
|
||||||
|
{
|
||||||
|
wxBoxSizer* s_panel_margin_x(new wxBoxSizer(wxHORIZONTAL));
|
||||||
|
wxBoxSizer* s_panel_margin_y(new wxBoxSizer(wxVERTICAL));
|
||||||
|
|
||||||
|
wxBoxSizer* s_panel(new wxBoxSizer(wxVERTICAL));
|
||||||
|
wxBoxSizer* s_t1_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||||
|
wxBoxSizer* s_t2_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||||
|
wxBoxSizer* s_t3_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||||
|
wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL));
|
||||||
|
|
||||||
|
wxStaticText* t1_text = new wxStaticText(this, wxID_ANY, "Register: ");
|
||||||
|
t1_register = new wxComboBox(this, wxID_ANY, wxEmptyString);
|
||||||
|
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Value (Hex):");
|
||||||
|
t2_value = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,-1));
|
||||||
|
|
||||||
|
s_t1_panel->Add(t1_text);
|
||||||
|
s_t1_panel->AddSpacer(8);
|
||||||
|
s_t1_panel->Add(t1_register);
|
||||||
|
|
||||||
|
s_t2_panel->Add(t2_text);
|
||||||
|
s_t2_panel->AddSpacer(8);
|
||||||
|
s_t2_panel->Add(t2_value);
|
||||||
|
|
||||||
|
s_b_panel->Add(new wxButton(this, wxID_OK), wxLEFT, 0, 5);
|
||||||
|
s_b_panel->AddSpacer(5);
|
||||||
|
s_b_panel->Add(new wxButton(this, wxID_CANCEL), wxLEFT, 0, 5);
|
||||||
|
|
||||||
|
s_panel->Add(s_t1_panel);
|
||||||
|
s_panel->AddSpacer(8);
|
||||||
|
s_panel->Add(s_t2_panel);
|
||||||
|
s_panel->AddSpacer(16);
|
||||||
|
s_panel->Add(s_b_panel);
|
||||||
|
|
||||||
|
s_panel_margin_y->AddSpacer(12);
|
||||||
|
s_panel_margin_y->Add(s_panel);
|
||||||
|
s_panel_margin_y->AddSpacer(12);
|
||||||
|
s_panel_margin_x->AddSpacer(12);
|
||||||
|
s_panel_margin_x->Add(s_panel_margin_y);
|
||||||
|
s_panel_margin_x->AddSpacer(12);
|
||||||
|
|
||||||
|
this->Connect(wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEventHandler(RegisterEditorDialog::updateRegister));
|
||||||
|
|
||||||
|
if (CPU->GetType() == PPC_THREAD_PPU)
|
||||||
|
{
|
||||||
|
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
|
||||||
|
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("FPR[%d]",i));
|
||||||
|
for (int i=0; i<32; i++) t1_register->Append(wxString::Format("VPR[%d]",i));
|
||||||
|
t1_register->Append("CR");
|
||||||
|
t1_register->Append("LR");
|
||||||
|
t1_register->Append("CTR");
|
||||||
|
t1_register->Append("XER");
|
||||||
|
t1_register->Append("FPSCR");
|
||||||
|
}
|
||||||
|
if (CPU->GetType() == PPC_THREAD_SPU)
|
||||||
|
{
|
||||||
|
for (int i=0; i<128; i++) t1_register->Append(wxString::Format("GPR[%d]",i));
|
||||||
|
}
|
||||||
|
if (CPU->GetType() == PPC_THREAD_RAW_SPU)
|
||||||
|
{
|
||||||
|
wxMessageBox("RawSPU threads not yet supported.","Error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->SetSizerAndFit(s_panel_margin_x);
|
||||||
|
|
||||||
|
if(this->ShowModal() == wxID_OK)
|
||||||
|
{
|
||||||
|
wxString reg = t1_register->GetStringSelection();
|
||||||
|
wxString value = t2_value->GetValue();
|
||||||
|
if (!CPU->WriteRegString(reg,value))
|
||||||
|
wxMessageBox("This value could not be converted.\nNo changes were made.","Error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterEditorDialog::updateRegister(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
wxString reg = t1_register->GetStringSelection();
|
||||||
|
t2_value->SetValue(CPU->ReadRegString(reg));
|
||||||
|
}
|
@ -265,7 +265,6 @@
|
|||||||
<ClCompile Include="Gui\Debugger.cpp" />
|
<ClCompile Include="Gui\Debugger.cpp" />
|
||||||
<ClCompile Include="Gui\DisAsmFrame.cpp" />
|
<ClCompile Include="Gui\DisAsmFrame.cpp" />
|
||||||
<ClCompile Include="Gui\GameViewer.cpp" />
|
<ClCompile Include="Gui\GameViewer.cpp" />
|
||||||
<ClCompile Include="Gui\InstructionEditor.cpp" />
|
|
||||||
<ClCompile Include="Gui\InterpreterDisAsm.cpp" />
|
<ClCompile Include="Gui\InterpreterDisAsm.cpp" />
|
||||||
<ClCompile Include="Gui\MainFrame.cpp" />
|
<ClCompile Include="Gui\MainFrame.cpp" />
|
||||||
<ClCompile Include="Gui\MemoryViewer.cpp" />
|
<ClCompile Include="Gui\MemoryViewer.cpp" />
|
||||||
|
@ -307,9 +307,6 @@
|
|||||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Mouse.cpp">
|
<ClCompile Include="Emu\SysCalls\lv2\SC_Mouse.cpp">
|
||||||
<Filter>Emu\SysCalls\lv2</Filter>
|
<Filter>Emu\SysCalls\lv2</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Gui\InstructionEditor.cpp">
|
|
||||||
<Filter>Gui</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="rpcs3.rc" />
|
<ResourceCompile Include="rpcs3.rc" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user