mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-21 12:26:11 +00:00
Improve seek backward and outside of function in Decompiler widget (#1916)
* Improve seek backward and outside of function * Improve seekToReference
This commit is contained in:
parent
108fff8925
commit
7a34cf2024
@ -62,3 +62,25 @@ bool CutterSeekable::isSynchronized()
|
|||||||
{
|
{
|
||||||
return synchronized;
|
return synchronized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CutterSeekable::seekToReference(RVA offset)
|
||||||
|
{
|
||||||
|
if (offset == RVA_INVALID)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RVA target;
|
||||||
|
QList<XrefDescription> refs = Core()->getXRefs(offset, false, false);
|
||||||
|
|
||||||
|
if (refs.length()) {
|
||||||
|
if (refs.length() > 1) {
|
||||||
|
qWarning() << "Too many references here. Weird behaviour expected.";
|
||||||
|
}
|
||||||
|
|
||||||
|
target = refs.at(0).to;
|
||||||
|
if (target != RVA_INVALID) {
|
||||||
|
seek(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -44,6 +44,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isSynchronized();
|
bool isSynchronized();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief seekToReference will seek to the function or the object which is referenced in a given offset
|
||||||
|
* @param offset - an address that contains a reference to jump to
|
||||||
|
*/
|
||||||
|
void seekToReference(RVA offset);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/**
|
/**
|
||||||
* @brief seekPrev seeks to last location.
|
* @brief seekPrev seeks to last location.
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "common/TempConfig.h"
|
#include "common/TempConfig.h"
|
||||||
#include "common/SelectionHighlight.h"
|
#include "common/SelectionHighlight.h"
|
||||||
#include "common/Decompiler.h"
|
#include "common/Decompiler.h"
|
||||||
|
#include "common/CutterSeekable.h"
|
||||||
|
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
@ -23,6 +24,9 @@ DecompilerWidget::DecompilerWidget(MainWindow *main, QAction *action) :
|
|||||||
|
|
||||||
syntaxHighlighter = Config()->createSyntaxHighlighter(ui->textEdit->document());
|
syntaxHighlighter = Config()->createSyntaxHighlighter(ui->textEdit->document());
|
||||||
|
|
||||||
|
// Event filter to intercept double clicks in the textbox
|
||||||
|
ui->textEdit->viewport()->installEventFilter(this);
|
||||||
|
|
||||||
setupFonts();
|
setupFonts();
|
||||||
colorsUpdatedSlot();
|
colorsUpdatedSlot();
|
||||||
|
|
||||||
@ -88,6 +92,13 @@ DecompilerWidget::DecompilerWidget(MainWindow *main, QAction *action) :
|
|||||||
connect(Core(), &CutterCore::commentsChanged, this, &DecompilerWidget::doAutoRefresh);
|
connect(Core(), &CutterCore::commentsChanged, this, &DecompilerWidget::doAutoRefresh);
|
||||||
connect(Core(), &CutterCore::instructionChanged, this, &DecompilerWidget::doAutoRefresh);
|
connect(Core(), &CutterCore::instructionChanged, this, &DecompilerWidget::doAutoRefresh);
|
||||||
connect(Core(), &CutterCore::refreshCodeViews, this, &DecompilerWidget::doAutoRefresh);
|
connect(Core(), &CutterCore::refreshCodeViews, this, &DecompilerWidget::doAutoRefresh);
|
||||||
|
|
||||||
|
// Esc to seek backward
|
||||||
|
QAction *seekPrevAction = new QAction(this);
|
||||||
|
seekPrevAction->setShortcut(Qt::Key_Escape);
|
||||||
|
seekPrevAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
|
||||||
|
addAction(seekPrevAction);
|
||||||
|
connect(seekPrevAction, &QAction::triggered, seekable, &CutterSeekable::seekPrev);
|
||||||
}
|
}
|
||||||
|
|
||||||
DecompilerWidget::~DecompilerWidget() = default;
|
DecompilerWidget::~DecompilerWidget() = default;
|
||||||
@ -295,3 +306,24 @@ void DecompilerWidget::showDisasContextMenu(const QPoint &pt)
|
|||||||
mCtxMenu->exec(ui->textEdit->mapToGlobal(pt));
|
mCtxMenu->exec(ui->textEdit->mapToGlobal(pt));
|
||||||
doRefresh();
|
doRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DecompilerWidget::seekToReference()
|
||||||
|
{
|
||||||
|
size_t pos = ui->textEdit->textCursor().position();
|
||||||
|
RVA offset = code.OffsetForPosition(pos);
|
||||||
|
seekable->seekToReference(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DecompilerWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (event->type() == QEvent::MouseButtonDblClick
|
||||||
|
&& (obj == ui->textEdit || obj == ui->textEdit->viewport())) {
|
||||||
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||||
|
|
||||||
|
const QTextCursor& cursor = ui->textEdit->cursorForPosition(QPoint(mouseEvent->x(), mouseEvent->y()));
|
||||||
|
seekToReference();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MemoryDockWidget::eventFilter(obj, event);
|
||||||
|
}
|
||||||
|
@ -70,6 +70,13 @@ private:
|
|||||||
void updateCursorPosition();
|
void updateCursorPosition();
|
||||||
|
|
||||||
QString getWindowTitle() const override;
|
QString getWindowTitle() const override;
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief a wrapper around CutterSeekable::seekToReference to seek to an object which is
|
||||||
|
* referenced from the address under cursor
|
||||||
|
*/
|
||||||
|
void seekToReference();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DECOMPILERWIDGET_H
|
#endif // DECOMPILERWIDGET_H
|
||||||
|
@ -996,18 +996,7 @@ void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMo
|
|||||||
QPoint pos)
|
QPoint pos)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
|
seekable->seekToReference(getAddrForMouseEvent(block, &pos));
|
||||||
RVA instr = getAddrForMouseEvent(block, &pos);
|
|
||||||
if (instr == RVA_INVALID) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QList<XrefDescription> refs = Core()->getXRefs(instr, false, false);
|
|
||||||
if (refs.length()) {
|
|
||||||
seekable->seek(refs.at(0).to);
|
|
||||||
}
|
|
||||||
if (refs.length() > 1) {
|
|
||||||
qWarning() << "Too many references here. Weird behaviour expected.";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassemblerGraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event,
|
void DisassemblerGraphView::blockHelpEvent(GraphView::GraphBlock &block, QHelpEvent *event,
|
||||||
|
@ -617,20 +617,7 @@ void DisassemblyWidget::moveCursorRelative(bool up, bool page)
|
|||||||
void DisassemblyWidget::jumpToOffsetUnderCursor(const QTextCursor &cursor)
|
void DisassemblyWidget::jumpToOffsetUnderCursor(const QTextCursor &cursor)
|
||||||
{
|
{
|
||||||
RVA offset = readDisassemblyOffset(cursor);
|
RVA offset = readDisassemblyOffset(cursor);
|
||||||
RVA jump = Core()->getOffsetJump(offset);
|
seekable->seekToReference(offset);
|
||||||
|
|
||||||
if (jump == RVA_INVALID) {
|
|
||||||
bool ok;
|
|
||||||
RVA xref = Core()->cmdj("axfj@" + QString::number(
|
|
||||||
offset)).array().first().toObject().value("to").toVariant().toULongLong(&ok);
|
|
||||||
if (ok) {
|
|
||||||
jump = xref;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jump != RVA_INVALID) {
|
|
||||||
seekable->seek(jump);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
Loading…
Reference in New Issue
Block a user