Beispiel #1
0
bool CverPruneStack::IsAnyCallesInvokeCast(
  Function *F, CallGraph &CG, SmallSet<Function *, 32> &Visited, int depth) {


  CVER_DEBUG("\t Analyzing " << F->getName() << "\n");
  // static int maxDepth = 500;
  // if (depth >= maxDepth) {
  //   return true;
  // }

  assert(!Visited.count(F));
  Visited.insert(F);
  
  CallGraphNode *CGNode = CG[F];

  bool mayCast = false;
  for (CallGraphNode::iterator I = CGNode->begin(); I != CGNode->end(); ++I) {
    Function *calleeFunction = I->second->getFunction();
    if (!calleeFunction)
      continue;
    
    if (calleeFunction->getName() == sCast)
      return true;

    if (!Visited.count(calleeFunction))
      mayCast |= IsAnyCallesInvokeCast(calleeFunction, CG, Visited, depth+1);

    // If the callee may cast, then simply return true.
    if (mayCast)
      return true;
  }
  return mayCast;
}
/// UpdateCallGraphAfterInlining - Once we have cloned code over from a callee
/// into the caller, update the specified callgraph to reflect the changes we
/// made.  Note that it's possible that not all code was copied over, so only
/// some edges of the callgraph will be remain.
static void UpdateCallGraphAfterInlining(const Function *Caller,
                                         const Function *Callee,
                                         Function::iterator FirstNewBlock,
                                       DenseMap<const Value*, Value*> &ValueMap,
                                         CallGraph &CG) {
  // Update the call graph by deleting the edge from Callee to Caller
  CallGraphNode *CalleeNode = CG[Callee];
  CallGraphNode *CallerNode = CG[Caller];
  CallerNode->removeCallEdgeTo(CalleeNode);
  
  // Since we inlined some uninlined call sites in the callee into the caller,
  // add edges from the caller to all of the callees of the callee.
  for (CallGraphNode::iterator I = CalleeNode->begin(),
       E = CalleeNode->end(); I != E; ++I) {
    const Instruction *OrigCall = I->first.getInstruction();
    
    DenseMap<const Value*, Value*>::iterator VMI = ValueMap.find(OrigCall);
    // Only copy the edge if the call was inlined!
    if (VMI != ValueMap.end() && VMI->second) {
      // If the call was inlined, but then constant folded, there is no edge to
      // add.  Check for this case.
      if (Instruction *NewCall = dyn_cast<Instruction>(VMI->second))
        CallerNode->addCalledFunction(CallSite::get(NewCall), I->second);
    }
  }
}
Beispiel #3
0
/// UpdateCallGraphAfterInlining - Once we have cloned code over from a callee
/// into the caller, update the specified callgraph to reflect the changes we
/// made.  Note that it's possible that not all code was copied over, so only
/// some edges of the callgraph may remain.
static void UpdateCallGraphAfterInlining(CallSite CS,
                                         Function::iterator FirstNewBlock,
                                         ValueToValueMapTy &VMap,
                                         InlineFunctionInfo &IFI) {
  CallGraph &CG = *IFI.CG;
  const Function *Caller = CS.getInstruction()->getParent()->getParent();
  const Function *Callee = CS.getCalledFunction();
  CallGraphNode *CalleeNode = CG[Callee];
  CallGraphNode *CallerNode = CG[Caller];

  // Since we inlined some uninlined call sites in the callee into the caller,
  // add edges from the caller to all of the callees of the callee.
  CallGraphNode::iterator I = CalleeNode->begin(), E = CalleeNode->end();

  // Consider the case where CalleeNode == CallerNode.
  CallGraphNode::CalledFunctionsVector CallCache;
  if (CalleeNode == CallerNode) {
    CallCache.assign(I, E);
    I = CallCache.begin();
    E = CallCache.end();
  }

  for (; I != E; ++I) {
    const Value *OrigCall = I->first;

    ValueToValueMapTy::iterator VMI = VMap.find(OrigCall);
    // Only copy the edge if the call was inlined!
    if (VMI == VMap.end() || VMI->second == 0)
      continue;
    
    // If the call was inlined, but then constant folded, there is no edge to
    // add.  Check for this case.
    Instruction *NewCall = dyn_cast<Instruction>(VMI->second);
    if (NewCall == 0) continue;

    // Remember that this call site got inlined for the client of
    // InlineFunction.
    IFI.InlinedCalls.push_back(NewCall);

    // It's possible that inlining the callsite will cause it to go from an
    // indirect to a direct call by resolving a function pointer.  If this
    // happens, set the callee of the new call site to a more precise
    // destination.  This can also happen if the call graph node of the caller
    // was just unnecessarily imprecise.
    if (I->second->getFunction() == 0)
      if (Function *F = CallSite(NewCall).getCalledFunction()) {
        // Indirect call site resolved to direct call.
        CallerNode->addCalledFunction(CallSite(NewCall), CG[F]);

        continue;
      }

    CallerNode->addCalledFunction(CallSite(NewCall), I->second);
  }
  
  // Update the call graph by deleting the edge from Callee to Caller.  We must
  // do this after the loop above in case Caller and Callee are the same.
  CallerNode->removeCallEdgeFor(CS);
}
Beispiel #4
0
bool CverPruneStack::IsInvokeStack(Function *F, CallGraph &CG) {
  CallGraphNode *CGNode = CG[F];

  for (CallGraphNode::iterator I = CGNode->begin(); I != CGNode->end(); ++I) {
    Function *calleeFunction = I->second->getFunction();
    if (calleeFunction && calleeFunction->getName() == sStackEnter)
      return true;
  }
  return false;
}
Beispiel #5
0
bool Fitness::callsUnknownFunction(const CallGraphNode &CGN) const {
  DEBUG(dbgs() << "Fitness::callsUnknownFunction()\n");
  DEBUG(CGN.print(dbgs()));
  return std::any_of(CGN.begin(), CGN.end(),
                     [this](const CallGraphNode::CallRecord &CR) {
    DEBUG(dbgs() << "Checking another CallRecord\n");
    assert(CR.second);
    auto fun = CR.second->getFunction();
    // if fun is nullptr, it is external
    return (!fun || getFunType(*fun) == FunType::Unknown);
  });
}
bool CallGraphChecker::existsInCallGraph(Instruction *Call, Function *Callee) {
  CallGraph &CG = getAnalysis<CallGraph>();

  assert(Call && Callee);
  CallGraphNode *CallerNode = CG[Call->getParent()->getParent()];
  CallGraphNode *CalleeNode = CG[Callee];
  assert(CallerNode && CalleeNode);

  if (find(CallerNode->begin(), CallerNode->end(),
           CallGraphNode::CallRecord(Call, CalleeNode))
      != CallerNode->end()) {
    return true;
  }

  // An instruction conservatively calls all functions by calling
  // CallsExternalNode.
  if (find(CallerNode->begin(), CallerNode->end(),
           CallGraphNode::CallRecord(Call, CG.getCallsExternalNode()))
      != CallerNode->end()) {
    return true;
  }

  return false;
}
bool StructuredModuleEditor::getCallSite(Function *Func, uint64_t Index,
		CallSite &CS) {
	CallGraphNode *FuncNode = CG->getOrInsertFunction(Func);

	uint64_t Count = 0;
	for (CallGraphNode::const_iterator I = FuncNode->begin(), E =
			FuncNode->end(); I != E; ++I) {
		if (Count == Index) {
			CS = CallSite((*I).first);
			return true;
		}

		Count++;
	}

	return false;
}
bool StructuredModuleEditor::removeFunc(Function *FunctionToRemove) {
// Checks to make sure the function we are trying to remove
// actually exists in the CFG
	if (FunctionToRemove == NULL) {
		OS << "Function does not exist in the call graph!\n";
		return false;
	}

	CallGraphNode *NodeToRemove = (*CG)[FunctionToRemove];

	// We cannot remove a node if it has any inteprocedural in-edges
	for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
		CallGraphNode *CallingNode = (*CG)[I];
		for (CallGraphNode::iterator CGNI = CallingNode->begin(), CGNE =
				CallingNode->end(); CGNI != CGNE; ++CGNI) {
			Function *Caller = I;
			Function *Callee = CGNI->second->getFunction();
			if (Callee == FunctionToRemove && Caller != Callee) {
				OS << "Cannot remove " << FunctionToRemove->getName()
						<< " because it has at least one interprocedural edge!\n";
				OS << "It is called by " << Caller->getName() << "\n";
				return false;
			}
		}
	}

// Removes all call graph edges from the node we are removing to its callees.
	NodeToRemove->removeAllCalledFunctions();
	CG->getExternalCallingNode()->removeAnyCallEdgeTo(NodeToRemove);

// Removes all call graph edges from callees to the node we are removing
	for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
		CallGraphNode *CallingNode = (*CG)[I];
		CallingNode->removeAnyCallEdgeTo(NodeToRemove);
	}
	NodeToRemove->removeAnyCallEdgeTo(CG->getCallsExternalNode());

// Removes the function from the module and the CFG
	FunctionToRemove->dropAllReferences();

	// Remove the function from the module
	CG->removeFunctionFromModule(NodeToRemove);

	return true;
}
/// UpdateCallGraphAfterInlining - Once we have cloned code over from a callee
/// into the caller, update the specified callgraph to reflect the changes we
/// made.  Note that it's possible that not all code was copied over, so only
/// some edges of the callgraph may remain.
static void UpdateCallGraphAfterInlining(CallSite CS,
                                         Function::iterator FirstNewBlock,
                                       DenseMap<const Value*, Value*> &ValueMap,
                                         CallGraph &CG) {
  const Function *Caller = CS.getInstruction()->getParent()->getParent();
  const Function *Callee = CS.getCalledFunction();
  CallGraphNode *CalleeNode = CG[Callee];
  CallGraphNode *CallerNode = CG[Caller];

  // Since we inlined some uninlined call sites in the callee into the caller,
  // add edges from the caller to all of the callees of the callee.
  CallGraphNode::iterator I = CalleeNode->begin(), E = CalleeNode->end();

  // Consider the case where CalleeNode == CallerNode.
  CallGraphNode::CalledFunctionsVector CallCache;
  if (CalleeNode == CallerNode) {
    CallCache.assign(I, E);
    I = CallCache.begin();
    E = CallCache.end();
  }

  for (; I != E; ++I) {
    const Instruction *OrigCall = I->first.getInstruction();

    DenseMap<const Value*, Value*>::iterator VMI = ValueMap.find(OrigCall);
    // Only copy the edge if the call was inlined!
    if (VMI != ValueMap.end() && VMI->second) {
      // If the call was inlined, but then constant folded, there is no edge to
      // add.  Check for this case.
      if (Instruction *NewCall = dyn_cast<Instruction>(VMI->second))
        CallerNode->addCalledFunction(CallSite::get(NewCall), I->second);
    }
  }
  // Update the call graph by deleting the edge from Callee to Caller.  We must
  // do this after the loop above in case Caller and Callee are the same.
  CallerNode->removeCallEdgeFor(CS);
}
Beispiel #10
0
bool Strator::runOnModule(Module &m) {
	errs() << "Strator started!\n";
	/// Get previous analysis results
	// multithreadedFunctionMap = &(getAnalysis<MultithreadFinder>().multithreadedFunctionMap);
//	if(UseLocalValueInfo)
//		localValueInfo = &(getAnalysis<LocalIdentifier>().localValueInfo);
	if(UseAliasAnalysis || DebugAliasAnalysis)
		aa = &getAnalysis<AliasAnalysis>();
		//aa = getAnalysis<LocalIdentifier>().aa;
	//useDefMap = &(getAnalysis<UseDefBuilder>().useDefMap);
	CallGraph& callGraph = getAnalysis<CallGraph>();

	GEPFactory = new GEPValueFactory(&m);

	if(PrintPrevPasses){
		printLocalModificationInfo();
	}

	CallGraphNode* externalNode = callGraph.getExternalCallingNode();

	if (DirectedRaceDetection){
		/// This is the first and default race detection strategy
		/// that only tracks a main function (like the
		/// unit test case). We call this directed race detection
		/// There is no thread pool in this case but a single worker
		threadPoolSize = 0;

		/// We use this simply to mark all the external entry point functions as initially not analyzed
		CallGraphNode::iterator it;
		for(it = externalNode->begin(); it != externalNode->end(); ++it){
			Function* f = 0;
			if((f = it->second->getFunction()))
				if(f->size() > 0){
					functionMap[f->getName().str()] = false;
					++functionCount;
				}
		}

		// cerr << "Total entry point count: " << functionCount << endl;

		CallGraphNode* root = callGraph.getRoot();
		assert(root->size() && "Size of the call graph root is 0! Something is wrong");
		cerr << "Root calls: " << root->size() << " functions"<< endl;

		if(!root->getFunction()){
			cerr << "The root represents an external node" << endl;
			assert(false && "You need to switch to global race detection!");
		}
		// cerr << root->getFunction()->getName().str() << endl;
		/// Initialize all functions to not-multithreaded
		workers.push_back(new StratorWorker(this));
		for(it = root->begin(); it != root->end(); ++it){
			Function* f = 0;
			if((f = it->second->getFunction())){
				if(f->size() > 0){
					workers[0]->multithreadedFunctionMap[it->second->getFunction()->getName().str()] = false;
				}
			}
		}
		Strator::StratorWorker::LockSet* lockSet = new Strator::StratorWorker::LockSet();
		workers[0]->traverseFunction(*(root->getFunction()), *lockSet);
	} else {
		/// This is the second variant of race detection. Here all the external
		/// functions with definitions are considered as root and race detection
		/// is performed over all their childeren. this variant is called global
		/// race detection
		pthread_t tids[50];
		threadPoolSize = 50;

		if(externalNode){
			/// TODO: We should investigate the following: Some static functions (thus
			/// having internal linkage) are considered as external nodes as they are
			/// used as parameters to some functions (like pthread_create). We should
			/// understand if it is necessary to add such functions as external nodes.
			CallGraphNode::iterator it;
			for(it = externalNode->begin(); it != externalNode->end(); ++it){
				Function* f = 0;
				if((f = it->second->getFunction()))
					if(f->size() > 0){
						cerr << "adding function \"" << it->second->getFunction()->getName().str() << "\" to task list" << endl;
						tasks.push_back(f);
						++functionCount;
					}
			}
			/// Create the thread pool
			threadPoolSize = (threadPoolSize < functionCount) ? threadPoolSize : functionCount;
			/// Create as many workers as the pool size
			// threadPoolSize = 1;
			cerr << "Thread pool size:" << threadPoolSize << endl;
			for(unsigned i=0; i<threadPoolSize; ++i)
				workers.push_back(new StratorWorker(this));
			/// trigger the
			for(unsigned i=0; i<threadPoolSize; ++i){
				int retVal = pthread_create(&tids[i], 0, stratorWorkerHelper, workers[i]);
				assert(retVal == 0 && "Problem with creating the threads");
			}

			/// Synchronize the threads
			for(unsigned i=0; i<threadPoolSize; ++i){
				int retVal = pthread_join(tids[i], 0);
				assert(retVal == 0 && "Problem with joining the threads");
			}
		}
	}

	if(ReportUnprocessed){
		/// list all the unprocessed entry point functions
		cerr << "Following entry point functions were not processed: " << endl;
		FunctionMap::iterator fMIt;
		for(fMIt = functionMap.begin(); fMIt != functionMap.end(); ++fMIt){
			if(!fMIt->second)
				cerr << fMIt->first << endl;
		}
	}

	/// We have gathered race detection data, now report
	reportRaces();
	/// We did not modify the module, return false
	return false;
}
Beispiel #11
0
bool PathList::runOnModule(Module &M) {
	module = &M;
	
	llvm::dbgs() << "[runOnModule]: Moduel M has " << M.getFunctionList().size() << " Functions in all.\n";
	
	// for test
	Function *f1 = M.getFunction("fprintf");
	if (!f1)
		dbgs() << "[Test]: can not find function fprintf.\n";
	else
		dbgs() << "[Test]: find function fprintf.\n";
	  
	CallGraph &CG = getAnalysis<CallGraph>();
//	CG.dump();
	
	CallGraphNode *cgNode = CG.getRoot();
	cgNode->dump();
//	errs()<<node->getFunction()->getName()<<'\n';
	
	Function *startFunc;
	Function *endFunc;
	startFunc = M.getFunction("__user_main");
	
	//std::string fileName("/home/xqx/data/xqx/projects/benckmarks-klee/texinfo-4.8/build-shit/makeinfo/../../makeinfo/insertion.c");
	//int lineNo = 407;
	
	BB = getBB(fileName, lineNo);
	*targetBbpp = getBB(fileName, lineNo);
	if (BB) {
		endFunc = BB->getParent();
		if (!endFunc) {
			errs()<<"Error: get endFunc failed.\n";
			return false;
		}
		if (!startFunc) {
		  	errs()<<"Error: get startFunc failed.\n";
			return false;
		}
		errs()<<startFunc->getName()<<'\n';
	}
	else {
		errs()<<"Error: get BB failed.\n";
		return false;
	}
	
	
	
	//read start and end from xml files
//	defectList enStart, enEnd;
//	getEntryList("/tmp/entrys.xml", &enStart, "start");
//	getEntryList("/tmp/entrys.xml", &enEnd, "end");
//	getEntryList("/tmp/entrys.xml", &dl, "end");
//	dumpEntryList(&enStart);
//	dumpEntryList(&enEnd);
//	dumpEntryList(&dl);
	
	//read bug information from xml file
/*	for (defectList::iterator dit = dl.begin(); dit != dl.end(); dit++) {
		StringRef file(dit->first.c_str());
		std::vector<int> lines = dit->second;
		BasicBlock *BB = getBB(file, *(lines.begin()));
		if (BB) {
			endFunc = BB->getParent();
		}
	}
*/	
	//to store temporary path
	std::vector<BasicBlock*> p;
	// a counter
	int map_count = 0;
	
	for (Module::iterator i = M.begin(), e = M.end(); i != e; ++i) {
		Function *F = i;
		if (!F) {
			llvm::errs() << "***NULL Function***\n";
			continue;
		}
		cgNode = CG.getOrInsertFunction(F);
		F = cgNode->getFunction();
//		
		for (CallGraphNode::iterator I = cgNode->begin(), E = cgNode->end();
				I != E; ++I){
			CallGraphNode::CallRecord *cr = &*I;
//			llvm::errs() << "\tCS<" << cr->first << "> calls";
			// check if the CallInst is existed
			if(cr->first){
				Instruction *TmpIns = dyn_cast<Instruction>(cr->first);
				if(TmpIns) {
//					errs() << "\t" << *TmpIns << "\n";
					//unsigned int l, c;
					//std::string cfi_path = getInstPath(TmpIns, l, c);
					//if (!cfi_path.empty()) {
					//	if (cfi_path.find("uclibc") != std::string::npos) {
					//		dbgs() << "[Filter Uclib]: find an instruction from uclibc.\n";
					//		continue;
					//	} else if (cfi_path.find("POSIX") != std::string::npos) {
					//		dbgs() << "[Filter Uclib]: find an instruction from POSIX.\n";
					//		continue;
					//	}
					//}
				} else
					continue;
			}
			// get the funciton pointer which is called by current CallRecord cr
			Function *FI = cr->second->getFunction();
			if (!FI)
				continue;
			
			// create a new CalledFunctions element and push it into calledFunctionMap.
			calledFunctionMap[FI].push_back(std::make_pair(F, dyn_cast<Instruction>(cr->first)));
			// for debuging
			map_count++;			
		}

	}
	
	dbgs() << "[Count Number of calledFunctionMap]: "<< calledFunctionMap.size() <<'\n';
	
	// analyze the global function pointer table
	if(function_pointer_analysis()) {
		errs() << "[Analyze global function pointer table success]\n";
	} else {
		errs() << "[Analyze global function pointer table failed]\n";
	}
	
	dbgs() << "[Count Number of calledFunctionMap]: "<< calledFunctionMap.size() <<'\n';
	
	// filter the instructions from uclibc
	//filter_uclibc();

	llvm::errs() << "=================================hh\n";
	llvm::errs() << "get Function Path: " << endFunc->getName() 
		<< " to " << startFunc->getName() << " \n";
	
//	printCalledFuncAndCFGPath(endFunc, startFunc, BB, p);
		
	// modification by wh
	evo_paths = new entire_path;
	//filter_paths = new func_bbs_type;
	//BB_paths_map = new std::map<std::pair<Function*, BasicBlock*>, std::vector<BasicBlock*> >;
	std::vector<std::pair< Function*, Instruction*> > tmp_func_path;
//	std::vector<BasicBlock*> tmp_bb_path;
//	explore_function_paths(endFunc, startFunc, bug_Inst, &tmp_func_path);
	collect_funcitons(endFunc, startFunc, bug_Inst, &tmp_func_path);
//	dbgs() << "++++++Found " << evo_paths->size() << " function paths.\n";
	
//	for (entire_path::iterator ep_it = evo_paths->begin(); ep_it != evo_paths->end(); ep_it++) {
//		for (std::vector<std::pair< Function*, Instruction*> >::iterator pair_it = ep_it->begin(); pair_it != ep_it->end(); pair_it++) {
//			if (filter_paths->size() != 0) {
//				std::vector<Instruction*>::iterator inst_it = std::find((*filter_paths)[pair_it->first].begin(), (*filter_paths)[pair_it->first].end(), pair_it->second);
//				if (inst_it != (*filter_paths)[pair_it->first].end()) {
//					continue;
//				}
//			}
//			(*filter_paths)[pair_it->first].push_back(pair_it->second);
//		}
//	}
	dbgs() << "[filter_paths]: contain " << filter_paths->size() << " functions in all.\n";
	
	for (func_bbs_type::iterator fbs_it = filter_paths->begin(); fbs_it != filter_paths->end(); fbs_it++) {
		for (std::vector<Instruction*>::iterator bb_it2 = fbs_it->second.begin(); bb_it2 != fbs_it->second.end(); bb_it2++) {
			dbgs() << "^^^^^^ " << fbs_it->first->getName() << ": " << (*bb_it2)->getParent()->getName() << '\n';
			// to expand functions
			call_insts.push_back((*bb_it2));
			
			explore_basicblock_paths(fbs_it->first, (*bb_it2)->getParent(), &(*BB_paths_map)[std::make_pair(fbs_it->first, *bb_it2)]);
			dbgs() << "^^^^^^ found " << (*BB_paths_map)[std::make_pair(fbs_it->first, *bb_it2)].size() << " basicblocks.\n";
		}
	}
	
	llvm::dbgs() << "!!!!!!!! Found " << call_insts.size() << " call instructions.\n";
	llvm::dbgs() << "!!!!!!!! Found " << path_basicblocks.size() << " path basicblocks.\n";
	
	// expand functions
	for (std::vector<Instruction*>::iterator ci_it = call_insts.begin(); ci_it != call_insts.end(); ci_it++) {
		BasicBlock *call_bb = (*ci_it)->getParent();
		if (!call_bb) {
			continue;
		}
		for (BasicBlock::iterator inst = call_bb->begin(); inst != call_bb->end(); inst++) {
			if (&*inst == *ci_it) {
				break;
			}
			if (isa<CallInst>(&*inst)) {
				std::vector<Instruction*>::iterator ci = std::find(path_call_insts.begin(), path_call_insts.end(), &*inst);
				if (ci != path_call_insts.end())
					continue;
				path_call_insts.push_back(&*inst);
			}
		}
	}
	llvm::dbgs() << "@@@@@@@@ After search call_insts, found " << path_call_insts.size() << " call instructions.\n";
	for (std::vector<BasicBlock*>::iterator p_bb_it = path_basicblocks.begin(); p_bb_it != path_basicblocks.end(); p_bb_it++) {
		for (BasicBlock::iterator inst = (*p_bb_it)->begin(); inst != (*p_bb_it)->end(); inst++) {
			if (isa<CallInst>(&*inst)) {
				std::vector<Instruction*>::iterator ci = std::find(path_call_insts.begin(), path_call_insts.end(), &*inst);
				if (ci != path_call_insts.end())
					continue;
				path_call_insts.push_back(&*inst);
			}
		}
	}
	llvm::dbgs() << "@@@@@@@@ After search path_basicblocks, found " << path_call_insts.size() << " call instructions.\n";
	for (std::vector<Instruction*>::iterator iit = path_call_insts.begin(); iit != path_call_insts.end(); iit++) {
		CallInst *ci = dyn_cast<CallInst>(*iit);
		if (!ci)
			continue;
		Function *ff = ci->getCalledFunction();
		if (!ff) {
			//ci->dump();
			//dbgs() << "\t[called value] " << ci->getOperand(0)->getName() << '\n'; 
			
			continue;
		}
		std::vector<Function*>::iterator fit = std::find(otherCalledFuncs->begin(), otherCalledFuncs->end(), ff);
		if (fit == otherCalledFuncs->end())
			otherCalledFuncs->push_back(ff);
	}
	llvm::dbgs() << "((((((((( Found " << otherCalledFuncs->size() << " functions.\n";
	
	for (int index = 0; index < otherCalledFuncs->size(); index++) {
		Function *f = otherCalledFuncs->at(index);
/*		if (!f) {
			//f->dump();
			llvm::dbgs() << "?????? index = " << index << " size = " << otherCalledFuncs->size()<< '\n';
			continue;
		}
*/		for (inst_iterator f_it = inst_begin(f); f_it != inst_end(f); f_it++) {
			CallInst *ci = dyn_cast<CallInst>(&*f_it);
			if (!ci)
				continue;
			if (!ci->getCalledFunction()) {
				//ci->dump();
				continue;
			}
			std::vector<Function*>::iterator fit = std::find(otherCalledFuncs->begin(), otherCalledFuncs->end(), ci->getCalledFunction());
			if (fit == otherCalledFuncs->end())
				otherCalledFuncs->push_back(ci->getCalledFunction());
		}
	}
	llvm::dbgs() << "((((((((( Found " << otherCalledFuncs->size() << " functions.\n";
	
	//This should be just for statistic.
	int tmp_funcNum_in_filter_notIn_other = 0;
	for (func_bbs_type::iterator fbs_it = filter_paths->begin(); fbs_it != filter_paths->end(); fbs_it++) {
		if (!fbs_it->first) {
			llvm::dbgs() << "[Warning]: Found a null Function pointer in filter_paths.\n";
			continue;
		}
		std::vector<Function*>::iterator fit = std::find(otherCalledFuncs->begin(), otherCalledFuncs->end(), fbs_it->first);
		if (fit == otherCalledFuncs->end())
			//otherCalledFuncs->push_back(fbs_it->first);
			tmp_funcNum_in_filter_notIn_other ++;
	}
	llvm::dbgs() << "<><><><> After searching filter_paths, found " << otherCalledFuncs->size() + tmp_funcNum_in_filter_notIn_other << " functions.\n";
/*	for (entire_path::iterator ep_it = evo_paths->begin(); ep_it != evo_paths->end(); ep_it++) {
		dbgs() << "Path length is: " << ep_it->size() << '\n';
		for (std::vector<std::pair< Function*, BasicBlock*> >::iterator pair_it = ep_it->begin(); pair_it != ep_it->end(); pair_it++) {
			 dbgs() << "^^^^^^ " << pair_it->first->getName() << ": " << pair_it->second->getName() << '\n';
			 explore_basicblock_paths(pair_it->first, pair_it->second, &(*BB_paths_map)[*pair_it]);
			 dbgs() << "^^^^^^ found " << (*BB_paths_map)[*pair_it].size() << " basicblocks.\n";
		}
	}
*/		
	llvm::errs() << "on-end\n";
	llvm::errs() << "=================================\n";
	
	// output all of the paths
/*	errs()<<"Find "<<paths_found->size()<<" paths in all.\n";
	for(paths::iterator ips = paths_found->begin();ips != paths_found->end();ips++) {
//		std::vector<BasicBlock*> *tmpP = dyn_cast<std::vector<BasicBlock*>*>(&*ips);
		dbgs() << "=========A Path Start============\n";
		for(std::vector<BasicBlock*>::iterator ps = ips->begin(), pe = ips->end(); ps != pe; ps++) {
			BasicBlock *tmpStr = *ps;
			errs()<<"\t"<<tmpStr->getParent()->getName()<<": "<<tmpStr->getName()<<" -> \n";
		}
		errs()<<"=================================\n";
	}
*/	
	return false;
}