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:
Alexandro Sánchez Bach 2013-09-22 13:34:54 +02:00
parent bf293ebbfc
commit 9c6ae554fa
9 changed files with 226 additions and 32 deletions

View File

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

View File

@ -753,6 +753,69 @@ public:
return ret; return ret;
} }
virtual wxString ReadRegString(wxString reg)
{
if (reg.Contains("["))
{
long reg_index;
reg.AfterFirst('[').RemoveLast().ToLong(&reg_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(&reg_index);
if (reg.StartsWith("GPR") || (reg.StartsWith("FPR")))
{
unsigned long long reg_value;
if (!value.SubString(16,32).ToULongLong(&reg_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(&reg_value0, 16)) return false;
if (!value.SubString(0,16).ToULongLong(&reg_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(&reg_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(&reg_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:

View File

@ -249,6 +249,37 @@ public:
return ret; return ret;
} }
virtual wxString ReadRegString(wxString reg)
{
if (reg.Contains("["))
{
long reg_index;
reg.AfterFirst('[').RemoveLast().ToLong(&reg_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(&reg_index);
if (reg.StartsWith("GPR"))
{
unsigned long long reg_value0;
unsigned long long reg_value1;
if (!value.SubString(16,32).ToULongLong(&reg_value0, 16)) return false;
if (!value.SubString(0,16).ToULongLong(&reg_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;

View File

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

View File

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

View File

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

View 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));
}

View File

@ -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" />

View File

@ -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" />