(self, richr_addr: RichR, size: int, expr=None)
return RichR(self.state.top(size * self.state.arch.byte_width), typevar=typevar)
:param RichR richr_addr:
        :param size:
        :return:
def _load(self, richr_addr: RichR, size: int, expr=None):
        """

        :param RichR richr_addr:
        :param size:
        :return:
        """

        addr: claripy.ast.Base = richr_addr.data
        codeloc = CodeLocation(self.block.addr, self.stmt_idx, ins_addr=self.ins_addr)
        typevar = None

        if self.state.is_stack_address(addr):
            stack_offset = self.state.get_stack_offset(addr)
            if stack_offset is not None:
                # Loading data from stack

                # split the offset into a concrete offset and a dynamic offset
                # the stack offset may not be a concrete offset
                # for example, SP-0xe0+var_1
                if type(stack_offset) is ArithmeticExpression:
                    if type(stack_offset.operands[0]) is int:
                        concrete_offset = stack_offset.operands[0]
                        dynamic_offset = stack_offset.operands[1]
                    elif type(stack_offset.operands[1]) is int:
                        concrete_offset = stack_offset.operands[1]
                        dynamic_offset = stack_offset.operands[0]
                    else:
                        # cannot determine the concrete offset. give up
                        concrete_offset = None
                        dynamic_offset = stack_offset
                else:
                    # type(stack_offset) is int
                    concrete_offset = stack_offset
                    dynamic_offset = None

                try:
                    values: Optional[MultiValues] = self.state.stack_region.load(
                        self.state.stack_addr_from_offset(concrete_offset),
                        size=size,
                        endness=self.state.arch.memory_endness)

                except SimMemoryMissingError:
                    values = None

                all_vars: Set[Tuple[int,SimVariable]] = set()
                if values:
                    for vs in values.values.values():
                        for v in vs:
                            for var_offset, var_ in self.state.extract_variables(v):
                                all_vars.add((var_offset, var_))

                if not all_vars:
                    variables = self.variable_manager[self.func_addr].find_variables_by_stack_offset(concrete_offset)
                    if not variables:
                        variable = SimStackVariable(concrete_offset, size, base='bp',
                                                    ident=self.variable_manager[self.func_addr].next_variable_ident(
                                                        'stack'),
                                                    region=self.func_addr,
                                                    )
                        self.variable_manager[self.func_addr].add_variable('stack', concrete_offset, variable)
                        variables = {variable}
                        l.debug('Identified a new stack variable %s at %#x.', variable, self.ins_addr)
                    for variable in variables:
                        v = self.state.top(size * self.state.arch.byte_width)
                        v = self.state.annotate_with_variables(v, [(0, variable)])
                        stack_addr = self.state.stack_addr_from_offset(concrete_offset)
                        self.state.stack_region.store(stack_addr, v, endness=self.state.arch.memory_endness)

                    all_vars = {(0, variable) for variable in variables}

                if len(all_vars) > 1:
                    # overlapping variables
                    l.warning("Reading memory with overlapping variables: %s. Ignoring all but the first one.",
                              all_vars)

                var_offset, var = next(iter(all_vars))  # won't fail
                # calculate variable_offset
                if dynamic_offset is None:
                    offset_into_variable = None
                else:
                    if var_offset == 0:
                        offset_into_variable = dynamic_offset
                    else:
                        offset_into_variable = ArithmeticExpression(ArithmeticExpression.Add,
                                                                    (dynamic_offset, var_offset,)
                                                                    )
                self.variable_manager[self.func_addr].read_from(var,
                                                                offset_into_variable,
                                                                codeloc,
                                                                atom=expr,
                                                                # overwrite=True
                                                                )

                # add delayed type constraints
                if var in self.state.delayed_type_constraints:
                    for constraint in self.state.delayed_type_constraints[var]:
                        self.state.add_type_constraint(constraint)
                    self.state.delayed_type_constraints.pop(var)
                # create type constraints
                if not self.state.typevars.has_type_variable_for(var, codeloc):
                    typevar = typevars.TypeVariable()
                    self.state.typevars.add_type_variable(var, codeloc, typevar)
                else:
                    typevar = self.state.typevars.get_type_variable(var, codeloc)
                # TODO: Create a tv_sp.load.<bits>@N type variable for the stack variable
                #typevar = typevars.DerivedTypeVariable(
                #    typevars.DerivedTypeVariable(typevar, typevars.Load()),
                #    typevars.HasField(size * 8, 0)
                #)

                r = self.state.top(size * self.state.arch.byte_width)
                r = self.state.annotate_with_variables(r, list(all_vars))
                return RichR(r, variable=var, typevar=typevar)

        elif addr.concrete:
            # Loading data from memory
            self._load_from_global(addr._model_concrete.value, size, expr=expr)

        elif self._addr_has_concrete_base(addr) and self._parse_offseted_addr(addr) is not None:
            # Loading data from a memory address with an offset
            base_addr, offset, elem_size = self._parse_offseted_addr(addr)
            self._load_from_global(base_addr._model_concrete.value, size, expr=expr, offset=offset,
                                   elem_size=elem_size)

        else:
            # Loading data from a pointer
            if richr_addr.type_constraints:
                for tc in richr_addr.type_constraints:
                    self.state.add_type_constraint(tc)

            # parse the loading offset
            offset = 0
            if (isinstance(richr_addr.typevar, typevars.DerivedTypeVariable) and
                    isinstance(richr_addr.typevar.label, typevars.AddN)):
                offset = richr_addr.typevar.label.n
                richr_addr_typevar = richr_addr.typevar.type_var  # unpack
            else:
                richr_addr_typevar = richr_addr.typevar

            if richr_addr_typevar is not None:
                # create a type constraint
                typevar = typevars.DerivedTypeVariable(
                    typevars.DerivedTypeVariable(richr_addr_typevar, typevars.Load()),
                    typevars.HasField(size * self.state.arch.byte_width, offset)
                )
                self.state.add_type_constraint(typevars.Existence(typevar))

        return RichR(self.state.top(size * self.state.arch.byte_width), typevar=typevar)
def _load ( self , richr_addr : RichR , size : int , expr = None ) : addr : claripy . ast . Base = richr_addr . data codeloc = CodeLocation ( self . block . addr , self . stmt_idx , ins_addr = self . ins_addr ) typevar = None if self . state . is_stack_address ( addr ) : stack_offset = self . state . get_stack_offset ( addr ) if stack_offset is not None : # Loading data from stack # split the offset into a concrete offset and a dynamic offset # the stack offset may not be a concrete offset # for example, SP-0xe0+var_1 if type ( stack_offset ) is ArithmeticExpression : if type ( stack_offset . operands [ 0 ] ) is int : concrete_offset = stack_offset . operands [ 0 ] dynamic_offset = stack_offset . operands [ 1 ] elif type ( stack_offset . operands [ 1 ] ) is int : concrete_offset = stack_offset . operands [ 1 ] dynamic_offset = stack_offset . operands [ 0 ] else : # cannot determine the concrete offset. give up concrete_offset = None dynamic_offset = stack_offset else : # type(stack_offset) is int concrete_offset = stack_offset dynamic_offset = None try : values : Optional [ MultiValues ] = self . state . stack_region . load ( self . state . stack_addr_from_offset ( concrete_offset ) , size = size , endness = self . state . arch . memory_endness ) except SimMemoryMissingError : values = None all_vars : Set [ Tuple [ int , SimVariable ] ] = set ( ) if values : for vs in values . values . values ( ) : for v in vs : for var_offset , var_ in self . state . extract_variables ( v ) : all_vars . add ( ( var_offset , var_ ) ) if not all_vars : variables = self . variable_manager [ self . func_addr ] . find_variables_by_stack_offset ( concrete_offset ) if not variables : variable = SimStackVariable ( concrete_offset , size , base = 'bp' , ident = self . variable_manager [ self . func_addr ] . next_variable_ident ( 'stack' ) , region = self . func_addr , ) self . variable_manager [ self . func_addr ] . add_variable ( 'stack' , concrete_offset , variable ) variables = { variable } l . debug ( 'Identified a new stack variable %s at %#x.' , variable , self . ins_addr ) for variable in variables : v = self . state . top ( size * self . state . arch . byte_width ) v = self . state . annotate_with_variables ( v , [ ( 0 , variable ) ] ) stack_addr = self . state . stack_addr_from_offset ( concrete_offset ) self . state . stack_region . store ( stack_addr , v , endness = self . state . arch . memory_endness ) all_vars = { ( 0 , variable ) for variable in variables } if len ( all_vars ) > 1 : # overlapping variables l . warning ( "Reading memory with overlapping variables: %s. Ignoring all but the first one." , all_vars ) var_offset , var = next ( iter ( all_vars ) ) # won't fail # calculate variable_offset if dynamic_offset is None : offset_into_variable = None else : if var_offset == 0 : offset_into_variable = dynamic_offset else : offset_into_variable = ArithmeticExpression ( ArithmeticExpression . Add , ( dynamic_offset , var_offset , ) ) self . variable_manager [ self . func_addr ] . read_from ( var , offset_into_variable , codeloc , atom = expr , # overwrite=True ) # add delayed type constraints if var in self . state . delayed_type_constraints : for constraint in self . state . delayed_type_constraints [ var ] : self . state . add_type_constraint ( constraint ) self . state . delayed_type_constraints . pop ( var ) # create type constraints if not self . state . typevars . has_type_variable_for ( var , codeloc ) : typevar = typevars . TypeVariable ( ) self . state . typevars . add_type_variable ( var , codeloc , typevar ) else : typevar = self . state . typevars . get_type_variable ( var , codeloc ) # TODO: Create a tv_sp.load.<bits>@N type variable for the stack variable #typevar = typevars.DerivedTypeVariable( #    typevars.DerivedTypeVariable(typevar, typevars.Load()), #    typevars.HasField(size * 8, 0) #) r = self . state . top ( size * self . state . arch . byte_width ) r = self . state . annotate_with_variables ( r , list ( all_vars ) ) return RichR ( r , variable = var , typevar = typevar ) elif addr . concrete : # Loading data from memory self . _load_from_global ( addr . _model_concrete . value , size , expr = expr ) elif self . _addr_has_concrete_base ( addr ) and self . _parse_offseted_addr ( addr ) is not None : # Loading data from a memory address with an offset base_addr , offset , elem_size = self . _parse_offseted_addr ( addr ) self . _load_from_global ( base_addr . _model_concrete . value , size , expr = expr , offset = offset , elem_size = elem_size ) else : # Loading data from a pointer if richr_addr . type_constraints : for tc in richr_addr . type_constraints : self . state . add_type_constraint ( tc ) # parse the loading offset offset = 0 if ( isinstance ( richr_addr . typevar , typevars . DerivedTypeVariable ) and isinstance ( richr_addr . typevar . label , typevars . AddN ) ) : offset = richr_addr . typevar . label . n richr_addr_typevar = richr_addr . typevar . type_var # unpack else : richr_addr_typevar = richr_addr . typevar if richr_addr_typevar is not None : # create a type constraint typevar = typevars . DerivedTypeVariable ( typevars . DerivedTypeVariable ( richr_addr_typevar , typevars . Load ( ) ) , typevars . HasField ( size * self . state . arch . byte_width , offset ) ) self . state . add_type_constraint ( typevars . Existence ( typevar ) ) return RichR ( self . state . top ( size * self . state . arch . byte_width ) , typevar = typevar )