summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2019-07-05 11:29:28 -0400
committerPeter LaFosse <peter@vector35.com>2019-07-14 14:42:52 -0400
commita096663fc17d08af0bf2581150b618a1a8f09767 (patch)
treea865bc30f99da2612ed4aa61d46e0c483fb35b19 /ui
parentc061061966ee12a7d6ace672b7798257eeb22cfd (diff)
Add support for sorting the symbol list by name or address
Refactoring Function List to support Symbols and Data Variables too Renaming FunctionList and FunctionsView to SymbolList/SymbolsView Keep track of current selection and scroll position between model resets
Diffstat (limited to 'ui')
-rw-r--r--ui/action.h1
-rw-r--r--ui/dockhandler.h4
-rw-r--r--ui/functionlist.h138
-rw-r--r--ui/symbollist.h294
-rw-r--r--ui/symbolsview.h (renamed from ui/functionsview.h)13
-rw-r--r--ui/viewframe.h2
6 files changed, 305 insertions, 147 deletions
diff --git a/ui/action.h b/ui/action.h
index dbeb06d1..7770a016 100644
--- a/ui/action.h
+++ b/ui/action.h
@@ -35,6 +35,7 @@ struct BINARYNINJAUIAPI HighlightTokenState
HighlightTokenState();
};
+
struct BINARYNINJAUIAPI UIActionContext
{
UIContext* context;
diff --git a/ui/dockhandler.h b/ui/dockhandler.h
index e0b62c27..ab6596c7 100644
--- a/ui/dockhandler.h
+++ b/ui/dockhandler.h
@@ -62,8 +62,8 @@ public:
DockContextHandler(QWidget* widget, const QString& name);
virtual ~DockContextHandler();
- QString getName() { return m_name; }
- QWidget* getParentWindow() { return m_parentWindow; }
+ QString getName() const { return m_name; }
+ QWidget* getParentWindow() const { return m_parentWindow; }
virtual void notifyFontChanged() { }
virtual void notifyOffsetChanged(uint64_t /*offset*/) { }
diff --git a/ui/functionlist.h b/ui/functionlist.h
deleted file mode 100644
index c9119d3e..00000000
--- a/ui/functionlist.h
+++ /dev/null
@@ -1,138 +0,0 @@
-#pragma once
-
-#include <QtWidgets/QListView>
-#include <QtCore/QAbstractItemModel>
-#include <QtCore/QTimer>
-#include <QtWidgets/QLineEdit>
-#include <vector>
-#include <mutex>
-#include "binaryninjaapi.h"
-#include "viewframe.h"
-#include "filter.h"
-#include "uicontext.h"
-
-#define FUNCTION_LIST_UPDATE_INTERVAL 250
-
-class FunctionsView;
-
-class BINARYNINJAUIAPI FunctionListModel: public QAbstractItemModel, public BinaryNinja::BinaryDataNotification
-{
- Q_OBJECT
-
- enum FunctonListUpdateType
- {
- AddedToFunctionList,
- RemovedFromFunctionList,
- UpdatedInFunctionList
- };
-
- struct FunctionListUpdateEvent
- {
- FunctionRef func;
- FunctonListUpdateType type;
- };
-
- struct NamedFunction
- {
- FunctionRef func;
- std::string name;
- bool named;
- };
-
- class FunctionListUpdate: public BinaryNinja::RefCountObject
- {
- std::mutex m_mutex;
- bool m_valid;
- FunctionListModel* m_model;
-
- public:
- FunctionListUpdate(FunctionListModel* model);
- void start();
- void abort();
- };
-
- QWidget* m_funcList;
- ViewFrame* m_view;
- BinaryViewRef m_data;
- std::vector<FunctionRef> m_funcs;
- std::vector<NamedFunction> m_allFuncs;
- FunctionRef m_currentFunc;
- std::string m_filter;
-
- std::mutex m_updateMutex;
- std::vector<FunctionListUpdateEvent> m_updates;
- bool m_fullUpdate;
-
- BinaryNinja::Ref<FunctionListUpdate> m_backgroundUpdate;
- volatile bool m_backgroundUpdateComplete;
- std::vector<FunctionRef> m_backgroundUpdateFuncs;
-
-
- static bool functionComparison(const FunctionRef& a, const FunctionRef& b);
- static bool allFunctionComparison(const NamedFunction& a, const NamedFunction& b);
-
-public:
- FunctionListModel(QWidget* parent, ViewFrame* view, BinaryViewRef data);
- virtual ~FunctionListModel();
-
- virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
- virtual QModelIndex parent(const QModelIndex& i) const override;
- virtual bool hasChildren(const QModelIndex& parent) const override;
- virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
- virtual int columnCount(const QModelIndex& parent) const override;
- virtual QVariant data(const QModelIndex& i, int role) const override;
-
- virtual void OnAnalysisFunctionAdded(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
- virtual void OnAnalysisFunctionRemoved(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
- virtual void OnAnalysisFunctionUpdated(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
-
- void updateFonts();
- bool setCurrentFunction(FunctionRef func);
- QModelIndex findFunction(FunctionRef func);
- QModelIndex findCurrentFunction();
- FunctionRef getFunctionForIndex(int i);
-
- void updateFunctions();
- void backgroundUpdate();
- bool hasFunctions() const;
-
- void setFilter(const std::string& filter);
-};
-
-class BINARYNINJAUIAPI FunctionList: public QListView, public FilterTarget
-{
- Q_OBJECT
-
- ViewFrame* m_view;
- BinaryViewRef m_data;
- FunctionsView* m_functionsView;
- FunctionListModel* m_list;
- QTimer* m_updateTimer;
- bool m_disableScrollToFunction;
-
-public:
- FunctionList(FunctionsView* parent, ViewFrame* frame, BinaryViewRef data);
-
- void updateFonts();
- void setCurrentFunction(FunctionRef func);
-
- virtual void scrollToFirstItem() override;
- virtual void scrollToCurrentItem() override;
- virtual void selectFirstItem() override;
- virtual void activateFirstItem() override;
- virtual void setFilter(const std::string& filter) override;
-
- bool hasFunctions();
-
- virtual void copy();
- virtual void paste();
- virtual bool canCopy();
-
-protected:
- virtual void focusOutEvent(QFocusEvent* event) override;
- virtual void keyPressEvent(QKeyEvent* event) override;
-
-private Q_SLOTS:
- void goToFunction(const QModelIndex& i);
- void updateTimerEvent();
-};
diff --git a/ui/symbollist.h b/ui/symbollist.h
new file mode 100644
index 00000000..e1edb6b5
--- /dev/null
+++ b/ui/symbollist.h
@@ -0,0 +1,294 @@
+#pragma once
+
+#include <QtWidgets/QListView>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QTimer>
+#include <QtWidgets/QLineEdit>
+#include <vector>
+#include <set>
+#include <mutex>
+#include "binaryninjaapi.h"
+#include "viewframe.h"
+#include "filter.h"
+#include "uicontext.h"
+#include "menus.h"
+
+#define FUNCTION_LIST_UPDATE_INTERVAL 250
+
+class SymbolsView;
+static std::string emptyArch;
+
+class BINARYNINJAUIAPI SymbolListModel: public QAbstractItemModel, public BinaryNinja::BinaryDataNotification
+{
+ Q_OBJECT
+public:
+ enum SortType
+ {
+ SortAcendingAddresses,
+ SortDecendingAddresses,
+ SortAlphabeticallyAcending,
+ SortAlphabeticallyDecending
+ };
+
+ struct NamedObject
+ {
+ SymbolRef sym;
+ std::string archName;
+ NamedObject() : sym(nullptr), archName(emptyArch) {}
+ NamedObject(SymbolRef s, std::string& a=emptyArch) : sym(s), archName(a) {}
+ NamedObject(const NamedObject& n)
+ {
+ sym = n.sym;
+ archName = n.archName;
+ }
+
+ // NamedObject(const NamedObject&& n)
+ // {
+ // sym = std::move(n.sym);
+ // archName = std::move(n.archName);
+ // }
+
+ // NamedObject& operation=(const NamedObject&& n)
+ // {
+ // sym = std::move(n.sym);
+ // archName = std::move(n.archName);
+ // }
+
+ bool operator<(const NamedObject& other) const
+ {
+ if (getStart() < other.getStart())
+ return true;
+ if (getStart() == other.getStart() &&
+ (sym->GetType() == FunctionSymbol && other.sym->GetType() == FunctionSymbol))
+ {
+ return archName < other.archName;
+ }
+ return false;
+ }
+
+ bool operator>(const NamedObject& other) const
+ {
+ if (getStart() > other.getStart())
+ return true;
+ if (getStart() == other.getStart() &&
+ (sym->GetType() == FunctionSymbol && other.sym->GetType() == FunctionSymbol))
+ {
+ return archName > other.archName;
+ }
+ return false;
+ }
+
+ bool isFunc() const { return sym->GetType() == FunctionSymbol; }
+ uint64_t getStart() const { return sym->GetAddress(); }
+ std::string getName() const { return sym->GetFullName(); }
+ BNSymbolType getType() const { return sym->GetType(); }
+ };
+
+private:
+ enum SymbolListUpdateType
+ {
+ AddedToSymbolList,
+ RemovedFromSymbolList,
+ UpdatedInSymbolList
+ };
+
+ struct SymbolListUpdateEvent
+ {
+ NamedObject rec;
+ SymbolListUpdateType type;
+ SymbolListUpdateEvent(const NamedObject& r, SymbolListUpdateType t) : rec(r), type(t) {}
+ SymbolListUpdateEvent(const SymbolListUpdateEvent& s)
+ {
+ rec = s.rec;
+ type = s.type;
+ }
+ };
+
+ class SymbolListUpdate: public BinaryNinja::RefCountObject
+ {
+ std::mutex m_mutex;
+ bool m_valid;
+ SymbolListModel* m_model;
+
+ public:
+ SymbolListUpdate(SymbolListModel* model);
+ void start();
+ void abort();
+ };
+
+ QWidget* m_funcList;
+ ViewFrame* m_view;
+ BinaryViewRef m_data;
+ std::set<std::string> m_archNames;
+ std::vector<NamedObject> m_allSyms;
+ std::vector<NamedObject> m_curSyms;
+ NamedObject m_currentSym;
+ std::string m_filter;
+
+ std::mutex m_updateMutex;
+ std::vector<SymbolListUpdateEvent> m_updates;
+ bool m_fullUpdate;
+
+ BinaryNinja::Ref<SymbolListUpdate> m_backgroundUpdate;
+ volatile bool m_backgroundUpdateComplete;
+ std::vector<NamedObject> m_backgroundUpdateFuncs;
+
+ bool m_showImports;
+ bool m_showExports;
+ bool m_showFunctions;
+ bool m_showDataVars;
+ SortType m_sortType;
+
+ // static bool allSymbolComparison(const NamedObject& a, const NamedObject& b);
+ static bool allSymbolComparisonLT(const NamedObject& a, const NamedObject& b);
+ static bool allSymbolComparisonGE(const NamedObject& a, const NamedObject& b);
+ static bool allSymbolComparisonNameLT(const NamedObject& a, const NamedObject& b);
+ static bool allSymbolComparisonNameGE(const NamedObject& a, const NamedObject& b);
+ typedef bool (*comparitor)(const NamedObject& a, const NamedObject& b);
+ static comparitor getComparitor(SortType type)
+ {
+ switch (type)
+ {
+ case SortAcendingAddresses: return allSymbolComparisonLT;
+ case SortDecendingAddresses: return allSymbolComparisonGE;
+ case SortAlphabeticallyAcending: return allSymbolComparisonNameLT;
+ case SortAlphabeticallyDecending:
+ default:
+ return allSymbolComparisonNameGE;
+ }
+ }
+ void getValidObject(std::vector<NamedObject>& result);
+
+public:
+ SymbolListModel(QWidget* parent, ViewFrame* view, BinaryViewRef data);
+ virtual ~SymbolListModel();
+
+ virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
+ virtual QModelIndex parent(const QModelIndex& i) const override;
+ virtual bool hasChildren(const QModelIndex& parent) const override;
+ virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+ virtual int columnCount(const QModelIndex& parent) const override;
+ virtual QVariant data(const QModelIndex& i, int role) const override;
+
+ virtual void OnAnalysisFunctionAdded(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionRemoved(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionUpdated(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnDataVariableAdded(BinaryNinja::BinaryView* data, const BinaryNinja::DataVariable& var) override;
+ virtual void OnDataVariableRemoved(BinaryNinja::BinaryView* data, const BinaryNinja::DataVariable& var) override;
+ virtual void OnDataVariableUpdated(BinaryNinja::BinaryView* data, const BinaryNinja::DataVariable& var) override;
+
+ void updateFonts();
+ bool isValidType(const NamedObject& rec);
+ bool setCurrentObject(const NamedObject& rec);
+ bool setCurrentFunction(FunctionRef func);
+ QModelIndex findSymbol(const NamedObject& rec);
+ QModelIndex findCurrentSymbol();
+ NamedObject getNamedObjectForIndex(int i);
+
+ void updateFunctions();
+ void backgroundUpdate();
+ bool hasSymbols() const;
+
+ void setFilter(const std::string& filter);
+ void showExports(bool show) { m_showExports = show; }
+ void showImports(bool show) { m_showImports = show; }
+ void showFunctions(bool show) { m_showFunctions = show; }
+ void showDataVars(bool show) { m_showDataVars = show; }
+
+ void toggleExports() {
+ m_showExports = !m_showExports;
+ if (m_showExports)
+ {
+ m_showImports = false;
+ m_showFunctions = true;
+ m_showDataVars = true;
+ }
+ }
+ void toggleImports() {
+ m_showImports = !m_showImports;
+ if (m_showImports && m_showExports)
+ m_showExports = false;
+ }
+ void toggleFunctions() {
+ m_showFunctions = !m_showFunctions;
+ if (m_showFunctions && m_showExports)
+ m_showExports = false;
+ }
+ void toggleDataVars() {
+ m_showDataVars = !m_showDataVars;
+ if (m_showDataVars && m_showExports)
+ m_showExports = false;
+ }
+
+ bool getShowExports() const { return m_showExports; }
+ bool getShowImports() const { return m_showImports; }
+ bool getShowFunctions() const { return m_showFunctions; }
+ bool getShowDataVars() const { return m_showDataVars; }
+
+ void sortSymbols(SortType type);
+ void setSortType(SortType type) { m_sortType = type; }
+ SortType getSortType() const { return m_sortType; }
+ NamedObject getCurrentSym() const { return m_currentSym; }
+
+Q_SIGNALS:
+ void afterListReset();
+ void beforeListReset();
+};
+
+
+class BINARYNINJAUIAPI SymbolList: public QListView, public FilterTarget
+{
+ Q_OBJECT
+
+ ViewFrame* m_view;
+ BinaryViewRef m_data;
+ SymbolsView* m_functionsView;
+ SymbolListModel* m_list;
+ QTimer* m_updateTimer;
+ bool m_disableScrollToFunction;
+ UIActionHandler m_actionHandler;
+ Menu m_menu;
+ ContextMenuManager m_contextMenuManager;
+
+ bool m_showExports;
+ bool m_showImports;
+ bool m_showFunctions;
+ bool m_showDataVars;
+ std::string m_filter;
+ SymbolListModel::SortType m_sortType;
+ SymbolListModel::NamedObject m_index;
+ int m_scrollPosition;
+ bool m_doubleClick;
+
+public:
+ SymbolList(SymbolsView* parent, ViewFrame* frame, BinaryViewRef data);
+
+ void updateFonts();
+ void setCurrentFunction(FunctionRef func);
+
+ virtual void scrollToFirstItem() override;
+ virtual void scrollToCurrentItem() override;
+ virtual void selectFirstItem() override;
+ virtual void activateFirstItem() override;
+ virtual void setFilter(const std::string& filter) override;
+
+ bool hasSymbols();
+
+ virtual void copy();
+ virtual void paste();
+ virtual bool canCopy();
+ void find();
+
+protected:
+ virtual void focusOutEvent(QFocusEvent* event) override;
+ virtual void keyPressEvent(QKeyEvent* event) override;
+ virtual void contextMenuEvent(QContextMenuEvent* /*event*/) override;
+
+private Q_SLOTS:
+ void goToSymbol(const QModelIndex& i);
+ void updateTimerEvent();
+ void savePosition();
+ void restorePosition();
+ void saveIndex(const QModelIndex& index);
+ void clearIndex(const QModelIndex& index);
+};
diff --git a/ui/functionsview.h b/ui/symbolsview.h
index 65b40c45..694f3ea4 100644
--- a/ui/functionsview.h
+++ b/ui/symbolsview.h
@@ -4,28 +4,29 @@
#include "binaryninjaapi.h"
#include "dockhandler.h"
#include "filter.h"
+#include "symbollist.h"
class ViewFrame;
-class FunctionList;
+class SymbolList;
-class BINARYNINJAUIAPI FunctionsView: public QWidget, public DockContextHandler, public BinaryNinja::BinaryDataNotification
+class BINARYNINJAUIAPI SymbolsView: public QWidget, public DockContextHandler, public BinaryNinja::BinaryDataNotification
{
Q_OBJECT
Q_INTERFACES(DockContextHandler)
BinaryViewRef m_data;
- FunctionList* m_funcList;
+ SymbolList* m_funcList;
FilteredView* m_funcFilter;
bool m_updatesPending;
QTimer* m_updateTimer;
public:
- FunctionsView(ViewFrame* frame, BinaryViewRef data);
- virtual ~FunctionsView();
+ SymbolsView(ViewFrame* frame, BinaryViewRef data);
+ virtual ~SymbolsView();
- FunctionList* getFunctionList() { return m_funcList; }
+ SymbolList* getSymbolList() { return m_funcList; }
FilteredView* getFunctionFilter() { return m_funcFilter; }
virtual void OnBinaryDataWritten(BinaryNinja::BinaryView* data, uint64_t offset, size_t len) override;
diff --git a/ui/viewframe.h b/ui/viewframe.h
index d08fa38e..0a73ad89 100644
--- a/ui/viewframe.h
+++ b/ui/viewframe.h
@@ -156,7 +156,7 @@ public:
virtual View* getView() = 0;
};
-class FunctionsView;
+class SymbolsView;
class BINARYNINJAUIAPI ViewFrame : public QWidget
{