'We want to build the type of DFG that\'s used in "Automated Ident. of Crypto
Primitives in Binary Code with Data Flow Graph Isomorphisms." Unlike that
paper, however, we\'re building it on Vex IR instead of assembly instructions.'

def _construct(self):

    cfg = self._cfg
    p = self.project
    dfgs = {}
    l.debug('Building    Vex    DFG...')
    for node in cfg.nodes():
        try:
            if (node.simprocedure_name == None):
                irsb = p.factory.block(node.addr).vex
            else:
                l.debug(('Cannot    process    SimProcedures,    ignoring    %s' % node.simprocedure_name))
                continue
        except Exception as e:
            l.debug(e)
            continue
        tmpsnodes = {}
        storesnodes = {}
        putsnodes = {}
        statements = irsb.statements
        dfg = DiGraph()
        for (stmt_idx, stmt) in enumerate(statements):
            if self._need_to_ignore(node.addr, stmt, stmt_idx):
                continue
            exprs = stmt.expressions
            stmt_node = stmt
            dfg.add_node(stmt)
            if (stmt.tag == 'Ist_WrTmp'):
                tmpsnodes[stmt.tmp] = stmt_node
                if (exprs[0].tag == 'Iex_Binop'):
                    if (exprs[1].tag == 'Iex_RdTmp'):
                        dfg.add_edge(tmpsnodes[exprs[1].tmp], stmt_node)
                    else:
                        dfg.add_edge(exprs[1], stmt_node)
                    if (exprs[2].tag == 'Iex_RdTmp'):
                        dfg.add_edge(tmpsnodes[exprs[2].tmp], stmt_node)
                    else:
                        dfg.add_edge(exprs[2], stmt_node)
                elif (exprs[0].tag == 'Iex_Unop'):
                    dfg.remove_node(stmt_node)
                    if (exprs[1].tag == 'Iex_RdTmp'):
                        tmpsnodes[stmt.tmp] = copy(tmpsnodes[exprs[1].tmp])
                        tmpsnodes[stmt.tmp].tmp = stmt.tmp
                    else:
                        tmpsnodes[stmt.tmp] = exprs[1]
                elif (exprs[0].tag == 'Iex_RdTmp'):
                    tmpsnodes[stmt.tmp] = copy(tmpsnodes[exprs[0].tmp])
                    tmpsnodes[stmt.tmp].tmp = stmt.tmp
                elif (exprs[0].tag == 'Iex_Get'):
                    if putsnodes.has_key(exprs[0].offset):
                        dfg.add_edge(putsnodes[exprs[0].offset], stmt_node)
                    if ((len(exprs) > 1) and (exprs[1].tag == 'Iex_RdTmp')):
                        dfg.add_edge(tmpsnodes[exprs[1].tmp], stmt_node)
                    elif (len(exprs) > 1):
                        dfg.add_edge(exprs[1], stmt_node)
                elif (exprs[0].tag == 'Iex_Load'):
                    if (exprs[1].tag == 'Iex_RdTmp'):
                        dfg.add_edge(tmpsnodes[exprs[1].tmp], stmt_node)
                    else:
                        dfg.add_edge(exprs[1], stmt_node)
                else:
                    for e in exprs[1:]:
                        if (e.tag == 'Iex_RdTmp'):
                            dfg.add_edge(tmpsnodes[e.tmp], stmt_node)
                        else:
                            dfg.add_edge(e, stmt_node)
            elif (stmt.tag == 'Ist_Store'):
                if (exprs[0].tag == 'Iex_RdTmp'):
                    dfg.add_edge(tmpsnodes[exprs[0].tmp], stmt_node)
                elif (exprs[0].tag == 'Iex_Const'):
                    dfg.add_edge(exprs[0], stmt_node)
                if (exprs[1].tag == 'Iex_RdTmp'):
                    dfg.add_edge(tmpsnodes[exprs[1].tmp], stmt_node)
                else:
                    dfg.add_edge(exprs[1], stmt_node)
            elif (stmt.tag == 'Ist_Put'):
                if (exprs[0].tag == 'Iex_RdTmp'):
                    dfg.add_edge(tmpsnodes[exprs[0].tmp], stmt_node)
                elif (exprs[0].tag == 'Iex_Const'):
                    dfg.add_edge(exprs[0], stmt_node)
                putsnodes[stmt.offset] = stmt_node
            elif (stmt.tag == 'Ist_Exit'):
                if (exprs[0].tag == 'Iex_RdTmp'):
                    dfg.add_edge(tmpsnodes[exprs[0].tmp], stmt_node)
            elif (stmt.tag == 'Ist_Dirty'):
                tmpsnodes[stmt.tmp] = stmt_node
            elif (stmt.tag == 'Ist_CAS'):
                tmpsnodes[stmt.oldLo] = stmt_node
            else:
                for e in stmt.expressions:
                    if (e.tag == 'Iex_RdTmp'):
                        dfg.add_edge(tmpsnodes[e.tmp], stmt_node)
                    else:
                        dfg.add_edge(e, stmt_node)
        for vtx in dfg.nodes():
            if (dfg.degree(vtx) == 0):
                dfg.remove_node(vtx)
        if (dfg.size() > 0):
            dfgs[node.addr] = dfg
    return dfgs
