GUI: better history in CPUDump + history in CPUStack
This commit is contained in:
parent
7d9881a7b1
commit
53bc89f515
|
@ -1352,11 +1352,6 @@ void Disassembly::disassembleAt(dsint parVA, dsint parCIP, bool history, dsint n
|
|||
dsint selectionTableOffset = getTableOffset();
|
||||
if(selectionVA && mVaHistory.size() && mVaHistory.last().va != selectionVA) //do not have 2x the same va in a row
|
||||
{
|
||||
if(mVaHistory.size() >= 1024) //max 1024 in the history
|
||||
{
|
||||
mCurrentVa--;
|
||||
mVaHistory.erase(mVaHistory.begin()); //remove the oldest element
|
||||
}
|
||||
mCurrentVa++;
|
||||
newHistory.va = selectionVA;
|
||||
newHistory.tableOffset = selectionTableOffset;
|
||||
|
@ -1467,13 +1462,12 @@ const dsint Disassembly::currentEIP() const
|
|||
return mCipRva;
|
||||
}
|
||||
|
||||
|
||||
void Disassembly::disassembleAt(dsint parVA, dsint parCIP)
|
||||
{
|
||||
setFocus();
|
||||
disassembleAt(parVA, parCIP, true, -1);
|
||||
}
|
||||
|
||||
|
||||
void Disassembly::disassembleClear()
|
||||
{
|
||||
mHighlightingMode = false;
|
||||
|
@ -1484,7 +1478,6 @@ void Disassembly::disassembleClear()
|
|||
reloadData();
|
||||
}
|
||||
|
||||
|
||||
void Disassembly::debugStateChangedSlot(DBGSTATE state)
|
||||
{
|
||||
switch(state)
|
||||
|
@ -1527,7 +1520,7 @@ void Disassembly::historyClear()
|
|||
|
||||
void Disassembly::historyPrevious()
|
||||
{
|
||||
if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry
|
||||
if(!historyHasPrevious())
|
||||
return;
|
||||
mCurrentVa--;
|
||||
disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
|
||||
|
@ -1538,8 +1531,7 @@ void Disassembly::historyPrevious()
|
|||
|
||||
void Disassembly::historyNext()
|
||||
{
|
||||
int size = mVaHistory.size();
|
||||
if(!size || mCurrentVa >= mVaHistory.size() - 1) //we are at the newest history entry
|
||||
if(!historyHasNext())
|
||||
return;
|
||||
mCurrentVa++;
|
||||
disassembleAt(mVaHistory.at(mCurrentVa).va, rvaToVa(mCipRva), false, mVaHistory.at(mCurrentVa).tableOffset);
|
||||
|
|
|
@ -26,6 +26,8 @@ HexDump::HexDump(QWidget* parent)
|
|||
mRvaDisplayEnabled = false;
|
||||
mSyncAddrExpression = "";
|
||||
|
||||
historyClear();
|
||||
|
||||
// Slots
|
||||
connect(Bridge::getBridge(), SIGNAL(updateDump()), this, SLOT(updateDumpSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChanged(DBGSTATE)));
|
||||
|
@ -124,6 +126,57 @@ duint HexDump::getTableOffsetRva()
|
|||
return getTableOffset() * getBytePerRowCount() - mByteOffset;
|
||||
}
|
||||
|
||||
void HexDump::addVaToHistory(dsint parVa)
|
||||
{
|
||||
//truncate everything right from the current VA
|
||||
if(mVaHistory.size() && mCurrentVa < mVaHistory.size() - 1) //mCurrentVa is not the last
|
||||
mVaHistory.erase(mVaHistory.begin() + mCurrentVa + 1, mVaHistory.end());
|
||||
|
||||
//do not have 2x the same va in a row
|
||||
if(!mVaHistory.size() || mVaHistory.last() != parVa)
|
||||
{
|
||||
mCurrentVa++;
|
||||
mVaHistory.push_back(parVa);
|
||||
}
|
||||
}
|
||||
|
||||
bool HexDump::historyHasPrev()
|
||||
{
|
||||
if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexDump::historyHasNext()
|
||||
{
|
||||
int size = mVaHistory.size();
|
||||
if(!size || mCurrentVa >= mVaHistory.size() - 1) //we are at the newest history entry
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HexDump::historyPrev()
|
||||
{
|
||||
if(!historyHasPrev())
|
||||
return;
|
||||
mCurrentVa--;
|
||||
printDumpAt(mVaHistory.at(mCurrentVa));
|
||||
}
|
||||
|
||||
void HexDump::historyNext()
|
||||
{
|
||||
if(!historyHasNext())
|
||||
return;
|
||||
mCurrentVa++;
|
||||
printDumpAt(mVaHistory.at(mCurrentVa));
|
||||
}
|
||||
|
||||
void HexDump::historyClear()
|
||||
{
|
||||
mCurrentVa = -1;
|
||||
mVaHistory.clear();
|
||||
}
|
||||
|
||||
void HexDump::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
bool wAccept = true;
|
||||
|
|
|
@ -135,6 +135,13 @@ public:
|
|||
duint rvaToVa(dsint rva);
|
||||
duint getTableOffsetRva();
|
||||
|
||||
void addVaToHistory(dsint parVa);
|
||||
bool historyHasPrev();
|
||||
bool historyHasNext();
|
||||
void historyPrev();
|
||||
void historyNext();
|
||||
void historyClear();
|
||||
|
||||
signals:
|
||||
void selectionUpdated();
|
||||
|
||||
|
@ -157,6 +164,9 @@ private:
|
|||
|
||||
GuiState_t mGuiState;
|
||||
|
||||
QList<dsint> mVaHistory;
|
||||
int mCurrentVa;
|
||||
|
||||
protected:
|
||||
MemoryPage* mMemPage;
|
||||
int mByteOffset;
|
||||
|
|
|
@ -28,6 +28,7 @@ CPUDisassembly::CPUDisassembly(CPUWidget* parent) : Disassembly(parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(selectionDisasmGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionDisasmSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(displayWarning(QString, QString)), this, SLOT(displayWarningSlot(QString, QString)));
|
||||
connect(Bridge::getBridge(), SIGNAL(focusDisasm()), this, SLOT(setFocus()));
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
@ -384,11 +385,11 @@ void CPUDisassembly::setupRightClickContextMenu()
|
|||
|
||||
MenuBuilder* gotoMenu = new MenuBuilder(this);
|
||||
gotoMenu->addAction(makeShortcutAction(tr("Origin"), SLOT(gotoOriginSlot()), "ActionGotoOrigin"));
|
||||
gotoMenu->addAction(makeShortcutAction(tr("Previous"), SLOT(gotoPreviousSlot()), "ActionGotoPrevious"), [this](QMenu*)
|
||||
gotoMenu->addAction(makeShortcutAction(QIcon(":/icons/images/previous.png"), tr("Previous"), SLOT(gotoPreviousSlot()), "ActionGotoPrevious"), [this](QMenu*)
|
||||
{
|
||||
return historyHasPrevious();
|
||||
});
|
||||
gotoMenu->addAction(makeShortcutAction(tr("Next"), SLOT(gotoNextSlot()), "ActionGotoNext"), [this](QMenu*)
|
||||
gotoMenu->addAction(makeShortcutAction(QIcon(":/icons/images/next.png"), tr("Next"), SLOT(gotoNextSlot()), "ActionGotoNext"), [this](QMenu*)
|
||||
{
|
||||
return historyHasNext();
|
||||
});
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
CPUDump::CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent) : HexDump(parent)
|
||||
{
|
||||
mDisas = disas;
|
||||
mCurrentVa = 0;
|
||||
mMultiDump = multiDump;
|
||||
|
||||
switch((ViewEnum_t)ConfigUint("HexDump", "DefaultView"))
|
||||
|
@ -331,20 +330,6 @@ void CPUDump::setupContextMenu()
|
|||
connect(mGotoFileOffset, SIGNAL(triggered()), this, SLOT(gotoFileOffsetSlot()));
|
||||
mGotoMenu->addAction(mGotoFileOffset);
|
||||
|
||||
// Goto->Previous
|
||||
mGotoPrevious = new QAction(tr("Previous"), this);
|
||||
mGotoPrevious->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mGotoPrevious);
|
||||
connect(mGotoPrevious, SIGNAL(triggered()), this, SLOT(gotoPrevSlot()));
|
||||
mGotoMenu->addAction(mGotoPrevious);
|
||||
|
||||
// Goto->Next
|
||||
mGotoNext = new QAction(tr("Next"), this);
|
||||
mGotoNext->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mGotoNext);
|
||||
connect(mGotoNext, SIGNAL(triggered()), this, SLOT(gotoNextSlot()));
|
||||
mGotoMenu->addAction(mGotoNext);
|
||||
|
||||
// Goto->Start of page
|
||||
mGotoStart = new QAction(tr("Start of Page"), this);
|
||||
mGotoStart->setShortcutContext(Qt::WidgetShortcut);
|
||||
|
@ -359,6 +344,20 @@ void CPUDump::setupContextMenu()
|
|||
connect(mGotoEnd, SIGNAL(triggered()), this, SLOT(gotoEndSlot()));
|
||||
mGotoMenu->addAction(mGotoEnd);
|
||||
|
||||
// Goto->Previous
|
||||
mGotoPrevious = new QAction(QIcon(":/icons/images/previous.png"), tr("Previous"), this);
|
||||
mGotoPrevious->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mGotoPrevious);
|
||||
connect(mGotoPrevious, SIGNAL(triggered()), this, SLOT(gotoPrevSlot()));
|
||||
mGotoMenu->addAction(mGotoPrevious);
|
||||
|
||||
// Goto->Next
|
||||
mGotoNext = new QAction(QIcon(":/icons/images/next.png"), tr("Next"), this);
|
||||
mGotoNext->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mGotoNext);
|
||||
connect(mGotoNext, SIGNAL(triggered()), this, SLOT(gotoNextSlot()));
|
||||
mGotoMenu->addAction(mGotoNext);
|
||||
|
||||
//Hex menu
|
||||
mHexMenu = new QMenu(tr("&Hex"), this);
|
||||
mHexMenu->setIcon(QIcon(":/icons/images/hex.png"));
|
||||
|
@ -614,15 +613,14 @@ void CPUDump::contextMenuEvent(QContextMenuEvent* event)
|
|||
wMenu->addMenu(mFollowInDumpMenu);
|
||||
}
|
||||
|
||||
mGotoMenu->removeAction(mGotoPrevious);
|
||||
mGotoMenu->removeAction(mGotoNext);
|
||||
|
||||
if(historyHasPrev())
|
||||
mGotoPrevious->setVisible(true);
|
||||
else
|
||||
mGotoPrevious->setVisible(false);
|
||||
mGotoMenu->addAction(mGotoPrevious);
|
||||
|
||||
if(historyHasNext())
|
||||
mGotoNext->setVisible(true);
|
||||
else
|
||||
mGotoNext->setVisible(false);
|
||||
mGotoMenu->addAction(mGotoNext);
|
||||
|
||||
wMenu->addAction(mSetLabelAction);
|
||||
if(getSizeOf(mDescriptor.at(0).data.itemSize) <= sizeof(duint))
|
||||
|
@ -761,57 +759,6 @@ void CPUDump::mouseMoveEvent(QMouseEvent* event)
|
|||
HexDump::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void CPUDump::addVaToHistory(dsint parVa)
|
||||
{
|
||||
mVaHistory.push_back(parVa);
|
||||
if(mVaHistory.size() > 1)
|
||||
mCurrentVa++;
|
||||
}
|
||||
|
||||
bool CPUDump::historyHasPrev()
|
||||
{
|
||||
if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPUDump::historyHasNext()
|
||||
{
|
||||
int size = mVaHistory.size();
|
||||
if(!size || mCurrentVa >= mVaHistory.size() - 1) //we are at the newest history entry
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPUDump::historyPrev()
|
||||
{
|
||||
if(!historyHasPrev())
|
||||
return;
|
||||
|
||||
if(!mCurrentVa || !mVaHistory.size()) //we are at the earliest history entry
|
||||
return;
|
||||
mCurrentVa--;
|
||||
printDumpAt(mVaHistory.at(mCurrentVa));
|
||||
}
|
||||
|
||||
void CPUDump::historyNext()
|
||||
{
|
||||
if(!historyHasNext())
|
||||
return;
|
||||
|
||||
int size = mVaHistory.size();
|
||||
if(!size || mCurrentVa >= mVaHistory.size() - 1) //we are at the newest history entry
|
||||
return;
|
||||
mCurrentVa++;
|
||||
printDumpAt(mVaHistory.at(mCurrentVa));
|
||||
}
|
||||
|
||||
void CPUDump::historyClear()
|
||||
{
|
||||
mCurrentVa = 0;
|
||||
mVaHistory.clear();
|
||||
}
|
||||
|
||||
void CPUDump::setLabelSlot()
|
||||
{
|
||||
if(!DbgIsDebugging())
|
||||
|
@ -1740,11 +1687,13 @@ void CPUDump::followInDumpNSlot()
|
|||
|
||||
void CPUDump::gotoNextSlot()
|
||||
{
|
||||
DbgCmdExec(QString("log \"next\"").toUtf8().constData());
|
||||
historyNext();
|
||||
}
|
||||
|
||||
void CPUDump::gotoPrevSlot()
|
||||
{
|
||||
DbgCmdExec(QString("log \"previous\"").toUtf8().constData());
|
||||
historyPrev();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,12 +18,6 @@ public:
|
|||
void contextMenuEvent(QContextMenuEvent* event);
|
||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
void mouseMoveEvent(QMouseEvent* event);
|
||||
void addVaToHistory(dsint parVa);
|
||||
bool historyHasPrev();
|
||||
bool historyHasNext();
|
||||
void historyPrev();
|
||||
void historyNext();
|
||||
void historyClear();
|
||||
|
||||
signals:
|
||||
void displayReferencesWidget();
|
||||
|
@ -215,9 +209,6 @@ private:
|
|||
CPUDisassembly* mDisas;
|
||||
CPUMultiDump* mMultiDump;
|
||||
|
||||
QList<dsint> mVaHistory;
|
||||
int mCurrentVa;
|
||||
|
||||
enum ViewEnum_t
|
||||
{
|
||||
ViewHexAscii = 0,
|
||||
|
|
|
@ -28,6 +28,7 @@ CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* pa
|
|||
connect(Bridge::getBridge(), SIGNAL(selectionDumpGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionDumpSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChangedSlot(DBGSTATE)));
|
||||
connect(Bridge::getBridge(), SIGNAL(focusDump()), this, SLOT(focusCurrentDumpSlot()));
|
||||
|
||||
connect(mCurrentCPUDump, SIGNAL(selectionUpdated()), mCurrentCPUDump, SLOT(selectionUpdatedSlot()));
|
||||
}
|
||||
|
@ -96,6 +97,7 @@ void CPUMultiDump::printDumpAtSlot(dsint parVa)
|
|||
{
|
||||
mCurrentCPUDump->printDumpAt(parVa);
|
||||
mCurrentCPUDump->addVaToHistory(parVa);
|
||||
mCurrentCPUDump->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,3 +145,8 @@ void CPUMultiDump::displayReferencesWidgetSlot()
|
|||
{
|
||||
emit displayReferencesWidget();
|
||||
}
|
||||
|
||||
void CPUMultiDump::focusCurrentDumpSlot()
|
||||
{
|
||||
mCurrentCPUDump->setFocus();
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ public slots:
|
|||
void dbgStateChangedSlot(DBGSTATE dbgState);
|
||||
void openChangeTabTitleDialogSlot(int tabIndex);
|
||||
void displayReferencesWidgetSlot();
|
||||
void focusCurrentDumpSlot();
|
||||
|
||||
private:
|
||||
CPUDump* mCurrentCPUDump;
|
||||
|
|
|
@ -47,6 +47,7 @@ CPUStack::CPUStack(CPUMultiDump* multiDump, QWidget* parent) : HexDump(parent)
|
|||
connect(Bridge::getBridge(), SIGNAL(selectionStackGet(SELECTIONDATA*)), this, SLOT(selectionGet(SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(selectionStackSet(const SELECTIONDATA*)), this, SLOT(selectionSet(const SELECTIONDATA*)));
|
||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChangedSlot(DBGSTATE)));
|
||||
connect(Bridge::getBridge(), SIGNAL(focusStack()), this, SLOT(setFocus()));
|
||||
|
||||
Initialize();
|
||||
}
|
||||
|
@ -218,12 +219,24 @@ void CPUStack::setupContextMenu()
|
|||
this->addAction(mFindPatternAction);
|
||||
connect(mFindPatternAction, SIGNAL(triggered()), this, SLOT(findPattern()));
|
||||
|
||||
//Expression
|
||||
//Go to Expression
|
||||
mGotoExpression = new QAction(QIcon(":/icons/images/goto.png"), tr("Go to &Expression"), this);
|
||||
mGotoExpression->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mGotoExpression);
|
||||
connect(mGotoExpression, SIGNAL(triggered()), this, SLOT(gotoExpressionSlot()));
|
||||
|
||||
//Go to Previous
|
||||
mGotoPrevious = new QAction(QIcon(":/icons/images/previous.png"), tr("Go to Previous"), this);
|
||||
mGotoPrevious->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mGotoPrevious);
|
||||
connect(mGotoPrevious, SIGNAL(triggered(bool)), this, SLOT(gotoPreviousSlot()));
|
||||
|
||||
//Go to Next
|
||||
mGotoNext = new QAction(QIcon(":/icons/images/next.png"), tr("Go to Next"), this);
|
||||
mGotoNext->setShortcutContext(Qt::WidgetShortcut);
|
||||
this->addAction(mGotoNext);
|
||||
connect(mGotoNext, SIGNAL(triggered(bool)), this, SLOT(gotoNextSlot()));
|
||||
|
||||
//Follow in Disassembler
|
||||
auto disasmIcon = QIcon(QString(":/icons/images/") + ArchValue("processor32.png", "processor64.png"));
|
||||
mFollowDisasm = new QAction(disasmIcon, tr("&Follow in Disassembler"), this);
|
||||
|
@ -292,6 +305,8 @@ void CPUStack::refreshShortcutsSlot()
|
|||
mGotoSp->setShortcut(ConfigShortcut("ActionGotoOrigin"));
|
||||
mFindPatternAction->setShortcut(ConfigShortcut("ActionFindPattern"));
|
||||
mGotoExpression->setShortcut(ConfigShortcut("ActionGotoExpression"));
|
||||
mGotoPrevious->setShortcut(ConfigShortcut("ActionGotoPrevious"));
|
||||
mGotoNext->setShortcut(ConfigShortcut("ActionGotoNext"));
|
||||
}
|
||||
|
||||
QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
||||
|
@ -454,6 +469,10 @@ void CPUStack::contextMenuEvent(QContextMenuEvent* event)
|
|||
wMenu->addAction(mGotoBp);
|
||||
wMenu->addAction(mFreezeStack);
|
||||
wMenu->addAction(mGotoExpression);
|
||||
if(historyHasPrev())
|
||||
wMenu->addAction(mGotoPrevious);
|
||||
if(historyHasNext())
|
||||
wMenu->addAction(mGotoNext);
|
||||
|
||||
duint selectedData;
|
||||
if(mMemPage->read((byte_t*)&selectedData, getInitialSelection(), sizeof(duint)))
|
||||
|
@ -535,6 +554,8 @@ void CPUStack::mouseDoubleClickEvent(QMouseEvent* event)
|
|||
|
||||
void CPUStack::stackDumpAt(duint addr, duint csp)
|
||||
{
|
||||
setFocus();
|
||||
addVaToHistory(addr);
|
||||
mCsp = csp;
|
||||
printDumpAt(addr);
|
||||
}
|
||||
|
@ -573,6 +594,16 @@ void CPUStack::gotoExpressionSlot()
|
|||
}
|
||||
}
|
||||
|
||||
void CPUStack::gotoPreviousSlot()
|
||||
{
|
||||
historyPrev();
|
||||
}
|
||||
|
||||
void CPUStack::gotoNextSlot()
|
||||
{
|
||||
historyNext();
|
||||
}
|
||||
|
||||
void CPUStack::selectionGet(SELECTIONDATA* selection)
|
||||
{
|
||||
selection->start = rvaToVa(getSelectionStart());
|
||||
|
|
|
@ -32,6 +32,8 @@ public slots:
|
|||
void gotoSpSlot();
|
||||
void gotoBpSlot();
|
||||
void gotoExpressionSlot();
|
||||
void gotoPreviousSlot();
|
||||
void gotoNextSlot();
|
||||
void selectionGet(SELECTIONDATA* selection);
|
||||
void selectionSet(const SELECTIONDATA* selection);
|
||||
void selectionUpdatedSlot();
|
||||
|
@ -103,6 +105,8 @@ private:
|
|||
QAction* mGotoBp;
|
||||
QAction* mFreezeStack;
|
||||
QAction* mGotoExpression;
|
||||
QAction* mGotoPrevious;
|
||||
QAction* mGotoNext;
|
||||
QAction* mFindPatternAction;
|
||||
QAction* mFollowDisasm;
|
||||
QAction* mFollowDump;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 485 B |
Binary file not shown.
After Width: | Height: | Size: 479 B |
|
@ -87,5 +87,7 @@
|
|||
<file>images/modify.png</file>
|
||||
<file>images/freeze.png</file>
|
||||
<file>images/cbp.png</file>
|
||||
<file>images/next.png</file>
|
||||
<file>images/previous.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Loading…
Reference in New Issue