summaryrefslogtreecommitdiff
path: root/python/callingconvention.py
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2018-09-10 20:31:23 -0400
committerRusty Wagner <rusty@vector35.com>2018-09-13 15:35:12 -0400
commit409de0f7804a49b6dcc9c8a14307de2be29ecd60 (patch)
tree92b04e17f71473ef39d87c62440b6e72b72ed9fb /python/callingconvention.py
parent59a2824b1ad36ea5d0520919e86ad779cd97cc8f (diff)
Add callee saved registers on calling conventions to specify which registers are assumed to be preserved (used in heuristics to avoid incomplete data flow cloberring these registers)
Diffstat (limited to 'python/callingconvention.py')
-rw-r--r--python/callingconvention.py26
1 files changed, 26 insertions, 0 deletions
diff --git a/python/callingconvention.py b/python/callingconvention.py
index 6b906184..f4349816 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -34,6 +34,7 @@ from binaryninja import range
class CallingConvention(object):
name = None
caller_saved_regs = []
+ callee_saved_regs = []
int_arg_regs = []
float_arg_regs = []
arg_regs_share_index = False
@@ -56,6 +57,7 @@ class CallingConvention(object):
self._cb = core.BNCustomCallingConvention()
self._cb.context = 0
self._cb.getCallerSavedRegisters = self._cb.getCallerSavedRegisters.__class__(self._get_caller_saved_regs)
+ self._cb.getCalleeSavedRegisters = self._cb.getCalleeSavedRegisters.__class__(self._get_callee_saved_regs)
self._cb.getIntegerArgumentRegisters = self._cb.getIntegerArgumentRegisters.__class__(self._get_int_arg_regs)
self._cb.getFloatArgumentRegisters = self._cb.getFloatArgumentRegisters.__class__(self._get_float_arg_regs)
self._cb.freeRegisterList = self._cb.freeRegisterList.__class__(self._free_register_list)
@@ -91,6 +93,15 @@ class CallingConvention(object):
self.__dict__["caller_saved_regs"] = result
count = ctypes.c_ulonglong()
+ regs = core.BNGetCalleeSavedRegisters(self.handle, count)
+ result = []
+ arch = self.arch
+ for i in range(0, count.value):
+ result.append(arch.get_reg_name(regs[i]))
+ core.BNFreeRegisterList(regs, count.value)
+ self.__dict__["callee_saved_regs"] = result
+
+ count = ctypes.c_ulonglong()
regs = core.BNGetIntegerArgumentRegisters(self.handle, count)
result = []
arch = self.arch
@@ -171,6 +182,21 @@ class CallingConvention(object):
count[0] = 0
return None
+ def _get_callee_saved_regs(self, ctxt, count):
+ try:
+ regs = self.__class__.callee_saved_regs
+ count[0] = len(regs)
+ reg_buf = (ctypes.c_uint * len(regs))()
+ for i in range(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_int_arg_regs(self, ctxt, count):
try:
regs = self.__class__.int_arg_regs