1
0
Fork 0

GUI: refactor disassembleAt slot to make CPUDisassembly independent

This commit is contained in:
Duncan Ogilvie 2020-07-09 16:07:41 +02:00
parent 156b604c46
commit 5c8476b6b4
7 changed files with 36 additions and 42 deletions

View File

@ -18,8 +18,6 @@ Disassembly::Disassembly(QWidget* parent) : AbstractTableView(parent)
memset(&mSelection, 0, sizeof(SelectionData));
mCipRva = 0;
mHighlightToken.text = "";
mHighlightingMode = false;
mShowMnemonicBrief = false;
@ -222,7 +220,7 @@ QString Disassembly::paintContent(QPainter* painter, dsint rowBase, int rowOffse
QString addrText = getAddrText(cur_addr, label);
BPXTYPE bpxtype = DbgGetBpxTypeAt(cur_addr);
bool isbookmark = DbgGetBookmarkAt(cur_addr);
if(mInstBuffer.at(rowOffset).rva == mCipRva && !Bridge::getBridge()->mIsRunning && DbgMemFindBaseAddr(DbgValFromString("cip"), nullptr)) //cip + not running + valid cip
if(rvaToVa(mInstBuffer.at(rowOffset).rva) == mCipVa && !Bridge::getBridge()->mIsRunning && DbgMemFindBaseAddr(DbgValFromString("cip"), nullptr)) //cip + not running + valid cip
{
painter->fillRect(QRect(x, y, w, h), QBrush(mCipBackgroundColor));
if(!isbookmark) //no bookmark
@ -1755,7 +1753,7 @@ duint Disassembly::rvaToVa(dsint rva) const
return mMemPage->va(rva);
}
void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset)
void Disassembly::disassembleAt(dsint parVA, bool history, dsint newTableOffset)
{
duint wSize;
auto wBase = DbgMemFindBaseAddr(parVA, &wSize);
@ -1764,7 +1762,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
if(!wBase || !wSize || !DbgMemRead(parVA, &test, sizeof(test)))
return;
dsint wRVA = parVA - wBase;
dsint wCipRva = parCIP - wBase;
HistoryData newHistory;
@ -1802,9 +1799,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
dsint wInstrSize = getInstructionRVA(wRVA, 1) - wRVA - 1;
expandSelectionUpTo(wRVA + wInstrSize);
//set CIP rva
mCipRva = wCipRva;
if(newTableOffset == -1) //nothing specified
{
// Update table offset depending on the location of the instruction to disassemble
@ -1876,7 +1870,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
MessageBoxA(GuiGetWindowHandle(), strList.toUtf8().constData(), QString().sprintf("mCurrentVa=%d", mCurrentVa).toUtf8().constData(), MB_ICONINFORMATION);
}
*/
emit disassembledAt(parVA, parCIP, history, newTableOffset);
}
QList<Instruction_t>* Disassembly::instructionsBuffer()
@ -1884,19 +1877,15 @@ QList<Instruction_t>* Disassembly::instructionsBuffer()
return &mInstBuffer;
}
const dsint Disassembly::currentEIP() const
{
return mCipRva;
}
void Disassembly::disassembleAt(dsint parVA, dsint parCIP)
void Disassembly::disassembleAtSlot(dsint parVA, dsint parCIP)
{
if(mCodeFoldingManager)
{
mCodeFoldingManager->expandFoldSegment(parVA);
mCodeFoldingManager->expandFoldSegment(parCIP);
}
disassembleAt(parVA, parCIP, true, -1);
mCipVa = parCIP; // TODO: emit a signal for this?
disassembleAt(parVA, true, -1);
}
void Disassembly::disassembleClear()
@ -1952,7 +1941,7 @@ void Disassembly::historyPrevious()
dsint va = mVaHistory.at(mCurrentVa).va;
if(mCodeFoldingManager && mCodeFoldingManager->isFolded(va))
mCodeFoldingManager->expandFoldSegment(va);
disassembleAt(va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
disassembleAt(va, false, mVaHistory.at(mCurrentVa).tableOffset);
// Update window title
DbgCmdExecDirect(QString("guiupdatetitle %1").arg(ToPtrString(va)));
@ -1967,7 +1956,7 @@ void Disassembly::historyNext()
dsint va = mVaHistory.at(mCurrentVa).va;
if(mCodeFoldingManager && mCodeFoldingManager->isFolded(va))
mCodeFoldingManager->expandFoldSegment(va);
disassembleAt(va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
disassembleAt(va, false, mVaHistory.at(mCurrentVa).tableOffset);
// Update window title
DbgCmdExecDirect(QString("guiupdatetitle %1").arg(ToPtrString(va)));

View File

@ -88,11 +88,10 @@ public:
bool historyHasNext() const;
//disassemble
void disassembleAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset);
void disassembleAt(dsint parVA, bool history, dsint newTableOffset);
QList<Instruction_t>* instructionsBuffer(); // ugly
const dsint baseAddress() const;
const dsint currentEIP() const;
QString getAddrText(dsint cur_addr, char label[MAX_LABEL_SIZE], bool getLabel = true);
void prepareDataCount(const QList<dsint> & wRVAs, QList<Instruction_t>* instBuffer);
@ -109,11 +108,10 @@ public:
signals:
void selectionChanged(dsint parVA);
void selectionExpanded();
void disassembledAt(dsint parVA, dsint parCIP, bool history, dsint newTableOffset);
void updateWindowTitle(QString title);
public slots:
void disassembleAt(dsint parVA, dsint parCIP);
void disassembleAtSlot(dsint parVA, dsint parCIP);
void debugStateChangedSlot(DBGSTATE state);
void selectionChangedSlot(dsint parVA);
void tokenizerConfigUpdatedSlot();
@ -158,7 +156,7 @@ private:
GuiState mGuiState;
dsint mCipRva;
duint mCipVa = 0;
QList<Instruction_t> mInstBuffer;

View File

@ -32,6 +32,7 @@ CPUArgumentWidget::CPUArgumentWidget(QWidget* parent) :
connect(mFollowAddrStack, SIGNAL(triggered()), this, SLOT(followStackSlot()));
connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(refreshData()));
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint)));
}
CPUArgumentWidget::~CPUArgumentWidget()
@ -45,8 +46,9 @@ void CPUArgumentWidget::updateStackOffset(bool iscall)
mStackOffset = cur.getStackOffset() + (iscall ? 0 : cur.getCallOffset());
}
void CPUArgumentWidget::disassembledAtSlot(dsint, dsint cip, bool, dsint)
void CPUArgumentWidget::disassembleAtSlot(dsint addr, dsint cip)
{
Q_UNUSED(addr);
if(mCurrentCallingConvention == -1) //no calling conventions
{
mTable->setRowCount(0);

View File

@ -41,7 +41,7 @@ public:
}
public slots:
void disassembledAtSlot(dsint addr, dsint cip, bool history, dsint newTableOffset);
void disassembleAtSlot(dsint addr, dsint cip);
void refreshData();
private slots:

View File

@ -26,24 +26,27 @@
#include "BreakpointMenu.h"
#include "BrowseDialog.h"
CPUDisassembly::CPUDisassembly(CPUWidget* parent) : Disassembly(parent)
CPUDisassembly::CPUDisassembly(QWidget* parent) : Disassembly(parent)
{
setWindowTitle("Disassembly");
// Set specific widget handles
mParentCPUWindow = parent;
// Create the action list for the right click context menu
setupRightClickContextMenu();
// TODO: refactor these signals out of the class (move to CPUWidget + CPUMultiDump)
// TODO: refactor all DbgCmdExec("disasm ...") commands (customization point)
// TODO: refactor mPluginMenu to be a singleton (so plugin menus show up in all instances)
// Connect bridge<->disasm calls
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAt(dsint, dsint)));
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint)));
connect(Bridge::getBridge(), SIGNAL(selectionDisasmGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
connect(Bridge::getBridge(), SIGNAL(selectionDisasmSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
connect(this, SIGNAL(selectionExpanded()), this, SLOT(selectionUpdatedSlot()));
connect(Bridge::getBridge(), SIGNAL(displayWarning(QString, QString)), this, SLOT(displayWarningSlot(QString, QString)));
connect(Bridge::getBridge(), SIGNAL(focusDisasm()), this, SLOT(setFocus()));
// Connect some internal signals
connect(this, SIGNAL(selectionExpanded()), this, SLOT(selectionUpdatedSlot()));
Initialize();
}
@ -674,9 +677,6 @@ void CPUDisassembly::gotoOriginSlot()
DbgCmdExec("disasm cip");
}
void CPUDisassembly::setNewOriginHereActionSlot()
{
if(!DbgIsDebugging())
@ -1492,6 +1492,11 @@ void CPUDisassembly::copySelectionToFileSlot(bool copyBytes)
}
}
void CPUDisassembly::setSideBar(CPUSideBar* sideBar)
{
mSideBar = sideBar;
}
void CPUDisassembly::pushSelectionInto(bool copyBytes, QTextStream & stream, QTextStream* htmlStream)
{
const int addressLen = getColumnWidth(0) / getCharWidth() - 1;
@ -1774,10 +1779,8 @@ void CPUDisassembly::paintEvent(QPaintEvent* event)
{
// Hook/hack to update the sidebar at the same time as this widget.
// Ensures the two widgets are synced and prevents "draw lag"
auto sidebar = mParentCPUWindow->getSidebarWidget();
if(sidebar)
sidebar->reload();
if(mSideBar)
mSideBar->reload();
// Signal to render the original content
Disassembly::paintEvent(event);

View File

@ -5,7 +5,7 @@
#include "BreakpointMenu.h"
// Needed forward declaration for parent container class
class CPUWidget;
class CPUSideBar;
class GotoDialog;
class XrefBrowseDialog;
@ -14,7 +14,7 @@ class CPUDisassembly : public Disassembly
Q_OBJECT
public:
explicit CPUDisassembly(CPUWidget* parent);
explicit CPUDisassembly(QWidget* parent);
// Mouse management
void contextMenuEvent(QContextMenuEvent* event);
@ -27,6 +27,7 @@ public:
void setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isReferences, bool isFollowInCPU);
void copySelectionSlot(bool copyBytes);
void copySelectionToFileSlot(bool copyBytes);
void setSideBar(CPUSideBar* sideBar);
signals:
void displayReferencesWidget();
@ -164,7 +165,7 @@ private:
XrefBrowseDialog* mXrefDlg = nullptr;
// Parent CPU window
CPUWidget* mParentCPUWindow;
CPUSideBar* mSideBar = nullptr;
MenuBuilder* mMenuBuilder;
MenuBuilder* mHighlightMenuBuilder;

View File

@ -20,14 +20,15 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
mDisas = new CPUDisassembly(this);
mSideBar = new CPUSideBar(mDisas);
mDisas->setSideBar(mSideBar);
mArgumentWidget = new CPUArgumentWidget(this);
connect(mDisas, SIGNAL(tableOffsetChanged(dsint)), mSideBar, SLOT(changeTopmostAddress(dsint)));
connect(mDisas, SIGNAL(viewableRowsChanged(int)), mSideBar, SLOT(setViewableRows(int)));
connect(mDisas, SIGNAL(selectionChanged(dsint)), mSideBar, SLOT(setSelection(dsint)));
connect(mDisas, SIGNAL(disassembledAt(dsint, dsint, bool, dsint)), mArgumentWidget, SLOT(disassembledAtSlot(dsint, dsint, bool, dsint)));
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), mSideBar, SLOT(debugStateChangedSlot(DBGSTATE)));
connect(Bridge::getBridge(), SIGNAL(updateSideBar()), mSideBar, SLOT(reload()));
connect(Bridge::getBridge(), SIGNAL(updateArgumentView()), mArgumentWidget, SLOT(refreshData()));
mDisas->setCodeFoldingManager(mSideBar->getCodeFoldingManager());
ui->mTopLeftUpperHSplitter->setCollapsible(0, true); //allow collapsing of the side bar