Skip to content

Commit

Permalink
Fix ARM Python bindings (capstone-engine#2127)
Browse files Browse the repository at this point in the history
  • Loading branch information
peace-maker authored Jul 29, 2023
1 parent 9099567 commit a4df92e
Show file tree
Hide file tree
Showing 25 changed files with 1,307 additions and 785 deletions.
2 changes: 1 addition & 1 deletion bindings/const_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
'comment_close': '',
},
'python': {
'header': "from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_MEM\n"
'header': "from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM\n"
"# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [%s_const.py]\n",
'footer': "",
'line_format': '%s = %s\n',
Expand Down
2 changes: 1 addition & 1 deletion bindings/python/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ PYTHON3 ?= python3
.PHONY: gen_const install install3 install_cython sdist sdist3 bdist bdist3 clean check

gen_const:
cd .. && $(PYTHON2) const_generator.py python
cd .. && $(PYTHON3) const_generator.py python

install:
rm -rf src/
Expand Down
23 changes: 20 additions & 3 deletions bindings/python/capstone/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,23 @@ def groups(self):
return self._raw.detail.contents.groups[:self._raw.detail.contents.groups_count]

raise CsError(CS_ERR_DETAIL)

# return whether instruction has writeback operands.
@property
def writeback(self):
if self._raw.id == 0:
raise CsError(CS_ERR_SKIPDATA)

if self._cs._diet:
# Diet engine cannot provide @writeback.
raise CsError(CS_ERR_DIET)

if self._cs._detail:
if hasattr(self, 'arm64_writeback'):
return self.arm64_writeback
return self._raw.detail.contents.writeback

raise CsError(CS_ERR_DETAIL)

def __gen_detail(self):
if self._raw.id == 0:
Expand All @@ -749,10 +766,10 @@ def __gen_detail(self):

arch = self._cs.arch
if arch == CS_ARCH_ARM:
(self.usermode, self.vector_size, self.vector_data, self.cps_mode, self.cps_flag, self.cc, self.update_flags, \
self.writeback, self.post_index, self.mem_barrier, self.operands) = arm.get_arch_info(self._raw.detail.contents.arch.arm)
(self.usermode, self.vector_size, self.vector_data, self.cps_mode, self.cps_flag, self.cc, self.vcc, self.update_flags, \
self.post_index, self.mem_barrier, self.pred_mask, self.operands) = arm.get_arch_info(self._raw.detail.contents.arch.arm)
elif arch == CS_ARCH_ARM64:
(self.cc, self.update_flags, self.writeback, self.post_index, self.operands) = \
(self.cc, self.update_flags, self.arm64_writeback, self.post_index, self.operands) = \
arm64.get_arch_info(self._raw.detail.contents.arch.arm64)
elif arch == CS_ARCH_X86:
(self.prefix, self.opcode, self.rex, self.addr_size, \
Expand Down
35 changes: 30 additions & 5 deletions bindings/python/capstone/arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,26 @@ class ArmOpShift(ctypes.Structure):
('value', ctypes.c_uint),
)

class ArmSysopReg(ctypes.Union):
_fields_ = (
('mclasssysreg', ctypes.c_uint),
('bankedreg', ctypes.c_uint),
)

class ArmOpSysop(ctypes.Structure):
_fields_ = (
('reg', ArmSysopReg),
('psr_bits', ctypes.c_uint),
('sysm', ctypes.c_uint16),
('msr_mask', ctypes.c_uint8),
)

class ArmOpValue(ctypes.Union):
_fields_ = (
('reg', ctypes.c_uint),
('sysop', ArmOpSysop),
('imm', ctypes.c_int32),
('pred', ctypes.c_int),
('fp', ctypes.c_double),
('mem', ArmOpMem),
('setend', ctypes.c_int),
Expand All @@ -40,13 +56,21 @@ class ArmOp(ctypes.Structure):
('neon_lane', ctypes.c_int8),
)

@property
def reg(self):
return self.value.reg

@property
def sysop(self):
return self.value.sysop

@property
def imm(self):
return self.value.imm

@property
def reg(self):
return self.value.reg
def pred(self):
return self.value.pred

@property
def fp(self):
Expand All @@ -69,15 +93,16 @@ class CsArm(ctypes.Structure):
('cps_mode', ctypes.c_int),
('cps_flag', ctypes.c_int),
('cc', ctypes.c_uint),
('vcc', ctypes.c_uint),
('update_flags', ctypes.c_bool),
('writeback', ctypes.c_bool),
('post_index', ctypes.c_bool),
('mem_barrier', ctypes.c_int),
('pred_mask', ctypes.c_uint8),
('op_count', ctypes.c_uint8),
('operands', ArmOp * 36),
)

def get_arch_info(a):
return (a.usermode, a.vector_size, a.vector_data, a.cps_mode, a.cps_flag, a.cc, a.update_flags, \
a.writeback, a.post_index, a.mem_barrier, copy_ctypes_list(a.operands[:a.op_count]))
return (a.usermode, a.vector_size, a.vector_data, a.cps_mode, a.cps_flag, a.cc, a.vcc, a.update_flags, \
a.post_index, a.mem_barrier, a.pred_mask, copy_ctypes_list(a.operands[:a.op_count]))

2 changes: 1 addition & 1 deletion bindings/python/capstone/arm64_const.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_MEM
from . import CS_OP_INVALID, CS_OP_REG, CS_OP_IMM, CS_OP_FP, CS_OP_PRED, CS_OP_SPECIAL, CS_OP_MEM
# For Capstone Engine. AUTO-GENERATED FILE, DO NOT EDIT [arm64_const.py]

ARM64_SFT_INVALID = 0
Expand Down
Loading

0 comments on commit a4df92e

Please sign in to comment.