Repository: angr/angr

Issue:
Iop_Sub64Fx2._calculate() errored
the error message is following:

WARNING | 2017-10-18 19:29:15,714 | angr.engines.vex.irop | IROp error (for operation Iop_Sub64Fx2)
Traceback (most recent call last):
  File "/home/qlnx/mdev/symexec/angr/angr-dev/angr/angr/engines/vex/irop.py", line 909, in translate_inner
    return irop.calculate(*s_args)
  File "/home/qlnx/mdev/symexec/angr/angr-dev/angr/angr/engines/vex/irop.py", line 351, in calculate
    return self.extend_size(self._calculate(args))
  File "/home/qlnx/mdev/symexec/angr/angr-dev/angr/angr/engines/vex/irop.py", line 408, in _op_mapped
    return getattr(claripy.ast.BV, o)(*sized_args)
  File "/home/qlnx/mdev/symexec/angr/angr-dev/claripy/claripy/operations.py", line 46, in _op
    fixed_args = tuple(_type_fixer(args))
  File "/home/qlnx/mdev/symexec/angr/angr-dev/claripy/claripy/operations.py", line 23, in _type_fixer
    "{} arguments ({} given)".format(name, len(arg_types), len(args)))
SimOperationError: ('Iop_Sub64Fx2._calculate() raised exception', <class 'claripy.errors.ClaripyTypeError'>, ClaripyTypeError('Operation __sub__ takes exactly 2 arguments (3 given)',))



Discussion:
1) can you please provide the instruction which produced this error?
2) can you please run `python -m angr.misc.bug_report` and post the result here?
1.the binary is https://github.com/zardus/cgc-bins/raw/master/all_unpatched/CROMU_00073 and faulting instruction is subpd at
.text:08048851                 subpd   xmm0, xmm1

2.see the attached result
[angr.misc.bug_report.txt](https://github.com/angr/angr/files/1397673/angr.misc.bug_report.txt)

Looks like we're missing support for vectorized floating point operations. We dealt with this during CGC by disabling floating point support entirely and forcing any FP instruction to be concretized and run through unicorn via the [oppologist](https://github.com/angr/angr/blob/master/angr/exploration_techniques/oppologist.py).

I will have a fix shortly.

Resolving patch:
diff --git a/angr/engines/vex/irop.py b/angr/engines/vex/irop.py
--- a/angr/engines/vex/irop.py
+++ b/angr/engines/vex/irop.py
@@ -299,6 +299,8 @@ def __init__(self, name, **attrs):
                 self._calculate = self._op_float_mapped
             elif not self._float and self._vector_count is not None:
                 self._calculate = self._op_vector_mapped
+            elif self._float and self._vector_count is not None:
+                self._calculate = self._op_vector_float_mapped
             else:
                 self._calculate = self._op_mapped
 
@@ -418,11 +420,12 @@ def _translate_rm(self, rm_num):
             l.warning("symbolic rounding mode found, using default")
             return claripy.fp.RM.default()
 
+    NO_RM = { 'Neg', 'Abs' }
+
     def _op_float_mapped(self, args):
-        NO_RM = { 'Neg', 'Abs' }
         op = getattr(claripy, 'fp' + self._generic_name)
 
-        if self._generic_name in NO_RM:
+        if self._generic_name in self.NO_RM:
             return op(*args)
 
         rm = self._translate_rm(args[0])
@@ -433,6 +436,16 @@ def _op_vector_mapped(self, args):
                         for i in reversed(xrange(self._vector_count)))
         return claripy.Concat(*(self._op_mapped(ca) for ca in chopped_args))
 
+    def _op_vector_float_mapped(self, args):
+        rm_part = [] if self._generic_name in self.NO_RM else [args[0]]
+        chopped_args = (
+                [
+                    claripy.Extract((i + 1) * self._vector_size - 1, i * self._vector_size, a).raw_to_fp()
+                    for a in (args if self._generic_name in self.NO_RM else args[1:])
+                ] for i in reversed(xrange(self._vector_count))
+            )
+        return claripy.Concat(*(self._op_float_mapped(rm_part + ca).raw_to_bv() for ca in chopped_args))
+
     def _op_float_op_just_low(self, args):
         chopped = [arg[(self._vector_size - 1):0].raw_to_fp() for arg in args]
         result = getattr(claripy, 'fp' + self._generic_name)(claripy.fp.RM.default(), *chopped).raw_to_bv()


Test patch: