2019-12-09 19:07:36 +00:00
|
|
|
#include "QtDebugger.h"
|
|
|
|
#include "ui_QtDebugger.h"
|
|
|
|
|
2020-01-05 21:37:00 +00:00
|
|
|
#include <QApplication>
|
2019-12-10 00:10:44 +00:00
|
|
|
#include <QInputDialog>
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
2019-08-31 12:33:24 -04:00
|
|
|
#include <iostream>
|
|
|
|
#include "AppConfig.h"
|
|
|
|
#include "MIPSAssembler.h"
|
|
|
|
#include "Ps2Const.h"
|
|
|
|
#include "ee/PS2OS.h"
|
|
|
|
#include "MipsFunctionPatternDb.h"
|
|
|
|
#include "StdStream.h"
|
2021-01-08 16:57:36 -05:00
|
|
|
#include "StdStreamUtils.h"
|
2019-08-31 12:33:24 -04:00
|
|
|
#include "xml/Parser.h"
|
|
|
|
#include "xml/Utils.h"
|
|
|
|
#include "string_cast.h"
|
|
|
|
#include "string_format.h"
|
2021-01-08 16:57:36 -05:00
|
|
|
#include "PathUtils.h"
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
#define PREF_DEBUGGER_MEMORYVIEW_BYTEWIDTH "debugger.memoryview.bytewidth"
|
|
|
|
|
|
|
|
#define FIND_MAX_ADDRESS 0x02000000
|
|
|
|
|
2019-12-20 17:48:02 +00:00
|
|
|
QtDebugger::QtDebugger(CPS2VM& virtualMachine)
|
2021-01-14 09:51:50 -05:00
|
|
|
: ui(new Ui::QtDebugger)
|
2019-12-09 19:07:36 +00:00
|
|
|
, m_virtualMachine(virtualMachine)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-09 19:07:36 +00:00
|
|
|
ui->setupUi(this);
|
|
|
|
|
2019-12-10 01:40:28 +00:00
|
|
|
// Setup QT Stuff
|
2019-08-31 12:33:24 -04:00
|
|
|
RegisterPreferences();
|
|
|
|
|
|
|
|
//ELF View Initialization
|
2022-07-22 17:01:59 -04:00
|
|
|
m_pELFView = new CELFView<CELF32>(ui->mdiArea);
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
//Functions View Initialization
|
2019-12-09 19:07:36 +00:00
|
|
|
m_pFunctionsView = new CFunctionsView(ui->mdiArea);
|
2019-12-10 00:59:39 +00:00
|
|
|
m_pFunctionsView->hide();
|
2019-12-10 00:37:53 +00:00
|
|
|
m_OnFunctionDblClickConnection = m_pFunctionsView->OnFunctionDblClick.Connect(std::bind(&QtDebugger::OnFunctionsViewFunctionDblClick, this, std::placeholders::_1));
|
|
|
|
m_OnFunctionsStateChangeConnection = m_pFunctionsView->OnFunctionsStateChange.Connect(std::bind(&QtDebugger::OnFunctionsViewFunctionsStateChange, this));
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
//Threads View Initialization
|
2022-09-06 19:40:46 -04:00
|
|
|
{
|
|
|
|
m_kernelObjectListViewWnd = new QMdiSubWindow(ui->mdiArea);
|
2022-09-10 12:23:26 -04:00
|
|
|
m_kernelObjectListView = new CKernelObjectListView(m_kernelObjectListViewWnd);
|
2022-09-06 19:40:46 -04:00
|
|
|
m_kernelObjectListViewWnd->setWidget(m_kernelObjectListView);
|
|
|
|
m_kernelObjectListViewWnd->setWindowTitle("Kernel Objects");
|
|
|
|
|
2022-09-10 12:23:26 -04:00
|
|
|
m_kernelObjectListViewWnd->move(0, 0);
|
2022-09-06 19:40:46 -04:00
|
|
|
m_kernelObjectListViewWnd->resize(700, 300);
|
|
|
|
m_kernelObjectListViewWnd->hide();
|
|
|
|
m_OnGotoAddressConnection = m_kernelObjectListView->OnGotoAddress.Connect(std::bind(&QtDebugger::OnKernelObjectsViewAddressDblClick, this, std::placeholders::_1));
|
2022-09-10 12:47:16 -04:00
|
|
|
m_OnKernelObjectListViewTypeChangedConnection = m_kernelObjectListView->OnObjectTypeChanged.Connect([&](const char* typeName) { m_kernelObjectListViewWnd->setWindowTitle(typeName); });
|
2022-09-06 19:40:46 -04:00
|
|
|
}
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
//Address List View Initialization
|
2019-12-09 19:07:36 +00:00
|
|
|
m_addressListView = new CAddressListViewWnd(ui->mdiArea);
|
2019-12-10 00:59:39 +00:00
|
|
|
m_addressListView->hide();
|
2019-12-10 00:37:53 +00:00
|
|
|
m_AddressSelectedConnection = m_addressListView->AddressSelected.Connect([&](uint32 address) { OnFindCallersAddressDblClick(address); });
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
//Debug Views Initialization
|
2019-12-10 12:29:34 +00:00
|
|
|
m_nCurrentView = -1;
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2021-01-11 15:06:10 +00:00
|
|
|
m_pView[DEBUGVIEW_EE] = new CDebugView(this, ui->mdiArea, m_virtualMachine, &m_virtualMachine.m_ee->m_EE,
|
2021-01-04 18:05:53 +00:00
|
|
|
std::bind(&CPS2VM::StepEe, &m_virtualMachine), m_virtualMachine.m_ee->m_os, "EmotionEngine", PS2::EE_RAM_SIZE + PS2::EE_BIOS_SIZE);
|
2021-01-11 15:06:10 +00:00
|
|
|
m_pView[DEBUGVIEW_VU0] = new CDebugView(this, ui->mdiArea, m_virtualMachine, &m_virtualMachine.m_ee->m_VU0,
|
2019-12-19 21:37:47 +00:00
|
|
|
std::bind(&CPS2VM::StepVu0, &m_virtualMachine), nullptr, "Vector Unit 0", PS2::VUMEM0SIZE, CQtDisAsmTableModel::DISASM_VU);
|
2021-01-11 15:06:10 +00:00
|
|
|
m_pView[DEBUGVIEW_VU1] = new CDebugView(this, ui->mdiArea, m_virtualMachine, &m_virtualMachine.m_ee->m_VU1,
|
2019-12-19 21:37:47 +00:00
|
|
|
std::bind(&CPS2VM::StepVu1, &m_virtualMachine), nullptr, "Vector Unit 1", PS2::VUMEM1SIZE, CQtDisAsmTableModel::DISASM_VU);
|
2021-01-11 15:06:10 +00:00
|
|
|
m_pView[DEBUGVIEW_IOP] = new CDebugView(this, ui->mdiArea, m_virtualMachine, &m_virtualMachine.m_iop->m_cpu,
|
2019-12-19 21:37:47 +00:00
|
|
|
std::bind(&CPS2VM::StepIop, &m_virtualMachine), m_virtualMachine.m_iop->m_bios.get(), "IO Processor", PS2::IOP_RAM_SIZE);
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
m_OnExecutableChangeConnection = m_virtualMachine.m_ee->m_os->OnExecutableChange.Connect(std::bind(&QtDebugger::OnExecutableChange, this));
|
|
|
|
m_OnExecutableUnloadingConnection = m_virtualMachine.m_ee->m_os->OnExecutableUnloading.Connect(std::bind(&QtDebugger::OnExecutableUnloading, this));
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
m_OnMachineStateChangeConnection = m_virtualMachine.OnMachineStateChange.Connect(std::bind(&QtDebugger::OnMachineStateChange, this));
|
|
|
|
m_OnRunningStateChangeConnection = m_virtualMachine.OnRunningStateChange.Connect(std::bind(&QtDebugger::OnRunningStateChange, this));
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 12:29:34 +00:00
|
|
|
ActivateView(DEBUGVIEW_EE);
|
2019-12-10 01:40:28 +00:00
|
|
|
LoadSettings();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-12 01:44:55 +00:00
|
|
|
if(GetDisassemblyWindow()->isVisible())
|
|
|
|
{
|
|
|
|
GetDisassemblyWindow()->setFocus(Qt::ActiveWindowFocusReason);
|
|
|
|
}
|
2020-02-06 12:33:19 +00:00
|
|
|
|
|
|
|
connect(this, &QtDebugger::OnMachineStateChange, this, &QtDebugger::OnMachineStateChangeMsg);
|
|
|
|
connect(this, &QtDebugger::OnRunningStateChange, this, &QtDebugger::OnRunningStateChangeMsg);
|
|
|
|
connect(this, &QtDebugger::OnExecutableChange, this, &QtDebugger::OnExecutableChangeMsg);
|
|
|
|
connect(this, &QtDebugger::OnExecutableUnloading, this, &QtDebugger::OnExecutableUnloadingMsg);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
QtDebugger::~QtDebugger()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-09 19:07:36 +00:00
|
|
|
delete ui;
|
|
|
|
|
2019-12-19 21:49:56 +00:00
|
|
|
OnExecutableUnloading();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
for(unsigned int i = 0; i < DEBUGVIEW_MAX; i++)
|
|
|
|
{
|
2019-12-10 01:11:56 +00:00
|
|
|
delete m_pView[i];
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-21 18:36:40 +00:00
|
|
|
delete m_pELFView;
|
2019-12-10 12:31:00 +00:00
|
|
|
delete m_pFunctionsView;
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-20 20:37:13 +00:00
|
|
|
void QtDebugger::closeEvent(QCloseEvent* event)
|
|
|
|
{
|
|
|
|
if(isVisible())
|
|
|
|
SaveSettings();
|
|
|
|
|
|
|
|
event->accept();
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::RegisterPreferences()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
CAppConfig& config(CAppConfig::GetInstance());
|
|
|
|
|
|
|
|
config.RegisterPreferenceInteger("debugger.disasm.posx", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.disasm.posy", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.disasm.sizex", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.disasm.sizey", 0);
|
|
|
|
config.RegisterPreferenceBoolean("debugger.disasm.visible", true);
|
|
|
|
|
|
|
|
config.RegisterPreferenceInteger("debugger.regview.posx", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.regview.posy", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.regview.sizex", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.regview.sizey", 0);
|
|
|
|
config.RegisterPreferenceBoolean("debugger.regview.visible", true);
|
|
|
|
|
|
|
|
config.RegisterPreferenceInteger("debugger.memoryview.posx", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.memoryview.posy", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.memoryview.sizex", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.memoryview.sizey", 0);
|
|
|
|
config.RegisterPreferenceBoolean("debugger.memoryview.visible", true);
|
|
|
|
config.RegisterPreferenceInteger(PREF_DEBUGGER_MEMORYVIEW_BYTEWIDTH, 0);
|
|
|
|
|
|
|
|
config.RegisterPreferenceInteger("debugger.callstack.posx", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.callstack.posy", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.callstack.sizex", 0);
|
|
|
|
config.RegisterPreferenceInteger("debugger.callstack.sizey", 0);
|
|
|
|
config.RegisterPreferenceBoolean("debugger.callstack.visible", true);
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::UpdateTitle()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-10 01:33:11 +00:00
|
|
|
std::string sTitle("Play! - Debugger");
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 01:33:11 +00:00
|
|
|
if(GetCurrentView() != NULL)
|
|
|
|
{
|
|
|
|
sTitle += (" - [ ");
|
|
|
|
sTitle += GetCurrentView()->GetName();
|
|
|
|
sTitle += (" ]");
|
|
|
|
}
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 01:33:11 +00:00
|
|
|
setWindowTitle(sTitle.c_str());
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::LoadSettings()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
LoadViewLayout();
|
|
|
|
LoadBytesPerLine();
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::SaveSettings()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
SaveViewLayout();
|
|
|
|
SaveBytesPerLine();
|
|
|
|
}
|
|
|
|
|
2020-02-02 18:18:12 +00:00
|
|
|
void QtDebugger::SerializeWindowGeometry(QWidget* pWindow, const char* sPosX, const char* sPosY, const char* sSizeX, const char* sSizeY, const char* sVisible)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-10 01:26:55 +00:00
|
|
|
CAppConfig& config(CAppConfig::GetInstance());
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 01:26:55 +00:00
|
|
|
auto geometry = pWindow->geometry();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 01:26:55 +00:00
|
|
|
config.SetPreferenceInteger(sPosX, geometry.x());
|
|
|
|
config.SetPreferenceInteger(sPosY, geometry.y());
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-19 21:37:47 +00:00
|
|
|
config.SetPreferenceInteger(sSizeX, geometry.width());
|
|
|
|
config.SetPreferenceInteger(sSizeY, geometry.height());
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 01:26:55 +00:00
|
|
|
config.SetPreferenceBoolean(sVisible, pWindow->isVisible());
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2020-02-02 18:18:12 +00:00
|
|
|
void QtDebugger::UnserializeWindowGeometry(QWidget* pWindow, const char* sPosX, const char* sPosY, const char* sSizeX, const char* sSizeY, const char* sVisible)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-10 01:26:55 +00:00
|
|
|
CAppConfig& config(CAppConfig::GetInstance());
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 01:26:55 +00:00
|
|
|
pWindow->setGeometry(config.GetPreferenceInteger(sPosX), config.GetPreferenceInteger(sPosY),
|
|
|
|
config.GetPreferenceInteger(sSizeX), config.GetPreferenceInteger(sSizeY));
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 01:26:55 +00:00
|
|
|
if(!config.GetPreferenceBoolean(sVisible))
|
|
|
|
{
|
|
|
|
pWindow->hide();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pWindow->show();
|
|
|
|
}
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::Resume()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
m_virtualMachine.Resume();
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::StepCPU()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
if(m_virtualMachine.GetStatus() == CVirtualMachine::RUNNING)
|
|
|
|
{
|
2020-01-05 21:37:00 +00:00
|
|
|
QApplication::beep();
|
2019-08-31 12:33:24 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-12-12 01:44:55 +00:00
|
|
|
if(!GetDisassemblyWindow()->hasFocus())
|
|
|
|
{
|
|
|
|
GetDisassemblyWindow()->setFocus(Qt::ActiveWindowFocusReason);
|
|
|
|
}
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
GetCurrentView()->Step();
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::FindWordValue(uint32 mask)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
uint32 targetValue = 0;
|
2019-12-10 00:10:44 +00:00
|
|
|
{
|
|
|
|
bool ok;
|
|
|
|
QString res = QInputDialog::getText(this, tr("Find Value in Memory"),
|
2019-12-19 21:37:47 +00:00
|
|
|
tr("Enter value to find:"), QLineEdit::Normal,
|
|
|
|
tr("00000000"), &ok);
|
|
|
|
if(!ok || res.isEmpty())
|
2019-12-10 00:10:44 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if(sscanf(res.toStdString().c_str(), "%x", &targetValue) <= 0)
|
|
|
|
{
|
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setText("Invalid hex value.");
|
|
|
|
msgBox.exec();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
auto context = GetCurrentView()->GetContext();
|
|
|
|
auto title = string_format("Search results for 0x%08X", targetValue);
|
|
|
|
auto refs = FindWordValueRefs(context, targetValue & mask, mask);
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 00:10:44 +00:00
|
|
|
m_addressListView->SetTitle(std::move(title));
|
|
|
|
m_addressListView->SetAddressList(std::move(refs));
|
|
|
|
m_addressListView->show();
|
2019-12-10 00:54:10 +00:00
|
|
|
m_addressListView->setFocus(Qt::ActiveWindowFocusReason);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::AssembleJAL()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-10 00:16:20 +00:00
|
|
|
uint32 nValueTarget = 0, nValueAssemble = 0;
|
2019-12-10 00:28:42 +00:00
|
|
|
auto getAddress =
|
2019-12-19 21:37:47 +00:00
|
|
|
[this](const char* prompt, uint32& address) {
|
|
|
|
bool ok;
|
|
|
|
QString res = QInputDialog::getText(this, tr("Assemble JAL"),
|
|
|
|
tr(prompt), QLineEdit::Normal,
|
|
|
|
tr("00000000"), &ok);
|
|
|
|
if(!ok || res.isEmpty())
|
|
|
|
return false;
|
|
|
|
uint32 addrValueTemp = 0;
|
|
|
|
if(sscanf(res.toStdString().c_str(), "%x", &address) <= 0)
|
|
|
|
{
|
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setText("Invalid value.");
|
|
|
|
msgBox.exec();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
2019-12-10 00:28:42 +00:00
|
|
|
if(!getAddress("Enter jump target:", nValueTarget)) return;
|
|
|
|
if(!getAddress("Enter address to assemble JAL to:", nValueAssemble)) return;
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-10 00:16:20 +00:00
|
|
|
*(uint32*)&m_virtualMachine.m_ee->m_ram[nValueAssemble] = 0x0C000000 | (nValueTarget / 4);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::ReanalyzeEe()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
if(m_virtualMachine.m_ee->m_os->GetELF() == nullptr) return;
|
|
|
|
|
|
|
|
auto executableRange = m_virtualMachine.m_ee->m_os->GetExecutableRange();
|
|
|
|
uint32 minAddr = executableRange.first;
|
|
|
|
uint32 maxAddr = executableRange.second & ~0x03;
|
|
|
|
|
2019-12-10 00:23:05 +00:00
|
|
|
auto getAddress =
|
2019-12-19 21:37:47 +00:00
|
|
|
[this](const char* prompt, uint32& address) {
|
|
|
|
bool ok;
|
|
|
|
QString res = QInputDialog::getText(this, tr("Analyze EE"),
|
|
|
|
tr(prompt), QLineEdit::Normal,
|
|
|
|
tr(string_format("0x%08X", address).c_str()), &ok);
|
|
|
|
if(!ok || res.isEmpty())
|
|
|
|
return false;
|
|
|
|
uint32 addrValueTemp = 0;
|
|
|
|
if(sscanf(res.toStdString().c_str(), "%x", &addrValueTemp) <= 0)
|
|
|
|
{
|
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setText("Invalid value.");
|
|
|
|
msgBox.exec();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(addrValueTemp != 0)
|
|
|
|
{
|
|
|
|
address = addrValueTemp & ~0x3;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
};
|
2019-12-10 00:23:05 +00:00
|
|
|
|
|
|
|
if(!getAddress("Start Address:", minAddr)) return;
|
|
|
|
if(!getAddress("End Address:", maxAddr)) return;
|
|
|
|
|
|
|
|
if(minAddr > maxAddr)
|
|
|
|
{
|
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setText("Start address is larger than end address.");
|
|
|
|
msgBox.exec();
|
|
|
|
return;
|
|
|
|
}
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
minAddr = std::min<uint32>(minAddr, PS2::EE_RAM_SIZE);
|
|
|
|
maxAddr = std::min<uint32>(maxAddr, PS2::EE_RAM_SIZE);
|
|
|
|
|
|
|
|
m_virtualMachine.m_ee->m_EE.m_analysis->Clear();
|
|
|
|
m_virtualMachine.m_ee->m_EE.m_analysis->Analyse(minAddr, maxAddr);
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::FindEeFunctions()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
if(m_virtualMachine.m_ee->m_os->GetELF() == nullptr) return;
|
|
|
|
|
|
|
|
auto executableRange = m_virtualMachine.m_ee->m_os->GetExecutableRange();
|
|
|
|
uint32 minAddr = executableRange.first;
|
|
|
|
uint32 maxAddr = executableRange.second & ~0x03;
|
|
|
|
|
2021-01-08 16:57:36 -05:00
|
|
|
auto functionsPath = Framework::PathUtils::GetAppResourcesPath() / "ee_functions.xml";
|
|
|
|
auto functionsStream = Framework::CreateInputStdStream(functionsPath.native());
|
2019-08-31 12:33:24 -04:00
|
|
|
auto functionsDocument = std::unique_ptr<Framework::Xml::CNode>(Framework::Xml::CParser::ParseDocument(functionsStream));
|
|
|
|
auto functionsNode = functionsDocument->Select("Functions");
|
|
|
|
|
|
|
|
//Check function patterns
|
|
|
|
{
|
|
|
|
CMipsFunctionPatternDb patternDb(functionsNode);
|
|
|
|
|
|
|
|
for(auto patternIterator(std::begin(patternDb.GetPatterns()));
|
|
|
|
patternIterator != std::end(patternDb.GetPatterns()); ++patternIterator)
|
|
|
|
{
|
|
|
|
auto pattern = *patternIterator;
|
|
|
|
for(uint32 address = minAddr; address <= maxAddr; address += 4)
|
|
|
|
{
|
|
|
|
uint32* text = reinterpret_cast<uint32*>(m_virtualMachine.m_ee->m_ram + address);
|
|
|
|
uint32 textSize = (maxAddr - address);
|
|
|
|
if(pattern.Matches(text, textSize))
|
|
|
|
{
|
|
|
|
m_virtualMachine.m_ee->m_EE.m_Functions.InsertTag(address, pattern.name.c_str());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//Check function comments
|
|
|
|
{
|
|
|
|
std::map<std::string, std::string> stringFuncs;
|
|
|
|
auto commentNodes = functionsNode->SelectNodes("FunctionComments/FunctionComment");
|
|
|
|
for(const auto& commentNode : commentNodes)
|
|
|
|
{
|
|
|
|
auto comment = Framework::Xml::GetAttributeStringValue(commentNode, "Comment");
|
|
|
|
auto functionName = Framework::Xml::GetAttributeStringValue(commentNode, "Function");
|
|
|
|
stringFuncs.insert(std::make_pair(comment, functionName));
|
|
|
|
}
|
|
|
|
|
|
|
|
//Identify functions that reference special string literals
|
|
|
|
{
|
|
|
|
auto& eeFunctions = m_virtualMachine.m_ee->m_EE.m_Functions;
|
|
|
|
const auto& eeComments = m_virtualMachine.m_ee->m_EE.m_Comments;
|
|
|
|
const auto& eeAnalysis = m_virtualMachine.m_ee->m_EE.m_analysis;
|
|
|
|
for(auto tagIterator = eeComments.GetTagsBegin();
|
|
|
|
tagIterator != eeComments.GetTagsEnd(); tagIterator++)
|
|
|
|
{
|
|
|
|
const auto& tag = *tagIterator;
|
|
|
|
auto subroutine = eeAnalysis->FindSubroutine(tag.first);
|
|
|
|
if(subroutine == nullptr) continue;
|
|
|
|
auto stringFunc = stringFuncs.find(tag.second);
|
|
|
|
if(stringFunc == std::end(stringFuncs)) continue;
|
|
|
|
eeFunctions.InsertTag(subroutine->start, stringFunc->second.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_virtualMachine.m_ee->m_EE.m_Functions.OnTagListChange();
|
|
|
|
}
|
|
|
|
|
2022-04-02 13:00:23 -04:00
|
|
|
void QtDebugger::Layout1024x768()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2020-02-02 18:18:12 +00:00
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->setGeometry(0, 0, 700, 435);
|
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetDisassemblyWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:47:31 +00:00
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->setGeometry(700, 0, 324, 572);
|
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetRegisterViewWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:17:51 +00:00
|
|
|
static_cast<QWidget*>(GetMemoryViewWindow()->parent())->setGeometry(0, 435, 700, 265);
|
|
|
|
static_cast<QWidget*>(GetMemoryViewWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetMemoryViewWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:33:18 +00:00
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->setGeometry(700, 572, 324, 128);
|
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetCallStackWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2022-04-02 13:01:42 -04:00
|
|
|
void QtDebugger::Layout1280x800()
|
|
|
|
{
|
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->setGeometry(0, 0, 1100, 475);
|
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->show();
|
|
|
|
GetDisassemblyWindow()->show();
|
|
|
|
|
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->setGeometry(1100, 0, 325, 475);
|
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->show();
|
|
|
|
GetRegisterViewWindow()->show();
|
|
|
|
|
|
|
|
static_cast<QWidget*>(GetMemoryViewWindow()->parent())->setGeometry(0, 475, 1100, 265);
|
|
|
|
static_cast<QWidget*>(GetMemoryViewWindow()->parent())->show();
|
|
|
|
GetMemoryViewWindow()->show();
|
|
|
|
|
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->setGeometry(1100, 475, 325, 265);
|
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->show();
|
|
|
|
GetCallStackWindow()->show();
|
|
|
|
}
|
|
|
|
|
2022-04-02 13:00:23 -04:00
|
|
|
void QtDebugger::Layout1280x1024()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2020-02-02 18:18:12 +00:00
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->setGeometry(0, 0, 900, 540);
|
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetDisassemblyWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:47:31 +00:00
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->setGeometry(900, 0, 380, 784);
|
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetRegisterViewWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:17:51 +00:00
|
|
|
static_cast<QWidget*>(GetMemoryViewWindow()->parent())->setGeometry(0, 540, 900, 416);
|
|
|
|
static_cast<QWidget*>(GetMemoryViewWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetMemoryViewWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:33:18 +00:00
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->setGeometry(900, 784, 380, 172);
|
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetCallStackWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2022-04-02 13:00:23 -04:00
|
|
|
void QtDebugger::Layout1600x1200()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2020-02-02 18:18:12 +00:00
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->setGeometry(0, 0, 1094, 725);
|
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetDisassemblyWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:47:31 +00:00
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->setGeometry(1094, 0, 506, 725);
|
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetRegisterViewWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:17:51 +00:00
|
|
|
static_cast<QWidget*>(GetMemoryViewWindow()->parent())->setGeometry(0, 725, 1094, 407);
|
|
|
|
static_cast<QWidget*>(GetMemoryViewWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetMemoryViewWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:33:18 +00:00
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->setGeometry(1094, 725, 506, 407);
|
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->show();
|
2021-01-09 22:44:14 +00:00
|
|
|
GetCallStackWindow()->show();
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::ActivateView(unsigned int nView)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
if(m_nCurrentView == nView) return;
|
|
|
|
|
|
|
|
if(m_nCurrentView != -1)
|
|
|
|
{
|
|
|
|
SaveBytesPerLine();
|
|
|
|
SaveViewLayout();
|
2019-12-10 01:11:56 +00:00
|
|
|
GetCurrentView()->Hide();
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-11 14:52:12 +00:00
|
|
|
m_findCallersRequestConnection.reset();
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
m_nCurrentView = nView;
|
|
|
|
LoadViewLayout();
|
|
|
|
LoadBytesPerLine();
|
|
|
|
UpdateTitle();
|
|
|
|
|
|
|
|
{
|
|
|
|
auto biosDebugInfoProvider = GetCurrentView()->GetBiosDebugInfoProvider();
|
2019-12-10 12:31:00 +00:00
|
|
|
m_pFunctionsView->SetContext(GetCurrentView()->GetContext(), biosDebugInfoProvider);
|
2022-09-06 19:40:46 -04:00
|
|
|
m_kernelObjectListView->SetContext(GetCurrentView()->GetContext(), biosDebugInfoProvider);
|
|
|
|
|
|
|
|
ui->menuKernelObjects->clear();
|
|
|
|
if(biosDebugInfoProvider)
|
|
|
|
{
|
2022-09-07 19:58:01 -04:00
|
|
|
auto objectTypes = biosDebugInfoProvider->GetBiosObjectsDebugInfo();
|
|
|
|
for(const auto& objectTypePair : objectTypes)
|
2022-09-06 19:40:46 -04:00
|
|
|
{
|
2022-09-07 19:58:01 -04:00
|
|
|
const auto& objectType = objectTypePair.second;
|
2022-09-06 19:40:46 -04:00
|
|
|
QAction* objectAction = new QAction(this);
|
2022-09-07 19:58:01 -04:00
|
|
|
objectAction->setText(QString::fromStdString(objectType.name));
|
|
|
|
objectAction->setData(objectTypePair.first);
|
2022-09-08 19:17:13 -04:00
|
|
|
if(objectTypePair.first == BIOS_DEBUG_OBJECT_TYPE_THREAD)
|
|
|
|
{
|
|
|
|
objectAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_T));
|
|
|
|
}
|
2022-09-06 19:40:46 -04:00
|
|
|
connect(objectAction, SIGNAL(triggered()), this, SLOT(on_actionViewKernelObject_triggered()));
|
|
|
|
ui->menuKernelObjects->addAction(objectAction);
|
|
|
|
}
|
|
|
|
}
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-12 01:44:55 +00:00
|
|
|
if(GetDisassemblyWindow()->isVisible())
|
|
|
|
{
|
|
|
|
GetDisassemblyWindow()->setFocus(Qt::ActiveWindowFocusReason);
|
|
|
|
}
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2019-12-19 22:20:32 +00:00
|
|
|
m_findCallersRequestConnection = GetCurrentView()->GetDisassemblyWindow()->FindCallersRequested.Connect(
|
2019-12-19 21:37:47 +00:00
|
|
|
[&](uint32 address) { OnFindCallersRequested(address); });
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::SaveViewLayout()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2020-02-02 18:18:12 +00:00
|
|
|
SerializeWindowGeometry(static_cast<QWidget*>(GetDisassemblyWindow()->parent()),
|
2019-12-11 14:52:12 +00:00
|
|
|
"debugger.disasm.posx",
|
|
|
|
"debugger.disasm.posy",
|
|
|
|
"debugger.disasm.sizex",
|
|
|
|
"debugger.disasm.sizey",
|
|
|
|
"debugger.disasm.visible");
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:47:31 +00:00
|
|
|
SerializeWindowGeometry(static_cast<QWidget*>(GetRegisterViewWindow()->parent()),
|
2019-08-31 12:33:24 -04:00
|
|
|
"debugger.regview.posx",
|
|
|
|
"debugger.regview.posy",
|
|
|
|
"debugger.regview.sizex",
|
|
|
|
"debugger.regview.sizey",
|
|
|
|
"debugger.regview.visible");
|
|
|
|
|
2020-02-05 21:17:51 +00:00
|
|
|
SerializeWindowGeometry(static_cast<QWidget*>(GetMemoryViewWindow()->parent()),
|
2019-12-19 11:58:52 +00:00
|
|
|
"debugger.memoryview.posx",
|
|
|
|
"debugger.memoryview.posy",
|
|
|
|
"debugger.memoryview.sizex",
|
|
|
|
"debugger.memoryview.sizey",
|
|
|
|
"debugger.memoryview.visible");
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:33:18 +00:00
|
|
|
SerializeWindowGeometry(static_cast<QWidget*>(GetCallStackWindow()->parent()),
|
2019-08-31 12:33:24 -04:00
|
|
|
"debugger.callstack.posx",
|
|
|
|
"debugger.callstack.posy",
|
|
|
|
"debugger.callstack.sizex",
|
|
|
|
"debugger.callstack.sizey",
|
|
|
|
"debugger.callstack.visible");
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::LoadViewLayout()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2020-02-02 18:18:12 +00:00
|
|
|
UnserializeWindowGeometry(static_cast<QWidget*>(GetDisassemblyWindow()->parent()),
|
2019-12-12 13:08:22 +00:00
|
|
|
"debugger.disasm.posx",
|
|
|
|
"debugger.disasm.posy",
|
|
|
|
"debugger.disasm.sizex",
|
|
|
|
"debugger.disasm.sizey",
|
|
|
|
"debugger.disasm.visible");
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:47:31 +00:00
|
|
|
UnserializeWindowGeometry(static_cast<QWidget*>(GetRegisterViewWindow()->parent()),
|
2019-08-31 12:33:24 -04:00
|
|
|
"debugger.regview.posx",
|
|
|
|
"debugger.regview.posy",
|
|
|
|
"debugger.regview.sizex",
|
|
|
|
"debugger.regview.sizey",
|
|
|
|
"debugger.regview.visible");
|
|
|
|
|
2020-02-05 21:17:51 +00:00
|
|
|
UnserializeWindowGeometry(static_cast<QWidget*>(GetMemoryViewWindow()->parent()),
|
2019-12-19 11:58:52 +00:00
|
|
|
"debugger.memoryview.posx",
|
|
|
|
"debugger.memoryview.posy",
|
|
|
|
"debugger.memoryview.sizex",
|
|
|
|
"debugger.memoryview.sizey",
|
|
|
|
"debugger.memoryview.visible");
|
2019-08-31 12:33:24 -04:00
|
|
|
|
2020-02-05 21:33:18 +00:00
|
|
|
UnserializeWindowGeometry(static_cast<QWidget*>(GetCallStackWindow()->parent()),
|
2019-08-31 12:33:24 -04:00
|
|
|
"debugger.callstack.posx",
|
|
|
|
"debugger.callstack.posy",
|
|
|
|
"debugger.callstack.sizex",
|
|
|
|
"debugger.callstack.sizey",
|
|
|
|
"debugger.callstack.visible");
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::SaveBytesPerLine()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-19 11:58:52 +00:00
|
|
|
auto memoryView = GetMemoryViewWindow();
|
|
|
|
auto bytesPerLine = GetMemoryViewWindow()->GetBytesPerLine();
|
|
|
|
CAppConfig::GetInstance().SetPreferenceInteger(PREF_DEBUGGER_MEMORYVIEW_BYTEWIDTH, bytesPerLine);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::LoadBytesPerLine()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-19 11:58:52 +00:00
|
|
|
auto bytesPerLine = CAppConfig::GetInstance().GetPreferenceInteger(PREF_DEBUGGER_MEMORYVIEW_BYTEWIDTH);
|
|
|
|
auto memoryView = GetMemoryViewWindow();
|
|
|
|
memoryView->SetBytesPerLine(bytesPerLine);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
CDebugView* QtDebugger::GetCurrentView()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
if(m_nCurrentView == -1) return NULL;
|
|
|
|
return m_pView[m_nCurrentView];
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
CDisAsmWnd* QtDebugger::GetDisassemblyWindow()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
return GetCurrentView()->GetDisassemblyWindow();
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
CMemoryViewMIPSWnd* QtDebugger::GetMemoryViewWindow()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
return GetCurrentView()->GetMemoryViewWindow();
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
CRegViewWnd* QtDebugger::GetRegisterViewWindow()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
return GetCurrentView()->GetRegisterViewWindow();
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
CCallStackWnd* QtDebugger::GetCallStackWindow()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
return GetCurrentView()->GetCallStackWindow();
|
|
|
|
}
|
2019-12-09 20:16:11 +00:00
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
std::vector<uint32> QtDebugger::FindCallers(CMIPS* context, uint32 address)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
std::vector<uint32> callers;
|
|
|
|
for(uint32 i = 0; i < FIND_MAX_ADDRESS; i += 4)
|
|
|
|
{
|
|
|
|
uint32 opcode = context->m_pMemoryMap->GetInstruction(i);
|
|
|
|
uint32 ea = context->m_pArch->GetInstructionEffectiveAddress(context, i, opcode);
|
2022-12-07 14:48:20 -05:00
|
|
|
if(ea == MIPS_INVALID_PC) continue;
|
2019-08-31 12:33:24 -04:00
|
|
|
if(ea == address)
|
|
|
|
{
|
|
|
|
callers.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return callers;
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
std::vector<uint32> QtDebugger::FindWordValueRefs(CMIPS* context, uint32 targetValue, uint32 valueMask)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
std::vector<uint32> refs;
|
|
|
|
for(uint32 i = 0; i < FIND_MAX_ADDRESS; i += 4)
|
|
|
|
{
|
|
|
|
uint32 valueAtAddress = context->m_pMemoryMap->GetWord(i);
|
|
|
|
if((valueAtAddress & valueMask) == targetValue)
|
|
|
|
{
|
|
|
|
refs.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return refs;
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::OnFunctionsViewFunctionDblClick(uint32 address)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-19 22:20:32 +00:00
|
|
|
GetDisassemblyWindow()->SetAddress(address);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::OnFunctionsViewFunctionsStateChange()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-11 14:52:12 +00:00
|
|
|
GetDisassemblyWindow()->HandleMachineStateChange();
|
2019-12-10 01:40:28 +00:00
|
|
|
GetCallStackWindow()->HandleMachineStateChange();
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2022-09-06 19:40:46 -04:00
|
|
|
void QtDebugger::OnKernelObjectsViewAddressDblClick(uint32 address)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-19 22:20:32 +00:00
|
|
|
auto disAsm = GetDisassemblyWindow();
|
2019-12-11 14:52:12 +00:00
|
|
|
disAsm->SetCenterAtAddress(address);
|
|
|
|
disAsm->SetSelectedAddress(address);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::OnFindCallersRequested(uint32 address)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-10 00:45:46 +00:00
|
|
|
auto context = GetCurrentView()->GetContext();
|
|
|
|
auto callers = FindCallers(context, address);
|
|
|
|
auto title =
|
2019-08-31 12:33:24 -04:00
|
|
|
[&]() {
|
|
|
|
auto functionName = context->m_Functions.Find(address);
|
|
|
|
if(functionName)
|
|
|
|
{
|
2019-12-10 00:45:46 +00:00
|
|
|
return string_format("Find Callers For '%s' (0x%08X)",
|
|
|
|
functionName, address);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-12-10 00:45:46 +00:00
|
|
|
return string_format("Find Callers For 0x%08X", address);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
}();
|
2019-12-19 21:37:47 +00:00
|
|
|
|
2019-12-10 00:45:46 +00:00
|
|
|
m_addressListView->SetAddressList(std::move(callers));
|
|
|
|
m_addressListView->SetTitle(std::move(title));
|
|
|
|
m_addressListView->show();
|
2019-12-10 00:54:10 +00:00
|
|
|
m_addressListView->setFocus(Qt::ActiveWindowFocusReason);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::OnFindCallersAddressDblClick(uint32 address)
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-19 22:20:32 +00:00
|
|
|
auto disAsm = GetDisassemblyWindow();
|
2019-12-11 14:52:12 +00:00
|
|
|
disAsm->SetCenterAtAddress(address);
|
|
|
|
disAsm->SetSelectedAddress(address);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2020-02-06 12:33:19 +00:00
|
|
|
void QtDebugger::OnExecutableChangeMsg()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-21 18:36:40 +00:00
|
|
|
m_pELFView->SetELF(m_virtualMachine.m_ee->m_os->GetELF());
|
2019-08-31 12:33:24 -04:00
|
|
|
|
|
|
|
LoadDebugTags();
|
|
|
|
|
2019-12-11 14:52:12 +00:00
|
|
|
GetDisassemblyWindow()->HandleMachineStateChange();
|
2019-12-10 01:40:28 +00:00
|
|
|
GetCallStackWindow()->HandleMachineStateChange();
|
2019-12-10 12:31:00 +00:00
|
|
|
m_pFunctionsView->Refresh();
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2020-02-06 12:33:19 +00:00
|
|
|
void QtDebugger::OnExecutableUnloadingMsg()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
SaveDebugTags();
|
2019-12-21 18:36:40 +00:00
|
|
|
m_pELFView->SetELF(NULL);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2020-02-06 12:33:19 +00:00
|
|
|
void QtDebugger::OnMachineStateChangeMsg()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-10 01:11:56 +00:00
|
|
|
for(auto& view : m_pView)
|
|
|
|
{
|
|
|
|
view->HandleMachineStateChange();
|
|
|
|
}
|
2022-09-06 19:40:46 -04:00
|
|
|
m_kernelObjectListView->HandleMachineStateChange();
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2020-02-06 12:33:19 +00:00
|
|
|
void QtDebugger::OnRunningStateChangeMsg()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
2019-12-10 12:29:34 +00:00
|
|
|
auto newState = m_virtualMachine.GetStatus();
|
2019-12-10 01:11:56 +00:00
|
|
|
for(auto& view : m_pView)
|
|
|
|
{
|
|
|
|
view->HandleRunningStateChange(newState);
|
|
|
|
}
|
2022-09-06 19:40:46 -04:00
|
|
|
m_kernelObjectListView->HandleRunningStateChange(newState);
|
2019-08-31 12:33:24 -04:00
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::LoadDebugTags()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
#ifdef DEBUGGER_INCLUDED
|
|
|
|
m_virtualMachine.LoadDebugTags(m_virtualMachine.m_ee->m_os->GetExecutableName());
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2019-12-09 19:07:36 +00:00
|
|
|
void QtDebugger::SaveDebugTags()
|
2019-08-31 12:33:24 -04:00
|
|
|
{
|
|
|
|
#ifdef DEBUGGER_INCLUDED
|
2019-12-10 01:40:28 +00:00
|
|
|
if(m_virtualMachine.m_ee != nullptr)
|
|
|
|
{
|
|
|
|
if(m_virtualMachine.m_ee->m_os->GetELF() != nullptr)
|
|
|
|
{
|
|
|
|
m_virtualMachine.SaveDebugTags(m_virtualMachine.m_ee->m_os->GetExecutableName());
|
|
|
|
}
|
|
|
|
}
|
2019-08-31 12:33:24 -04:00
|
|
|
#endif
|
|
|
|
}
|
2019-12-09 19:50:02 +00:00
|
|
|
|
|
|
|
void QtDebugger::on_actionResume_triggered()
|
|
|
|
{
|
|
|
|
Resume();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionStep_CPU_triggered()
|
|
|
|
{
|
|
|
|
StepCPU();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionAssemble_JAL_triggered()
|
|
|
|
{
|
|
|
|
AssembleJAL();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionReanalyse_ee_triggered()
|
|
|
|
{
|
|
|
|
ReanalyzeEe();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionFind_Functions_triggered()
|
|
|
|
{
|
|
|
|
FindEeFunctions();
|
|
|
|
}
|
2019-12-09 20:21:08 +00:00
|
|
|
|
|
|
|
void QtDebugger::on_actionCascade_triggered()
|
|
|
|
{
|
|
|
|
ui->mdiArea->cascadeSubWindows();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionTile_triggered()
|
|
|
|
{
|
|
|
|
ui->mdiArea->tileSubWindows();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionLayout_1024x768_triggered()
|
|
|
|
{
|
2022-04-02 13:00:23 -04:00
|
|
|
Layout1024x768();
|
2019-12-09 20:21:08 +00:00
|
|
|
}
|
|
|
|
|
2022-04-02 13:01:42 -04:00
|
|
|
void QtDebugger::on_actionLayout_1280x800_triggered()
|
|
|
|
{
|
|
|
|
Layout1280x800();
|
|
|
|
}
|
|
|
|
|
2019-12-09 20:21:08 +00:00
|
|
|
void QtDebugger::on_actionLayout_1280x1024_triggered()
|
|
|
|
{
|
2022-04-02 13:00:23 -04:00
|
|
|
Layout1280x1024();
|
2019-12-09 20:21:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionLayout_1600x1200_triggered()
|
|
|
|
{
|
2022-04-02 13:00:23 -04:00
|
|
|
Layout1600x1200();
|
2019-12-09 20:21:08 +00:00
|
|
|
}
|
2019-12-10 00:10:44 +00:00
|
|
|
|
|
|
|
void QtDebugger::on_actionfind_word_value_triggered()
|
|
|
|
{
|
|
|
|
FindWordValue(~0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionFind_Word_Half_Value_triggered()
|
|
|
|
{
|
|
|
|
FindWordValue(0xFFFF);
|
|
|
|
}
|
2019-12-10 00:44:54 +00:00
|
|
|
|
|
|
|
void QtDebugger::on_actionCall_Stack_triggered()
|
|
|
|
{
|
2021-01-09 22:44:14 +00:00
|
|
|
GetCallStackWindow()->show();
|
2020-02-05 21:33:18 +00:00
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->show();
|
|
|
|
static_cast<QWidget*>(GetCallStackWindow()->parent())->setFocus(Qt::ActiveWindowFocusReason);
|
2019-12-10 00:44:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionFunctions_triggered()
|
|
|
|
{
|
|
|
|
m_pFunctionsView->show();
|
2019-12-10 00:54:10 +00:00
|
|
|
m_pFunctionsView->setFocus(Qt::ActiveWindowFocusReason);
|
2019-12-10 00:44:54 +00:00
|
|
|
}
|
|
|
|
|
2022-04-05 10:40:34 -04:00
|
|
|
void QtDebugger::on_actionELF_File_Information_triggered()
|
|
|
|
{
|
|
|
|
m_pELFView->show();
|
|
|
|
m_pELFView->setFocus(Qt::ActiveWindowFocusReason);
|
|
|
|
}
|
|
|
|
|
2022-09-06 19:40:46 -04:00
|
|
|
void QtDebugger::on_actionViewKernelObject_triggered()
|
|
|
|
{
|
|
|
|
QAction* source = static_cast<QAction*>(sender());
|
|
|
|
uint32 objectTypeId = source->data().toInt();
|
2022-09-08 19:17:13 -04:00
|
|
|
m_kernelObjectListView->SetObjectType(objectTypeId);
|
|
|
|
m_kernelObjectListView->show();
|
|
|
|
m_kernelObjectListViewWnd->show();
|
|
|
|
m_kernelObjectListViewWnd->setFocus(Qt::ActiveWindowFocusReason);
|
2019-12-10 00:44:54 +00:00
|
|
|
}
|
2019-12-10 01:11:56 +00:00
|
|
|
|
2019-12-12 01:44:55 +00:00
|
|
|
void QtDebugger::on_actionView_Disassmebly_triggered()
|
|
|
|
{
|
2021-01-09 22:44:14 +00:00
|
|
|
GetDisassemblyWindow()->show();
|
2020-02-05 21:35:11 +00:00
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->show();
|
|
|
|
static_cast<QWidget*>(GetDisassemblyWindow()->parent())->setFocus(Qt::ActiveWindowFocusReason);
|
2019-12-12 01:44:55 +00:00
|
|
|
}
|
|
|
|
|
2019-12-12 12:55:58 +00:00
|
|
|
void QtDebugger::on_actionView_Registers_triggered()
|
|
|
|
{
|
2021-01-09 22:44:14 +00:00
|
|
|
GetRegisterViewWindow()->show();
|
2020-02-05 21:47:31 +00:00
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->show();
|
|
|
|
static_cast<QWidget*>(GetRegisterViewWindow()->parent())->setFocus(Qt::ActiveWindowFocusReason);
|
2019-12-12 12:55:58 +00:00
|
|
|
}
|
|
|
|
|
2019-12-19 11:58:52 +00:00
|
|
|
void QtDebugger::on_actionMemory_triggered()
|
|
|
|
{
|
|
|
|
GetMemoryViewWindow()->show();
|
|
|
|
GetMemoryViewWindow()->setFocus(Qt::ActiveWindowFocusReason);
|
|
|
|
}
|
|
|
|
|
2019-12-10 01:11:56 +00:00
|
|
|
void QtDebugger::on_actionEmotionEngine_View_triggered()
|
|
|
|
{
|
|
|
|
ActivateView(DEBUGVIEW_EE);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionVector_Unit_0_triggered()
|
|
|
|
{
|
|
|
|
ActivateView(DEBUGVIEW_VU0);
|
|
|
|
}
|
|
|
|
|
2019-12-19 21:36:33 +00:00
|
|
|
void QtDebugger::on_actionVector_Unit_1_triggered()
|
2019-12-10 01:11:56 +00:00
|
|
|
{
|
|
|
|
ActivateView(DEBUGVIEW_VU1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void QtDebugger::on_actionIOP_View_triggered()
|
|
|
|
{
|
|
|
|
ActivateView(DEBUGVIEW_IOP);
|
|
|
|
}
|