mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-18 10:56:11 +00:00
Keep topOffset history in disassembly widget. (#3171)
This commit adds support for a `topOffset` history (on top of the rizin-managed history), that keeps track of the offset of the top instruction in the disassembly widget. closes #2970
This commit is contained in:
parent
b63ea5b3e4
commit
beec78b4e2
@ -13,18 +13,18 @@ CutterSeekable::~CutterSeekable() {}
|
||||
void CutterSeekable::setSynchronization(bool sync)
|
||||
{
|
||||
synchronized = sync;
|
||||
onCoreSeekChanged(Core()->getOffset());
|
||||
onCoreSeekChanged(Core()->getOffset(), CutterCore::SeekHistoryType::New);
|
||||
emit syncChanged();
|
||||
}
|
||||
|
||||
void CutterSeekable::onCoreSeekChanged(RVA addr)
|
||||
void CutterSeekable::onCoreSeekChanged(RVA addr, CutterCore::SeekHistoryType type)
|
||||
{
|
||||
if (synchronized && widgetOffset != addr) {
|
||||
updateSeek(addr, true);
|
||||
updateSeek(addr, type, true);
|
||||
}
|
||||
}
|
||||
|
||||
void CutterSeekable::updateSeek(RVA addr, bool localOnly)
|
||||
void CutterSeekable::updateSeek(RVA addr, CutterCore::SeekHistoryType type, bool localOnly)
|
||||
{
|
||||
previousOffset = widgetOffset;
|
||||
widgetOffset = addr;
|
||||
@ -32,7 +32,7 @@ void CutterSeekable::updateSeek(RVA addr, bool localOnly)
|
||||
Core()->seek(addr);
|
||||
}
|
||||
|
||||
emit seekableSeekChanged(addr);
|
||||
emit seekableSeekChanged(addr, type);
|
||||
}
|
||||
|
||||
void CutterSeekable::seekPrev()
|
||||
@ -40,7 +40,7 @@ void CutterSeekable::seekPrev()
|
||||
if (synchronized) {
|
||||
Core()->seekPrev();
|
||||
} else {
|
||||
this->seek(previousOffset);
|
||||
this->seek(previousOffset, CutterCore::SeekHistoryType::Undo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,12 @@ public:
|
||||
* signal will be emitted.
|
||||
* In any case, CutterSeekable::seekableSeekChanged is emitted.
|
||||
* @param addr the location to seek at.
|
||||
* @param type the type of seek wrt history (Undo, Redo, or New)
|
||||
*/
|
||||
void seek(RVA addr) { updateSeek(addr, false); }
|
||||
void seek(RVA addr, CutterCore::SeekHistoryType type = CutterCore::SeekHistoryType::New)
|
||||
{
|
||||
updateSeek(addr, type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setSynchronization sets
|
||||
@ -67,7 +71,7 @@ private slots:
|
||||
/**
|
||||
* @brief onCoreSeekChanged
|
||||
*/
|
||||
void onCoreSeekChanged(RVA addr);
|
||||
void onCoreSeekChanged(RVA addr, CutterCore::SeekHistoryType type);
|
||||
|
||||
private:
|
||||
/**
|
||||
@ -91,9 +95,9 @@ private:
|
||||
* @brief internal method for changing the seek
|
||||
* @param localOnly whether the seek should be updated globally if synchronized
|
||||
*/
|
||||
void updateSeek(RVA addr, bool localOnly);
|
||||
void updateSeek(RVA addr, CutterCore::SeekHistoryType type, bool localOnly);
|
||||
|
||||
signals:
|
||||
void seekableSeekChanged(RVA addr);
|
||||
void seekableSeekChanged(RVA addr, CutterCore::SeekHistoryType type);
|
||||
void syncChanged();
|
||||
};
|
||||
|
@ -1002,19 +1002,19 @@ void CutterCore::seekPrev()
|
||||
{
|
||||
CORE_LOCK();
|
||||
rz_core_seek_undo(core);
|
||||
updateSeek();
|
||||
updateSeek(SeekHistoryType::Undo);
|
||||
}
|
||||
|
||||
void CutterCore::seekNext()
|
||||
{
|
||||
CORE_LOCK();
|
||||
rz_core_seek_redo(core);
|
||||
updateSeek();
|
||||
updateSeek(SeekHistoryType::Redo);
|
||||
}
|
||||
|
||||
void CutterCore::updateSeek()
|
||||
void CutterCore::updateSeek(SeekHistoryType type)
|
||||
{
|
||||
emit seekChanged(getOffset());
|
||||
emit seekChanged(getOffset(), type);
|
||||
}
|
||||
|
||||
RVA CutterCore::prevOpAddr(RVA startAddr, int count)
|
||||
|
@ -172,6 +172,8 @@ public:
|
||||
return returner;
|
||||
}
|
||||
|
||||
enum class SeekHistoryType { New, Undo, Redo };
|
||||
|
||||
CutterJson cmdj(const char *str);
|
||||
CutterJson cmdj(const QString &str) { return cmdj(str.toUtf8().constData()); }
|
||||
QString cmdTask(const QString &str);
|
||||
@ -324,7 +326,7 @@ public:
|
||||
void seekSilent(QString thing) { seekSilent(math(thing)); }
|
||||
void seekPrev();
|
||||
void seekNext();
|
||||
void updateSeek();
|
||||
void updateSeek(SeekHistoryType type = SeekHistoryType::New);
|
||||
/**
|
||||
* @brief Raise a memory widget showing current offset, prefer last active
|
||||
* memory widget.
|
||||
@ -794,8 +796,9 @@ signals:
|
||||
/**
|
||||
* @brief seekChanged is emitted each time Rizin's seek value is modified
|
||||
* @param offset
|
||||
* @param historyType
|
||||
*/
|
||||
void seekChanged(RVA offset);
|
||||
void seekChanged(RVA offset, SeekHistoryType type = SeekHistoryType::New);
|
||||
|
||||
void toggleDebugView();
|
||||
|
||||
|
@ -327,6 +327,7 @@ void DisassemblyWidget::scrollInstructions(int count)
|
||||
}
|
||||
|
||||
refreshDisasm(offset);
|
||||
topOffsetHistory[topOffsetHistoryPos] = offset;
|
||||
}
|
||||
|
||||
bool DisassemblyWidget::updateMaxLines()
|
||||
@ -660,19 +661,32 @@ QString DisassemblyWidget::getWindowTitle() const
|
||||
return tr("Disassembly");
|
||||
}
|
||||
|
||||
void DisassemblyWidget::on_seekChanged(RVA offset)
|
||||
void DisassemblyWidget::on_seekChanged(RVA offset, CutterCore::SeekHistoryType type)
|
||||
{
|
||||
if (type == CutterCore::SeekHistoryType::New) {
|
||||
// Erase previous history past this point.
|
||||
topOffsetHistory.erase(topOffsetHistory.begin() + topOffsetHistoryPos + 1,
|
||||
topOffsetHistory.end());
|
||||
topOffsetHistory.push_back(offset);
|
||||
topOffsetHistoryPos = topOffsetHistory.size() - 1;
|
||||
} else if (type == CutterCore::SeekHistoryType::Undo) {
|
||||
--topOffsetHistoryPos;
|
||||
} else if (type == CutterCore::SeekHistoryType::Redo) {
|
||||
++topOffsetHistoryPos;
|
||||
}
|
||||
if (!seekFromCursor) {
|
||||
cursorLineOffset = 0;
|
||||
cursorCharOffset = 0;
|
||||
}
|
||||
|
||||
if (topOffset != RVA_INVALID && offset >= topOffset && offset <= bottomOffset) {
|
||||
if (topOffset != RVA_INVALID && offset >= topOffset && offset <= bottomOffset
|
||||
&& type == CutterCore::SeekHistoryType::New) {
|
||||
// if the line with the seek offset is currently visible, just move the cursor there
|
||||
updateCursorPosition();
|
||||
topOffsetHistory[topOffsetHistoryPos] = topOffset;
|
||||
} else {
|
||||
// otherwise scroll there
|
||||
refreshDisasm(offset);
|
||||
refreshDisasm(topOffsetHistory[topOffsetHistoryPos]);
|
||||
}
|
||||
mCtxMenu->setOffset(offset);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public slots:
|
||||
QList<DisassemblyLine> getLines();
|
||||
|
||||
protected slots:
|
||||
void on_seekChanged(RVA offset);
|
||||
void on_seekChanged(RVA offset, CutterCore::SeekHistoryType type);
|
||||
void refreshIfInRange(RVA offset);
|
||||
void refreshDisasm(RVA offset = RVA_INVALID);
|
||||
|
||||
@ -87,6 +87,9 @@ private:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
QString getWindowTitle() const override;
|
||||
|
||||
int topOffsetHistoryPos = 0;
|
||||
QList<RVA> topOffsetHistory;
|
||||
|
||||
QList<RVA> breakpoints;
|
||||
|
||||
void setupFonts();
|
||||
|
Loading…
Reference in New Issue
Block a user