summaryrefslogtreecommitdiff
path: root/ui/variablelist.h
blob: cc1e1de5f205d83ec70b120bc8acfe0318bcd3e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#pragma once

#include <QtCore/QTimer>
#include <QtWidgets/QListView>
#include <QtWidgets/QStyledItemDelegate>
#include <QtWidgets/QWidget>

#include "binaryninjacore.h"
#include "dockhandler.h"
#include "uitypes.h"
#include "viewframe.h"

//! A variable list item can represent either a function-local variable, or a
//! data variable referenced by the current function.
enum class VariableListItemType
{
	LocalVariable,
	DataVariable
};

//! An item part of VariableListModel.
class VariableListItem
{
	FunctionRef m_func;
	VariableListItemType m_type;
	std::string m_name;

	uint64_t m_refPoint;

	BinaryNinja::Variable m_var;
	BinaryNinja::DataVariable m_dataVar;
	BinaryNinja::PossibleValueSet m_pvs;
	bool m_hasUidf;

 public:
	//! Create a new VariableListItem of the LocalVariable type.
	VariableListItem(FunctionRef func, BinaryNinja::Variable var, BinaryNinja::PossibleValueSet pvs,
	    bool hasUidf, std::string name);

	//! Create a new VariableListItem of the DataVariable type.
	VariableListItem(
	    FunctionRef func, BinaryNinja::DataVariable dataVar, uint64_t refPoint, std::string name);

	//! Get the type of this list item.
	VariableListItemType type() const;

	//! Get the represented variable's display name.
	std::string name() const;

	//! Get the data variable's value; use with data variable items only.
	std::string constantValue() const;

	//! Get the variable possible value set; use with local variable items only.
	BinaryNinja::PossibleValueSet possibleValueSet() const;

	//! Is the PVS user-provided? Use with local variable items only.
	bool hasUidf() const;

	std::vector<BinaryNinja::InstructionTextToken> tokensBeforeName() const;
	std::vector<BinaryNinja::InstructionTextToken> tokensAfterName() const;

	//! Shorthand to get concatenated type, name, and value tokens.
	std::vector<BinaryNinja::InstructionTextToken> displayTokens() const;

	//! Get the represented variable; use with variable items only.
	BinaryNinja::Variable variable() const;

	//! Get the represented data variable; use with data variable items only.
	BinaryNinja::DataVariable dataVariable() const;

	//! Get the first use of this variable; use with data variables items only.
	uint64_t refPoint() const;

	//! Is any part of this item user-defined?
	bool isUserDefined() const;
};

//! The backing model for the variable list widget, holds VariableListItem.
class BINARYNINJAUIAPI VariableListModel : public QAbstractListModel
{
	Q_OBJECT

	ViewFrame* m_view;
	BinaryViewRef m_data;
	FunctionRef m_func;
	BinaryNinja::AdvancedFunctionAnalysisDataRequestor m_analysisRequestor;
	std::vector<VariableListItem> m_items;

	QItemSelectionModel* m_selModel;

	size_t m_prevVariableCount;
	uint64_t m_prevSelectionId;

 public:
	VariableListModel(QWidget* parent, ViewFrame* view, BinaryViewRef data);

	//! Clear the list's content.
	void clear();

	//! Get the current function.
	FunctionRef function() const;

	//! Set the focused function and update the content of the list.
	void setFunction(FunctionRef func, BNFunctionGraphType il, const HighlightTokenState& hts);

	//! Set the selection model, should correspond to the parent widget's.
	void setSelectionModel(QItemSelectionModel* model);

	virtual QVariant data(const QModelIndex& i, int role) const override;
	virtual QModelIndex index(
	    int row, int col, const QModelIndex& parent = QModelIndex()) const override;
	virtual int columnCount(const QModelIndex& parent = QModelIndex()) const override;
	virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
	Qt::ItemFlags flags(const QModelIndex& index) const override;
	virtual QVariant headerData(int column, Qt::Orientation orientation, int role) const override;
};

class VariableListItemDelegate : public QStyledItemDelegate
{
	Q_OBJECT
 public:
	VariableListItemDelegate();

	void paint(QPainter* painter, const QStyleOptionViewItem& opt, const QModelIndex& index) const;
	QSize sizeHint(const QStyleOptionViewItem& opt, const QModelIndex& index) const;
};

//! The main variable list dock widget.
class BINARYNINJAUIAPI VariableList : public SidebarWidget
{
	Q_OBJECT

	QWidget* m_header;

	ViewFrame* m_view;
	BinaryViewRef m_data;

	VariableListModel* m_listModel;
	QListView* m_list;

	uint64_t m_lastOffset;
	QTimer* m_refreshTimer;

	void processRefresh();

 public:
	VariableList(ViewFrame* view, BinaryViewRef data);

	QWidget* headerWidget() override { return m_header; }
	void focus() override { refresh(); }

	void refresh();

	//! Get the VariableListItem corresponding to the current selection.
	VariableListItem* selectedItem() const;

	//! Show the rename dialog for the selected variable.
	void changeSelectedVariableName();

	//! Show the new type dialog for the seleected variable.
	void changeSelectedVariableType();

	//! Clear the selected variable's name.
	void clearSelectedVariableName();

	//! Clear the selected variable's type.
	void clearSelectedVariableType();

	//! Undefine the selected variable's user symbol.
	void clearSelectedVariableNameAndType();

	//! Navigate to the first usage of the selected variable.
	void showSelectedVariableFirstUsage();

	//! Navigate to the definition of the selected data variable.
	void showSelectedDataVariableDefinition();

	//! Set the selected variable's DSE policy.
	void setSelectedVariableDeadStoreElimination(BNDeadStoreElimination dse);
};

class BINARYNINJAUIAPI VariableListSidebarWidgetType : public SidebarWidgetType
{
 public:
	VariableListSidebarWidgetType();
	virtual SidebarWidget* createWidget(ViewFrame* frame, BinaryViewRef data) override;
};