mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-20 20:06:12 +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;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* @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:
|
||||
/**
|
||||
* @brief seekPrev seeks to last location.
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "common/TempConfig.h"
|
||||
#include "common/SelectionHighlight.h"
|
||||
#include "common/Decompiler.h"
|
||||
#include "common/CutterSeekable.h"
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QPlainTextEdit>
|
||||
@ -23,6 +24,9 @@ DecompilerWidget::DecompilerWidget(MainWindow *main, QAction *action) :
|
||||
|
||||
syntaxHighlighter = Config()->createSyntaxHighlighter(ui->textEdit->document());
|
||||
|
||||
// Event filter to intercept double clicks in the textbox
|
||||
ui->textEdit->viewport()->installEventFilter(this);
|
||||
|
||||
setupFonts();
|
||||
colorsUpdatedSlot();
|
||||
|
||||
@ -88,6 +92,13 @@ DecompilerWidget::DecompilerWidget(MainWindow *main, QAction *action) :
|
||||
connect(Core(), &CutterCore::commentsChanged, this, &DecompilerWidget::doAutoRefresh);
|
||||
connect(Core(), &CutterCore::instructionChanged, 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;
|
||||
@ -295,3 +306,24 @@ void DecompilerWidget::showDisasContextMenu(const QPoint &pt)
|
||||
mCtxMenu->exec(ui->textEdit->mapToGlobal(pt));
|
||||
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();
|
||||
|
||||
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
|
||||
|
@ -996,18 +996,7 @@ void DisassemblerGraphView::blockDoubleClicked(GraphView::GraphBlock &block, QMo
|
||||
QPoint pos)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
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.";
|
||||
}
|
||||
seekable->seekToReference(getAddrForMouseEvent(block, &pos));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
RVA offset = readDisassemblyOffset(cursor);
|
||||
RVA jump = Core()->getOffsetJump(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);
|
||||
}
|
||||
seekable->seekToReference(offset);
|
||||
}
|
||||
|
||||
bool DisassemblyWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
|
Loading…
Reference in New Issue
Block a user