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
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 __init__(self, *args, **kargs): self.support = MemoryZone() self.overlay = None super(graph, self).__init__(*args, **kargs)
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])
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])
def __init__(self, *args, **kargs): self.support = MemoryZone() Graph.__init__(self, *args, **kargs)