mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-24 05:45:27 +00:00
Highlight Breakpoints and PC in decompiler (#1948)
This commit is contained in:
parent
58b44893f9
commit
4e84d1b502
@ -35,13 +35,32 @@ QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textE
|
|||||||
return selections;
|
return selections;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor)
|
|
||||||
|
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor)
|
||||||
{
|
{
|
||||||
QColor highlightColor = ConfigColor("lineHighlight");
|
|
||||||
QTextEdit::ExtraSelection highlightSelection;
|
QTextEdit::ExtraSelection highlightSelection;
|
||||||
highlightSelection.cursor = cursor;
|
highlightSelection.cursor = cursor;
|
||||||
highlightSelection.format.setBackground(highlightColor);
|
highlightSelection.format.setBackground(highlightColor);
|
||||||
highlightSelection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
highlightSelection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||||
highlightSelection.cursor.clearSelection();
|
highlightSelection.cursor.clearSelection();
|
||||||
return highlightSelection;
|
return highlightSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
QColor highlightColor = ConfigColor("lineHighlight");
|
||||||
|
return createLineHighlight(cursor, highlightColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
QColor highlightColor = ConfigColor("highlightPC");
|
||||||
|
return createLineHighlight(cursor, highlightColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextEdit::ExtraSelection createLineHighlightBP(const QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
QColor highlightColor = ConfigColor("gui.breakpoint_background");
|
||||||
|
return createLineHighlight(cursor, highlightColor);
|
||||||
}
|
}
|
@ -6,7 +6,41 @@
|
|||||||
class QPlainTextEdit;
|
class QPlainTextEdit;
|
||||||
class QString;
|
class QString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief createSameWordsSelections se
|
||||||
|
* @param textEdit
|
||||||
|
* @param word
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word);
|
QList<QTextEdit::ExtraSelection> createSameWordsSelections(QPlainTextEdit *textEdit, const QString &word);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief createLineHighlight
|
||||||
|
* @param cursor - a Cursor object represents the line to be highlighted
|
||||||
|
* @param highlightColor - the color to be used for highlighting. The color is decided by the callee for different usages (BP, PC, Current line, ...)
|
||||||
|
* @return ExtraSelection with highlighted line
|
||||||
|
*/
|
||||||
|
QTextEdit::ExtraSelection createLineHighlight(const QTextCursor &cursor, QColor highlightColor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function responsible to highlight the currently selected line
|
||||||
|
* @param cursor - a Cursor object represents the line to be highlighted
|
||||||
|
* @return ExtraSelection with highlighted line
|
||||||
|
*/
|
||||||
QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor);
|
QTextEdit::ExtraSelection createLineHighlightSelection(const QTextCursor &cursor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function responsible to highlight the program counter line
|
||||||
|
* @param cursor - a Cursor object represents the line to be highlighted
|
||||||
|
* @return ExtraSelection with highlighted line
|
||||||
|
*/
|
||||||
|
QTextEdit::ExtraSelection createLineHighlightPC(const QTextCursor &cursor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function responsible to highlight a line with breakpoint
|
||||||
|
* @param cursor - a Cursor object represents the line to be highlighted
|
||||||
|
* @return ExtraSelection with highlighted line
|
||||||
|
*/
|
||||||
|
QTextEdit::ExtraSelection createLineHighlightBP(const QTextCursor &cursor);
|
||||||
|
|
||||||
#endif //CUTTER_SELECTIONHIGHLIGHT_H
|
#endif //CUTTER_SELECTIONHIGHLIGHT_H
|
||||||
|
@ -1802,6 +1802,19 @@ QList<RVA> CutterCore::getBreakpointsAddresses()
|
|||||||
return bpAddresses;
|
return bpAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<RVA> CutterCore::getBreakpointsInFunction(RVA funcAddr)
|
||||||
|
{
|
||||||
|
QList<RVA> allBreakpoints = getBreakpointsAddresses();
|
||||||
|
QList<RVA> functionBreakpoints;
|
||||||
|
|
||||||
|
// Use std manipulations to take only the breakpoints that belong to this function
|
||||||
|
std::copy_if(allBreakpoints.begin(),
|
||||||
|
allBreakpoints.end(),
|
||||||
|
std::back_inserter(functionBreakpoints),
|
||||||
|
[this, funcAddr](RVA BPadd) { return getFunctionStart(BPadd) == funcAddr; });
|
||||||
|
return functionBreakpoints;
|
||||||
|
}
|
||||||
|
|
||||||
bool CutterCore::isBreakpoint(const QList<RVA> &breakpoints, RVA addr)
|
bool CutterCore::isBreakpoint(const QList<RVA> &breakpoints, RVA addr)
|
||||||
{
|
{
|
||||||
return breakpoints.contains(addr);
|
return breakpoints.contains(addr);
|
||||||
|
@ -327,6 +327,11 @@ public:
|
|||||||
void disableBreakpoint(RVA addr);
|
void disableBreakpoint(RVA addr);
|
||||||
bool isBreakpoint(const QList<RVA> &breakpoints, RVA addr);
|
bool isBreakpoint(const QList<RVA> &breakpoints, RVA addr);
|
||||||
QList<RVA> getBreakpointsAddresses();
|
QList<RVA> getBreakpointsAddresses();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get all breakpoinst that are belong to a functions at this address
|
||||||
|
*/
|
||||||
|
QList<RVA> getBreakpointsInFunction(RVA funcAddr);
|
||||||
QString getActiveDebugPlugin();
|
QString getActiveDebugPlugin();
|
||||||
QStringList getDebugPlugins();
|
QStringList getDebugPlugins();
|
||||||
void setDebugPlugin(QString plugin);
|
void setDebugPlugin(QString plugin);
|
||||||
|
@ -32,6 +32,7 @@ DecompilerWidget::DecompilerWidget(MainWindow *main, QAction *action) :
|
|||||||
|
|
||||||
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot()));
|
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot()));
|
||||||
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
|
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
|
||||||
|
connect(Core(), SIGNAL(registersChanged()), this, SLOT(highlightPC()));
|
||||||
|
|
||||||
decompiledFunctionAddr = RVA_INVALID;
|
decompiledFunctionAddr = RVA_INVALID;
|
||||||
decompilerWasBusy = false;
|
decompilerWasBusy = false;
|
||||||
@ -158,6 +159,8 @@ void DecompilerWidget::doRefresh(RVA addr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear all selections since we just refreshed
|
||||||
|
ui->textEdit->setExtraSelections({});
|
||||||
decompiledFunctionAddr = Core()->getFunctionStart(addr);
|
decompiledFunctionAddr = Core()->getFunctionStart(addr);
|
||||||
dec->decompileAt(addr);
|
dec->decompileAt(addr);
|
||||||
if (dec->isRunning()) {
|
if (dec->isRunning()) {
|
||||||
@ -173,6 +176,18 @@ void DecompilerWidget::refreshDecompiler()
|
|||||||
doRefresh();
|
doRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTextCursor DecompilerWidget::getCursorForAddress(RVA addr)
|
||||||
|
{
|
||||||
|
size_t pos = code.PositionForOffset(addr);
|
||||||
|
if (pos == SIZE_MAX || pos == 0) {
|
||||||
|
return QTextCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor cursor = ui->textEdit->textCursor();
|
||||||
|
cursor.setPosition(pos);
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
void DecompilerWidget::decompilationFinished(AnnotatedCode code)
|
void DecompilerWidget::decompilationFinished(AnnotatedCode code)
|
||||||
{
|
{
|
||||||
ui->progressLabel->setVisible(false);
|
ui->progressLabel->setVisible(false);
|
||||||
@ -188,6 +203,8 @@ void DecompilerWidget::decompilationFinished(AnnotatedCode code)
|
|||||||
ui->textEdit->setPlainText(code.code);
|
ui->textEdit->setPlainText(code.code);
|
||||||
connectCursorPositionChanged(false);
|
connectCursorPositionChanged(false);
|
||||||
updateCursorPosition();
|
updateCursorPosition();
|
||||||
|
highlightPC();
|
||||||
|
highlightBreakpoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decompilerWasBusy) {
|
if (decompilerWasBusy) {
|
||||||
@ -284,6 +301,8 @@ void DecompilerWidget::updateSelection()
|
|||||||
extraSelections.append(createSameWordsSelections(ui->textEdit, searchString));
|
extraSelections.append(createSameWordsSelections(ui->textEdit, searchString));
|
||||||
|
|
||||||
ui->textEdit->setExtraSelections(extraSelections);
|
ui->textEdit->setExtraSelections(extraSelections);
|
||||||
|
// Highlight PC after updating the selected line
|
||||||
|
highlightPC();
|
||||||
mCtxMenu->setCurHighlightedWord(searchString);
|
mCtxMenu->setCurHighlightedWord(searchString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,3 +346,46 @@ bool DecompilerWidget::eventFilter(QObject *obj, QEvent *event)
|
|||||||
|
|
||||||
return MemoryDockWidget::eventFilter(obj, event);
|
return MemoryDockWidget::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DecompilerWidget::highlightPC()
|
||||||
|
{
|
||||||
|
RVA PCAddress = Core()->getProgramCounterValue();
|
||||||
|
if (PCAddress == RVA_INVALID || (Core()->getFunctionStart(PCAddress) != decompiledFunctionAddr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextCursor cursor = getCursorForAddress(PCAddress);
|
||||||
|
if (!cursor.isNull()) {
|
||||||
|
colorLine(createLineHighlightPC(cursor));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecompilerWidget::highlightBreakpoints()
|
||||||
|
{
|
||||||
|
|
||||||
|
QList<RVA> functionBreakpoints = Core()->getBreakpointsInFunction(decompiledFunctionAddr);
|
||||||
|
QTextCursor cursor;
|
||||||
|
foreach(auto &bp, functionBreakpoints) {
|
||||||
|
if (bp == RVA_INVALID) {
|
||||||
|
continue;;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor = getCursorForAddress(bp);
|
||||||
|
if (!cursor.isNull()) {
|
||||||
|
// Use a Block formatting since these lines are not updated frequently as selections and PC
|
||||||
|
QTextBlockFormat f;
|
||||||
|
f.setBackground(ConfigColor("gui.breakpoint_background"));
|
||||||
|
cursor.setBlockFormat(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DecompilerWidget::colorLine(QTextEdit::ExtraSelection extraSelection)
|
||||||
|
{
|
||||||
|
QList<QTextEdit::ExtraSelection> extraSelections = ui->textEdit->extraSelections();
|
||||||
|
extraSelections.append(extraSelection);
|
||||||
|
ui->textEdit->setExtraSelections(extraSelections);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef DECOMPILERWIDGET_H
|
#ifndef DECOMPILERWIDGET_H
|
||||||
#define DECOMPILERWIDGET_H
|
#define DECOMPILERWIDGET_H
|
||||||
|
|
||||||
|
#include <QTextEdit>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
@ -29,6 +30,7 @@ public:
|
|||||||
public slots:
|
public slots:
|
||||||
void showDisasContextMenu(const QPoint &pt);
|
void showDisasContextMenu(const QPoint &pt);
|
||||||
|
|
||||||
|
void highlightPC();
|
||||||
private slots:
|
private slots:
|
||||||
void fontsUpdatedSlot();
|
void fontsUpdatedSlot();
|
||||||
void colorsUpdatedSlot();
|
void colorsUpdatedSlot();
|
||||||
@ -77,6 +79,26 @@ private:
|
|||||||
* referenced from the address under cursor
|
* referenced from the address under cursor
|
||||||
*/
|
*/
|
||||||
void seekToReference();
|
void seekToReference();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieve the Cursor for a location as close as possible to the given address
|
||||||
|
* @param addr - an address in the decompiled function
|
||||||
|
* @return a Cursor object for the given address
|
||||||
|
*/
|
||||||
|
QTextCursor getCursorForAddress(RVA addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Append a highlighted line to the TextEdit
|
||||||
|
* @param extraSelection - an ExtraSelection object colored with the appropriate color
|
||||||
|
* @return True on success, otherwise False
|
||||||
|
*/
|
||||||
|
bool colorLine(QTextEdit::ExtraSelection extraSelection);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function responsible to highlight all the breakpoints in the decompiler view.
|
||||||
|
* It will also run when a breakpoint is added, removed or modified.
|
||||||
|
*/
|
||||||
|
void highlightBreakpoints();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // DECOMPILERWIDGET_H
|
#endif // DECOMPILERWIDGET_H
|
||||||
|
Loading…
Reference in New Issue
Block a user