mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-20 20:06: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 <QJsonObject>
|
||||
#include <utils/TempConfig.h>
|
||||
#include "utils/Configuration.h"
|
||||
#include "cutter.h"
|
||||
#include "sdb.h"
|
||||
@ -1331,3 +1332,22 @@ void CutterCore::setNotes(const QString ¬es)
|
||||
this->notes = 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;
|
||||
};
|
||||
|
||||
struct DisassemblyLine
|
||||
{
|
||||
RVA offset;
|
||||
QString text;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(FunctionDescription)
|
||||
Q_DECLARE_METATYPE(ImportDescription)
|
||||
Q_DECLARE_METATYPE(ExportDescription)
|
||||
@ -202,6 +208,9 @@ public:
|
||||
QString cmd(const QString &str);
|
||||
QJsonDocument cmdj(const QString &str);
|
||||
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 delFunction(RVA addr);
|
||||
void renameFlag(QString old_name, QString new_name);
|
||||
|
@ -11,6 +11,19 @@
|
||||
#include <QJsonObject>
|
||||
#include <QVBoxLayout>
|
||||
#include <QRegularExpression>
|
||||
#include <QTextBlockUserData>
|
||||
|
||||
|
||||
class DisassemblyTextBlockUserData: public QTextBlockUserData
|
||||
{
|
||||
public:
|
||||
DisassemblyLine line;
|
||||
|
||||
explicit DisassemblyTextBlockUserData(const DisassemblyLine &line)
|
||||
{
|
||||
this->line = line;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
DisassemblyWidget::DisassemblyWidget(QWidget *parent)
|
||||
@ -126,25 +139,6 @@ QWidget* DisassemblyWidget::getTextWidget()
|
||||
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)
|
||||
{
|
||||
if (offset != RVA_INVALID)
|
||||
@ -168,11 +162,25 @@ void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||
int horizontalScrollValue = mDisasTextEdit->horizontalScrollBar()->value();
|
||||
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);
|
||||
|
||||
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.
|
||||
// because pd N may return more than N lines, move maxLines lines down from the top
|
||||
@ -307,32 +315,14 @@ RVA DisassemblyWidget::readCurrentDisassemblyOffset()
|
||||
|
||||
RVA DisassemblyWidget::readDisassemblyOffset(QTextCursor tc)
|
||||
{
|
||||
// TODO: do this in a different way without parsing the disassembly text
|
||||
|
||||
static const QRegularExpression offsetRegExp("^0x[0-9A-Fa-f]*");
|
||||
|
||||
while (true)
|
||||
QTextBlockUserData *userData = tc.block().userData();
|
||||
if (!userData)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
auto *dsUserData = static_cast<DisassemblyTextBlockUserData *>(userData);
|
||||
return dsUserData->line.offset;
|
||||
}
|
||||
|
||||
void DisassemblyWidget::updateCursorPosition()
|
||||
|
@ -46,7 +46,6 @@ private:
|
||||
RVA bottomOffset;
|
||||
int maxLines;
|
||||
|
||||
QString readDisasm(const QString &cmd, bool stripLastNewline);
|
||||
RVA readCurrentDisassemblyOffset();
|
||||
RVA readDisassemblyOffset(QTextCursor tc);
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
Loading…
Reference in New Issue
Block a user