def initView(self): cfg = self.func.cfg vertexs = {} done = set() for block in cfg.blocks: if block in done: continue done.add(block) startLockey = block.loc_key endLockey = block.loc_key blocks = [block] while (block.lines[-1].name == 'CALL') and (len(cfg.predecessors(block.get_next())) == 1): nextLockey = block.get_next() if block.loc_key in cfg.successors(nextLockey): break block = cfg.loc_key_to_block(nextLockey) blocks.append(block) endLockey = block.loc_key done.add(block) vertex = Vertex(startLockey) vertexs[startLockey] = vertex vertex.view = AsmBlockView(startLockey, endLockey, blocks, self.func) edges = [] for src in vertexs.values(): successLocKeys = cfg.successors(src.view.endLockey) for key in successLocKeys: vSrc = vertexs[src.view.lockey] vDst = vertexs[key] edge = Edge(vSrc, vDst) edge.view = BasicEdge(vDst) edges.append(edge) vSrc.view.outBlocks.append(vDst.view) vDst.view.inBlocks.append(vSrc.view) self.graph = Graph(vertexs.values(), edges) sugLayout = SugiyamaLayout(self.graph.C[0]) sugLayout.route_edge = route_with_lines sugLayout.init_all() sugLayout.draw() for v in vertexs.values(): self.addBlock(v.view, v.view.xy[0] - (v.view.w / 2), v.view.xy[1] - (v.view.h / 2)) v.view.gotoAddress.connect(self.selectAddress) for e in edges: srcView = e.v[0].view srcBlock = e.v[0].data dstBlock = e.v[1].data if len(srcView.outBlocks) == 1: color = Qt.darkBlue elif dstBlock == cfg.successors(srcBlock)[0]: color = Qt.darkRed else: color = Qt.darkGreen edge_view = e.view edge_view.color = color self.scene.addItem(edge_view)
def __init__(self, vertexes, edges): # # Just a reminder about naming conventions: # +------------X # | # | # | # | # Y # V = {v: Vertex(" {} ".format(v)) for v in vertexes} # NOTE: reverting edges to correctly orientate the graph E = [Edge(V[e], V[s]) for s, e in edges] V = V.values() g = Graph(V, E) class VertexViewer(object): h = 3 # top and bottom box edges + text def __init__(self, name): self.w = len(name) + 2 # right and left bottom edges + text for v in V: v.view = VertexViewer(v.data) # NOTE: determine min box length to create the best layout minw = min([v.view.w for v in V]) for e in E: e.view = EdgeViewer() sug = SugiyamaLayout(g.C[0]) gr = g.C[0] r = list(filter(lambda x: len(x.e_in()) == 0, gr.sV)) sug.init_all(roots=r, optimize=True) sug.yspace = VertexViewer.h sug.xspace = minw sug.route_edge = route_with_lines sug.draw() self.sug = sug
def _build_sugiyama_layout(vertexes: Union[List, Dict, ValuesView], edges: List) -> SugiyamaLayout: # # Just a reminder about naming conventions: # +------------X # | # | # | # | # Y # vertexes = {v: Vertex(f" {v} ") for v in vertexes} # NOTE: reverting edges to correctly orientate the graph edges = [Edge(vertexes[e], vertexes[s]) for s, e in edges] vertexes = vertexes.values() graph = Graph(vertexes, edges) for vertex in vertexes: vertex.view = VertexViewer(vertex.data) # NOTE: determine min box length to create the best layout minw = min(v.view.w for v in vertexes) for edge in edges: edge.view = EdgeViewer() sug = SugiyamaLayout(graph.C[0]) graph = graph.C[0] roots = list(filter(lambda x: len(x.e_in()) == 0, graph.sV)) sug.init_all(roots=roots, optimize=True) sug.yspace = VertexViewer.HEIGHT sug.xspace = minw sug.route_edge = route_with_lines sug.draw() return sug
def test_sugiyama_ranking(): gr, data_to_vertex = create_scenario() sug = SugiyamaLayout(gr) sug.route_edge = route_with_rounded_corners sug.init_all() # rank 0: v4 v0 # \ / | # rank 1: \ v1 | # \ / | # rank 2: v5 / # \ / # rank 3: v2 # | # rank 4: v3 rank_to_data = _compute_rank_to_data(sug) assert rank_to_data == { 0: ['v4', 'v0'], 1: ['v1'], 2: ['v5'], 3: ['v2'], 4: ['v3'], } sug.draw(N=10)
def initView(self): vertexs = {} for lockey, block in self.ircfg.blocks.items(): vertexs[lockey] = Vertex(block) vertexs[lockey].view = IRBlockView(lockey, block, False) edges = [] for src in vertexs: successLocKeys = self.ircfg.successors(src) for key in successLocKeys: if key in vertexs: vSrc = vertexs[src] vDst = vertexs[key] edge = Edge(vSrc, vDst) edge.view = BasicEdge(vDst) edges.append(edge) vSrc.view.outBlocks.append(vDst.view) vDst.view.inBlocks.append(vSrc.view) self.graph = Graph(vertexs.values(), edges) sugLayout = SugiyamaLayout(self.graph.C[0]) sugLayout.route_edge = route_with_lines sugLayout.init_all() sugLayout.draw() for v in vertexs.values(): self.addBlock(v.view, v.view.xy[0] - (v.view.w / 2), v.view.xy[1] - (v.view.h / 2)) for e in edges: srcView = e.v[0].view srcBlock = e.v[0].data dstBlock = e.v[1].data if len(srcView.outBlocks) == 1: color = Qt.darkBlue elif dstBlock.loc_key == self.ircfg.successors(srcBlock.loc_key)[0]: color = Qt.darkRed else: color = Qt.darkGreen edge_view = e.view edge_view.color = color self.scene.addItem(edge_view)
def create_sug_layout(self, graph): sug = SugiyamaLayout(graph.C[0]) sug.route_edge = route_with_splines sug.init_all(optimize=True) sug.draw(10) return sug
def _layout_nodes_and_edges(self, start): """ Compute coordinates for all CFG nodes and edges in the view :param int start: The starting address :return: a mapping between nodes' names and their coordinates (dict), and a list of edge coordinates (list) :rtype: tuple """ coordinates = {} node_map = {} # Create the map for child in self.children(): if not isinstance(child, QtContainer): continue node_map[child.declaration.addr] = child if start not in node_map: return { } vertices = {} edges = [ ] # Create all edges for s, d in self.declaration.edges: src, dst = int(s), int(d) if src in vertices: src_v = vertices[src] else: src_v = Vertex(src) vertices[src] = src_v if dst in vertices: dst_v = vertices[dst] else: dst_v = Vertex(dst) vertices[dst] = dst_v edge = Edge(src_v, dst_v) edge.view = EdgeViewer() edges.append(edge) # Create all vertices for child in self.children(): addr = child.declaration.addr if addr not in vertices: vertices[addr] = Vertex(addr) g = Graph(vertices.values(), edges) # create a view for each node for addr, vertex in vertices.iteritems(): node = node_map[addr] width, height = node._layout_manager.best_size() vertex.view = VertexViewer(width, height) sug = SugiyamaLayout(g.C[0]) sug.route_edge = self._route_edges sug.init_all(roots=[vertices[start]]) sug.draw() # extract coordinates for nodes for addr, vertex in vertices.iteritems(): x, y = vertex.view.xy # Convert the center coordinate to left corner coordinate coordinates[addr] = (x - vertex.view.w / 2, y - vertex.view.h / 2) # extract coordinates for edges edge_coordinates = [ ] for edge in edges: if hasattr(edge.view, '_pts'): edge_coordinates.append(edge.view._pts) return coordinates, edge_coordinates