mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-21 04:16:12 +00:00
* Use pdJ for DisassemblyWidget * Attach DisassemblyLine to QTextBlock in DisassemblyWidget
This commit is contained in:
parent
fb796d0758
commit
4213852419
@ -1,5 +1,6 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <utils/TempConfig.h>
|
||||||
#include "utils/Configuration.h"
|
#include "utils/Configuration.h"
|
||||||
#include "cutter.h"
|
#include "cutter.h"
|
||||||
#include "sdb.h"
|
#include "sdb.h"
|
||||||
@ -1331,3 +1332,22 @@ void CutterCore::setNotes(const QString ¬es)
|
|||||||
this->notes = notes;
|
this->notes = notes;
|
||||||
emit notesChanged(this->notes);
|
emit notesChanged(this->notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<DisassemblyLine> CutterCore::disassembleLines(RVA offset, int lines)
|
||||||
|
{
|
||||||
|
QJsonArray array = cmdj(QString("pdJ ") + QString::number(lines) + QString(" @ ") + QString::number(offset)).array();
|
||||||
|
QList<DisassemblyLine> r;
|
||||||
|
|
||||||
|
for (QJsonValue value : array)
|
||||||
|
{
|
||||||
|
QJsonObject object = value.toObject();
|
||||||
|
|
||||||
|
DisassemblyLine line;
|
||||||
|
line.offset = object["offset"].toVariant().toULongLong();
|
||||||
|
line.text = object["text"].toString();
|
||||||
|
|
||||||
|
r << line;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
@ -168,6 +168,12 @@ struct RBinPluginDescription
|
|||||||
QString type;
|
QString type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DisassemblyLine
|
||||||
|
{
|
||||||
|
RVA offset;
|
||||||
|
QString text;
|
||||||
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(FunctionDescription)
|
Q_DECLARE_METATYPE(FunctionDescription)
|
||||||
Q_DECLARE_METATYPE(ImportDescription)
|
Q_DECLARE_METATYPE(ImportDescription)
|
||||||
Q_DECLARE_METATYPE(ExportDescription)
|
Q_DECLARE_METATYPE(ExportDescription)
|
||||||
@ -202,6 +208,9 @@ public:
|
|||||||
QString cmd(const QString &str);
|
QString cmd(const QString &str);
|
||||||
QJsonDocument cmdj(const QString &str);
|
QJsonDocument cmdj(const QString &str);
|
||||||
QStringList cmdList(const QString &str) { auto l = cmd(str).split("\n"); l.removeAll(""); return l; }
|
QStringList cmdList(const QString &str) { auto l = cmd(str).split("\n"); l.removeAll(""); return l; }
|
||||||
|
|
||||||
|
QList<DisassemblyLine> disassembleLines(RVA offset, int lines);
|
||||||
|
|
||||||
void renameFunction(QString prev_name, QString new_name);
|
void renameFunction(QString prev_name, QString new_name);
|
||||||
void delFunction(RVA addr);
|
void delFunction(RVA addr);
|
||||||
void renameFlag(QString old_name, QString new_name);
|
void renameFlag(QString old_name, QString new_name);
|
||||||
|
@ -11,6 +11,19 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QTextBlockUserData>
|
||||||
|
|
||||||
|
|
||||||
|
class DisassemblyTextBlockUserData: public QTextBlockUserData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DisassemblyLine line;
|
||||||
|
|
||||||
|
explicit DisassemblyTextBlockUserData(const DisassemblyLine &line)
|
||||||
|
{
|
||||||
|
this->line = line;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
DisassemblyWidget::DisassemblyWidget(QWidget *parent)
|
DisassemblyWidget::DisassemblyWidget(QWidget *parent)
|
||||||
@ -126,25 +139,6 @@ QWidget* DisassemblyWidget::getTextWidget()
|
|||||||
return mDisasTextEdit;
|
return mDisasTextEdit;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString DisassemblyWidget::readDisasm(const QString &cmd, bool stripLastNewline)
|
|
||||||
{
|
|
||||||
TempConfig tempConfig;
|
|
||||||
tempConfig.set("scr.html", true)
|
|
||||||
.set("scr.color", true);
|
|
||||||
|
|
||||||
QString disas = Core()->cmd(cmd);
|
|
||||||
|
|
||||||
if (stripLastNewline)
|
|
||||||
{
|
|
||||||
// ugly hack to remove trailing newline
|
|
||||||
static const auto trimBrRegExp = QRegularExpression("<br />$");
|
|
||||||
disas = disas.remove(trimBrRegExp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return disas.trimmed();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DisassemblyWidget::refreshDisasm(RVA offset)
|
void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||||
{
|
{
|
||||||
if (offset != RVA_INVALID)
|
if (offset != RVA_INVALID)
|
||||||
@ -168,11 +162,25 @@ void DisassemblyWidget::refreshDisasm(RVA offset)
|
|||||||
int horizontalScrollValue = mDisasTextEdit->horizontalScrollBar()->value();
|
int horizontalScrollValue = mDisasTextEdit->horizontalScrollBar()->value();
|
||||||
mDisasTextEdit->setLockScroll(true); // avoid flicker
|
mDisasTextEdit->setLockScroll(true); // avoid flicker
|
||||||
|
|
||||||
QString disas = readDisasm("pd " + QString::number(maxLines) + "@" + QString::number(topOffset), true);
|
QList<DisassemblyLine> disassemblyLines;
|
||||||
|
{
|
||||||
|
TempConfig tempConfig;
|
||||||
|
tempConfig.set("scr.html", true)
|
||||||
|
.set("scr.color", true);
|
||||||
|
disassemblyLines = Core()->disassembleLines(topOffset, maxLines);
|
||||||
|
}
|
||||||
|
|
||||||
connectCursorPositionChanged(true);
|
connectCursorPositionChanged(true);
|
||||||
|
|
||||||
mDisasTextEdit->document()->setHtml(disas);
|
mDisasTextEdit->document()->clear();
|
||||||
|
QTextCursor cursor(mDisasTextEdit->document());
|
||||||
|
for (DisassemblyLine line : disassemblyLines)
|
||||||
|
{
|
||||||
|
cursor.insertHtml(line.text);
|
||||||
|
auto a = new DisassemblyTextBlockUserData(line);
|
||||||
|
cursor.block().setUserData(a);
|
||||||
|
cursor.insertBlock();
|
||||||
|
}
|
||||||
|
|
||||||
// get bottomOffset from last visible line.
|
// get bottomOffset from last visible line.
|
||||||
// because pd N may return more than N lines, move maxLines lines down from the top
|
// because pd N may return more than N lines, move maxLines lines down from the top
|
||||||
@ -307,34 +315,16 @@ RVA DisassemblyWidget::readCurrentDisassemblyOffset()
|
|||||||
|
|
||||||
RVA DisassemblyWidget::readDisassemblyOffset(QTextCursor tc)
|
RVA DisassemblyWidget::readDisassemblyOffset(QTextCursor tc)
|
||||||
{
|
{
|
||||||
// TODO: do this in a different way without parsing the disassembly text
|
QTextBlockUserData *userData = tc.block().userData();
|
||||||
|
if (!userData)
|
||||||
static const QRegularExpression offsetRegExp("^0x[0-9A-Fa-f]*");
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
tc.select(QTextCursor::LineUnderCursor);
|
|
||||||
|
|
||||||
QString line = tc.selectedText();
|
|
||||||
|
|
||||||
auto match = offsetRegExp.match(line);
|
|
||||||
if (match.hasMatch())
|
|
||||||
{
|
|
||||||
return match.captured(0).toULongLong(nullptr, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
tc.movePosition(QTextCursor::StartOfLine);
|
|
||||||
if (tc.atStart())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tc.movePosition(QTextCursor::Up);
|
|
||||||
}
|
|
||||||
|
|
||||||
return RVA_INVALID;
|
return RVA_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto *dsUserData = static_cast<DisassemblyTextBlockUserData *>(userData);
|
||||||
|
return dsUserData->line.offset;
|
||||||
|
}
|
||||||
|
|
||||||
void DisassemblyWidget::updateCursorPosition()
|
void DisassemblyWidget::updateCursorPosition()
|
||||||
{
|
{
|
||||||
RVA offset = Core()->getOffset();
|
RVA offset = Core()->getOffset();
|
||||||
|
@ -46,7 +46,6 @@ private:
|
|||||||
RVA bottomOffset;
|
RVA bottomOffset;
|
||||||
int maxLines;
|
int maxLines;
|
||||||
|
|
||||||
QString readDisasm(const QString &cmd, bool stripLastNewline);
|
|
||||||
RVA readCurrentDisassemblyOffset();
|
RVA readCurrentDisassemblyOffset();
|
||||||
RVA readDisassemblyOffset(QTextCursor tc);
|
RVA readDisassemblyOffset(QTextCursor tc);
|
||||||
bool eventFilter(QObject *obj, QEvent *event);
|
bool eventFilter(QObject *obj, QEvent *event);
|
||||||
|
Loading…
Reference in New Issue
Block a user