summaryrefslogtreecommitdiff
path: root/python/callingconvention.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/callingconvention.py')
-rw-r--r--python/callingconvention.py87
1 files changed, 87 insertions, 0 deletions
diff --git a/python/callingconvention.py b/python/callingconvention.py
index 21c8c95a..609c71b0 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -26,6 +26,8 @@ import _binaryninjacore as core
import architecture
import log
import types
+import function
+import binaryview
class CallingConvention(object):
@@ -38,6 +40,8 @@ class CallingConvention(object):
int_return_reg = None
high_int_return_reg = None
float_return_reg = None
+ global_pointer_reg = None
+ implicitly_defined_regs = []
_registered_calling_conventions = []
@@ -58,6 +62,10 @@ class CallingConvention(object):
self._cb.getIntegerReturnValueRegister = self._cb.getIntegerReturnValueRegister.__class__(self._get_int_return_reg)
self._cb.getHighIntegerReturnValueRegister = self._cb.getHighIntegerReturnValueRegister.__class__(self._get_high_int_return_reg)
self._cb.getFloatReturnValueRegister = self._cb.getFloatReturnValueRegister.__class__(self._get_float_return_reg)
+ self._cb.getGlobalPointerRegister = self._cb.getGlobalPointerRegister.__class__(self._get_global_pointer_reg)
+ self._cb.getImplicitlyDefinedRegisters = self._cb.getImplicitlyDefinedRegisters.__class__(self._get_implicitly_defined_regs)
+ self._cb.getIncomingRegisterValue = self._cb.getIncomingRegisterValue.__class__(self._get_incoming_reg_value)
+ self._cb.getIncomingFlagValue = self._cb.getIncomingFlagValue.__class__(self._get_incoming_flag_value)
self.handle = core.BNCreateCallingConvention(arch.handle, name, self._cb)
self.__class__._registered_calling_conventions.append(self)
else:
@@ -112,6 +120,21 @@ class CallingConvention(object):
else:
self.__dict__["float_return_reg"] = self.arch.get_reg_name(reg)
+ reg = core.BNGetGlobalPointerRegister(self.handle)
+ if reg == 0xffffffff:
+ self.__dict__["global_pointer_reg"] = None
+ else:
+ self.__dict__["global_pointer_reg"] = self.arch.get_reg_name(reg)
+
+ count = ctypes.c_ulonglong()
+ regs = core.BNGetImplicitlyDefinedRegisters(self.handle, count)
+ result = []
+ arch = self.arch
+ for i in xrange(0, count.value):
+ result.append(arch.get_reg_name(regs[i]))
+ core.BNFreeRegisterList(regs, count.value)
+ self.__dict__["implicitly_defined_regs"] = result
+
self.confidence = confidence
def __del__(self):
@@ -220,12 +243,76 @@ class CallingConvention(object):
log.log_error(traceback.format_exc())
return False
+ def _get_global_pointer_reg(self, ctxt):
+ try:
+ if self.__class__.global_pointer_reg is None:
+ return 0xffffffff
+ return self.arch.regs[self.__class__.global_pointer_reg].index
+ except:
+ log.log_error(traceback.format_exc())
+ return False
+
+ def _get_implicitly_defined_regs(self, ctxt, count):
+ try:
+ regs = self.__class__.implicitly_defined_regs
+ count[0] = len(regs)
+ reg_buf = (ctypes.c_uint * len(regs))()
+ for i in xrange(0, len(regs)):
+ reg_buf[i] = self.arch.regs[regs[i]].index
+ result = ctypes.cast(reg_buf, ctypes.c_void_p)
+ self._pending_reg_lists[result.value] = (result, reg_buf)
+ return result.value
+ except:
+ log.log_error(traceback.format_exc())
+ count[0] = 0
+ return None
+
+ def _get_incoming_reg_value(self, ctxt, reg, func):
+ try:
+ func_obj = function.Function(binaryview.BinaryView(handle = core.BNGetFunctionData(func)),
+ core.BNNewFunctionReference(func))
+ reg_name = self.arch.get_reg_name(reg)
+ return self.perform_get_incoming_reg_value(reg_name, func_obj)._to_api_object()
+ except:
+ log.log_error(traceback.format_exc())
+ return function.RegisterValue()._to_api_object()
+
+ def _get_incoming_flag_value(self, ctxt, reg, func):
+ try:
+ func_obj = function.Function(binaryview.BinaryView(handle = core.BNGetFunctionData(func)),
+ core.BNNewFunctionReference(func))
+ reg_name = self.arch.get_reg_name(reg)
+ return self.perform_get_incoming_flag_value(reg_name, func_obj)._to_api_object()
+ except:
+ log.log_error(traceback.format_exc())
+ return function.RegisterValue()._to_api_object()
+
def __repr__(self):
return "<calling convention: %s %s>" % (self.arch.name, self.name)
def __str__(self):
return self.name
+ def perform_get_incoming_reg_value(self, reg, func):
+ return function.RegisterValue()
+
+ def perform_get_incoming_flag_value(self, reg, func):
+ return function.RegisterValue()
+
def with_confidence(self, confidence):
return CallingConvention(self.arch, handle = core.BNNewCallingConventionReference(self.handle),
confidence = confidence)
+
+ def get_incoming_reg_value(self, reg, func):
+ reg_num = self.arch.get_reg_index(reg)
+ func_handle = None
+ if func is not None:
+ func_handle = func.handle
+ return function.RegisterValue(self.arch, core.BNGetIncomingRegisterValue(self.handle, reg_num, func_handle))
+
+ def get_incoming_flag_value(self, flag, func):
+ reg_num = self.arch.get_flag_index(flag)
+ func_handle = None
+ if func is not None:
+ func_handle = func.handle
+ return function.RegisterValue(self.arch, core.BNGetIncomingFlagValue(self.handle, reg_num, func_handle))