summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h18
-rw-r--r--binaryninjacore.h5
-rw-r--r--binaryview.cpp2
-rw-r--r--flowgraph.cpp12
-rw-r--r--python/binaryview.py17
-rw-r--r--python/flowgraph.py16
6 files changed, 59 insertions, 11 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 2df09818..daf3db4f 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -95,15 +95,22 @@ namespace BinaryNinja
{
#ifdef WIN32
if (InterlockedDecrement((LONG*)&m_refs) == 0)
- delete this;
+ {
+ if (!m_registeredRef)
+ delete this;
+ }
#else
if (__sync_fetch_and_add(&m_refs, -1) == 1)
- delete this;
+ {
+ if (!m_registeredRef)
+ delete this;
+ }
#endif
}
public:
int m_refs;
+ bool m_registeredRef = false;
T* m_object;
CoreRefCountObject(): m_refs(0), m_object(nullptr) {}
virtual ~CoreRefCountObject() {}
@@ -133,13 +140,15 @@ namespace BinaryNinja
void AddRefForRegistration()
{
- AddRefInternal();
+ m_registeredRef = true;
}
void ReleaseForRegistration()
{
m_object = nullptr;
- ReleaseInternal();
+ m_registeredRef = false;
+ if (m_refs == 0)
+ delete this;
}
};
@@ -2806,6 +2815,7 @@ namespace BinaryNinja
static void PopulateNodesCallback(void* ctxt);
static void CompleteLayoutCallback(void* ctxt);
static BNFlowGraph* UpdateCallback(void* ctxt);
+ static void FreeObjectCallback(void* ctxt);
protected:
FlowGraph(BNFlowGraph* graph);
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 25bf1e46..e29b813c 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -1083,6 +1083,8 @@ extern "C"
void* context;
bool (*init)(void* ctxt);
void (*freeObject)(void* ctxt);
+ void (*externalRefTaken)(void* ctxt);
+ void (*externalRefReleased)(void* ctxt);
size_t (*read)(void* ctxt, void* dest, uint64_t offset, size_t len);
size_t (*write)(void* ctxt, uint64_t offset, const void* src, size_t len);
size_t (*insert)(void* ctxt, uint64_t offset, const void* src, size_t len);
@@ -1961,6 +1963,9 @@ extern "C"
void (*populateNodes)(void* ctxt);
void (*completeLayout)(void* ctxt);
BNFlowGraph* (*update)(void* ctxt);
+ void (*freeObject)(void* ctxt);
+ void (*externalRefTaken)(void* ctxt);
+ void (*externalRefReleased)(void* ctxt);
};
struct BNRange
diff --git a/binaryview.cpp b/binaryview.cpp
index c70685ed..e0948a1c 100644
--- a/binaryview.cpp
+++ b/binaryview.cpp
@@ -479,6 +479,8 @@ BinaryView::BinaryView(const std::string& typeName, FileMetadata* file, BinaryVi
view.context = this;
view.init = InitCallback;
view.freeObject = FreeCallback;
+ view.externalRefTaken = nullptr;
+ view.externalRefReleased = nullptr;
view.read = ReadCallback;
view.write = WriteCallback;
view.insert = InsertCallback;
diff --git a/flowgraph.cpp b/flowgraph.cpp
index 3de9c90e..9e3466c8 100644
--- a/flowgraph.cpp
+++ b/flowgraph.cpp
@@ -76,6 +76,11 @@ FlowGraph::FlowGraph()
callbacks.prepareForLayout = PrepareForLayoutCallback;
callbacks.populateNodes = PopulateNodesCallback;
callbacks.completeLayout = CompleteLayoutCallback;
+ callbacks.update = UpdateCallback;
+ callbacks.freeObject = FreeObjectCallback;
+ callbacks.externalRefTaken = nullptr;
+ callbacks.externalRefReleased = nullptr;
+ AddRefForRegistration();
m_object = BNCreateCustomFlowGraph(&callbacks);
}
@@ -117,6 +122,13 @@ BNFlowGraph* FlowGraph::UpdateCallback(void* ctxt)
}
+void FlowGraph::FreeObjectCallback(void* ctxt)
+{
+ FlowGraph* graph = (FlowGraph*)ctxt;
+ graph->ReleaseForRegistration();
+}
+
+
void FlowGraph::FinishPrepareForLayout()
{
BNFinishPrepareForLayout(m_object);
diff --git a/python/binaryview.py b/python/binaryview.py
index 1baeab2b..66c30d06 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -735,7 +735,6 @@ class BinaryView(object):
_registered_instances = []
def __init__(self, file_metadata=None, parent_view=None, handle=None):
- self._must_free = True
if handle is not None:
self.handle = core.handle_of_type(handle, core.BNBinaryView)
if file_metadata is None:
@@ -755,7 +754,8 @@ class BinaryView(object):
self._cb = core.BNCustomBinaryView()
self._cb.context = 0
self._cb.init = self._cb.init.__class__(self._init)
- self._cb.freeObject = self._cb.freeObject.__class__(self._free_object)
+ self._cb.externalRefTaken = self._cb.externalRefTaken.__class__(self._external_ref_taken)
+ self._cb.externalRefReleased = self._cb.externalRefReleased.__class__(self._external_ref_released)
self._cb.read = self._cb.read.__class__(self._read)
self._cb.write = self._cb.write.__class__(self._write)
self._cb.insert = self._cb.insert.__class__(self._insert)
@@ -778,8 +778,6 @@ class BinaryView(object):
if parent_view is not None:
parent_view = parent_view.handle
self.handle = core.BNCreateCustomBinaryView(self.__class__.name, file_metadata.handle, parent_view, self._cb)
- self.__class__._registered_instances.append(self)
- self._must_free = False
self.notifications = {}
self.next_address = None # Do NOT try to access view before init() is called, use placeholder
@@ -925,8 +923,7 @@ class BinaryView(object):
def __del__(self):
for i in self.notifications.values():
i._unregister()
- if self._must_free:
- core.BNFreeBinaryView(self.handle)
+ core.BNFreeBinaryView(self.handle)
def __iter__(self):
count = ctypes.c_ulonglong(0)
@@ -1388,7 +1385,13 @@ class BinaryView(object):
log.log_error(traceback.format_exc())
return False
- def _free_object(self, ctxt):
+ def _external_ref_taken(self, ctxt):
+ try:
+ self.__class__._registered_instances.append(self)
+ except:
+ log.log_error(traceback.format_exc())
+
+ def _external_ref_released(self, ctxt):
try:
self.__class__._registered_instances.remove(self)
except:
diff --git a/python/flowgraph.py b/python/flowgraph.py
index 58add8b0..189b075c 100644
--- a/python/flowgraph.py
+++ b/python/flowgraph.py
@@ -338,6 +338,8 @@ class FlowGraph(object):
from incoming edges, or graphs that have disjoint subgraphs will not render correctly. This will be fixed \
in a future version.
"""
+ _registered_instances = []
+
def __init__(self, handle = None):
if handle is None:
self._ext_cb = core.BNCustomFlowGraph()
@@ -346,6 +348,8 @@ class FlowGraph(object):
self._ext_cb.populateNodes = self._ext_cb.populateNodes.__class__(self._populate_nodes)
self._ext_cb.completeLayout = self._ext_cb.completeLayout.__class__(self._complete_layout)
self._ext_cb.update = self._ext_cb.update.__class__(self._update)
+ self._ext_cb.externalRefTaken = self._ext_cb.externalRefTaken.__class__(self._external_ref_taken)
+ self._ext_cb.externalRefReleased = self._ext_cb.externalRefReleased.__class__(self._external_ref_released)
handle = core.BNCreateCustomFlowGraph(self._ext_cb)
self.handle = handle
@@ -390,6 +394,18 @@ class FlowGraph(object):
log.log_error(traceback.format_exc())
return None
+ def _external_ref_taken(self, ctxt):
+ try:
+ self.__class__._registered_instances.append(self)
+ except:
+ log.log_error(traceback.format_exc())
+
+ def _external_ref_released(self, ctxt):
+ try:
+ self.__class__._registered_instances.remove(self)
+ except:
+ log.log_error(traceback.format_exc())
+
def finish_prepare_for_layout(self):
"""
``finish_prepare_for_layout`` signals that preparations for rendering a graph are complete.