Beispiel #1
0
class func(Graph):
    def __init__(self, *args, **kargs):
        self.support = MemoryZone()
        Graph.__init__(self, *args, **kargs)

    def spool(self, n=None):
        L = []
        for v in self.V():
            if len(v.e_out()) == 0: L.append(v)
        return L

    def add_vertex(self, v):
        vaddr = v.data.address
        i = self.support.locate(vaddr)
        if i is not None:
            mo = self.support._map[i]
            if vaddr in mo:
                oldnode = mo.data.val
                if oldnode == v: return 0
                # so v cuts an existing node/block:
                # repair oldblock and fix self
                childs = oldnode.N(+1)
                oldblock = oldnode.data
                oldblock.cut(vaddr)
                Graph.add_vertex(self, v)  # ! avoid recursion for add_edge
                self.support.write(vaddr, v)
                self.add_edge(link(oldnode, v))
                for n in childs:
                    self.add_edge(link(v, n))
                    self.remove_edge(oldnode.e_to(n))
                return 1
            else:  #v does not cut an existing block,
                try:  # but may swallow next one...
                    nextmo = self.support._map[i + 1]
                except IndexError:
                    # no more nodes here so back to default case:
                    pass
                else:
                    nextnode = nextmo.data.val
                    if vaddr + len(v) >= nextnode.data.address:
                        v.data.cut(nextnode.data.address)
        Graph.add_vertex(self, v)  # before support write !!
        self.support.write(vaddr, v)
        return 1

    def get_node(self, name):
        for v in self.V():
            if v.name == name: return v
        return None
Beispiel #2
0
 def __cut_add_vertex(self, v, mz, vaddr, mo):
     oldnode = mo.data.val
     if oldnode == v: return oldnode
     # so v cuts an existing node/block:
     # repair oldblock and fix self
     childs = oldnode.N(+1)
     oldblock = oldnode.data
     # if vaddr is aligned with an oldblock instr, cut it:
     # this reduces oldblock up to vaddr if the cut is possible.
     cutdone = oldblock.cut(vaddr)
     if not cutdone:
         if mz is self.overlay:
             logger.warning("double overlay block at %s" % vaddr)
             v = super(graph, self).add_vertex(v)
             v.data.misc['double-overlay'] = 1
             return v
         overlay = self.overlay or MemoryZone()
         return self.add_vertex(v, support=overlay)
     else:
         v = super(graph,
                   self).add_vertex(v)  # ! avoid recursion for add_edge
         mz.write(vaddr, v)
         self.add_edge(link(oldnode, v))
         for n in childs:
             self.add_edge(link(v, n))
             self.remove_edge(oldnode.e_to(n))
         return v
Beispiel #3
0
 def add_vertex(self, v, support=None):
     if len(v) == 0: return super(graph, self).add_vertex(v)
     vaddr = v.data.address
     if support is None:
         support = self.support
     else:
         logger.verbose("add overlay block at %s" % vaddr)
         self.overlay = support
     i = support.locate(vaddr)
     if i is not None:
         mo = support._map[i]
         if vaddr in mo:
             return self.__cut_add_vertex(v, support, vaddr, mo)
         else:  #v does not cut an existing block,
             try:  # but may swallow next one...
                 nextmo = support._map[i + 1]
             except IndexError:
                 # no more nodes here so back to default case:
                 pass
             else:
                 nextnode = nextmo.data.val
                 if vaddr + len(v) > nextnode.data.address:
                     cutdone = v.data.cut(nextnode.data.address)
                     if not cutdone:
                         if support is self.overlay:
                             logger.warning("double overlay block at %s" %
                                            vaddr)
                             v = super(graph, self).add_vertex(v)
                             v.data.misc['double-overlay'] = 1
                             return v
                         support = self.overlay or MemoryZone()
     v = super(graph, self).add_vertex(v)  # before support write !!
     support.write(vaddr, v)
     return v
Beispiel #4
0
 def __init__(self, *args, **kargs):
     self.support = MemoryZone()
     self.overlay = None
     super(graph, self).__init__(*args, **kargs)
Beispiel #5
0
class graph(Graph):
    def __init__(self, *args, **kargs):
        self.support = MemoryZone()
        self.overlay = None
        super(graph, self).__init__(*args, **kargs)

    def spool(self, n=None):
        L = []
        for v in self.V():
            if len(v.e_out()) == 0: L.append(v)
        return L

    def __cut_add_vertex(self, v, mz, vaddr, mo):
        oldnode = mo.data.val
        if oldnode == v: return oldnode
        # so v cuts an existing node/block:
        # repair oldblock and fix self
        childs = oldnode.N(+1)
        oldblock = oldnode.data
        # if vaddr is aligned with an oldblock instr, cut it:
        # this reduces oldblock up to vaddr if the cut is possible.
        cutdone = oldblock.cut(vaddr)
        if not cutdone:
            if mz is self.overlay:
                logger.warning("double overlay block at %s" % vaddr)
                v = super(graph, self).add_vertex(v)
                v.data.misc['double-overlay'] = 1
                return v
            overlay = self.overlay or MemoryZone()
            return self.add_vertex(v, support=overlay)
        else:
            v = super(graph,
                      self).add_vertex(v)  # ! avoid recursion for add_edge
            mz.write(vaddr, v)
            self.add_edge(link(oldnode, v))
            for n in childs:
                self.add_edge(link(v, n))
                self.remove_edge(oldnode.e_to(n))
            return v

    def add_vertex(self, v, support=None):
        if len(v) == 0: return super(graph, self).add_vertex(v)
        vaddr = v.data.address
        if support is None:
            support = self.support
        else:
            logger.verbose("add overlay block at %s" % vaddr)
            self.overlay = support
        i = support.locate(vaddr)
        if i is not None:
            mo = support._map[i]
            if vaddr in mo:
                return self.__cut_add_vertex(v, support, vaddr, mo)
            else:  #v does not cut an existing block,
                try:  # but may swallow next one...
                    nextmo = support._map[i + 1]
                except IndexError:
                    # no more nodes here so back to default case:
                    pass
                else:
                    nextnode = nextmo.data.val
                    if vaddr + len(v) > nextnode.data.address:
                        cutdone = v.data.cut(nextnode.data.address)
                        if not cutdone:
                            if support is self.overlay:
                                logger.warning("double overlay block at %s" %
                                               vaddr)
                                v = super(graph, self).add_vertex(v)
                                v.data.misc['double-overlay'] = 1
                                return v
                            support = self.overlay or MemoryZone()
        v = super(graph, self).add_vertex(v)  # before support write !!
        support.write(vaddr, v)
        return v

    def get_by_name(self, name):
        for v in self.V():
            if v.name == name: return v
        return None

    def get_with_address(self, vaddr):
        i = self.support.locate(vaddr)
        if i is not None:
            mo = self.support._map[i]
            if vaddr in mo:
                return mo.data.val
        return None

    def signature(self):
        return ''.join([signature(g) for g in self.C])
Beispiel #6
0
class graph(Graph):
    """a :ref:`<grandalf:Graph>` that represents a set of functions as its
    individual components.

    Args:
        V (iterable[node]) : the set of (possibly detached) nodes.
        E (iterable[link]) : the set of links of this graph.

    Attributes:
        C : the list of :class:`graph_core <grandalf:graph_core>` connected
            components of the graph.
        support (:class:`~system.core.MemoryZone`): the abstract memory zone
            holding all nodes contained in this graph.
        overlay : defaults to None, another instance of MemoryZone
            with nodes of the graph that overlap other nodes already mapped
            in :attr:`support`.

    Methods:
        get_by_name(name): get the node with the given name (as string).

        get_with_address(vaddr): get the node that contains the given *vaddr*
            :class:`~cas.expressions.cst` expression.

        signature(): returns the full signature string of all connected
            components.

        add_vertex(v,[support=None]): add node v to the graph and declare
            node support in the default MemoryZone or the overlay zone if
            provided as support argument. This method deals with a node v
            that cuts or swallows a previously added node.

        remove_vertex(v): remove node v from the graph.

        add_edge(e): add link to the graph as well as possible new nodes.

        remove_edge(e): remove the provided link.

        get_vertices_count(): a synonym for :meth:`order`.

        V(): generator of all nodes of the graph.

        E(): generator of all links of the graph.

        N(v,f_io=0): returns the neighbors of node v in direction f_io.

        path(x,y,f_io=0,hook=None):

        order(): number of nodes in the graph.

        norm(): number of links in the graph.

        deg_min(): minimum degree of nodes.

        deg_max(): maximum degree of nodes.

        deg_avg(): average degree of nodes.

        eps(): ratio of links over nodes (norm/order).

        connected(): boolean flag indicating that the graph as
            only one connected component.

        components(): synonym for attribute :attr:`C`.

    """
    def __init__(self, *args, **kargs):
        self.support = MemoryZone()
        self.overlay = None
        super(graph, self).__init__(*args, **kargs)

    def __cut_add_vertex(self, v, mz, vaddr, mo):
        oldnode = mo.data.val
        if oldnode == v: return oldnode
        # so v cuts an existing node/block:
        # repair oldblock and fix self
        childs = oldnode.N(+1)
        oldblock = oldnode.data
        # if vaddr is aligned with an oldblock instr, cut it:
        # this reduces oldblock up to vaddr if the cut is possible.
        cutdone = oldblock.cut(vaddr)
        if not cutdone:
            if mz is self.overlay:
                logger.warning("double overlay block at %s" % vaddr)
                v = super(graph, self).add_vertex(v)
                v.data.misc['double-overlay'] = 1
                return v
            overlay = self.overlay or MemoryZone()
            return self.add_vertex(v, support=overlay)
        else:
            v = super(graph,
                      self).add_vertex(v)  # ! avoid recursion for add_edge
            mz.write(vaddr, v)
            self.add_edge(link(oldnode, v))
            for n in childs:
                self.add_edge(link(v, n))
                self.remove_edge(oldnode.e_to(n))
            return v

    def add_vertex(self, v, support=None):
        if len(v) == 0: return super(graph, self).add_vertex(v)
        vaddr = v.data.address
        if support is None:
            support = self.support
        else:
            logger.verbose("add overlay block at %s" % vaddr)
            self.overlay = support
        i = support.locate(vaddr)
        if i is not None:
            mo = support._map[i]
            if vaddr in mo:
                return self.__cut_add_vertex(v, support, vaddr, mo)
            else:  #v does not cut an existing block,
                try:  # but may swallow next one...
                    nextmo = support._map[i + 1]
                except IndexError:
                    # no more nodes here so back to default case:
                    pass
                else:
                    nextnode = nextmo.data.val
                    if vaddr + len(v) > nextnode.data.address:
                        cutdone = v.data.cut(nextnode.data.address)
                        if not cutdone:
                            if support is self.overlay:
                                logger.warning("double overlay block at %s" %
                                               vaddr)
                                v = super(graph, self).add_vertex(v)
                                v.data.misc['double-overlay'] = 1
                                return v
                            support = self.overlay or MemoryZone()
        v = super(graph, self).add_vertex(v)  # before support write !!
        support.write(vaddr, v)
        return v

    def get_by_name(self, name):
        for v in self.V():
            if v.name == name: return v
        return None

    def get_with_address(self, vaddr):
        i = self.support.locate(vaddr)
        if i is not None:
            mo = self.support._map[i]
            if vaddr in mo:
                return mo.data.val
        return None

    def signature(self):
        return ''.join([signature(g) for g in self.C])
Beispiel #7
0
 def __init__(self, *args, **kargs):
     self.support = MemoryZone()
     Graph.__init__(self, *args, **kargs)