blob: c5e2d7bf9740c52b74148cb65090afb640dcf3c7 (
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
|
#include <progresstask.h>
#include "symboltable.h"
#include <QHeaderView>
#include "binaryninjaapi.h"
using namespace BinaryNinja;
using namespace SharedCacheAPI;
SymbolTableModel::SymbolTableModel(SymbolTableView* parent)
: QAbstractTableModel(parent), m_parent(parent) {
}
int SymbolTableModel::rowCount(const QModelIndex& parent) const {
Q_UNUSED(parent);
return static_cast<int>(m_symbols.size());
}
int SymbolTableModel::columnCount(const QModelIndex& parent) const {
Q_UNUSED(parent);
// We have 2 columns: Address, Name
return 2;
}
QVariant SymbolTableModel::data(const QModelIndex& index, int role) const {
if (!index.isValid() || role != Qt::DisplayRole) {
return QVariant();
}
const CacheSymbol& symbol = m_symbols.at(index.row());
switch (index.column()) {
case 0: // Address column
return QString("0x%1").arg(symbol.address, 0, 16); // Display address as hexadecimal
case 1: // Name column
return QString::fromUtf8(symbol.name.c_str(), symbol.name.size());
default:
return QVariant();
}
}
QVariant SymbolTableModel::headerData(int section, Qt::Orientation orientation, int role) const {
if (role != Qt::DisplayRole || orientation != Qt::Horizontal) {
return QVariant();
}
switch (section) {
case 0:
return QString("Address");
case 1:
return QString("Name");
default:
return QVariant();
}
}
void SymbolTableModel::updateSymbols() {
m_symbols = m_parent->m_symbols;
setFilter(m_filter);
}
const CacheSymbol& SymbolTableModel::symbolAt(int row) const {
return m_symbols.at(row);
}
void SymbolTableModel::setFilter(std::string text)
{
beginResetModel();
m_filter = text;
m_symbols.clear();
if (m_filter.empty())
{
m_symbols = m_parent->m_symbols;
}
else
{
m_symbols.reserve(m_parent->m_symbols.size());
for (const auto& symbol : m_parent->m_symbols)
{
if (((std::string_view)symbol.name).find(m_filter) != std::string::npos)
{
m_symbols.push_back(symbol);
}
}
m_symbols.shrink_to_fit();
}
endResetModel();
}
SymbolTableView::SymbolTableView(QWidget* parent)
: m_model(new SymbolTableModel(this)) {
// Set up the filter model
setModel(m_model);
// Configure view settings
horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::SingleSelection);
setSortingEnabled(true);
}
SymbolTableView::~SymbolTableView() {
delete m_model;
}
void SymbolTableView::populateSymbols(BinaryView &view)
{
if (auto controller = SharedCacheController::GetController(view)) {
BackgroundThread::create(this)
->thenBackground([this, controller]() {
std::vector<CacheSymbol> newSymbols = controller->GetSymbols();
m_symbols.swap(newSymbols);
})
->thenMainThread([this](){ m_model->updateSymbols(); })
->start();
}
}
void SymbolTableView::setFilter(const std::string& filter) {
m_model->setFilter(filter);
}
|