コード例 #1
0
ファイル: resilience.py プロジェクト: AOS002/angr-fork
 def _check_errored_op(self, op, args):
     ty = pyvex.get_op_retty(op)
     if o.BYPASS_ERRORED_IROP not in self.state.options:
         return super()._check_errored_op(op, args)
     self.state.history.add_event('resilience',
                                  resilience_type='irop',
                                  op=op,
                                  message='unsupported IROp')
     return self.__make_default(ty, True, 'errored_' + op)
コード例 #2
0
ファイル: resilience.py プロジェクト: AOS002/angr-fork
 def _check_unsupported_op(self, op, args):
     ty = pyvex.get_op_retty(op)
     if o.BYPASS_UNSUPPORTED_IROP not in self.state.options:
         return super()._check_unsupported_op(op, args)
     self.state.history.add_event('resilience',
                                  resilience_type='irop',
                                  op=op,
                                  message='unsupported IROp')
     return self.__make_default(
         ty, o.UNSUPPORTED_BYPASS_ZERO_DEFAULT not in self.state.options,
         'unsupported_' + op)
コード例 #3
0
    def __init__(self, name, **attrs):
        self.name = name
        self.op_attrs = attrs

        self._generic_name = None
        self._from_size = None
        self._from_side = None
        self._from_type = None
        self._from_signed = None
        self._to_size = None
        self._to_type = None
        self._to_signed = None
        self._conversion = None
        self._vector_size = None
        self._vector_signed = None
        self._vector_type = None
        self._vector_zero = None
        self._vector_count = None

        self._rounding_mode = None

        for k, v in self.op_attrs.items():
            if v is not None and ('size' in k or 'count' in k):
                v = int(v)
            setattr(self, '_%s' % k, v)

        # determine the output size
        #pylint:disable=no-member
        self._output_type = pyvex.get_op_retty(name)
        #pylint:enable=no-member
        self._output_size_bits = pyvex.const.get_type_size(self._output_type)

        size_check = self._to_size is None or (
            self._to_size * 2 if self._generic_name == 'DivMod' else
            self._to_size) == self._output_size_bits
        if not size_check:
            raise SimOperationError(
                "VEX output size doesn't match detected output size")

        #
        # Some categorization
        #

        generic_names.add(self._generic_name)
        if self._conversion is not None:
            conversions[(self._from_type, self._from_signed, self._to_type,
                         self._to_signed)].append(self)

        if len({self._vector_type, self._from_type, self._to_type}
               & {'F', 'D'}) != 0:
            self._float = True

            if len({self._vector_type, self._from_type, self._to_type}
                   & {'D'}) != 0:
                # fp_ops.add(self.name)
                raise UnsupportedIROpError("BCD ops aren't supported")
        else:
            self._float = False

        #
        # Now determine the operation
        #

        self._calculate = None

        # is it explicitly implemented?
        if hasattr(self, '_op_' + name):
            self._calculate = getattr(self, '_op_' + name)
        # if the generic name is None and there's a conversion present, this is a standard
        # widening or narrowing or sign-extension
        elif self._generic_name is None and self._conversion:
            # convert int to float
            if self._float and self._from_type == 'I':
                self._calculate = self._op_int_to_fp

            # convert float to differently-sized float
            elif self._from_type == 'F' and self._to_type == 'F':
                self._calculate = self._op_fp_to_fp

            elif self._from_type == 'F' and self._to_type == 'I':
                self._calculate = self._op_fp_to_int

            # this concatenates the args into the high and low halves of the result
            elif self._from_side == 'HL':
                self._calculate = self._op_concat

            # this just returns the high half of the first arg
            elif self._from_size > self._to_size and self._from_side == 'HI':
                self._calculate = self._op_hi_half

            # this just returns the high half of the first arg
            elif self._from_size > self._to_size and self._from_side in ('L',
                                                                         'LO'):
                self._calculate = self._op_lo_half

            elif self._from_size > self._to_size and self._from_side is None:
                self._calculate = self._op_extract

            elif self._from_size < self._to_size and self.is_signed:
                self._calculate = self._op_sign_extend

            elif self._from_size < self._to_size and not self.is_signed:
                self._calculate = self._op_zero_extend

            else:
                l.error(
                    "%s is an unexpected conversion operation configuration",
                    self)
                assert False

        elif self._float and self._vector_zero:
            # /* --- lowest-lane-only scalar FP --- */
            f = getattr(claripy, 'fp' + self._generic_name, None)
            if f is not None:
                f = partial(f, claripy.fp.RM.default())  # always? really?

            f = f if f is not None else getattr(
                self, '_op_fgeneric_' + self._generic_name, None)
            if f is None:
                raise SimOperationError(
                    "no fp implementation found for operation {}".format(
                        self._generic_name))

            self._calculate = partial(self._auto_vectorize, f)

        # other conversions
        elif self._conversion and self._generic_name not in {
                'Round', 'Reinterp'
        }:
            if self._generic_name == "DivMod":
                self._calculate = self._op_divmod
            else:
                unsupported_conversions.append(self.name)
                common_unsupported_generics[self._generic_name] += 1

        # generic bitwise
        elif self._generic_name in bitwise_operation_map:
            assert self._from_side is None
            self._calculate = self._op_mapped

        # generic mapping operations
        elif    self._generic_name in arithmetic_operation_map or \
                self._generic_name in shift_operation_map:
            assert self._from_side is None

            if self._float and self._vector_count is None:
                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

        # TODO: clean up this mess
        # specifically-implemented generics
        elif self._float and hasattr(self,
                                     '_op_fgeneric_%s' % self._generic_name):
            calculate = getattr(self, '_op_fgeneric_%s' % self._generic_name)
            if self._vector_size is not None and \
               not hasattr(calculate, 'supports_vector'):
                # NOTE: originally this branch just marked the op as unsupported but I think we can do better
                # "marking unsupported" seems to include adding the op to the vector_operations list? why
                self._calculate = partial(self._auto_vectorize, calculate)
            else:
                self._calculate = calculate

        elif not self._float and hasattr(
                self, '_op_generic_%s' % self._generic_name):
            calculate = getattr(self, '_op_generic_%s' % self._generic_name)
            if self._vector_size is not None and \
               not hasattr(calculate, 'supports_vector'):
                # NOTE: same as above
                self._calculate = partial(self._auto_vectorize, calculate)
            else:
                self._calculate = calculate

        else:
            common_unsupported_generics[self._generic_name] += 1
            other_operations.append(name)

        # if we're here and calculate is None, we don't support this
        if self._calculate is None:
            raise UnsupportedIROpError(
                "no calculate function identified for %s" % self.name)
コード例 #4
0
    def __init__(self, name, **attrs):
        l.debug("Creating SimIROp(%s)", name)
        self.name = name
        self.op_attrs = attrs

        self._generic_name = None
        self._from_size = None
        self._from_side = None
        self._from_type = None
        self._from_signed = None
        self._to_size = None
        self._to_type = None
        self._to_signed = None
        self._conversion = None
        self._vector_size = None
        self._vector_signed = None
        self._vector_type = None
        self._vector_zero = None
        self._vector_count = None

        self._rounding_mode = None

        for k, v in self.op_attrs.items():
            if v is not None and ('size' in k or 'count' in k):
                v = int(v)
            setattr(self, '_%s' % k, v)

        # determine the output size
        #pylint:disable=no-member
        self._output_type = pyvex.get_op_retty(name)
        #pylint:enable=no-member
        self._output_size_bits = size_bits(self._output_type)
        l.debug("... VEX says the output size should be %s",
                self._output_size_bits)

        size_check = self._to_size is None or (
            self._to_size * 2 if self._generic_name == 'DivMod' else
            self._to_size) == self._output_size_bits
        if not size_check:
            raise SimOperationError(
                "VEX output size doesn't match detected output size")

        #
        # Some categorization
        #

        generic_names.add(self._generic_name)
        if self._conversion is not None:
            conversions[(self._from_type, self._from_signed, self._to_type,
                         self._to_signed)].append(self)

        if len({self._vector_type, self._from_type, self._to_type}
               & {'F', 'D'}) != 0:
            self._float = True

            if len({self._vector_type, self._from_type, self._to_type}
                   & {'D'}) != 0:
                l.debug('... aborting on BCD!')
                # fp_ops.add(self.name)
                raise UnsupportedIROpError("BCD ops aren't supported")
        else:
            self._float = False

        #
        # Now determine the operation
        #

        self._calculate = None

        # is it explicitly implemented?
        if hasattr(self, '_op_' + name):
            self._calculate = getattr(self, '_op_' + name)
        # if the generic name is None and there's a conversion present, this is a standard
        # widening or narrowing or sign-extension
        elif self._generic_name is None and self._conversion:
            # convert int to float
            if self._float and self._from_type == 'I':
                self._calculate = self._op_int_to_fp

            # convert float to differently-sized float
            elif self._from_type == 'F' and self._to_type == 'F':
                self._calculate = self._op_fp_to_fp

            elif self._from_type == 'F' and self._to_type == 'I':
                self._calculate = self._op_fp_to_int

            # this concatenates the args into the high and low halves of the result
            elif self._from_side == 'HL':
                l.debug("... using simple concat")
                self._calculate = self._op_concat

            # this just returns the high half of the first arg
            elif self._from_size > self._to_size and self._from_side == 'HI':
                l.debug("... using hi half")
                self._calculate = self._op_hi_half

            # this just returns the high half of the first arg
            elif self._from_size > self._to_size and self._from_side in ('L',
                                                                         'LO'):
                l.debug("... using lo half")
                self._calculate = self._op_lo_half

            elif self._from_size > self._to_size and self._from_side is None:
                l.debug("... just extracting")
                self._calculate = self._op_extract

            elif self._from_size < self._to_size and self.is_signed:
                l.debug("... using simple sign-extend")
                self._calculate = self._op_sign_extend

            elif self._from_size < self._to_size and not self.is_signed:
                l.debug("... using simple zero-extend")
                self._calculate = self._op_zero_extend

            else:
                l.error(
                    "%s is an unexpected conversion operation configuration",
                    self)
                assert False

        # other conversions
        elif self._conversion and self._generic_name != 'Round' and self._generic_name != 'Reinterp':
            if self._generic_name == "DivMod":
                l.debug("... using divmod")
                self._calculate = self._op_divmod
            else:
                unsupported_conversions.append(self.name)
                common_unsupported_generics[self._generic_name] += 1

        # generic bitwise
        elif self._generic_name in bitwise_operation_map:
            l.debug("... using generic mapping op")
            assert self._from_side is None
            self._calculate = self._op_mapped

        # generic mapping operations
        elif self._generic_name in arithmetic_operation_map or self._generic_name in shift_operation_map:
            l.debug("... using generic mapping op")
            assert self._from_side is None

            if self._float and self._vector_zero:
                self._calculate = self._op_float_op_just_low
            elif self._float and self._vector_count is None:
                self._calculate = self._op_float_mapped
            elif not self._float and self._vector_count is not None:
                self._calculate = self._op_vector_mapped
            else:
                self._calculate = self._op_mapped

        # TODO: clean up this mess
        # specifically-implemented generics
        elif self._float and hasattr(self,
                                     '_op_fgeneric_%s' % self._generic_name):
            l.debug("... using generic method")
            calculate = getattr(self, '_op_fgeneric_%s' % self._generic_name)
            if self._vector_size is not None and \
               not hasattr(calculate, 'supports_vector'):
                # unsupported vector ops
                vector_operations.append(name)
            else:
                self._calculate = calculate

        elif not self._float and hasattr(
                self, '_op_generic_%s' % self._generic_name):
            l.debug("... using generic method")
            calculate = getattr(self, '_op_generic_%s' % self._generic_name)
            if self._vector_size is not None and \
               not hasattr(calculate, 'supports_vector'):
                # unsupported vector ops
                vector_operations.append(name)
            else:
                self._calculate = calculate

        else:
            common_unsupported_generics[self._generic_name] += 1
            other_operations.append(name)

        # if we're here and calculate is None, we don't support this
        if self._calculate is None:
            l.debug("... can't support operations")
            raise UnsupportedIROpError(
                "no calculate function identified for %s" % self.name)
コード例 #5
0
ファイル: irop.py プロジェクト: tiffanyb/angr
    def __init__(self, name, **attrs):
        l.debug("Creating SimIROp(%s)", name)
        self.name = name
        self.op_attrs = attrs

        self._generic_name = None
        self._from_size = None
        self._from_side = None
        self._from_type = None
        self._from_signed = None
        self._to_size = None
        self._to_type = None
        self._to_signed = None
        self._conversion = None
        self._vector_size = None
        self._vector_signed = None
        self._vector_type = None
        self._vector_zero = None
        self._vector_count = None

        self._rounding_mode = None

        for k,v in self.op_attrs.items():
            if v is not None and ('size' in k or 'count' in k):
                v = int(v)
            setattr(self, '_%s'%k, v)

        # determine the output size
        #pylint:disable=no-member
        self._output_type = pyvex.get_op_retty(name)
        #pylint:enable=no-member
        self._output_size_bits = size_bits(self._output_type)
        l.debug("... VEX says the output size should be %s", self._output_size_bits)

        size_check = self._to_size is None or (self._to_size*2 if self._generic_name == 'DivMod' else self._to_size) == self._output_size_bits
        if not size_check:
            raise SimOperationError("VEX output size doesn't match detected output size")


        #
        # Some categorization
        #

        generic_names.add(self._generic_name)
        if self._conversion is not None:
            conversions[(self._from_type, self._from_signed, self._to_type, self._to_signed)].append(self)

        if len({self._vector_type, self._from_type, self._to_type} & {'F', 'D'}) != 0:
            self._float = True

            if len({self._vector_type, self._from_type, self._to_type} & {'D'}) != 0:
                l.debug('... aborting on BCD!')
                # fp_ops.add(self.name)
                raise UnsupportedIROpError("BCD ops aren't supported")
        else:
            self._float = False

        #
        # Now determine the operation
        #

        self._calculate = None

        # is it explicitly implemented?
        if hasattr(self, '_op_' + name):
            self._calculate = getattr(self, '_op_' + name)
        # if the generic name is None and there's a conversion present, this is a standard
        # widening or narrowing or sign-extension
        elif self._generic_name is None and self._conversion:
            # convert int to float
            if self._float and self._from_type == 'I':
                self._calculate = self._op_int_to_fp

            # convert float to differently-sized float
            elif self._from_type == 'F' and self._to_type == 'F':
                self._calculate = self._op_fp_to_fp

            elif self._from_type == 'F' and self._to_type == 'I':
                self._calculate = self._op_fp_to_int

            # this concatenates the args into the high and low halves of the result
            elif self._from_side == 'HL':
                l.debug("... using simple concat")
                self._calculate = self._op_concat

            # this just returns the high half of the first arg
            elif self._from_size > self._to_size and self._from_side == 'HI':
                l.debug("... using hi half")
                self._calculate = self._op_hi_half

            # this just returns the high half of the first arg
            elif self._from_size > self._to_size and self._from_side in ('L', 'LO'):
                l.debug("... using lo half")
                self._calculate = self._op_lo_half

            elif self._from_size > self._to_size and self._from_side is None:
                l.debug("... just extracting")
                self._calculate = self._op_extract

            elif self._from_size < self._to_size and self.is_signed:
                l.debug("... using simple sign-extend")
                self._calculate = self._op_sign_extend

            elif self._from_size < self._to_size and not self.is_signed:
                l.debug("... using simple zero-extend")
                self._calculate = self._op_zero_extend

            else:
                l.error("%s is an unexpected conversion operation configuration", self)
                assert False

        # other conversions
        elif self._conversion and self._generic_name != 'Round' and self._generic_name != 'Reinterp':
            if self._generic_name == "DivMod":
                l.debug("... using divmod")
                self._calculate = self._op_divmod
            else:
                unsupported_conversions.append(self.name)
                common_unsupported_generics[self._generic_name] += 1

        # generic bitwise
        elif self._generic_name in bitwise_operation_map:
            l.debug("... using generic mapping op")
            assert self._from_side is None
            self._calculate = self._op_mapped

        # generic mapping operations
        elif self._generic_name in arithmetic_operation_map or self._generic_name in shift_operation_map:
            l.debug("... using generic mapping op")
            assert self._from_side is None

            if self._float and self._vector_zero:
                self._calculate = self._op_float_op_just_low
            elif self._float and self._vector_count is None:
                self._calculate = self._op_float_mapped
            elif not self._float and self._vector_count is not None:
                self._calculate = self._op_vector_mapped
            else:
                self._calculate = self._op_mapped

        # TODO: clean up this mess
        # specifically-implemented generics
        elif self._float and hasattr(self, '_op_fgeneric_%s' % self._generic_name):
            l.debug("... using generic method")
            calculate = getattr(self, '_op_fgeneric_%s' % self._generic_name)
            if self._vector_size is not None and \
               not hasattr(calculate, 'supports_vector'):
                # unsupported vector ops
                vector_operations.append(name)
            else:
                self._calculate = calculate

        elif not self._float and hasattr(self, '_op_generic_%s' % self._generic_name):
            l.debug("... using generic method")
            calculate = getattr(self, '_op_generic_%s' % self._generic_name)
            if self._vector_size is not None and \
               not hasattr(calculate, 'supports_vector'):
                # unsupported vector ops
                vector_operations.append(name)
            else:
                self._calculate = calculate

        else:
            common_unsupported_generics[self._generic_name] += 1
            other_operations.append(name)


        # if we're here and calculate is None, we don't support this
        if self._calculate is None:
            l.debug("... can't support operations")
            raise UnsupportedIROpError("no calculate function identified for %s" % self.name)