diff --git a/src/core/Cutter.cpp b/src/core/Cutter.cpp index bf799b78f..2878be15a 100644 --- a/src/core/Cutter.cpp +++ b/src/core/Cutter.cpp @@ -2068,23 +2068,7 @@ void CutterCore::setDebugPlugin(QString plugin) void CutterCore::toggleBreakpoint(RVA addr) { cmdRaw(QString("dbs %1").arg(addr)); - emit instructionChanged(addr); - emit breakpointsChanged(); -} - -void CutterCore::toggleBreakpoint(QString addr) -{ - cmdRaw("dbs " + addr); - emit instructionChanged(addr.toULongLong()); - emit breakpointsChanged(); -} - - -void CutterCore::addBreakpoint(QString addr) -{ - cmdRaw("db " + addr); - emit instructionChanged(addr.toULongLong()); - emit breakpointsChanged(); + emit breakpointsChanged(addr); } void CutterCore::addBreakpoint(const BreakpointDescription &config) @@ -2138,8 +2122,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) @@ -2157,8 +2140,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() @@ -2170,15 +2152,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) diff --git a/src/core/Cutter.h b/src/core/Cutter.h index 36744968c..52bb2685e 100644 --- a/src/core/Cutter.h +++ b/src/core/Cutter.h @@ -392,11 +392,9 @@ class CutterCore: public QObject void stepOverDebug(); void stepOutDebug(); - void addBreakpoint(QString addr); void addBreakpoint(const BreakpointDescription &config); void updateBreakpoint(int index, const BreakpointDescription &config); void toggleBreakpoint(RVA addr); - void toggleBreakpoint(QString addr); void delBreakpoint(RVA addr); void delAllBreakpoints(); void enableBreakpoint(RVA addr); @@ -644,7 +642,7 @@ class CutterCore: public QObject void commentsChanged(); void registersChanged(); void instructionChanged(RVA offset); - void breakpointsChanged(); + void breakpointsChanged(RVA offset); void refreshCodeViews(); void stackChanged(); /** diff --git a/src/widgets/DecompilerWidget.cpp b/src/widgets/DecompilerWidget.cpp index 0e58938d8..34d25fc7b 100644 --- a/src/widgets/DecompilerWidget.cpp +++ b/src/widgets/DecompilerWidget.cpp @@ -15,11 +15,18 @@ #include #include #include +#include +#include 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) { @@ -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(); }); @@ -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); @@ -182,6 +186,19 @@ 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()); + ui->textEdit->setExtraSelections({}); + highlightPC(); + highlightBreakpoints(); + updateSelection(); +} + void DecompilerWidget::setInfoForBreakpoints() { if (mCtxMenu->getIsTogglingBreakpoints()) @@ -250,6 +267,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()) { @@ -280,6 +298,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(); @@ -303,6 +328,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) diff --git a/src/widgets/DecompilerWidget.h b/src/widgets/DecompilerWidget.h index 518603b35..3109fd3c5 100644 --- a/src/widgets/DecompilerWidget.h +++ b/src/widgets/DecompilerWidget.h @@ -56,6 +56,9 @@ private slots: */ bool decompilerWasBusy; + int scrollerHorizontal; + int scrollerVertical; + RVA previousFunctionAddr; RVA decompiledFunctionAddr; std::unique_ptr code; bool seekFromCursor = false; @@ -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); diff --git a/src/widgets/DisassemblerGraphView.cpp b/src/widgets/DisassemblerGraphView.cpp index b37f195dd..e222e32bf 100644 --- a/src/widgets/DisassemblerGraphView.cpp +++ b/src/widgets/DisassemblerGraphView.cpp @@ -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())); diff --git a/src/widgets/DisassemblyWidget.cpp b/src/widgets/DisassemblyWidget.cpp index 954177cde..557a94730 100644 --- a/src/widgets/DisassemblyWidget.cpp +++ b/src/widgets/DisassemblyWidget.cpp @@ -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())); @@ -249,6 +246,13 @@ QList DisassemblyWidget::getLines() return lines; } +void DisassemblyWidget::refreshIfInRange(RVA offset) +{ + if (offset >= topOffset && offset <= bottomOffset) { + refreshDisasm(); + } +} + void DisassemblyWidget::refreshDisasm(RVA offset) { if(!disasmRefresh->attemptRefresh(offset == RVA_INVALID ? nullptr : new RVA(offset))) { diff --git a/src/widgets/DisassemblyWidget.h b/src/widgets/DisassemblyWidget.h index 0ddaa2d7a..36aaf3ec1 100644 --- a/src/widgets/DisassemblyWidget.h +++ b/src/widgets/DisassemblyWidget.h @@ -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(); diff --git a/src/widgets/HexdumpWidget.cpp b/src/widgets/HexdumpWidget.cpp index c09764161..f880eda9f 100644 --- a/src/widgets/HexdumpWidget.cpp +++ b/src/widgets/HexdumpWidget.cpp @@ -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(); });