Debugger improved: Instruction editor added

How to use the instruction editor:
1. Load an .ELF file
2. Select an instruction from any valid memory address inside any
thread.
3. Press 'E' key and have fun. :P

Note1: I suggest to remove the function InterpreterDisAsmFrame::DClick
and use InterpreterDisAsmFrame::InstrKey to do all debugging-related
actions (Add breakpoint, Edit, Step, Run, etc.) using the same keyboard
layout as debuggers like OllyDbg.

Note2: The final binary is 200 KB larger due to this feature. This issue
should be fixed in the future. This has probably something to do with
the #include's.
This commit is contained in:
Alexandro Sánchez Bach 2013-09-21 02:40:36 +02:00
parent a11de0f607
commit bf293ebbfc
6 changed files with 136 additions and 0 deletions

View File

@ -0,0 +1,88 @@
#include "stdafx.h"
#include "InstructionEditor.h"
InstructionEditorDialog::InstructionEditorDialog(wxPanel *parent, u64 _pc, PPCThread* _CPU, PPC_Decoder* _decoder, PPC_DisAsm* _disasm)
: wxDialog(parent, wxID_ANY, "Edit instruction", 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, "Address: ");
wxStaticText* t1_addr = new wxStaticText(this, wxID_ANY, wxString::Format("%08x",pc));
wxStaticText* t2_text = new wxStaticText(this, wxID_ANY, "Instruction:");
t2_instr = new wxTextCtrl(this, wxID_ANY);
wxStaticText* t3_text = new wxStaticText(this, wxID_ANY, "Preview: ");
t3_preview = new wxStaticText(this, wxID_ANY, "");
s_t1_panel->Add(t1_text);
s_t1_panel->AddSpacer(8);
s_t1_panel->Add(t1_addr);
s_t2_panel->Add(t2_text);
s_t2_panel->AddSpacer(8);
s_t2_panel->Add(t2_instr);
s_t3_panel->Add(t3_text);
s_t3_panel->AddSpacer(8);
s_t3_panel->Add(t3_preview);
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), wxRIGHT, 0, 5);
s_panel->Add(s_t1_panel);
s_panel->AddSpacer(8);
s_panel->Add(s_t3_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_TEXT_UPDATED, wxCommandEventHandler(InstructionEditorDialog::updatePreview));
t2_instr->SetValue(wxString::Format("%08x", Memory.Read32(pc)));
this->SetSizerAndFit(s_panel_margin_x);
if(this->ShowModal() == wxID_OK)
{
unsigned long opcode;
if (!t2_instr->GetValue().ToULong(&opcode, 16))
wxMessageBox("This instruction could not be parsed.\nNo changes were made.","Error");
else
Memory.Write32(CPU->GetOffset() + pc, (u32)opcode);
}
}
void InstructionEditorDialog::updatePreview(wxCommandEvent& event)
{
unsigned long opcode;
if (t2_instr->GetValue().ToULong(&opcode, 16))
{
decoder->Decode((u32)opcode);
wxString preview = disasm->last_opcode;
while (preview[0] != ':') preview.Remove(0,1);
preview.Remove(0,1);
t3_preview->SetLabel(preview);
}
else
{
t3_preview->SetLabel("Could not parse instruction.");
}
}

View File

@ -0,0 +1,24 @@
#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,5 +1,6 @@
#include "stdafx.h"
#include "InterpreterDisAsm.h"
#include "InstructionEditor.h"
//static const int show_lines = 30;
@ -67,6 +68,7 @@ InterpreterDisAsmFrame::InterpreterDisAsmFrame(wxWindow* parent)
Connect(m_btn_step->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoStep));
Connect(m_btn_run->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoRun));
Connect(m_btn_pause->GetId(), wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(InterpreterDisAsmFrame::DoPause));
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_KEY_DOWN, wxListEventHandler(InterpreterDisAsmFrame::InstrKey));
Connect(m_list->GetId(), wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler(InterpreterDisAsmFrame::DClick));
Connect(m_choice_units->GetId(),wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler(InterpreterDisAsmFrame::OnSelectUnit));
Connect(wxEVT_SIZE, wxSizeEventHandler(InterpreterDisAsmFrame::OnResize));
@ -442,6 +444,23 @@ void InterpreterDisAsmFrame::DoStep(wxCommandEvent& WXUNUSED(event))
ThreadBase::Start();
}
void InterpreterDisAsmFrame::InstrKey(wxListEvent& event)
{
long i = m_list->GetFirstSelected();
if(i < 0) return;
const u64 start_pc = PC - m_item_count*4;
const u64 pc = start_pc + i*4;
switch(event.GetKeyCode())
{
case 'E':
InstructionEditorDialog(this, pc, CPU, decoder, disasm);
DoUpdate();
return;
}
}
void InterpreterDisAsmFrame::DClick(wxListEvent& event)
{
long i = m_list->GetFirstSelected();

View File

@ -46,6 +46,7 @@ public:
void DoRun(wxCommandEvent& event);
void DoPause(wxCommandEvent& event);
void DoStep(wxCommandEvent& event);
void InstrKey(wxListEvent& event);
void DClick(wxListEvent& event);
void MouseWheel(wxMouseEvent& event);

View File

@ -265,6 +265,7 @@
<ClCompile Include="Gui\Debugger.cpp" />
<ClCompile Include="Gui\DisAsmFrame.cpp" />
<ClCompile Include="Gui\GameViewer.cpp" />
<ClCompile Include="Gui\InstructionEditor.cpp" />
<ClCompile Include="Gui\InterpreterDisAsm.cpp" />
<ClCompile Include="Gui\MainFrame.cpp" />
<ClCompile Include="Gui\MemoryViewer.cpp" />

View File

@ -307,6 +307,9 @@
<ClCompile Include="Emu\SysCalls\lv2\SC_Mouse.cpp">
<Filter>Emu\SysCalls\lv2</Filter>
</ClCompile>
<ClCompile Include="Gui\InstructionEditor.cpp">
<Filter>Gui</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="rpcs3.rc" />