mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-18 18:38:51 +00:00
Display jumping fix useless decompilation (#2351)
* save scroll position and reset to that if the newly decompiled function is the same as the previous one * instructionChanged signal replaced completely by breakpointsChanged in toggle/add breakpoint functions. * removed addbreakpoint(QString) and toggleBreakpoint(QString)
This commit is contained in:
parent
37fc01478f
commit
b42a19e995
@ -2068,23 +2068,7 @@ void CutterCore::setDebugPlugin(QString plugin)
|
|||||||
void CutterCore::toggleBreakpoint(RVA addr)
|
void CutterCore::toggleBreakpoint(RVA addr)
|
||||||
{
|
{
|
||||||
cmdRaw(QString("dbs %1").arg(addr));
|
cmdRaw(QString("dbs %1").arg(addr));
|
||||||
emit instructionChanged(addr);
|
emit breakpointsChanged(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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::addBreakpoint(const BreakpointDescription &config)
|
void CutterCore::addBreakpoint(const BreakpointDescription &config)
|
||||||
@ -2138,8 +2122,7 @@ void CutterCore::addBreakpoint(const BreakpointDescription &config)
|
|||||||
if (!config.command.isEmpty()) {
|
if (!config.command.isEmpty()) {
|
||||||
updateOwnedCharPtr(breakpoint->data, config.command);
|
updateOwnedCharPtr(breakpoint->data, config.command);
|
||||||
}
|
}
|
||||||
emit instructionChanged(breakpoint->addr);
|
emit breakpointsChanged(breakpoint->addr);
|
||||||
emit breakpointsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::updateBreakpoint(int index, const BreakpointDescription &config)
|
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)
|
void CutterCore::delBreakpoint(RVA addr)
|
||||||
{
|
{
|
||||||
cmdRaw("db- " + RAddressString(addr));
|
cmdRaw("db- " + RAddressString(addr));
|
||||||
emit instructionChanged(addr);
|
emit breakpointsChanged(addr);
|
||||||
emit breakpointsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::delAllBreakpoints()
|
void CutterCore::delAllBreakpoints()
|
||||||
@ -2170,15 +2152,13 @@ void CutterCore::delAllBreakpoints()
|
|||||||
void CutterCore::enableBreakpoint(RVA addr)
|
void CutterCore::enableBreakpoint(RVA addr)
|
||||||
{
|
{
|
||||||
cmdRaw("dbe " + RAddressString(addr));
|
cmdRaw("dbe " + RAddressString(addr));
|
||||||
emit instructionChanged(addr);
|
emit breakpointsChanged(addr);
|
||||||
emit breakpointsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::disableBreakpoint(RVA addr)
|
void CutterCore::disableBreakpoint(RVA addr)
|
||||||
{
|
{
|
||||||
cmdRaw("dbd " + RAddressString(addr));
|
cmdRaw("dbd " + RAddressString(addr));
|
||||||
emit instructionChanged(addr);
|
emit breakpointsChanged(addr);
|
||||||
emit breakpointsChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CutterCore::setBreakpointTrace(int index, bool enabled)
|
void CutterCore::setBreakpointTrace(int index, bool enabled)
|
||||||
|
@ -391,11 +391,9 @@ public:
|
|||||||
void stepOverDebug();
|
void stepOverDebug();
|
||||||
void stepOutDebug();
|
void stepOutDebug();
|
||||||
|
|
||||||
void addBreakpoint(QString addr);
|
|
||||||
void addBreakpoint(const BreakpointDescription &config);
|
void addBreakpoint(const BreakpointDescription &config);
|
||||||
void updateBreakpoint(int index, const BreakpointDescription &config);
|
void updateBreakpoint(int index, const BreakpointDescription &config);
|
||||||
void toggleBreakpoint(RVA addr);
|
void toggleBreakpoint(RVA addr);
|
||||||
void toggleBreakpoint(QString addr);
|
|
||||||
void delBreakpoint(RVA addr);
|
void delBreakpoint(RVA addr);
|
||||||
void delAllBreakpoints();
|
void delAllBreakpoints();
|
||||||
void enableBreakpoint(RVA addr);
|
void enableBreakpoint(RVA addr);
|
||||||
@ -643,7 +641,7 @@ signals:
|
|||||||
void commentsChanged();
|
void commentsChanged();
|
||||||
void registersChanged();
|
void registersChanged();
|
||||||
void instructionChanged(RVA offset);
|
void instructionChanged(RVA offset);
|
||||||
void breakpointsChanged();
|
void breakpointsChanged(RVA offset);
|
||||||
void refreshCodeViews();
|
void refreshCodeViews();
|
||||||
void stackChanged();
|
void stackChanged();
|
||||||
/**
|
/**
|
||||||
|
@ -15,11 +15,18 @@
|
|||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTextBlockUserData>
|
#include <QTextBlockUserData>
|
||||||
|
#include <QScrollBar>
|
||||||
|
#include <QAbstractSlider>
|
||||||
|
|
||||||
DecompilerWidget::DecompilerWidget(MainWindow *main) :
|
DecompilerWidget::DecompilerWidget(MainWindow *main) :
|
||||||
MemoryDockWidget(MemoryWidgetType::Decompiler, main),
|
MemoryDockWidget(MemoryWidgetType::Decompiler, main),
|
||||||
mCtxMenu(new DecompilerContextMenu(this, main)),
|
mCtxMenu(new DecompilerContextMenu(this, main)),
|
||||||
ui(new Ui::DecompilerWidget),
|
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")),
|
code(Decompiler::makeWarning(tr("Choose an offset and refresh to get decompiled code")),
|
||||||
&r_annotated_code_free)
|
&r_annotated_code_free)
|
||||||
{
|
{
|
||||||
@ -38,9 +45,6 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
|
|||||||
connect(Core(), &CutterCore::registersChanged, this, &DecompilerWidget::highlightPC);
|
connect(Core(), &CutterCore::registersChanged, this, &DecompilerWidget::highlightPC);
|
||||||
connect(mCtxMenu, &DecompilerContextMenu::copy, this, &DecompilerWidget::copy);
|
connect(mCtxMenu, &DecompilerContextMenu::copy, this, &DecompilerWidget::copy);
|
||||||
|
|
||||||
decompiledFunctionAddr = RVA_INVALID;
|
|
||||||
decompilerWasBusy = false;
|
|
||||||
|
|
||||||
connect(ui->refreshButton, &QAbstractButton::clicked, this, [this]() {
|
connect(ui->refreshButton, &QAbstractButton::clicked, this, [this]() {
|
||||||
doRefresh();
|
doRefresh();
|
||||||
});
|
});
|
||||||
@ -88,7 +92,7 @@ DecompilerWidget::DecompilerWidget(MainWindow *main) :
|
|||||||
connect(ui->textEdit, &QWidget::customContextMenuRequested,
|
connect(ui->textEdit, &QWidget::customContextMenuRequested,
|
||||||
this, &DecompilerWidget::showDisasContextMenu);
|
this, &DecompilerWidget::showDisasContextMenu);
|
||||||
|
|
||||||
connect(Core(), &CutterCore::breakpointsChanged, this, &DecompilerWidget::setInfoForBreakpoints);
|
connect(Core(), &CutterCore::breakpointsChanged, this, &DecompilerWidget::updateBreakpoints);
|
||||||
addActions(mCtxMenu->actions());
|
addActions(mCtxMenu->actions());
|
||||||
|
|
||||||
ui->progressLabel->setVisible(false);
|
ui->progressLabel->setVisible(false);
|
||||||
@ -182,6 +186,19 @@ static size_t positionForOffset(RAnnotatedCode &codeDecompiled, ut64 offset)
|
|||||||
return closestPos;
|
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()
|
void DecompilerWidget::setInfoForBreakpoints()
|
||||||
{
|
{
|
||||||
if (mCtxMenu->getIsTogglingBreakpoints())
|
if (mCtxMenu->getIsTogglingBreakpoints())
|
||||||
@ -250,6 +267,7 @@ void DecompilerWidget::doRefresh(RVA addr)
|
|||||||
|
|
||||||
// Clear all selections since we just refreshed
|
// Clear all selections since we just refreshed
|
||||||
ui->textEdit->setExtraSelections({});
|
ui->textEdit->setExtraSelections({});
|
||||||
|
previousFunctionAddr = decompiledFunctionAddr;
|
||||||
decompiledFunctionAddr = Core()->getFunctionStart(addr);
|
decompiledFunctionAddr = Core()->getFunctionStart(addr);
|
||||||
dec->decompileAt(addr);
|
dec->decompileAt(addr);
|
||||||
if (dec->isRunning()) {
|
if (dec->isRunning()) {
|
||||||
@ -280,6 +298,13 @@ QTextCursor DecompilerWidget::getCursorForAddress(RVA addr)
|
|||||||
|
|
||||||
void DecompilerWidget::decompilationFinished(RAnnotatedCode *codeDecompiled)
|
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->progressLabel->setVisible(false);
|
||||||
ui->decompilerComboBox->setEnabled(decompilerSelectionEnabled);
|
ui->decompilerComboBox->setEnabled(decompilerSelectionEnabled);
|
||||||
updateRefreshButton();
|
updateRefreshButton();
|
||||||
@ -303,6 +328,11 @@ void DecompilerWidget::decompilationFinished(RAnnotatedCode *codeDecompiled)
|
|||||||
decompilerWasBusy = false;
|
decompilerWasBusy = false;
|
||||||
doAutoRefresh();
|
doAutoRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDisplayReset) {
|
||||||
|
ui->textEdit->horizontalScrollBar()->setSliderPosition(scrollerHorizontal);
|
||||||
|
ui->textEdit->verticalScrollBar()->setSliderPosition(scrollerVertical);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecompilerWidget::setAnnotationsAtCursor(size_t pos)
|
void DecompilerWidget::setAnnotationsAtCursor(size_t pos)
|
||||||
|
@ -56,6 +56,9 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool decompilerWasBusy;
|
bool decompilerWasBusy;
|
||||||
|
|
||||||
|
int scrollerHorizontal;
|
||||||
|
int scrollerVertical;
|
||||||
|
RVA previousFunctionAddr;
|
||||||
RVA decompiledFunctionAddr;
|
RVA decompiledFunctionAddr;
|
||||||
std::unique_ptr<RAnnotatedCode, void (*)(RAnnotatedCode *)> code;
|
std::unique_ptr<RAnnotatedCode, void (*)(RAnnotatedCode *)> code;
|
||||||
bool seekFromCursor = false;
|
bool seekFromCursor = false;
|
||||||
@ -113,6 +116,7 @@ private:
|
|||||||
*/
|
*/
|
||||||
void gatherBreakpointInfo(RAnnotatedCode &codeDecompiled, size_t startPos, size_t endPos);
|
void gatherBreakpointInfo(RAnnotatedCode &codeDecompiled, size_t startPos, size_t endPos);
|
||||||
|
|
||||||
|
void updateBreakpoints();
|
||||||
void setInfoForBreakpoints();
|
void setInfoForBreakpoints();
|
||||||
|
|
||||||
void setAnnotationsAtCursor(size_t pos);
|
void setAnnotationsAtCursor(size_t pos);
|
||||||
|
@ -47,6 +47,7 @@ DisassemblerGraphView::DisassemblerGraphView(QWidget *parent, CutterSeekable *se
|
|||||||
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshView()));
|
connect(Core(), SIGNAL(flagsChanged()), this, SLOT(refreshView()));
|
||||||
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshView()));
|
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshView()));
|
||||||
connect(Core(), SIGNAL(instructionChanged(RVA)), 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(functionsChanged()), this, SLOT(refreshView()));
|
||||||
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshView()));
|
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshView()));
|
||||||
connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshView()));
|
connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshView()));
|
||||||
|
@ -151,11 +151,8 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main)
|
|||||||
connect(Core(), &CutterCore::functionRenamed, this, [this]() {refreshDisasm();});
|
connect(Core(), &CutterCore::functionRenamed, this, [this]() {refreshDisasm();});
|
||||||
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshDisasm()));
|
connect(Core(), SIGNAL(varsChanged()), this, SLOT(refreshDisasm()));
|
||||||
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshDisasm()));
|
connect(Core(), SIGNAL(asmOptionsChanged()), this, SLOT(refreshDisasm()));
|
||||||
connect(Core(), &CutterCore::instructionChanged, this, [this](RVA offset) {
|
connect(Core(), &CutterCore::instructionChanged, this, &DisassemblyWidget::refreshIfInRange);
|
||||||
if (offset >= topOffset && offset <= bottomOffset) {
|
connect(Core(), &CutterCore::breakpointsChanged, this, &DisassemblyWidget::refreshIfInRange);
|
||||||
refreshDisasm();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshDisasm()));
|
connect(Core(), SIGNAL(refreshCodeViews()), this, SLOT(refreshDisasm()));
|
||||||
|
|
||||||
connect(Config(), &Configuration::fontsUpdated, this, &DisassemblyWidget::fontsUpdatedSlot);
|
connect(Config(), &Configuration::fontsUpdated, this, &DisassemblyWidget::fontsUpdatedSlot);
|
||||||
@ -249,6 +246,13 @@ QList<DisassemblyLine> DisassemblyWidget::getLines()
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisassemblyWidget::refreshIfInRange(RVA offset)
|
||||||
|
{
|
||||||
|
if (offset >= topOffset && offset <= bottomOffset) {
|
||||||
|
refreshDisasm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DisassemblyWidget::refreshDisasm(RVA offset)
|
void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||||
{
|
{
|
||||||
if(!disasmRefresh->attemptRefresh(offset == RVA_INVALID ? nullptr : new RVA(offset))) {
|
if(!disasmRefresh->attemptRefresh(offset == RVA_INVALID ? nullptr : new RVA(offset))) {
|
||||||
|
@ -40,6 +40,7 @@ public slots:
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void on_seekChanged(RVA offset);
|
void on_seekChanged(RVA offset);
|
||||||
|
void refreshIfInRange(RVA offset);
|
||||||
void refreshDisasm(RVA offset = RVA_INVALID);
|
void refreshDisasm(RVA offset = RVA_INVALID);
|
||||||
|
|
||||||
bool updateMaxLines();
|
bool updateMaxLines();
|
||||||
|
Loading…
Reference in New Issue
Block a user