mirror of
https://github.com/rizinorg/cutter.git
synced 2024-12-24 13:55:26 +00:00
Register refs widget improvements (#2038)
* Move register refs to the new telescoping function and add an addressable context menu
This commit is contained in:
parent
969ce5ac30
commit
a1b5a41e56
@ -1156,6 +1156,86 @@ QJsonDocument CutterCore::getSignatureInfo()
|
|||||||
return cmdj("iCj");
|
return cmdj("iCj");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utility function to check if a telescoped item exists and add it with prefixes to the desc
|
||||||
|
static inline const QString appendVar(QString &dst, const QString val, const QString prepend_val,
|
||||||
|
const QString append_val)
|
||||||
|
{
|
||||||
|
if (!val.isEmpty()) {
|
||||||
|
dst += prepend_val + val + append_val;
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefDescription CutterCore::formatRefDesc(QJsonObject refItem)
|
||||||
|
{
|
||||||
|
RefDescription desc;
|
||||||
|
|
||||||
|
// Ignore empty refs and refs that only contain addr
|
||||||
|
if (refItem.size() <= 1) {
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString str = refItem["string"].toVariant().toString();
|
||||||
|
if (!str.isEmpty()) {
|
||||||
|
desc.ref = str;
|
||||||
|
desc.refColor = ConfigColor("comment");
|
||||||
|
} else {
|
||||||
|
QString type, string;
|
||||||
|
do {
|
||||||
|
desc.ref += " ->";
|
||||||
|
appendVar(desc.ref, refItem["reg"].toVariant().toString(), " @", "");
|
||||||
|
appendVar(desc.ref, refItem["mapname"].toVariant().toString(), " (", ")");
|
||||||
|
appendVar(desc.ref, refItem["section"].toVariant().toString(), " (", ")");
|
||||||
|
appendVar(desc.ref, refItem["func"].toVariant().toString(), " ", "");
|
||||||
|
type = appendVar(desc.ref, refItem["type"].toVariant().toString(), " ", "");
|
||||||
|
appendVar(desc.ref, refItem["perms"].toVariant().toString(), " ", "");
|
||||||
|
appendVar(desc.ref, refItem["asm"].toVariant().toString(), " \"", "\"");
|
||||||
|
string = appendVar(desc.ref, refItem["string"].toVariant().toString(), " ", "");
|
||||||
|
if (!string.isNull()) {
|
||||||
|
// There is no point in adding ascii and addr info after a string
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!refItem["value"].isNull()) {
|
||||||
|
appendVar(desc.ref, RAddressString(refItem["value"].toVariant().toULongLong()), " ", "");
|
||||||
|
}
|
||||||
|
refItem = refItem["ref"].toObject();
|
||||||
|
} while (!refItem.empty());
|
||||||
|
|
||||||
|
// Set the ref's color according to the last item type
|
||||||
|
if (type == "ascii" || !string.isEmpty()) {
|
||||||
|
desc.refColor = ConfigColor("comment");
|
||||||
|
} else if (type == "program") {
|
||||||
|
desc.refColor = ConfigColor("fname");
|
||||||
|
} else if (type == "library") {
|
||||||
|
desc.refColor = ConfigColor("floc");
|
||||||
|
} else if (type == "stack") {
|
||||||
|
desc.refColor = ConfigColor("offset");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QJsonObject> CutterCore::getRegisterRefs(int depth)
|
||||||
|
{
|
||||||
|
QList<QJsonObject> ret;
|
||||||
|
if (!currentlyDebugging) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject registers = cmdj("drj").object();
|
||||||
|
|
||||||
|
for (const QString &key : registers.keys()) {
|
||||||
|
QJsonObject reg;
|
||||||
|
reg["value"] = registers.value(key);
|
||||||
|
reg["ref"] = getAddrRefs(registers.value(key).toVariant().toULongLong(), depth);
|
||||||
|
reg["name"] = key;
|
||||||
|
ret.append(reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
QList<QJsonObject> CutterCore::getStack(int size, int depth)
|
QList<QJsonObject> CutterCore::getStack(int size, int depth)
|
||||||
{
|
{
|
||||||
QList<QJsonObject> stack;
|
QList<QJsonObject> stack;
|
||||||
@ -1321,26 +1401,6 @@ QJsonDocument CutterCore::getRegisterValues()
|
|||||||
return cmdj("drj");
|
return cmdj("drj");
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<RegisterRefDescription> CutterCore::getRegisterRefs()
|
|
||||||
{
|
|
||||||
QList<RegisterRefDescription> ret;
|
|
||||||
QJsonArray registerRefArray = cmdj("drrj").array();
|
|
||||||
|
|
||||||
for (const QJsonValue &value : registerRefArray) {
|
|
||||||
QJsonObject regRefObject = value.toObject();
|
|
||||||
|
|
||||||
RegisterRefDescription regRef;
|
|
||||||
|
|
||||||
regRef.reg = regRefObject[RJsonKey::reg].toString();
|
|
||||||
regRef.value = regRefObject[RJsonKey::value].toString();
|
|
||||||
regRef.ref = regRefObject[RJsonKey::ref].toString();
|
|
||||||
|
|
||||||
ret << regRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<VariableDescription> CutterCore::getVariables(RVA at)
|
QList<VariableDescription> CutterCore::getVariables(RVA at)
|
||||||
{
|
{
|
||||||
QList<VariableDescription> ret;
|
QList<VariableDescription> ret;
|
||||||
|
@ -312,6 +312,11 @@ public:
|
|||||||
* @param depth telescoping depth
|
* @param depth telescoping depth
|
||||||
*/
|
*/
|
||||||
QJsonObject getAddrRefs(RVA addr, int depth);
|
QJsonObject getAddrRefs(RVA addr, int depth);
|
||||||
|
/**
|
||||||
|
* @brief return a RefDescription with a formatted ref string and configured colors
|
||||||
|
* @param ref the "ref" JSON node from getAddrRefs
|
||||||
|
*/
|
||||||
|
RefDescription formatRefDesc(QJsonObject ref);
|
||||||
/**
|
/**
|
||||||
* @brief Get a list of a given process's threads
|
* @brief Get a list of a given process's threads
|
||||||
* @param pid The pid of the process, -1 for the currently debugged process
|
* @param pid The pid of the process, -1 for the currently debugged process
|
||||||
@ -525,7 +530,11 @@ public:
|
|||||||
BlockStatistics getBlockStatistics(unsigned int blocksCount);
|
BlockStatistics getBlockStatistics(unsigned int blocksCount);
|
||||||
QList<BreakpointDescription> getBreakpoints();
|
QList<BreakpointDescription> getBreakpoints();
|
||||||
QList<ProcessDescription> getAllProcesses();
|
QList<ProcessDescription> getAllProcesses();
|
||||||
QList<RegisterRefDescription> getRegisterRefs();
|
/**
|
||||||
|
* @brief returns a list of reg values and their telescoped references
|
||||||
|
* @param depth telescoping depth
|
||||||
|
*/
|
||||||
|
QList<QJsonObject> getRegisterRefs(int depth = 6);
|
||||||
QJsonObject getRegisterJson();
|
QJsonObject getRegisterJson();
|
||||||
QList<VariableDescription> getVariables(RVA at);
|
QList<VariableDescription> getVariables(RVA at);
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
#include <QColor>
|
||||||
#include "core/CutterCommon.h"
|
#include "core/CutterCommon.h"
|
||||||
|
|
||||||
struct FunctionDescription {
|
struct FunctionDescription {
|
||||||
@ -308,10 +309,9 @@ struct ProcessDescription {
|
|||||||
QString path;
|
QString path;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RegisterRefDescription {
|
struct RefDescription {
|
||||||
QString reg;
|
|
||||||
QString value;
|
|
||||||
QString ref;
|
QString ref;
|
||||||
|
QColor refColor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariableDescription {
|
struct VariableDescription {
|
||||||
@ -357,7 +357,7 @@ Q_DECLARE_METATYPE(MemoryMapDescription)
|
|||||||
Q_DECLARE_METATYPE(BreakpointDescription)
|
Q_DECLARE_METATYPE(BreakpointDescription)
|
||||||
Q_DECLARE_METATYPE(BreakpointDescription::PositionType)
|
Q_DECLARE_METATYPE(BreakpointDescription::PositionType)
|
||||||
Q_DECLARE_METATYPE(ProcessDescription)
|
Q_DECLARE_METATYPE(ProcessDescription)
|
||||||
Q_DECLARE_METATYPE(RegisterRefDescription)
|
Q_DECLARE_METATYPE(RefDescription)
|
||||||
Q_DECLARE_METATYPE(VariableDescription)
|
Q_DECLARE_METATYPE(VariableDescription)
|
||||||
|
|
||||||
#endif // DESCRIPTIONS_H
|
#endif // DESCRIPTIONS_H
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "core/MainWindow.h"
|
#include "core/MainWindow.h"
|
||||||
#include "common/Helpers.h"
|
#include "common/Helpers.h"
|
||||||
|
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QClipboard>
|
#include <QClipboard>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
@ -38,7 +39,14 @@ QVariant RegisterRefModel::data(const QModelIndex &index, int role) const
|
|||||||
case ValueColumn:
|
case ValueColumn:
|
||||||
return registerRef.value;
|
return registerRef.value;
|
||||||
case RefColumn:
|
case RefColumn:
|
||||||
return registerRef.ref;
|
return registerRef.refDesc.ref;
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
case Qt::ForegroundRole:
|
||||||
|
switch (index.column()) {
|
||||||
|
case RefColumn:
|
||||||
|
return registerRef.refDesc.refColor;
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
@ -93,7 +101,7 @@ bool RegisterRefProxyModel::lessThan(const QModelIndex &left, const QModelIndex
|
|||||||
case RegisterRefModel::RegColumn:
|
case RegisterRefModel::RegColumn:
|
||||||
return leftRegRef.reg < rightRegRef.reg;
|
return leftRegRef.reg < rightRegRef.reg;
|
||||||
case RegisterRefModel::RefColumn:
|
case RegisterRefModel::RefColumn:
|
||||||
return leftRegRef.ref < rightRegRef.ref;
|
return leftRegRef.refDesc.ref < rightRegRef.refDesc.ref;
|
||||||
case RegisterRefModel::ValueColumn:
|
case RegisterRefModel::ValueColumn:
|
||||||
return leftRegRef.value < rightRegRef.value;
|
return leftRegRef.value < rightRegRef.value;
|
||||||
default:
|
default:
|
||||||
@ -106,7 +114,8 @@ bool RegisterRefProxyModel::lessThan(const QModelIndex &left, const QModelIndex
|
|||||||
RegisterRefsWidget::RegisterRefsWidget(MainWindow *main, QAction *action) :
|
RegisterRefsWidget::RegisterRefsWidget(MainWindow *main, QAction *action) :
|
||||||
CutterDockWidget(main, action),
|
CutterDockWidget(main, action),
|
||||||
ui(new Ui::RegisterRefsWidget),
|
ui(new Ui::RegisterRefsWidget),
|
||||||
tree(new CutterTreeWidget(this))
|
tree(new CutterTreeWidget(this)),
|
||||||
|
addressableItemContextMenu(this, main)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
@ -122,6 +131,13 @@ RegisterRefsWidget::RegisterRefsWidget(MainWindow *main, QAction *action) :
|
|||||||
actionCopyValue = new QAction(tr("Copy register value"), this);
|
actionCopyValue = new QAction(tr("Copy register value"), this);
|
||||||
actionCopyRef = new QAction(tr("Copy register reference"), this);
|
actionCopyRef = new QAction(tr("Copy register reference"), this);
|
||||||
|
|
||||||
|
addressableItemContextMenu.addAction(actionCopyValue);
|
||||||
|
addressableItemContextMenu.addAction(actionCopyRef);
|
||||||
|
addActions(addressableItemContextMenu.actions());
|
||||||
|
|
||||||
|
connect(ui->registerRefTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
|
||||||
|
this, &RegisterRefsWidget::onCurrentChanged);
|
||||||
|
|
||||||
refreshDeferrer = createRefreshDeferrer([this](){
|
refreshDeferrer = createRefreshDeferrer([this](){
|
||||||
refreshRegisterRef();
|
refreshRegisterRef();
|
||||||
});
|
});
|
||||||
@ -144,8 +160,8 @@ RegisterRefsWidget::RegisterRefsWidget(MainWindow *main, QAction *action) :
|
|||||||
copyClip(RegisterRefModel::RefColumn);
|
copyClip(RegisterRefModel::RefColumn);
|
||||||
});
|
});
|
||||||
ui->registerRefTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
ui->registerRefTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
connect(ui->registerRefTreeView, SIGNAL(customContextMenuRequested(const QPoint &)),
|
connect(ui->registerRefTreeView, &QMenu::customContextMenuRequested,
|
||||||
this, SLOT(showRegRefContextMenu(const QPoint &)));
|
this, &RegisterRefsWidget::customMenuRequested);
|
||||||
|
|
||||||
connect(ui->quickFilterView, &QuickFilterView::filterTextChanged, this, [this] {
|
connect(ui->quickFilterView, &QuickFilterView::filterTextChanged, this, [this] {
|
||||||
tree->showItemsNumber(registerRefProxyModel->rowCount());
|
tree->showItemsNumber(registerRefProxyModel->rowCount());
|
||||||
@ -161,7 +177,19 @@ void RegisterRefsWidget::refreshRegisterRef()
|
|||||||
}
|
}
|
||||||
|
|
||||||
registerRefModel->beginResetModel();
|
registerRefModel->beginResetModel();
|
||||||
registerRefs = Core()->getRegisterRefs();
|
|
||||||
|
QList<QJsonObject> regRefs = Core()->getRegisterRefs();
|
||||||
|
registerRefs.clear();
|
||||||
|
for (const QJsonObject ® : regRefs) {
|
||||||
|
RegisterRefDescription desc;
|
||||||
|
|
||||||
|
desc.value = RAddressString(reg["value"].toVariant().toULongLong());
|
||||||
|
desc.reg = reg["name"].toVariant().toString();
|
||||||
|
desc.refDesc = Core()->formatRefDesc(reg["ref"].toObject());
|
||||||
|
|
||||||
|
registerRefs.push_back(desc);
|
||||||
|
}
|
||||||
|
|
||||||
registerRefModel->endResetModel();
|
registerRefModel->endResetModel();
|
||||||
|
|
||||||
ui->registerRefTreeView->resizeColumnToContents(0);
|
ui->registerRefTreeView->resizeColumnToContents(0);
|
||||||
@ -183,15 +211,27 @@ void RegisterRefsWidget::on_registerRefTreeView_doubleClicked(const QModelIndex
|
|||||||
Core()->seekAndShow(item.value);
|
Core()->seekAndShow(item.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterRefsWidget::showRegRefContextMenu(const QPoint &pt)
|
void RegisterRefsWidget::customMenuRequested(QPoint pos)
|
||||||
{
|
{
|
||||||
QMenu *menu = new QMenu(ui->registerRefTreeView);
|
addressableItemContextMenu.exec(ui->registerRefTreeView->viewport()->mapToGlobal(pos));
|
||||||
menu->clear();
|
}
|
||||||
menu->addAction(actionCopyValue);
|
|
||||||
menu->addAction(actionCopyRef);
|
|
||||||
|
|
||||||
menu->exec(ui->registerRefTreeView->viewport()->mapToGlobal(pt));
|
void RegisterRefsWidget::onCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous)
|
||||||
delete menu;
|
{
|
||||||
|
Q_UNUSED(current)
|
||||||
|
Q_UNUSED(previous)
|
||||||
|
auto currentIndex = ui->registerRefTreeView->selectionModel()->currentIndex();
|
||||||
|
|
||||||
|
// Use the value column as the offset
|
||||||
|
QString offsetString;
|
||||||
|
if (currentIndex.column() != RegisterRefModel::RefColumn) {
|
||||||
|
offsetString = currentIndex.data().toString();
|
||||||
|
} else {
|
||||||
|
offsetString = currentIndex.sibling(currentIndex.row(), RegisterRefModel::ValueColumn).data().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
RVA offset = Core()->math(offsetString);
|
||||||
|
addressableItemContextMenu.setTarget(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterRefsWidget::copyClip(int column)
|
void RegisterRefsWidget::copyClip(int column)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "core/Cutter.h"
|
#include "core/Cutter.h"
|
||||||
#include "CutterDockWidget.h"
|
#include "CutterDockWidget.h"
|
||||||
#include "CutterTreeWidget.h"
|
#include "CutterTreeWidget.h"
|
||||||
|
#include "menus/AddressableItemContextMenu.h"
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
@ -21,6 +22,12 @@ class RegisterRefsWidget;
|
|||||||
class MainWindow;
|
class MainWindow;
|
||||||
class QTreeWidgetItem;
|
class QTreeWidgetItem;
|
||||||
|
|
||||||
|
struct RegisterRefDescription {
|
||||||
|
QString reg;
|
||||||
|
QString value;
|
||||||
|
RefDescription refDesc;
|
||||||
|
};
|
||||||
|
Q_DECLARE_METATYPE(RegisterRefDescription)
|
||||||
|
|
||||||
class RegisterRefModel: public QAbstractListModel
|
class RegisterRefModel: public QAbstractListModel
|
||||||
{
|
{
|
||||||
@ -44,8 +51,6 @@ public:
|
|||||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RegisterRefProxyModel : public QSortFilterProxyModel
|
class RegisterRefProxyModel : public QSortFilterProxyModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -71,7 +76,8 @@ private slots:
|
|||||||
void on_registerRefTreeView_doubleClicked(const QModelIndex &index);
|
void on_registerRefTreeView_doubleClicked(const QModelIndex &index);
|
||||||
void refreshRegisterRef();
|
void refreshRegisterRef();
|
||||||
void copyClip(int column);
|
void copyClip(int column);
|
||||||
void showRegRefContextMenu(const QPoint &pt);
|
void customMenuRequested(QPoint pos);
|
||||||
|
void onCurrentChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::RegisterRefsWidget> ui;
|
std::unique_ptr<Ui::RegisterRefsWidget> ui;
|
||||||
@ -79,10 +85,12 @@ private:
|
|||||||
RegisterRefModel *registerRefModel;
|
RegisterRefModel *registerRefModel;
|
||||||
RegisterRefProxyModel *registerRefProxyModel;
|
RegisterRefProxyModel *registerRefProxyModel;
|
||||||
QList<RegisterRefDescription> registerRefs;
|
QList<RegisterRefDescription> registerRefs;
|
||||||
QAction *actionCopyValue;
|
|
||||||
QAction *actionCopyRef;
|
|
||||||
CutterTreeWidget *tree;
|
CutterTreeWidget *tree;
|
||||||
void setScrollMode();
|
void setScrollMode();
|
||||||
|
|
||||||
RefreshDeferrer *refreshDeferrer;
|
RefreshDeferrer *refreshDeferrer;
|
||||||
|
|
||||||
|
QAction *actionCopyValue;
|
||||||
|
QAction *actionCopyRef;
|
||||||
|
AddressableItemContextMenu addressableItemContextMenu;
|
||||||
};
|
};
|
||||||
|
@ -144,16 +144,6 @@ StackModel::StackModel(QObject *parent)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function to check if a telescoped item exists and add it with prefixes to the desc
|
|
||||||
static inline const QString append_var(QString &dst, const QString val, const QString prepend_val,
|
|
||||||
const QString append_val)
|
|
||||||
{
|
|
||||||
if (!val.isEmpty()) {
|
|
||||||
dst += prepend_val + val + append_val;
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StackModel::reload()
|
void StackModel::reload()
|
||||||
{
|
{
|
||||||
QList<QJsonObject> stackItems = Core()->getStack();
|
QList<QJsonObject> stackItems = Core()->getStack();
|
||||||
@ -165,47 +155,8 @@ void StackModel::reload()
|
|||||||
|
|
||||||
item.offset = stackItem["addr"].toVariant().toULongLong();
|
item.offset = stackItem["addr"].toVariant().toULongLong();
|
||||||
item.value = RAddressString(stackItem["value"].toVariant().toULongLong());
|
item.value = RAddressString(stackItem["value"].toVariant().toULongLong());
|
||||||
|
item.refDesc = Core()->formatRefDesc(stackItem["ref"].toObject());
|
||||||
|
|
||||||
QJsonObject refItem = stackItem["ref"].toObject();
|
|
||||||
if (!refItem.empty()) {
|
|
||||||
QString str = refItem["string"].toVariant().toString();
|
|
||||||
if (!str.isEmpty()) {
|
|
||||||
item.description = str;
|
|
||||||
item.descriptionColor = ConfigColor("comment");
|
|
||||||
} else {
|
|
||||||
QString type, string;
|
|
||||||
do {
|
|
||||||
item.description += " ->";
|
|
||||||
append_var(item.description, refItem["reg"].toVariant().toString(), " @", "");
|
|
||||||
append_var(item.description, refItem["mapname"].toVariant().toString(), " (", ")");
|
|
||||||
append_var(item.description, refItem["section"].toVariant().toString(), " (", ")");
|
|
||||||
append_var(item.description, refItem["func"].toVariant().toString(), " ", "");
|
|
||||||
type = append_var(item.description, refItem["type"].toVariant().toString(), " ", "");
|
|
||||||
append_var(item.description, refItem["perms"].toVariant().toString(), " ", "");
|
|
||||||
append_var(item.description, refItem["asm"].toVariant().toString(), " \"", "\"");
|
|
||||||
string = append_var(item.description, refItem["string"].toVariant().toString(), " ", "");
|
|
||||||
if (!string.isNull()) {
|
|
||||||
// There is no point in adding ascii and addr info after a string
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!refItem["value"].isNull()) {
|
|
||||||
append_var(item.description, RAddressString(refItem["value"].toVariant().toULongLong()), " ", "");
|
|
||||||
}
|
|
||||||
refItem = refItem["ref"].toObject();
|
|
||||||
} while (!refItem.empty());
|
|
||||||
|
|
||||||
// Set the description's color according to the last item type
|
|
||||||
if (type == "ascii" || !string.isEmpty()) {
|
|
||||||
item.descriptionColor = ConfigColor("comment");
|
|
||||||
} else if (type == "program") {
|
|
||||||
item.descriptionColor = ConfigColor("fname");
|
|
||||||
} else if (type == "library") {
|
|
||||||
item.descriptionColor = ConfigColor("floc");
|
|
||||||
} else if (type == "stack") {
|
|
||||||
item.descriptionColor = ConfigColor("offset");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
values.push_back(item);
|
values.push_back(item);
|
||||||
}
|
}
|
||||||
endResetModel();
|
endResetModel();
|
||||||
@ -236,14 +187,14 @@ QVariant StackModel::data(const QModelIndex &index, int role) const
|
|||||||
case ValueColumn:
|
case ValueColumn:
|
||||||
return item.value;
|
return item.value;
|
||||||
case DescriptionColumn:
|
case DescriptionColumn:
|
||||||
return item.description;
|
return item.refDesc.ref;
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
case Qt::ForegroundRole:
|
case Qt::ForegroundRole:
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case DescriptionColumn:
|
case DescriptionColumn:
|
||||||
return item.descriptionColor;
|
return item.refDesc.refColor;
|
||||||
default:
|
default:
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,7 @@ public:
|
|||||||
struct Item {
|
struct Item {
|
||||||
RVA offset;
|
RVA offset;
|
||||||
QString value;
|
QString value;
|
||||||
QString description;
|
RefDescription refDesc;
|
||||||
QVariant descriptionColor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Column { OffsetColumn = 0, ValueColumn, DescriptionColumn, ColumnCount};
|
enum Column { OffsetColumn = 0, ValueColumn, DescriptionColumn, ColumnCount};
|
||||||
|
Loading…
Reference in New Issue
Block a user