From 5c8476b6b43ff0ec6b9b0a4fc3dcf296b7a8ce9a Mon Sep 17 00:00:00 2001 From: Duncan Ogilvie Date: Thu, 9 Jul 2020 16:07:41 +0200 Subject: [PATCH] GUI: refactor disassembleAt slot to make CPUDisassembly independent --- src/gui/Src/BasicView/Disassembly.cpp | 25 +++++++---------------- src/gui/Src/BasicView/Disassembly.h | 8 +++----- src/gui/Src/Gui/CPUArgumentWidget.cpp | 4 +++- src/gui/Src/Gui/CPUArgumentWidget.h | 2 +- src/gui/Src/Gui/CPUDisassembly.cpp | 29 +++++++++++++++------------ src/gui/Src/Gui/CPUDisassembly.h | 7 ++++--- src/gui/Src/Gui/CPUWidget.cpp | 3 ++- 7 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/gui/Src/BasicView/Disassembly.cpp b/src/gui/Src/BasicView/Disassembly.cpp index fc4445aa..9ed125cd 100644 --- a/src/gui/Src/BasicView/Disassembly.cpp +++ b/src/gui/Src/BasicView/Disassembly.cpp @@ -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* Disassembly::instructionsBuffer() @@ -1884,19 +1877,15 @@ QList* 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))); diff --git a/src/gui/Src/BasicView/Disassembly.h b/src/gui/Src/BasicView/Disassembly.h index 415a310d..3fcdd280 100644 --- a/src/gui/Src/BasicView/Disassembly.h +++ b/src/gui/Src/BasicView/Disassembly.h @@ -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* 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 & wRVAs, QList* 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 mInstBuffer; diff --git a/src/gui/Src/Gui/CPUArgumentWidget.cpp b/src/gui/Src/Gui/CPUArgumentWidget.cpp index 50c13c99..87842fd6 100644 --- a/src/gui/Src/Gui/CPUArgumentWidget.cpp +++ b/src/gui/Src/Gui/CPUArgumentWidget.cpp @@ -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); diff --git a/src/gui/Src/Gui/CPUArgumentWidget.h b/src/gui/Src/Gui/CPUArgumentWidget.h index 0097678e..246676b5 100644 --- a/src/gui/Src/Gui/CPUArgumentWidget.h +++ b/src/gui/Src/Gui/CPUArgumentWidget.h @@ -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: diff --git a/src/gui/Src/Gui/CPUDisassembly.cpp b/src/gui/Src/Gui/CPUDisassembly.cpp index 300642d6..ae3c0389 100644 --- a/src/gui/Src/Gui/CPUDisassembly.cpp +++ b/src/gui/Src/Gui/CPUDisassembly.cpp @@ -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); diff --git a/src/gui/Src/Gui/CPUDisassembly.h b/src/gui/Src/Gui/CPUDisassembly.h index ee444098..63e26999 100644 --- a/src/gui/Src/Gui/CPUDisassembly.h +++ b/src/gui/Src/Gui/CPUDisassembly.h @@ -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; diff --git a/src/gui/Src/Gui/CPUWidget.cpp b/src/gui/Src/Gui/CPUWidget.cpp index 510a1cfe..dfa6559b 100644 --- a/src/gui/Src/Gui/CPUWidget.cpp +++ b/src/gui/Src/Gui/CPUWidget.cpp @@ -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