angr/analyses/typehoon/simple_solver.py
def _join(self, t1, t2, translate):
        """
        Get the least upper bound of t1 and t2.

        :param t1:
        :param t2:
        :return:
        """

        # Trivial cases
        t1 = translate(t1)
        t2 = translate(t2)

        if t1 == t2:
            return t1
        if isinstance(t1, TopType):
            return t2
        elif isinstance(t2, TopType):
            return t1

        if isinstance(t1, TypeVariableReference) and not isinstance(t2, TypeVariableReference):
            return t1
        elif isinstance(t2, TypeVariableReference) and not isinstance(t1, TypeVariableReference):
            return t2

        # consult the graph
        t1_cls = self._abstract(t1)
        t2_cls = self._abstract(t2)

        if t1_cls in BASE_LATTICE and t2_cls in BASE_LATTICE:
            queue = [ t1_cls ]
            while queue:
                n = queue[0]
                queue = queue[1:]

                if networkx.has_path(BASE_LATTICE, n, t2_cls):
                    return self._concretize(n, t1, t2, translate)
                # go up
                queue.extend(BASE_LATTICE.predecessors(n))

        # handling Struct
        if t1_cls is Struct and t2_cls is Struct:
            fields = { }
            for offset in sorted(set(itertools.chain(t1.fields.keys(), t2.fields.keys()))):
                if offset in t1.fields and offset in t2.fields:
                    v = self._join(t1.fields[offset], t2.fields[offset], translate)
                elif offset in t1.fields:
                    v = t1.fields[offset]
                elif offset in t2.fields:
                    v = t2.fields[offset]
                else:
                    raise Exception("Impossible")
                fields[offset] = v
            return Struct(fields)

        if t1_cls is Pointer64 and t2_cls is Struct:
            # swap them
            t1, t1_cls, t2, t2_cls = t2, t2_cls, t1, t1_cls
        if t1_cls is Struct and len(t1.fields) == 1 and 0 in t1.fields:
            if t1.fields[0].size == 8 and t2_cls is Pointer64:
                # they are equivalent
                # e.g., struct{0: int64}  ptr64(int8)
                # return t2 since t2 is more specific
                return t2
            elif t1.fields[0].size == 4 and t2_cls is Pointer32:
                return t2

        # import ipdb; ipdb.set_trace()
        return TopType()

        Get the least upper bound of t1 and t2.

        :param t1:
        :param t2:
        :return:
        
Get the least upper bound of t1 and t2.
Get the least upper bound of t1 and t2 .
def _join(self, t1, t2, translate):
        t1 = translate(t1)
        t2 = translate(t2)
        if t1 == t2:
            return t1
        if isinstance(t1, TopType):
            return t2
        elif isinstance(t2, TopType):
            return t1
        if isinstance(t1, TypeVariableReference) and not isinstance(t2, TypeVariableReference):
            return t1
        elif isinstance(t2, TypeVariableReference) and not isinstance(t1, TypeVariableReference):
            return t2
        t1_cls = self._abstract(t1)
        t2_cls = self._abstract(t2)
        if t1_cls in BASE_LATTICE and t2_cls in BASE_LATTICE:
            queue = [ t1_cls ]
            while queue:
                n = queue[0]
                queue = queue[1:]
                if networkx.has_path(BASE_LATTICE, n, t2_cls):
                    return self._concretize(n, t1, t2, translate)
                queue.extend(BASE_LATTICE.predecessors(n))
        if t1_cls is Struct and t2_cls is Struct:
            fields = { }
            for offset in sorted(set(itertools.chain(t1.fields.keys(), t2.fields.keys()))):
                if offset in t1.fields and offset in t2.fields:
                    v = self._join(t1.fields[offset], t2.fields[offset], translate)
                elif offset in t1.fields:
                    v = t1.fields[offset]
                elif offset in t2.fields:
                    v = t2.fields[offset]
                else:
                    raise Exception("Impossible")
                fields[offset] = v
            return Struct(fields)
        if t1_cls is Pointer64 and t2_cls is Struct:
            t1, t1_cls, t2, t2_cls = t2, t2_cls, t1, t1_cls
        if t1_cls is Struct and len(t1.fields) == 1 and 0 in t1.fields:
            if t1.fields[0].size == 8 and t2_cls is Pointer64:
                return t2
            elif t1.fields[0].size == 4 and t2_cls is Pointer32:
                return t2
        return TopType()
def _join ( self , t1 , t2 , translate ) : t1 = translate ( t1 ) t2 = translate ( t2 ) if t1 == t2 : return t1 if isinstance ( t1 , TopType ) : return t2 elif isinstance ( t2 , TopType ) : return t1 if isinstance ( t1 , TypeVariableReference ) and not isinstance ( t2 , TypeVariableReference ) : return t1 elif isinstance ( t2 , TypeVariableReference ) and not isinstance ( t1 , TypeVariableReference ) : return t2 t1_cls = self . _abstract ( t1 ) t2_cls = self . _abstract ( t2 ) if t1_cls in BASE_LATTICE and t2_cls in BASE_LATTICE : queue = [ t1_cls ] while queue : n = queue [ 0 ] queue = queue [ 1 : ] if networkx . has_path ( BASE_LATTICE , n , t2_cls ) : return self . _concretize ( n , t1 , t2 , translate ) queue . extend ( BASE_LATTICE . predecessors ( n ) ) if t1_cls is Struct and t2_cls is Struct : fields = { } for offset in sorted ( set ( itertools . chain ( t1 . fields . keys ( ) , t2 . fields . keys ( ) ) ) ) : if offset in t1 . fields and offset in t2 . fields : v = self . _join ( t1 . fields [ offset ] , t2 . fields [ offset ] , translate ) elif offset in t1 . fields : v = t1 . fields [ offset ] elif offset in t2 . fields : v = t2 . fields [ offset ] else : raise Exception ( "Impossible" ) fields [ offset ] = v return Struct ( fields ) if t1_cls is Pointer64 and t2_cls is Struct : t1 , t1_cls , t2 , t2_cls = t2 , t2_cls , t1 , t1_cls if t1_cls is Struct and len ( t1 . fields ) == 1 and 0 in t1 . fields : if t1 . fields [ 0 ] . size == 8 and t2_cls is Pointer64 : return t2 elif t1 . fields [ 0 ] . size == 4 and t2_cls is Pointer32 : return t2 return TopType ( )
Get the least upper bound of t1 and t2.
Get the least upper bound of t1 and t2 .
"""
        Get the least upper bound of t1 and t2.

        :param t1:
        :param t2:
        :return:
        """ # Trivial cases # consult the graph # go up # handling Struct # swap them # they are equivalent # e.g., struct{0: int64}  ptr64(int8) # return t2 since t2 is more specific # import ipdb; ipdb.set_trace()
None
self
t1
None
t2
None
translate