Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display jumping fix useless decompilation #2351

21 changes: 7 additions & 14 deletions src/core/Cutter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2068,23 +2068,20 @@ void CutterCore::setDebugPlugin(QString plugin)
void CutterCore::toggleBreakpoint(RVA addr)
{
cmdRaw(QString("dbs %1").arg(addr));
emit instructionChanged(addr);
emit breakpointsChanged();
emit breakpointsChanged(addr);
}

void CutterCore::toggleBreakpoint(QString addr)
{
cmdRaw("dbs " + addr);
emit instructionChanged(addr.toULongLong());
emit breakpointsChanged();
emit breakpointsChanged(addr.toULongLong());
karliss marked this conversation as resolved.
Show resolved Hide resolved
}


void CutterCore::addBreakpoint(QString addr)
{
cmdRaw("db " + addr);
emit instructionChanged(addr.toULongLong());
emit breakpointsChanged();
emit breakpointsChanged(addr.toULongLong());
}

void CutterCore::addBreakpoint(const BreakpointDescription &config)
Expand Down Expand Up @@ -2138,8 +2135,7 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config)
if (!config.command.isEmpty()) {
updateOwnedCharPtr(breakpoint->data, config.command);
}
emit instructionChanged(breakpoint->addr);
emit breakpointsChanged();
emit breakpointsChanged(breakpoint->addr);
}

void CutterCore::updateBreakpoint(int index, const BreakpointDescription &config)
Expand All @@ -2157,8 +2153,7 @@ void CutterCore::updateBreakpoint(int index, const BreakpointDescription &config
void CutterCore::delBreakpoint(RVA addr)
{
cmdRaw("db- " + RAddressString(addr));
emit instructionChanged(addr);
emit breakpointsChanged();
emit breakpointsChanged(addr);
}

void CutterCore::delAllBreakpoints()
Expand All @@ -2170,15 +2165,13 @@ void CutterCore::delAllBreakpoints()
void CutterCore::enableBreakpoint(RVA addr)
{
cmdRaw("dbe " + RAddressString(addr));
emit instructionChanged(addr);
emit breakpointsChanged();
emit breakpointsChanged(addr);
}

void CutterCore::disableBreakpoint(RVA addr)
{
cmdRaw("dbd " + RAddressString(addr));
emit instructionChanged(addr);
emit breakpointsChanged();
emit breakpointsChanged(addr);
}

void CutterCore::setBreakpointTrace(int index, bool enabled)
Expand Down
2 changes: 1 addition & 1 deletion src/core/Cutter.h
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ class CutterCore: public QObject
void commentsChanged();
void registersChanged();
void instructionChanged(RVA offset);
void breakpointsChanged();
void breakpointsChanged(RVA offset);
void refreshCodeViews();
void stackChanged();
/**
Expand Down
39 changes: 35 additions & 4 deletions src/widgets/DecompilerWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@
#include <QClipboard>
#include <QObject>
#include <QTextBlockUserData>
#include <QScrollBar>
#include <QAbstractSlider>

DecompilerWidget::DecompilerWidget(MainWindow *main) :
MemoryDockWidget(MemoryWidgetType::Decompiler, main),
mCtxMenu(new DecompilerContextMenu(this, main)),
ui(new Ui::DecompilerWidget),
decompilerWasBusy(false),
scrollerHorizontal(0),
scrollerVertical(0),
previousFunctionAddr(RVA_INVALID),
decompiledFunctionAddr(RVA_INVALID),
code(Decompiler::makeWarning(tr("Choose an offset and refresh to get decompiled code")),
&r_annotated_code_free)
{
Expand All @@ -38,9 +45,6 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
connect(Core(), SIGNAL(registersChanged()), this, SLOT(highlightPC()));
connect(mCtxMenu, &DecompilerContextMenu::copy, this, &DecompilerWidget::copy);

decompiledFunctionAddr = RVA_INVALID;
decompilerWasBusy = false;

connect(ui->refreshButton, &QAbstractButton::clicked, this, [this]() {
doRefresh();
});
Expand Down Expand Up @@ -88,7 +92,7 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
connect(ui->textEdit, SIGNAL(customContextMenuRequested(const QPoint &)),
this, SLOT(showDisasContextMenu(const QPoint &)));

connect(Core(), &CutterCore::breakpointsChanged, this, &DecompilerWidget::setInfoForBreakpoints);
connect(Core(), &CutterCore::breakpointsChanged, this, &DecompilerWidget::updateBreakpoints);
addActions(mCtxMenu->actions());

ui->progressLabel->setVisible(false);
Expand Down Expand Up @@ -182,6 +186,20 @@ static size_t positionForOffset(RAnnotatedCode &codeDecompiled, ut64 offset)
return closestPos;
}

void DecompilerWidget::updateBreakpoints()
{
setInfoForBreakpoints();
QTextCursor cursor = ui->textEdit->textCursor();
cursor.select(QTextCursor::Document);
cursor.setCharFormat(QTextCharFormat());
cursor.setBlockFormat(QTextBlockFormat());
cursor.clearSelection();
karliss marked this conversation as resolved.
Show resolved Hide resolved
ui->textEdit->setExtraSelections({});
highlightPC();
highlightBreakpoints();
updateSelection();
}

void DecompilerWidget::setInfoForBreakpoints()
{
if (mCtxMenu->getIsTogglingBreakpoints())
Expand Down Expand Up @@ -250,6 +268,7 @@ void DecompilerWidget::doRefresh(RVA addr)

// Clear all selections since we just refreshed
ui->textEdit->setExtraSelections({});
previousFunctionAddr = decompiledFunctionAddr;
decompiledFunctionAddr = Core()->getFunctionStart(addr);
dec->decompileAt(addr);
if (dec->isRunning()) {
Expand Down Expand Up @@ -280,6 +299,13 @@ QTextCursor DecompilerWidget::getCursorForAddress(RVA addr)

void DecompilerWidget::decompilationFinished(RAnnotatedCode *codeDecompiled)
{
bool isDisplayReset = false;
if (previousFunctionAddr == decompiledFunctionAddr) {
scrollerHorizontal = ui->textEdit->horizontalScrollBar()->sliderPosition();
scrollerVertical = ui->textEdit->verticalScrollBar()->sliderPosition();
isDisplayReset = true;
}

ui->progressLabel->setVisible(false);
ui->decompilerComboBox->setEnabled(decompilerSelectionEnabled);
updateRefreshButton();
Expand All @@ -303,6 +329,11 @@ void DecompilerWidget::decompilationFinished(RAnnotatedCode *codeDecompiled)
decompilerWasBusy = false;
doAutoRefresh();
}

if (isDisplayReset) {
ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollerHorizontal);
ui->textEdit->verticalScrollBar()->setSliderPosition(scrollerVertical);
}
}

void DecompilerWidget::setAnnotationsAtCursor(size_t pos)
Expand Down
4 changes: 4 additions & 0 deletions src/widgets/DecompilerWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ private slots:
*/
bool decompilerWasBusy;

int scrollerHorizontal;
int scrollerVertical;
RVA previousFunctionAddr;
RVA decompiledFunctionAddr;
std::unique_ptr<RAnnotatedCode, void (*)(RAnnotatedCode *)> code;
bool seekFromCursor = false;
Expand Down Expand Up @@ -113,6 +116,7 @@ private slots:
*/
void gatherBreakpointInfo(RAnnotatedCode &codeDecompiled, size_t startPos, size_t endPos);

void updateBreakpoints();
void setInfoForBreakpoints();

void setAnnotationsAtCursor(size_t pos);
Expand Down
1 change: 1 addition & 0 deletions src/widgets/DisassemblerGraphView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable *se
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshView()));
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshView()));
connect(Core(), SIGNAL(instructionChanged(RVA)), this, SLOT(refreshView()));
connect(Core(), &CutterCore::breakpointsChanged, this, &DisassemblerGraphView::refreshView);
connect(Core(), SIGNAL(functionsChanged()), this, SLOT(refreshView()));
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshView()));
connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshView()));
Expand Down
14 changes: 9 additions & 5 deletions src/widgets/DisassemblyWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,8 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main)
connect(Core(), &CutterCore::functionRenamed, this, [this]() {refreshDisasm();});
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshDisasm()));
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshDisasm()));
connect(Core(), &CutterCore::instructionChanged, this, [this](RVA offset) {
if (offset >= topOffset && offset <= bottomOffset) {
refreshDisasm();
}
});
connect(Core(), &CutterCore::instructionChanged, this, &DisassemblyWidget::refreshIfInRange);
connect(Core(), &CutterCore::breakpointsChanged, this, &DisassemblyWidget::refreshIfInRange);
connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshDisasm()));

connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot()));
Expand Down Expand Up @@ -249,6 +246,13 @@ QList<DisassemblyLine> DisassemblyWidget::getLines()
return lines;
}

void DisassemblyWidget::refreshIfInRange(RVA offset)
{
if (offset >= topOffset && offset <= bottomOffset) {
refreshDisasm();
}
}

karliss marked this conversation as resolved.
Show resolved Hide resolved
void DisassemblyWidget::refreshDisasm(RVA offset)
{
if(!disasmRefresh->attemptRefresh(offset == RVA_INVALID ? nullptr : new RVA(offset))) {
Expand Down
1 change: 1 addition & 0 deletions src/widgets/DisassemblyWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public slots:

protected slots:
void on_seekChanged(RVA offset);
void refreshIfInRange(RVA offset);
void refreshDisasm(RVA offset = RVA_INVALID);

bool updateMaxLines();
Expand Down
1 change: 1 addition & 0 deletions src/widgets/HexdumpWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ HexdumpWidget::HexdumpWidget(MainWindow *main) :
connect(Core(), &CutterCore::refreshAll, this, [this]() { refresh(); });
connect(Core(), &CutterCore::refreshCodeViews, this, [this]() { refresh(); });
connect(Core(), &CutterCore::instructionChanged, this, [this]() { refresh(); });
connect(Core(), &CutterCore::breakpointsChanged, this, [this]() { refresh(); });
connect(Core(), &CutterCore::stackChanged, this, [this]() { refresh(); });
connect(Core(), &CutterCore::registersChanged, this, [this]() { refresh(); });

Expand Down