Example #1
0
/**************************************************************************
 * Main function. This function is run on each node that is being traversed
 * in the graph. For each node, we determine the successors and check
 * if those have been previously seen. If yes, a cycle may exist.
 **************************************************************************/
bool 
CompassAnalyses::CycleDetection::Traversal::run(string& name, SgGraphNode* node,
                                                SgGraphNode* previous){
  // check known function calls and resolve variables
  ROSE_ASSERT(node);

  //cerr << " cycledetection->run " << node->get_name() << endl;
  SgAsmFunction* func = isSgAsmFunction(node->get_SgNode());
  if (func) {
    // if the node is a function, we clear the visited nodes
    // this should speed up our search
    visited.clear();
    return false;
  }
  successors.clear();
  ROSE_ASSERT(vizzGraph);
  vizzGraph->getSuccessors(node, successors);    
  vector<SgGraphNode*>::iterator succ = successors.begin();
  for (;succ!=successors.end();++succ) {
    // for each successor do...
    SgGraphNode* next = *succ;
    // if the node is an instruction, we check if it was visited
    // if not, we add it to the visited set, otherwise a cycle is present
    std::set<SgGraphNode*>::iterator it =visited.find(next);
    if (it!=visited.end()) {
      // found this node in visited list
      SgAsmX86Instruction* nodeSg = isSgAsmX86Instruction(node->get_SgNode());
      SgAsmX86Instruction* nextSg = isSgAsmX86Instruction(next->get_SgNode());
      if (debug) {
        std::string outputText = "Found possible cycle between  ";
        outputText+=stringifyX86InstructionKind(nodeSg->get_kind()) + " (";
        outputText+=RoseBin_support::HexToString(nodeSg->get_address()) + ") and ";
        outputText+=stringifyX86InstructionKind(nextSg->get_kind()) + " (";
        outputText+=RoseBin_support::HexToString(nextSg->get_address()) + ")";
        std::cerr << outputText << std::endl;
        output->addOutput(new CheckerOutput(nodeSg, outputText));
      }
      bool validCycle = checkIfValidCycle(node,next);
      if (validCycle) {
        std::string outputText = "Found cycle between  ";
        outputText+=stringifyX86InstructionKind(nodeSg->get_kind()) + " (";
        outputText+=RoseBin_support::HexToString(nodeSg->get_address()) + ") and ";
        outputText+=stringifyX86InstructionKind(nextSg->get_kind()) + " (";
        outputText+=RoseBin_support::HexToString(nextSg->get_address()) + ")";
        std::cerr << outputText << std::endl;
        output->addOutput(new CheckerOutput(nodeSg, outputText));
	cycleFound[node]=next;
      } else {
	if (debug)
	  std::cerr << "This is not a cyclic node "  << std::endl;
      }
    }
  }
  visited.insert(node);
  return false;
}
Example #2
0
void
AstDOTGeneration::writeIncidenceGraphToDOTFile(SgIncidenceDirectedGraph* graph,  const std::string& filename)
   {
  // Output all nodes
     rose_graph_integer_node_hash_map & nodes = graph->get_node_index_to_node_map ();

     for( rose_graph_integer_node_hash_map::iterator it = nodes.begin(); it != nodes.end(); ++it )
        {
          SgGraphNode* node = it->second;

          if( commentOutNodeInGraph(node) == false )
             {
               string nodeoption;
               string nodelabel=string("\\n")+node->get_name();

               nodelabel += additionalNodeInfo(node);

               string additionalOptions = additionalNodeOptions(node);

               string x;
               string y;
               x += additionalOptions;

               nodeoption += additionalOptions;

            // dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
               dotrep.addNode(node,nodelabel,nodeoption);

               addAdditionalNodesAndEdges(node);
             }
        }

  // Output edges
     rose_graph_integer_edge_hash_multimap & outEdges = graph->get_node_index_to_edge_multimap_edgesOut ();

     for( rose_graph_integer_edge_hash_multimap::const_iterator outEdgeIt = outEdges.begin(); outEdgeIt != outEdges.end(); ++outEdgeIt )
        {
       // if(debug) std::cerr << " add edge from node ... " << std::endl; // debug
          SgDirectedGraphEdge* graphEdge = isSgDirectedGraphEdge(outEdgeIt->second);
          ROSE_ASSERT(graphEdge!=NULL);

          if ( commentOutNodeInGraph(graphEdge) == false )
             {
               string edgelabel=string("\\n")+graphEdge->get_name();

               string edgeoption = additionalEdgeOptions(graphEdge->get_from(),graphEdge->get_to(),edgelabel);
               dotrep.addEdge(graphEdge->get_from(),edgelabel,graphEdge->get_to(),edgeoption + "dir=forward");
               addAdditionalNodesAndEdges(graphEdge);
             }

        }

     dotrep.writeToFileAsGraph(filename);
   }
void
CompassAnalyses::BinaryInterruptAnalysis::Traversal::getValueForDefinition(std::vector<uint64_t>& vec,
                                                                std::vector<uint64_t>& positions,
                                                                uint64_t& fpos,
                                                                SgGraphNode* node,
                                                                std::pair<X86RegisterClass, int> reg ) {
  set <SgGraphNode*> defNodeSet = getDefFor(node, reg);
  if (RoseBin_support::DEBUG_MODE()) 
    cout << "    size of found NodeSet = " << defNodeSet.size() <<endl;
  set <SgGraphNode*>::const_iterator it = defNodeSet.begin();
  for (;it!=defNodeSet.end();++it) {
    SgGraphNode* defNode = *it;
    if (RoseBin_support::DEBUG_MODE() && defNode) 
      cout << "    investigating ... " << defNode->get_name() <<endl;
    ROSE_ASSERT(defNode);
    SgAsmx86Instruction* inst = isSgAsmx86Instruction(defNode->get_SgNode());
    ROSE_ASSERT(inst);
    positions.push_back(inst->get_address());
    // the right hand side of the instruction is either a use or a value
    bool memRef = false, regRef = false;
    std::pair<X86RegisterClass, int> regRight =
      check_isRegister(defNode, inst, true, memRef, regRef);

    if (RoseBin_support::DEBUG_MODE()) {
      string regName = unparseX86Register(RegisterDescriptor(reg.first, reg.second, 0, 64), NULL);
      string regNameRight = unparseX86Register(RegisterDescriptor(regRight.first, regRight.second, 0, 64), NULL);
      cout << " VarAnalysis: getValueForDef . " << regName << "  right hand : " << regNameRight <<endl;
    }
    if (!regRef) {
      // it is either a memref or a value
      if (!memRef) {
	// get value of right hand side instruction
	uint64_t val = getValueOfInstr(inst, true);
	vec.push_back(val);
	fpos = inst->get_address();
	if (RoseBin_support::DEBUG_MODE()) 
      	  cout << "    found  valueOfInst = " << RoseBin_support::ToString(val) <<endl;
      }
    } else {
      // it is a register reference. I.e we need to follow the usage edge to find the 
      // definition of that node
      SgGraphNode* usageNode = g_algo->getDefinitionForUsage(vizzGraph,defNode);
      if (usageNode && usageNode!=node) {
	if (RoseBin_support::DEBUG_MODE() && usageNode) 
      	  cout << "    following up usage for " << usageNode->get_name() <<endl;
	getValueForDefinition(vec, positions, fpos, usageNode, regRight);
      } else {
	// we look at the same node.
	cout << " ERROR :: Either following usage to itself or usageNode = NULL. " << usageNode << endl;
      }
    }
  }
}
 foreach(SgDirectedGraphEdge *edge, edges) {
     SgGraphNode *toNode = edge->get_to();
     SgFunctionDeclaration *toDecl = isSgFunctionDeclaration(toNode->get_SgNode());
     ROSE_ASSERT(toDecl != NULL);
     
     if(toDecl->get_specialFunctionModifier().isConstructor() || toDecl->get_specialFunctionModifier().isDestructor())
         continue;
     
     if(find(functions.begin(), functions.end(), toDecl) == functions.end()) {
          graph->removeDirectedEdge(edge);
          std::cout << "Edge removed from " << defDecl->get_qualified_name().getString() << " to " << 
                  toDecl->get_qualified_name().getString()<< std::endl;
     }
     
 }
void
RoseBin_ControlFlowAnalysis::getCFGNodesForFunction(std::set<SgGraphNode*>& visited_f,
                                                    std::set<std::string>& visited_names,
                                                    SgGraphNode* next_n, std::string nodeName){
#if 1
    ASSERT_not_reachable("no longer supported");
#else
  // traverse the graph from next to node
  std::vector<SgGraphNode*> successors_f;
  //  std::set<SgGraphNode*> visited_f;
  //std::set<std::string> visited_names;
  vector<SgGraphNode*> worklist;
  worklist.push_back(next_n);
  visited_f.insert(next_n);
  visited_names.insert(nodeName);
  while (!worklist.empty()) {
    SgGraphNode* current = worklist.back();
    worklist.pop_back();
    successors_f.clear();

    vizzGraph->getSuccessors(current, successors_f);
    vector<SgGraphNode*>::iterator succ = successors_f.begin();
    for (;succ!=successors_f.end();++succ) {
      SgGraphNode* next = *succ;

        std::set<SgGraphNode*>::iterator
          it =visited_f.find(next);
        if (sameParents(current,next))
        if (it==visited_f.end()) {
          //      if (sameParents(current,next))
            worklist.push_back(next);
          visited_f.insert(next);
          SgNode* internal = next->get_SgNode();
          SgAsmInstruction* inst = isSgAsmInstruction(internal);
          if (inst) {
            string name = RoseBin_support::HexToString(inst->get_address());
            if (debug)
            cerr << " adding node to function : ."<<name<<"."<<endl;
            visited_names.insert(name);
          }
        }

    } // for
  } // while
#endif
}
SgGraphNode*
RoseBin_FlowAnalysis::addCFNode(string& name, string& type, int address, bool isFunction, SgNode* int_node) {
  ROSE_ASSERT(int_node);
  ostringstream addrhex;
  addrhex << hex << setw(8) << address ;
  string addr_str = addrhex.str();
  SgGraphNode* n_source = NULL;
  if (isFunction) {
    addr_str+="_f";
  }

  rose_graph_string_integer_hash_multimap::iterator name_iterator = 
    vizzGraph->get_string_to_node_index_multimap().find(addr_str);
  if (name_iterator == vizzGraph->get_string_to_node_index_multimap().end()) {

    n_source=vizzGraph->addNode(addr_str,int_node);
    ROSE_ASSERT(n_source);
    //cerr << " ............ RoseBin_FlowAnalysis >>>>>>>>>>>>>>>> Adding node : " << 
    // addr_str << "   idx: " << n_source->get_index() << endl;
    n_source->append_properties(SgGraph::name, name);
    n_source->set_SgNode(int_node);
    //n_source->set_type(type);
  } else {
   // exit(1);
    int index = name_iterator->second;
    ROSE_ASSERT(index>=0);
    rose_graph_integer_node_hash_map themap = 
      vizzGraph->get_node_index_to_node_map();
    //cerr << " RoseBin_FlowAnalysis -- NODE ALREADY EXISTS! at index: " << index << endl;
    rose_graph_integer_node_hash_map::iterator it = themap.find(index);
    if (it==themap.end()) {
      ROSE_ASSERT(false);
    }
    SgGraphNode* node = it->second;
    ROSE_ASSERT(node->get_SgNode());
    return node;
  }

  ROSE_ASSERT(n_source->get_SgNode());
  return n_source;
}
void
RoseBin_FlowAnalysis::getRootNodes(vector <SgGraphNode*>& rootNodes) {
  nrOfFunctions=0;
  ROSE_ASSERT(vizzGraph);
  //cerr << " get Root nodes " << endl;
  rose_graph_integer_node_hash_map::const_iterator itn = vizzGraph->get_node_index_to_node_map().begin();
  for (; itn!=vizzGraph->get_node_index_to_node_map().end();++itn) {
    //    string hex_address = itn->first;
    SgGraphNode* node = isSgGraphNode(itn->second);
    string hex_address = node->get_name();
    //ROSE_ASSERT(hex_address==hex_addr_tmp);

    SgNode* internal = node->get_SgNode();
    SgAsmFunction* func = isSgAsmFunction(internal);
    if (func) {
      rootNodes.push_back(node);
      //cerr <<  " ............................. rootNode : " << hex_address << " " << node->get_name() << endl;
      nrOfFunctions++;
    }
  }
}
void
RoseBin_DataFlowAnalysis::traverseNodes(RoseBin_DataFlowAbstract* analysis) {
  if (RoseBin_support::DEBUG_MODE_MIN())
    cerr << " >> Traversing over all nodes and adding label ... " << endl;
  rose_graph_integer_node_hash_map::iterator itn = vizzGraph->get_node_index_to_node_map().begin();
  for (; itn!=vizzGraph->get_node_index_to_node_map().end();++itn) {
    SgGraphNode* node = isSgGraphNode(itn->second);
    ROSE_ASSERT(node);
    SgNode* internal = node->get_SgNode();
    ROSE_ASSERT(internal);
    SgAsmInstruction* inst = isSgAsmInstruction(internal);
    if (inst) {
      uint64_t address = inst->get_address();
      RoseBin_Variable* var = analysis->getVariable(address);
      if (var) {
        std::string var_str = var->toString();
        node->append_properties(SgGraph::variable,var_str);
      }
    }
  }
}
std::set < uint64_t >
RoseBin_DataFlowAnalysis::getDefForInst( uint64_t inst, std::pair<X86RegisterClass, int> initName) {
  std::set <uint64_t> hexSet;
  SgGraphNode* node = getNodeFor(inst);
  if (node==NULL)
    cerr << "ERROR: getDefForInst " << RoseBin_support::HexToString(inst) << "  does not exist! " << endl;

  set<SgGraphNode*> nodes = defuse->getDefFor(node, initName);
  set<SgGraphNode*>::iterator it = nodes.begin();
  for (;it!=nodes.end();++it) {
    SgGraphNode* n = *it;
    if (n) {
      SgAsmInstruction* instNode = isSgAsmInstruction(n->get_SgNode());
      if (instNode) {
        hexSet.insert(instNode->get_address());
        //cerr << "INSERT: getDefForInst " <<
        //RoseBin_support::HexToString(instNode->get_address()) << endl;
      }
    }
  }
  return hexSet;
}
void
RoseBin_DataFlowAbstract::printDefTableToFile(
                                              std::string fileName) {
  std::ofstream myfile;
  myfile.open(fileName.c_str());

  vector<SgGraphNode*> sorted;
  tabletype::iterator it2 = deftable.begin();
  for (;it2!=deftable.end();++it2) {
    SgGraphNode* node = it2->first;
    sorted.push_back(node);
  }
  std::sort(sorted.begin(), sorted.end());

  //  tabletype::iterator it = deftable.begin();
  //for (;it!=deftable.end();++it) {
  vector<SgGraphNode*>::iterator it = sorted.begin();
  for (;it!=sorted.end();++it) {
    //    SgGraphNode* node = it->first;
    SgGraphNode* node = *it;
    //    const multitype& type = getDefinitionsFor(node);
    const multitype& type = getDefMultiMapFor(node);
    multitype::const_iterator itm = type.begin();
    if (node) {
      string line = ""+node->get_name()+" : \n";
      for (;itm!=type.end();++itm) {
        std::pair<X86RegisterClass, int>  code = itm->first;
        SgGraphNode* nodeDef = itm->second;
        string registerName = unparseX86Register(RegisterDescriptor(code.first, code.second, 0, 64));

        string def = registerName+" - "+nodeDef->get_name();
        line+="   "+def+"\n";
      }
      myfile << line ;
    }
  }

  myfile.close();
}
Example #11
0
void CFG::buildCFG(CFGNode n)
{
    ROSE_ASSERT(n.getNode());

    if (explored_.count(n) > 0)
        return;
    explored_.insert(n);

    SgGraphNode* from = NULL;
    if (all_nodes_.count(n) > 0)
    {
        from = all_nodes_[n];
    }
    else
    {
        from = new SgGraphNode;
        from->set_SgNode(n.getNode());
        from->addNewAttribute("info", new CFGNodeAttribute(n.getIndex(), graph_));
        all_nodes_[n] = from;
        graph_->addNode(from);
    }

    std::vector<VirtualCFG::CFGEdge> outEdges = n.outEdges();
    foreach (const VirtualCFG::CFGEdge& edge, outEdges)
    {
        CFGNode tar = edge.target();

        SgGraphNode* to = NULL;
        if (all_nodes_.count(tar) > 0)
            to = all_nodes_[tar];
        else
        {
            to = new SgGraphNode;
            to->set_SgNode(tar.getNode());
            to->addNewAttribute("info", new CFGNodeAttribute(tar.getIndex(), graph_));
            all_nodes_[tar] = to;
            graph_->addNode(to);
        }

        graph_->addDirectedEdge(new SgDirectedGraphEdge(from, to));
    }
/***********************************************************************
 * (10/31/07) tps: Traverses the graph for each node in rootNodes
 * and applies to each node the evaluate function
 * which can be either def_use, variable detection or emulation
 * Each node in the controlflow of rootNode is traversed (forward)
 * and only if the hasChanged function returns false, the algorithm
 * comes to a fixpoint
 ***********************************************************************/
void
RoseBin_DataFlowAnalysis::traverseGraph(vector <SgGraphNode*>& rootNodes,
                                        RoseBin_DataFlowAbstract* analysis,
                                        bool interprocedural){
  if (RoseBin_support::DEBUG_MODE_MIN())
    cerr << " traverseGraph : debug: " << RoseBin_support::resBool(RoseBin_support::DEBUG_MODE()) <<
      "  debug_min : " <<  RoseBin_support::resBool(RoseBin_support::DEBUG_MODE_MIN()) << endl;
  // Number of functions traversed
  int funcNr =0;
  // ---------------------------------------------------------------------
  // stores the nodes that still needs to be visited
  //  vector<SgGraphNode*> worklist;
  deque<SgGraphNode*> worklist;
  nodeHashSetType worklist_hash;
  // a vector of successors of the current node
  vector<SgGraphNode*> successors;
  // ---------------------------------------------------------------------


  // iterate through all functions
  vector<SgGraphNode*>::iterator it = rootNodes.begin();
  for (; it!=rootNodes.end();++it) {
    // current node
    SgGraphNode* node = *it;

    string func_name = vizzGraph->getProperty(SgGraph::name, node);
    RoseBin_support::checkText(func_name);
    funcNr++;
    if (RoseBin_support::DEBUG_MODE()) {
      cout << "\n\n -----------  dataflow analysis of function ("+RoseBin_support::ToString(funcNr)+"/"+
        RoseBin_support::ToString(rootNodes.size())+") : " << func_name <<
        "  visited size : " << visited.size() <<
        "  total visited nodes : " << nrOfNodesVisited << endl;
      // debug
    }
    if (RoseBin_support::DEBUG_MODE_MIN()) {
      cerr << " -----------  dataflow analysis of function ("+RoseBin_support::ToString(funcNr)+"/"+
        RoseBin_support::ToString(rootNodes.size())+") : " << func_name <<
        "  visited size : " << visited.size() <<
        "  total visited nodes : " << nrOfNodesVisited <<
        "  def size  : " << analysis->getDefinitionSize() << endl;
    }

    // indicates whether the current value for this node has changed
    bool hasChanged=false;
    // pushback into worklist and visited list
    worklist.push_back(node);
    worklist_hash.insert(node);
    visited.insert(node);
    visitedCounter[node] = 1;
    vector <SgGraphNode*> pre;
    // while there are still graph nodes in the worklist do

    while (worklist.size()>0) {
      nrOfNodesVisited++;
      // the new node is taken from the back of the worklist
      //node = worklist.back();
      //worklist.pop_back();
      node = worklist.front();
      worklist.pop_front();

      worklist_hash.erase(node);
      // get the successors of the current node and store in successors vector
      string name = vizzGraph->getProperty(SgGraph::name, node);

      //if (RoseBin_support::DEBUG_MODE_MIN() && node)
      //        if (node->get_SgNode())
      //  cerr << node->get_SgNode()->class_name() << "  " << node << "  " << node->get_name() << endl;

      if (RoseBin_support::DEBUG_MODE_MIN() && node) {
        SgAsmInstruction* instr = isSgAsmInstruction(node->get_SgNode());
        if (instr) {
          SgAsmFunction* funcParent = isSgAsmFunction(instr->get_parent());
          if (funcParent) {
            string parent = funcParent->get_name();
            cout << " ---- analysis of node in function : " << parent <<
              "  defs " << analysis->getDefinitionSize() <<
              " visited : " << RoseBin_support::ToString(visitedCounter[node]) << endl;
          }
        }
      }


      if (RoseBin_support::DEBUG_MODE())
        cout << "\n evaluating: " << name << endl;
      // do something with the current node
      // e.g. checkVariables(name, node);
      SgGraphNode* nodeBefore= NULL;
      BeforeMapType::const_iterator it =
        nodeBeforeMap.find(node);
      if (it!=nodeBeforeMap.end())
        nodeBefore = it->second;
      // successor vector is empty on each new node
      successors.clear();
      ROSE_ASSERT(isSgIncidenceDirectedGraph(vizzGraph));
      isSgIncidenceDirectedGraph(vizzGraph)->getSuccessors(node, successors);

      hasChanged = analysis->run(name, node, nodeBefore);

      // append the successors to the worklist
      if (RoseBin_support::DEBUG_MODE())
        cout << ">> getting successors  (" << successors.size() << ") for : " << name << endl;
      //        if (successors.size()==0)
      //          cout << "PROBLEM ..................................................... : " << endl;
      vector<SgGraphNode*>::iterator succ = successors.begin();
      for (;succ!=successors.end();++succ) {
        // for each successor do...
        SgGraphNode* next = *succ;
        SgAsmX86Instruction* nodeN = isSgAsmX86Instruction(node->get_SgNode());
        //if (!nodeN) continue;
        SgAsmX86Instruction* nextN = isSgAsmX86Instruction(next->get_SgNode());
        //if (!nextN) continue;

        string name_n = vizzGraph->getProperty(SgGraph::name, next);



        bool call = false;
        bool exceptionCallNext = false;
        if (nextN)
          exceptionCallNext = exceptionCall(nextN->get_kind() == x86_call ? nextN : 0);
        bool exceptionCallNode = false;
        if (nodeN)
          exceptionCallNode = exceptionCall(nodeN->get_kind() == x86_call ? nodeN : 0);
        if (RoseBin_support::DEBUG_MODE())
          std::cout << " exceptionCallNode : " << exceptionCallNode << " exceptionCallNext : " << exceptionCallNext << endl;
        // if function call is call to malloc we have an exception and follow the call path
        if ((exceptionCallNode && !exceptionCallNext)) {
        } else if (
                   //if (
                   (nodeN && nodeN->get_kind() == x86_call) ||
                   (nextN && nextN->get_kind() == x86_ret) )
          call = true;
        //bool sameParent = analysis->sameParents(node, next);

        bool validNode=false;
        if (g_algo->isValidCFGEdge(next, node) || exceptionCallNode)
          validNode = true;

        // debug ------------------------
        if (RoseBin_support::DEBUG_MODE()) {
          string nodeBeforeStr="";
          if (nodeBefore) nodeBeforeStr= nodeBefore->get_name();
          cout << "  DEBUG : >>>>>>>> previous node " << nodeBeforeStr
               << "      This node : " << name << "  next node : " << name_n
               << "  ** validNode : " << RoseBin_support::resBool(validNode) << endl;
        }


        // ----------------------------------
        if (( interprocedural==false && !call) //
            ||  (interprocedural==true && validNode)) {
          if (visited.find(next)==visited.end()) {
            // if the successor is not yet visited
            // mark as visited and put into worklist
            if (RoseBin_support::DEBUG_MODE())
              cout << " never visited next node before... " << name_n <<
                " interprocedural : " << interprocedural << "  call : " << call << endl;
            if (RoseBin_support::DEBUG_MODE())
              cout << "adding to visited : " << name_n << endl;

            visited.insert(next);
            nodeBeforeMap[next]=node;
            visitedCounter[next]=1;
            vizzGraph->setProperty(SgGraph::visitedCounter, next, RoseBin_support::ToString(1));
            if (!containsHash(worklist_hash,next)) {
              // add next node only if the next node
              if (RoseBin_support::DEBUG_MODE())
                cout << "adding to worklist: " << name_n << endl;
              worklist.push_back(next);
              worklist_hash.insert(next);
            }
          } else {
            // if the successor has been visited, we need to check if it has changed
            // if it has not, we continue, else we need to push it back to the worklist
            int nr = visitedCounter[next];
            if (RoseBin_support::DEBUG_MODE())
              cout << " visited next node before... " << RoseBin_support::ToString(nr) <<
                "  Changed == " << RoseBin_support::resBool(hasChanged) << endl;

            if (hasChanged) {
              visitedCounter[next]=++nr;
              vizzGraph->setProperty(SgGraph::visitedCounter, next, RoseBin_support::ToString(nr));
              if (RoseBin_support::DEBUG_MODE())
                cout << " has changed : " << RoseBin_support::resBool(hasChanged) <<
                  "  -- interprocedural : " << RoseBin_support::resBool(interprocedural) <<
                  "  -- Call : " << RoseBin_support::resBool(call) <<
                  "  ------> new number: " << RoseBin_support::ToString(nr) <<
                  "  -- contained in hash? : " << RoseBin_support::resBool(containsHash(worklist_hash,next)) <<
                  "  ---- nr of Defs: " << RoseBin_support::ToString(analysis->getDefinitionSize()) <<
                  "  ---- nr of Use: " << RoseBin_support::ToString(analysis->getUsageSize())
                     << endl;

              if (interprocedural || (!interprocedural && !call)){ //sameParent)) { //!call && ) {
                if (!containsHash(worklist_hash,next)) {
                  worklist_hash.insert(next);
                  worklist.push_back(next);
                  if (RoseBin_support::DEBUG_MODE())
                    cout << " adding to worklist: " << name_n << endl;
                }
              }
            } else
              if (RoseBin_support::DEBUG_MODE())
                cout << " has NOT changed. " << endl;
            //else we continue with the next node
          }
        }
      } // for
    } // while worklist.size()>0

  } // for rootNodes
}
void RoseBin_GMLGraph::printEdges( VirtualBinCFG::AuxiliaryInformation* info, bool forward_analysis, std::ofstream& myfile, SgDirectedGraphEdge* edge) {
  // traverse edges and visualize results of graph
    SgGraphNode* source = isSgGraphNode(edge->get_from());
    SgGraphNode* target = isSgGraphNode(edge->get_to());
    ROSE_ASSERT(source);
    ROSE_ASSERT(target);

    string edgeLabel="";
    map < int , string> edge_p = edge->get_properties();
    map < int , string>::iterator prop = edge_p.begin();
    //string type = node->get_type();
    for (; prop!=edge_p.end(); ++prop) {
      int addr = prop->first;
      // cerr << " dot : property for addr : " << addr << " and node " << hex_address << endl;
      if (addr==SgGraph::edgeLabel)
        edgeLabel = prop->second;
      if (edgeLabel.length()>1)
        if (edgeLabel[0]!='U')
          edgeLabel="";
    }

    SgAsmStatement* binStat_s = isSgAsmStatement(source->get_SgNode());
    SgAsmStatement* binStat_t = isSgAsmStatement(target->get_SgNode());
    if (binStat_s==NULL || binStat_t==NULL) {
      //cerr << "binStat_s==NULL || binStat_t==NULL" << endl;
    } else {
      map <SgAsmStatement*, int>::iterator it_s = nodesMap.find(binStat_s);
      map <SgAsmStatement*, int>::iterator it_t = nodesMap.find(binStat_t);
      int pos_s=0;
      int pos_t=0;
      if (it_s!=nodesMap.end())
        pos_s = it_s->second;
      if (it_t!=nodesMap.end())
        pos_t = it_t->second;

      if (pos_s==0 || pos_t==0) {
        //cerr << " GMLGraph edge, node == 0 " << endl;
      }

      string output = "edge [\n  label \""+edgeLabel+"\"\n source " + RoseBin_support::ToString(pos_s) +
        "\n   target " + RoseBin_support::ToString(pos_t) + "\n";

      // ------------------
      SgAsmX86Instruction* contrl = isSgAsmX86Instruction(source->get_SgNode());
      string add = "";
      if (contrl && x86InstructionIsControlTransfer(contrl)) {
        // the source is a control transfer function

        // we use either dest or dest_list
        // dest is used for single destinations during cfg run
        // dest_list is used for a static cfg image
        vector<VirtualBinCFG::CFGEdge> outEdges = contrl->cfgBinOutEdges(info);
        SgAsmX86Instruction* dest = isSgAsmX86Instruction(outEdges.empty() ? NULL : outEdges.back().target().getNode());
        bool dest_list_empty = true;
        if (contrl->get_kind() == x86_ret)
          dest_list_empty = outEdges.empty();

        SgAsmInstruction* nextNode = isSgAsmInstruction(target->get_SgNode());
        ROSE_ASSERT(nextNode);

        if (dest) {
          //string type = "jmp_if";
          if (dest==nextNode) {
            if (contrl->get_kind() == x86_call || contrl->get_kind() == x86_ret) {
              add += "   graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#FF0000\" ]  ]\n";
            } else if (contrl->get_kind() == x86_jmp) {
              add += "   graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#FF0000\" ]  ]\n";
            } else
              add += "   graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#00FF00\" ]  ]\n";
          } else
            if (forward_analysis &&
                (contrl->get_kind() == x86_call || contrl->get_kind() == x86_jmp)) {
              add += "   graphics [ type \"line\" arrow \"last\" fill \"#FFFF00\" ]  ]\n";
            }
        } else
          if (contrl->get_kind() == x86_ret ) { //&& dest_list_empty) {
            // in case of a multiple return
            add += "   graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#3399FF\" ]  ]\n";
          }
      }

      string type_n = getProperty(SgGraph::type, edge);
      if (type_n==RoseBin_support::ToString(SgGraph::usage)) {
        add = "   graphics [ type \"line\" style \"dashed\" arrow \"last\" fill \"#000000\" ]  ]\n";
      }

      // skip the function declaration edges for now
      //      bool blankOutput=false;
      //if (skipFunctions)
      //if (isSgAsmFunction(binStat_s))
      //  blankOutput=true;
      if (skipInternalEdges) {
        SgAsmX86Instruction* contrl = isSgAsmX86Instruction(source->get_SgNode());
        if (contrl && x86InstructionIsControlTransfer(contrl) && contrl->get_kind() != x86_ret) {
          if (contrl->get_kind() == x86_call)
            output += "  Edge_Color_ FF0000  \n  Type_ \"[ 33554432 CALL_EDGE ]\" \n";
          else if (contrl->get_kind() == x86_jmp)
            output += "  Edge_Color_ 00FF00  \n  Type_ \"[ 33554432 FILECALL_EDGE ]\" \n";
          else
            output += "  Edge_Color_ 0000FF  \n   ";
        }
        //else
        //  blankOutput=true;
      }

      if (add=="")
        output += "   graphics [ type \"line\" arrow \"last\" fill \"#000000\" ]  ]\n";
      else output +=add;

      myfile << output;
    }

    //  }
  // ----------
    //  nodesMap.clear();

}
void
RoseBin_GMLGraph::printNodes(    bool dfg, RoseBin_FlowAnalysis* flow,bool forward_analysis,
                                 std::ofstream& myfile, string& recursiveFunctionName) {
  //bool firstFunc = true;
  // traverse nodes and visualize results of graph

  funcMap.clear();
  nodesMap.clear();
  //cerr << " Preparing graph - Nr of Nodes : " << nodes.size() << "  edges : " << edges.size() << endl;
  //SgGraphNodeList* gnodes = get_nodes();

  //  rose_graph_hash_multimap& nodes = get_nodes()->get_nodes();
  rose_graph_integer_node_hash_map nodes = get_node_index_to_node_map();
  int counter=nodes.size();
  int count=0;
  rose_graph_integer_node_hash_map::iterator itn2 = nodes.begin();
  for (; itn2!=nodes.end();++itn2) {
    counter++;
    count++;
    pair<int, SgGraphNode*> nt = *itn2;
    //    string hex_address = itn2->first;
    SgGraphNode* node = isSgGraphNode(itn2->second);
    string hex_address =node->get_name();
    SgNode* internal = node->get_SgNode();
    SgAsmFunction* func = isSgAsmFunction(internal);
    if (func) {
      vector<SgNode*> list;
      FindInstructionsVisitorx86 vis;
#ifdef _MSC_VER
//#pragma message ("WARNING: Removed reference to AstQueryNamespace::querySubTree()")
//        ROSE_ASSERT(false);

          // CH (4/7/2010): Workaround for MSVC
          vector<SgAsmX86Instruction*> temp_list;
          AstQueryNamespace::querySubTree(func, std::bind2nd( vis, &temp_list ));
          list.resize(temp_list.size());
          std::copy(temp_list.begin(), temp_list.end(), list.begin());
#else
#if defined(__APPLE__) && defined(__MACH__)
          //Pei-Hung (7/28/2016): OSX El Capitan has issue with bind2nd.  
          vector<SgAsmX86Instruction*> temp_list;
          AstQueryNamespace::querySubTree(func, std::bind2nd( vis, &temp_list ));
          list.resize(temp_list.size());
          std::copy(temp_list.begin(), temp_list.end(), list.begin());
#else
          AstQueryNamespace::querySubTree(func, std::bind2nd( vis, &list ));
#endif
#endif
      int validInstructions = func->nrOfValidInstructions(list);
      funcMap[func]=counter;
      nodesMap[func]=count;
      string name = func->get_name();
      string text = "node [\n   id " + RoseBin_support::ToString(counter) + "\n  id_ " +
        RoseBin_support::ToString(counter) + "\n  label \"" + name + "\"\n  ";
      text +="   nrinstr_ "+RoseBin_support::ToString(validInstructions)+" \n";
      text+= " isGroup 1\n isGroup_ 1\n ]\n";

      if (name=="frame_dummy") {
        //cerr << text << endl;
        vector<SgNode*> succs = func->get_traversalSuccessorContainer();
        vector<SgNode*>::iterator j = succs.begin();
        //cerr << " ------------- free_dummy"<<endl;
        int ii=0;
        for (;j!=succs.end();j++) {
          //SgNode* n = *j;
          //cerr << " Node contained at pos:"<<ii<<"  - " << n->class_name() << endl;
          ii++;
        }
        //cerr << " number of validInstructions: " << validInstructions << endl;
      }



      if (grouping)
        myfile << text;
    }
    SgAsmInstruction* bin_inst = isSgAsmInstruction(internal);
    if (bin_inst)
      nodesMap[bin_inst]=count;

  }

  //cerr << " Writing graph to GML - Nr of Nodes : " << nodes.size() << endl;
  int pos=0;
  rose_graph_integer_node_hash_map::iterator itn = nodes.begin();
  for (; itn!=nodes.end();++itn) {
    pos++;
    //    string hex_address = itn->first;
    SgGraphNode* node = isSgGraphNode(itn->second);
    string hex_address = node->get_name();
    SgNode* internal = node->get_SgNode();
    SgAsmFunction* func = isSgAsmFunction(internal);
    string text="";
    // specifies that this node has no destination address
    nodest_jmp = false;
    // specifies that there is a node that has a call error (calling itself)
    error =false;
    // specifies a call to a unknown location
    nodest_call = false;
    // specifies where its an int instruction
    interrupt = false;
    if (func) {
      string name = func->get_name();
      //cerr << " if part name : " << name << endl;
      ROSE_ASSERT(node);
      if (grouping==false) {
        map < int , string> node_p = node->get_properties();
        map < int , string>::iterator prop = node_p.begin();
        string name = "noname";
        string type = "removed";//node->get_type();
        for (; prop!=node_p.end(); ++prop) {
          int addr = prop->first;
          //cerr << " gml : property for addr : " << addr << endl;
          if (addr==SgGraph::nodest_jmp)
            nodest_jmp = true;
          else if (addr==SgGraph::itself_call)
            error = true;
          else if (addr==SgGraph::nodest_call)
            nodest_call = true;
          else if (addr==SgGraph::interrupt)
            interrupt = true;
          //      else
          //  name = prop->second;
        }
      }

      int parent = funcMap[func];
      RoseBin_support::checkText(name);
      int length = name.length();
      text = "node [\n   id " + RoseBin_support::ToString(pos) + "\n   label \"" + name + "\"\n";
      if (nodest_jmp) {
        text += "  graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#FF0000\"  ]\n";
        text +="   Node_Color_ \"FF0000\" \n";
      }      else if (nodest_call) {
        text += "  graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#FF9900\"  ]\n";
        text +="   Node_Color_ \"FF9900\" \n";
      }      else if (interrupt) {
        text += "  graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#0000FF\"  ]\n";
        text +="   Node_Color_ \"0000FF\" \n";
      }      else if (error) {
        text += "  graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#66FFFF\"  ]\n";
        text +="   Node_Color_ \"66FFFF\" \n";
      }else {
        text += "  graphics [ h 30.0 w " + RoseBin_support::ToString(length*7) + " type \"circle\" fill \"#9933FF\"  ]\n";
        text +="   Node_Color_ \"9933FF\" \n";
      }
      text +="   gid "+RoseBin_support::ToString(parent)+" \n";
      text +="   skip_ 1 \n";
      text +="   gid_ "+RoseBin_support::ToString(parent)+" ]\n";
      // skip functions for now
      //      if (skipFunctions)
      //        text ="";
    } /*not a func*/ else {
      SgAsmX86Instruction* bin_inst = isSgAsmX86Instruction(internal);
      //cerr << " else part " << endl;
      SgAsmFunction* funcDecl_parent = NULL;
      if (bin_inst) {
        funcDecl_parent = isSgAsmFunction(bin_inst->get_parent());
        if (funcDecl_parent==NULL)
          funcDecl_parent = isSgAsmFunction(bin_inst->get_parent()->get_parent());
      }
      if (funcDecl_parent==NULL) {
        cerr << " ERROR : printNodes preparation . No parent found for node : " << bin_inst->class_name() <<
          "  " << hex_address << endl;
        continue;
      }
      if ((pos % 10000)==0)
        cout << " GMLGraph:: printing GML Nodes : " << pos << endl;
      string name = getInternalNodes(node, forward_analysis,bin_inst);
      int parent=0;
      map <SgAsmFunction*, int>::iterator its = funcMap.find(funcDecl_parent);
      if (its!=funcMap.end())
        parent = funcMap[funcDecl_parent];
      if (parent==0)
        cerr << " GMLGraph parent == 0 " << endl;

      if (onlyControlStructure && x86InstructionIsControlTransfer(bin_inst)) {
        text = "node [\n   id " + RoseBin_support::ToString(pos) + "\n" + name ;
        int instrnr = funcDecl_parent->get_childIndex(bin_inst);
        text +="   instrnr_ "+RoseBin_support::ToString(instrnr)+" \n";
        text +="   gid_ "+RoseBin_support::ToString(parent)+" \n";
        text +="   gid "+RoseBin_support::ToString(parent)+" ]\n";
      } else {
        text = "node [\n   id " + RoseBin_support::ToString(pos) + "\n" + name ;
        int instrnr = funcDecl_parent->get_childIndex(bin_inst);
        text +="   instrnr_ "+RoseBin_support::ToString(instrnr)+" \n";
        text +="   gid_ "+RoseBin_support::ToString(parent)+" \n";
        text +="   gid "+RoseBin_support::ToString(parent)+" ]\n";
      }
    }

    myfile << text;
    //    cerr << " this node : " << text << endl;
  }
  funcMap.clear();
}
/****************************************************
 * traverse the binary AST
 ****************************************************/
void
RoseBin_FlowAnalysis::visit(SgNode* node) {

  //  cerr << " traversing node " << node->class_name() << endl;

  if (isSgAsmFunction(node) ) {
    SgAsmFunction* binDecl = isSgAsmFunction(node);
    string name = binDecl->get_name();
    ostringstream addrhex;
    addrhex << hex << setw(8) << binDecl->get_address() ;
    if (name=="") {
      name=addrhex.str();
      binDecl->set_name(name);
    }
    SgAsmStatement* stat = NULL;
    //    SgAsmStatementPtrList& list = binDecl->get_statementList();

    vector<SgAsmInstruction*> list;
    FindInstructionsVisitor vis;
    AstQueryNamespace::querySubTree(binDecl, std::bind2nd( vis, &list ));

    int sizeList = list.size();
    if (sizeList==0) {
      //cerr << " this function is empty!! " << endl;
      return;
    }

    //if ((func_nr % 1)==0)
    //  if (RoseBin_support::DEBUG_MODE())
    //    cout  << analysisName << " Func Nr: " << (++func_nr) << "  blocks:" <<
    //     sizeList << "  ***************** checking function : " << name << endl;

    if (forward_analysis) {
      stat = list.front();
    } else {
      // get the last instruction in a function (backward control flow)
      stat = list.back();
    }
    ROSE_ASSERT(stat);

    //   if (RoseBin_support::DEBUG_MODE())
    //cout << ">>>>>>>>>>>>>. checking statement in function : " << name << " .. " << stat->class_name() << endl;
    if (isSgAsmInstruction(stat)) {
      SgAsmInstruction* inst = isSgAsmInstruction(stat);
      ROSE_ASSERT(inst);
      // check the control flow of the first instruction in a function
      string typeFunction ="function";
      SgGraphNode* src=NULL;
      if (analysisName=="callgraph") {
        //      src = vizzGraph->createNode (name, typeFunction, binDecl->get_address(), vizzGraph->graph->get_graph_id(), false, binDecl);
        src = addCFNode (name, typeFunction, binDecl->get_address(), false, binDecl);
      } else {
        //src = vizzGraph->createNode (name, typeFunction, binDecl->get_address(), vizzGraph->graph->get_graph_id(), true, binDecl);
        //cerr << ">> adding node (f) src: " << RoseBin_support::HexToString(binDecl->get_address()) << endl;
        src = addCFNode (name, typeFunction, binDecl->get_address(), true, binDecl);
        string mnemonic=inst->get_mnemonic();
        //SgGraphNode* trg = vizzGraph->createNode (mnemonic, typeNode, inst->get_address(), vizzGraph->graph->get_graph_id(),false, inst);
        //cerr << ">> adding node (first) trg: " << RoseBin_support::HexToString(inst->get_address()) << endl;
        SgGraphNode* trg = addCFNode (mnemonic, typeNode, inst->get_address(), false, inst);
        string unp_name = unparseInstructionWithAddress(inst);
        trg->append_properties(SgGraph::name,unp_name);
        if (analysisName=="dfa")
          trg->append_properties(SgGraph::dfa_standard,unp_name);
        //cerr << "Create edge " << endl;
        //      SgDirectedGraphEdge* edge = vizzGraph->createEdge ( typeFunction, vizzGraph->graph->get_graph_id(), src, binDecl->get_address(), trg, inst->get_address());
        SgDirectedGraphEdge* edge = vizzGraph->addDirectedEdge ( src, trg, typeFunction);
        vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg));
      }

      local_visited.clear();
      worklist_forthisfunction.push(inst);

      funcDecl = binDecl;
      funcDeclNode = src;
      checkControlFlow(inst, sizeList, sizeList, name, func_nr);
    } else {
    if (RoseBin_support::DEBUG_MODE())
      cerr << "This is not an Instruction " << endl;
    }
  }
}
void RoseBin_ControlFlowAnalysis::printGraph(std::string fileName, std::set<std::string>& filter) {
#if 1
    ASSERT_not_reachable("no longer supported");
#else
  std::set<std::string>::const_iterator it = filter.begin();
  for (;it!=filter.end();++it) {
    std::cerr << "CFG -- contains filter: ." << *it << "." << endl;
  }

// typedef rose_hash::unordered_map <std::string, SgGraphNode*> nodeType;
// typedef rose_hash::unordered_map <string, SgGraphNode*,hash_stringptr> nodeType;
  rose_graph_integer_node_hash_map result;
  //rose_graph_hash_multimap& nodes = vizzGraph->get_node_index_to_node_map();
  rose_graph_integer_node_hash_map nodes = vizzGraph->get_node_index_to_node_map();
  rose_graph_integer_node_hash_map::iterator itn2 = nodes.begin();
  for (; itn2 != nodes.end();++itn2) {
    //    string hex_address = itn2->first;

    SgGraphNode* node = itn2->second;
    string hex_address = node->get_name();
    //string hex_addr_tmp = node->get_name();
    //ROSE_ASSERT(hex_address==hex_addr_tmp);

    SgNode* internal = node->get_SgNode();
    SgAsmFunction* func = isSgAsmFunction(internal);
    if (func) {
      std::cerr << "ControlFlowAnalysis:: found function: ." << hex_address << "." <<endl;
      std::set<std::string>::const_iterator it = filter.find(hex_address);
      if (it!=filter.end()) {
        //std::cerr << " ******************* match ********************* " << std::endl;
        set<SgGraphNode*> gns;
        set<std::string> names;
        getCFGNodesForFunction(gns,names,node,hex_address);
        if (debug)
        cerr << " nodes in function: " << gns.size() << " " << names.size() <<endl;
        ROSE_ASSERT(gns.size()==names.size());
        set<SgGraphNode*>::const_iterator it2 = gns.begin();
        set<std::string>::const_iterator it3 = names.begin();
        for (;it2!=gns.end();++it2, ++it3) {
          std::string name = *it3;
          SgGraphNode* n = *it2;
          if (debug)
          cerr << " adding to result ."<<name<<"."<<endl;
          result.insert(make_pair(itn2->first,n));
        }

      }
    }
  }
  rose_graph_integer_node_hash_map nodesResult = nodes;
  rose_graph_integer_node_hash_map::iterator itn23 = nodes.begin();
  for (; itn23!=nodes.end();++itn23) {
    //string hex_address = isSgGraphNode(itn23->second)->get_name();
    int pos = itn23->first;
    //    rose_graph_integer_node_hash_map::iterator it = result.find(hex_address);
    rose_graph_integer_node_hash_map::iterator it = result.find(pos);
    if (it==result.end()) {
      // not found in result, i.e. delete
      //nodesResult.erase(hex_address);
      nodesResult.erase(pos);
    }
  }
  //  vizzGraph->nodes=nodesResult;

#if 0
  // vizzGraph->nodes=result;

  // create file
  bool forward_analysis=true;
  bool multiedge=false;
  std::ofstream myfile;
  myfile.open(fileName.c_str());

  string name = "ROSE Graph";
  vizzGraph->printProlog(myfile, name);

  string functionName="";

  vizzGraph->setGrouping(true);
  vizzGraph->printNodes(true, this, forward_analysis, myfile,functionName);
  nrNodes=vizzGraph->nodes.size();

  vizzGraph->printEdges(this,myfile, multiedge);
  nrEdges=vizzGraph->get_node_index_to_edge_multimap_edgesOut().size();

  vizzGraph->printEpilog(myfile);
  myfile.close();

#endif



#if 1
  RoseBin_Graph* gr = new RoseBin_DotGraph();
  gr->graph = new SgIncidenceDirectedGraph("test");//SgDirectedGraph("test","test");
  gr->get_node_index_to_node_map()=nodesResult;

  //typedef SB_DirectedGraph::edgeType edgeType;
  rose_graph_integer_edge_hash_multimap edges = vizzGraph->get_node_index_to_edge_multimap_edgesOut();
  rose_graph_integer_edge_hash_multimap resultEdges;
  rose_graph_integer_edge_hash_multimap::iterator itEdg = edges.begin();

  for (; itEdg!=edges.end();++itEdg) {
    int index  = itEdg->first;
    SgGraphNode* node = NULL;
    rose_graph_integer_node_hash_map::iterator nIT = vizzGraph->get_node_index_to_node_map().find(index);
    if (nIT!=vizzGraph->get_node_index_to_node_map().end())
      node=nIT->second;
    ROSE_ASSERT(node);
    SgDirectedGraphEdge* edge = isSgDirectedGraphEdge(itEdg->second);
    SgGraphNode* target = isSgGraphNode(edge->get_to());
    rose_graph_integer_node_hash_map::iterator itn2 = nodesResult.begin();
    bool foundS=false;
    if (node)
      foundS=true;
    bool foundT=false;
    for (; itn2!=nodesResult.end();++itn2) {
      SgGraphNode* n = itn2->second;
      //if (n==source) foundS=true;
      if (n==target) foundT=true;
    }
    if (foundS==false || foundT==false) {

    } else
      resultEdges.insert(make_pair(node->get_index(),edge));
  }

  gr->get_node_index_to_edge_multimap_edgesOut()=resultEdges;

  // create file
  bool forward_analysis=true;
  bool multiedge=false;
  std::ofstream myfile;
  myfile.open(fileName.c_str());

  string name = "ROSE Graph";
  gr->printProlog(myfile, name);

  string functionName="";

  gr->setGrouping(true);
  gr->printNodes(true, this, forward_analysis, myfile,functionName);
  nrNodes=gr->get_node_index_to_node_map().size();
  ROSE_ASSERT(g_algo->info);
  gr->printEdges(g_algo->info, this,myfile, multiedge);
  nrEdges=gr->get_node_index_to_edge_multimap_edgesOut().size();

  gr->printEpilog(myfile);
  myfile.close();
#endif
#endif
}
void
RoseBin_FlowAnalysis::checkControlFlow( SgAsmInstruction* binInst,
                                        int functionSize, int countDown,
                                        string& currentFunctionName, int func_nr) {
  //cerr << "check control flow" << endl;
  while (!worklist_forthisfunction.empty()) {
    SgAsmInstruction* binInst = worklist_forthisfunction.top();
    worklist_forthisfunction.pop();
    ROSE_ASSERT(binInst);

    countDown--;

    int address = binInst->get_address();
    ostringstream addrhex;
    addrhex << hex << setw(8) << address ;

    ROSE_ASSERT(g_algo->info);
    vector <VirtualBinCFG::CFGEdge> vec;
    if (forward_analysis) {
      vec = binInst->cfgBinOutEdges(g_algo->info);
      if (isSgAsmx86Instruction(binInst) && isSgAsmx86Instruction(binInst)->get_kind() == x86_call) {
        // vec.push_back(VirtualBinCFG::CFGEdge(VirtualBinCFG::CFGNode(binInst), VirtualBinCFG::CFGNode(g_algo->info->getInstructionAtAddress(binInst->get_address() + binInst->get_raw_bytes().size())), g_algo->info));
      }
    }
    else
      vec = binInst->cfgBinInEdges(g_algo->info);


    string name = binInst->get_mnemonic();
    //    if (RoseBin_support::DEBUG_MODE())
    //         cout << " " << addrhex.str() << "  " << func_nr << " :: " << functionSize <<
    //  "/" << countDown << "  ---------- next CFG instruction : " << name <<   "  vecSize : " << vec.size() << endl;



    for (int i=0; i < (int)vec.size(); i++) {
      VirtualBinCFG::CFGEdge edge = vec[i];
      VirtualBinCFG::CFGNode cfg_target = edge.target();
      VirtualBinCFG::CFGNode cfg_source = edge.source();
      if (!forward_analysis) {
        cfg_target = edge.source();
        cfg_source = edge.target();
      }
      SgAsmInstruction* bin_target = isSgAsmInstruction(cfg_target.getNode());
      SgAsmInstruction* thisbin = isSgAsmInstruction(cfg_source.getNode());
      ROSE_ASSERT(thisbin);
      SgAsmx86Instruction* thisbinX86 = isSgAsmx86Instruction(thisbin);
      ROSE_ASSERT (thisbinX86);

      string src_mnemonic = thisbin->get_mnemonic();
      int src_address = thisbin->get_address();
      if (analysisName=="callgraph")
        src_address = funcDecl->get_address();
      ostringstream addrhex_s;
      addrhex_s << hex << setw(8) << src_address ;

      SgGraphNode* src =NULL;
      string hexStr = addrhex_s.str();
      if (analysisName!="callgraph") {
        vector<SgGraphNode*> sources;
        vizzGraph->checkIfGraphNodeExists(hexStr, sources);
        vector<SgGraphNode*>::const_iterator src_it = 
          sources.begin();
        for (;src_it!=sources.end();++src_it) {
          // should only be one node! adapted to new interface
          src = *src_it;
        }
        if (src==NULL) {
          //  src= vizzGraph->createNode (src_mnemonic, typeNode, src_address, vizzGraph->graph->get_graph_id(), false, thisbin);
          src= addCFNode (src_mnemonic, typeNode, src_address,  false, thisbin);

          string unp_name = unparseInstructionWithAddress(thisbin);
          src->append_properties(SgGraph::name,unp_name);
          if (analysisName=="dfa")
            src->append_properties(SgGraph::dfa_standard,unp_name);
        }
        ROSE_ASSERT(src);
        if (thisbinX86->get_kind() == x86_call) {
          uint64_t returnAddr = thisbinX86->get_address() + thisbinX86->get_raw_bytes().size();
          ROSE_ASSERT(g_algo->info);
          SgAsmInstruction* retInsn = g_algo->info->getInstructionAtAddress(returnAddr);
          if (retInsn) {
            //worklist_forthisfunction.push(retInsn);
            //ostringstream tgthex_s;
            //tgthex_s << hex << setw(8) << returnAddr ;
            //string tgtStr = tgthex_s.str();
            //SgGraphNode* tgt = vizzGraph->checkIfGraphNodeExists(tgtStr);

            // tps (25 Aug 2008) : this line seems broken!
            //string mne = retInsn->get_mnemonic();

            //if (!tgt) {tgt = vizzGraph->createNode(mne, typeNode, returnAddr, vizzGraph->graph->get_graph_id(), false, retInsn);}
            // cerr << " ------> Creating return edge : " << thisbinX86->get_address() << " " << returnAddr << endl;
            // vizzGraph->createEdge( typeEdge, vizzGraph->graph->get_graph_id(), src, thisbinX86->get_address(), tgt, returnAddr);


          }
        }
      }

      else if (analysisName=="callgraph") {
        // These are special cases that annotate the call graph (nodes)
        // so that the visualization can pick up the properties and color correctly
        ROSE_ASSERT(g_algo->info);
        if (thisbinX86->get_kind() == x86_jmp) {

          if (thisbinX86->cfgBinOutEdges(g_algo->info).empty()) {
            funcDeclNode->append_properties(SgGraph::nodest_jmp,RoseBin_support::ToString("nodest_jmp"));
          }
        }
        else if (thisbinX86->get_kind() == x86_call) {
          //cerr << "CallGRAPH: Found call : " <<
          //  RoseBin_support::HexToString(VirtualBinCFG::CFGNode(thisbinX86).getNode()->get_address()) << " to " <<
          //  RoseBin_support::HexToString(VirtualBinCFG::CFGNode(g_algo->info->getInstructionAtAddress(thisbinX86->get_address() + thisbinX86->get_raw_bytes().size())).getNode()->get_address()) <<  endl;

          vector<VirtualBinCFG::CFGEdge> dests = thisbinX86->cfgBinOutEdges(g_algo->info);
          dests.push_back(VirtualBinCFG::CFGEdge(VirtualBinCFG::CFGNode(thisbinX86), VirtualBinCFG::CFGNode(g_algo->info->getInstructionAtAddress(thisbinX86->get_address() + thisbinX86->get_raw_bytes().size())), g_algo->info));
          if (!dests.empty()) {
            SgAsmNode* parent = isSgAsmNode(dests[0].target().getNode()->get_parent());
            if (!db)
              parent = isSgAsmNode(parent->get_parent());
            if (parent) {
              SgAsmFunction* funcdestparent = isSgAsmFunction(parent);
              string trg_func_name = funcdestparent->get_name();
              if (trg_func_name==currentFunctionName) {
                funcDeclNode->append_properties(SgGraph::itself_call,RoseBin_support::ToString("itself_call"));
              }
            }
          } else {
            funcDeclNode->append_properties(SgGraph::nodest_call,RoseBin_support::ToString("nodest_call"));
            //cerr << " no destination found for call " << addrhex.str() << endl;
          }
        }
        else if (thisbinX86->get_kind() == x86_int) {
          funcDeclNode->append_properties(SgGraph::interrupt,RoseBin_support::ToString("interrupt"));
        }
      }


      if (bin_target!=NULL) {
        string trg_func_name = "";
        int trg_func_address =1;
        string hexStrf = "";

        SgAsmFunction* funcDeclparent=NULL;
        if (analysisName=="callgraph") {
          SgAsmNode* parent = dynamic_cast<SgAsmNode*>(bin_target->get_parent());
          if (parent==NULL)
            continue;
          if (!db)
            parent = isSgAsmNode(parent->get_parent());
          ROSE_ASSERT(parent);

          funcDeclparent = isSgAsmFunction(parent);
          ROSE_ASSERT(funcDeclparent);

          trg_func_name = funcDeclparent->get_name();
          trg_func_address = funcDeclparent->get_address();
          ostringstream addrhex_tf;
          addrhex_tf << hex << setw(8) << trg_func_address ;
          hexStrf = addrhex_tf.str();
          //cerr << " CALLGRAPH TARGET PARENT : " << hexStrf << endl;
        }

        string trg_mnemonic = bin_target->get_mnemonic();
        int trg_address = bin_target->get_address();
        ostringstream addrhex_t;
        addrhex_t << hex << setw(8) << trg_address ;

        if (RoseBin_support::DEBUG_MODE())
          cout << "     OUTEDGES TO: vec[" << i << "/" << vec.size() << "]  :" <<
            addrhex_t.str() << "  " << trg_mnemonic << endl;

        string hexStr = addrhex_t.str();
        SgGraphNode* trg=NULL;
        vector<SgGraphNode*> targets;
        if (analysisName=="callgraph")
          vizzGraph->checkIfGraphNodeExists(hexStrf, targets);
        else
          vizzGraph->checkIfGraphNodeExists(hexStr, targets);
        vector<SgGraphNode*>::const_iterator src_it = 
          targets.begin();
        for (;src_it!=targets.end();++src_it) {
          // should only be one node! adapted to new interface
          trg = *src_it;
        }
        //ROSE_ASSERT(trg);

        bool target_visited = false;

        // DQ (4/23/2009): We want the type defined in the base class.
        // rose_hash::unordered_map <string, SgAsmInstruction*>::iterator vis = local_visited.find(hexStr);
// CH (4/9/2010): Use boost::unordered instead   
//#ifndef _MSCx_VER
#if 1
        rose_hash::unordered_map <string, SgAsmInstruction*>::iterator vis = local_visited.find(hexStr);
#else
        rose_hash::unordered_map <string, SgAsmInstruction*,rose_hash::hash_string>::iterator vis = local_visited.find(hexStr);
#endif
        if (vis!=local_visited.end())
          target_visited=true;

        if (trg==NULL) {
          if (analysisName=="callgraph") {
            //      cerr << " >>> TARGET FUNC NAME " << trg_func_name << endl;
            //trg = vizzGraph->createNode (trg_func_name, typeNode, trg_func_address, vizzGraph->graph->get_graph_id(),false, funcDeclparent);
            trg = addCFNode (trg_func_name, typeNode, trg_func_address,false, funcDeclparent);
          }       else {
            //trg = vizzGraph->createNode (trg_mnemonic, typeNode, trg_address, vizzGraph->graph->get_graph_id(),false, bin_target);
            trg = addCFNode (trg_mnemonic, typeNode, trg_address, false, bin_target);
          }
          string unp_name = unparseInstructionWithAddress(bin_target);
          //cout << " (target==NULL) unparse name : " << unp_name << endl;
          trg->append_properties(SgGraph::name,unp_name);
          if (analysisName=="dfa")
            trg->append_properties(SgGraph::dfa_standard,unp_name);

        } else {
          string unp_name = unparseInstructionWithAddress(bin_target);
          //cout << "    unparse name : " << unp_name << endl;
          trg->append_properties(SgGraph::name,unp_name);
          if (analysisName=="dfa")
            trg->append_properties(SgGraph::dfa_standard,unp_name);
        }


        ROSE_ASSERT(trg);
        local_visited[hexStr] = bin_target;

        string name="";
        if (analysisName=="callgraph")
          name = RoseBin_support::ToString(src_address)+RoseBin_support::ToString(trg_func_address);
        else
          name = RoseBin_support::ToString(src_address)+RoseBin_support::ToString(trg_address);

        bool exists = vizzGraph->checkIfDirectedGraphEdgeExists(src, trg);
        if (!exists) {
          if (analysisName=="callgraph") {
            if (currentFunctionName!=trg_func_name && thisbinX86->get_kind() != x86_ret) {
              //              SgDirectedGraphEdge* edge = vizzGraph->createEdge( typeEdge, vizzGraph->graph->get_graph_id(), funcDeclNode, src_address, trg, trg_func_address);
              SgDirectedGraphEdge* edge = vizzGraph->addDirectedEdge( funcDeclNode, trg, typeEdge);
              //cerr << "CallGraph : create edge : " << RoseBin_support::HexToString(src_address) << " to func : " << RoseBin_support::HexToString(trg_func_address) << endl;
              vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg));
            }
          } else {
            //string addr = RoseBin_support::HexToString(binInst->get_address());
            //if (addr==" 8048392" || addr==" 80482fd")
            //  cerr << " >>>>>>>>>> found " << addr << "  -- target_address : " << RoseBin_support::HexToString(trg_address) << endl;
            //      SgDirectedGraphEdge* edge =vizzGraph->createEdge( typeEdge, vizzGraph->graph->get_graph_id(), src, src_address, trg, trg_address);
            SgDirectedGraphEdge* edge = vizzGraph->addDirectedEdge( src, trg, typeEdge);
            vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg));
          }
        }



        if (analysisName!="callgraph") {
          // handle return edges
          SgAsmStatementPtrList sources = thisbin->get_sources();
          SgAsmStatementPtrList::iterator it = sources.begin();
          for (;it!=sources.end();++it) {
            SgAsmInstruction* instT = isSgAsmInstruction(*it);
            //cerr << " This node is called from : " << instT->get_address() << endl;
            ostringstream addr_t;
            addr_t << hex << setw(8) << instT->get_address() ;
            SgGraphNode* trg =NULL;
            string hexStr = addr_t.str();
            vector<SgGraphNode*> targets;
            vizzGraph->checkIfGraphNodeExists(hexStr, targets);
            vector<SgGraphNode*>::const_iterator src_it = 
              targets.begin();
            for (;src_it!=targets.end();++src_it) {
          // should only be one node! adapted to new interface
              trg = *src_it;
            }
            //trg= vizzGraph->checkIfGraphNodeExists(hexStr);
            if (trg==NULL) {
              string hexa = RoseBin_support::HexToString(instT->get_address());
              hexa = hexa.substr(1,hexa.size());
              string name = "0x"+hexa+":"+instT->get_mnemonic();
              //trg= vizzGraph->createNode (name, typeNode, instT->get_address(), vizzGraph->graph->get_graph_id(), false, instT);
              trg= addCFNode(name, typeNode, instT->get_address(),  false, instT);

            }

            bool exists = vizzGraph->checkIfDirectedGraphEdgeExists( trg,src);
            if (!exists) {
              bool same = sameParents(trg,src);
              if (!same) {
                SgDirectedGraphEdge* edge =vizzGraph->addDirectedEdge( trg, src, typeEdge);
                //SgDirectedGraphEdge* edge =vizzGraph->createEdge( typeEdge, vizzGraph->graph->get_graph_id(),  trg, instT->get_address(), src, src_address);
                vizzGraph->setProperty(SgGraph::type, edge, RoseBin_support::ToString(SgGraph::cfg));
              }
            }
          }
        }

        if (!target_visited) {
          // check if target is in the same function!!!
          SgAsmNode* block = bin_target;
          if (!db)
            block = isSgAsmNode(bin_target->get_parent());
          ROSE_ASSERT(block);
          SgAsmFunction* funcPar = isSgAsmFunction(block->get_parent());
          if (funcPar) {
            string nameFunc = funcPar->get_name();
            if (nameFunc==currentFunctionName) {
              //checkControlFlow(bin_target, functionSize, countDown, currentFunctionName);
              worklist_forthisfunction.push(bin_target);
            }
          } else {
            if (RoseBin_support::DEBUG_MODE())
            cerr << " ERROR:: Target Instruction has no parent! " << bin_target->class_name() << endl;
          }
        } // if visited
      } else {
        nr_target_missed++;
        if (binInst)
          if (RoseBin_support::DEBUG_MODE())
          cerr << " WARNING:: no target found for " << RoseBin_support::HexToString(binInst->get_address()) << " " << binInst->class_name() << endl;
      }
    }
  }

  //  if (RoseBin_support::DEBUG_MODE())
  //  cout << " ------------------------ done with instr: " << name << " " << addrhex.str() << endl;
}