StructuredModuleEditor::FuncList* StructuredModuleEditor::getFuncsWithSameSignature(
		Function *Func) {
	if (Func == NULL) {
		OS << "Function not found!\n";
		return NULL;
	}

	FuncList *MatchingFuncs = new FuncList;
	for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) {
		if (signaturesMatch(Func, FI))
			MatchingFuncs->push_back(FI);
	}

	return MatchingFuncs;
}
void StructuredModuleEditor::dumpFuncsWithSameSignature(Function *Func) {
	FuncList *Funcs = getFuncsWithSameSignature(Func);

	OS << Funcs->size() << " functions with the following signature:\n";
	OS << "*** RETURN TYPE: " << *(Func->getFunctionType()) << "\n";
	for (Function::arg_iterator AI = Func->arg_begin(), AE = Func->arg_end();
			AI != AE; ++AI) {
		OS << "*** ARG TYPE: " << *AI << "\n";
	}
	OS << "\n";

	for (FuncList::iterator FI = Funcs->begin(), FE = Funcs->end(); FI != FE;
			++FI) {
		OS << (*FI)->getName() << "\n";
	}
}
Esempio n. 3
0
bool ImageSorter::_msort(const Info& a, const Info& b, FuncList criteria) {
    for (size_t n = 0; n < criteria.size(); ++n) {
        const int diff = criteria[n](a, b);
        if (diff != 0)
            return diff < 0;
    }
    return 0;
}
Esempio n. 4
0
void SymbolManager::cleanFunctions() {
	this->funcListMutex.lock();
	for (auto &item : this->funcList) {
		assert(item);
		item->updateTypes();
	}

	auto item = this->funcList.begin();
	std::sort(
		item,
		funcList.end(),
		[](const Function *a, const Function *b) {
			return *a < *b;
		}
	);

	item = this->funcList.begin();

	if (item == this->funcList.end()) {
		return;
	}

	Function *oldPtr = *item;
	Function *delPtr = nullptr;
	item++;

	FuncList tmp;

	while (item != funcList.end()) {
		if (*oldPtr == *(*item)) {
			delPtr = *item;
			this->addAlternativeID(oldPtr->getID(), delPtr->getID());
			delete delPtr;
		} else {
			tmp.push_back(*item);
			oldPtr = (*item);
		}
		item++;
	}

	tmp.shrink_to_fit();
	this->funcList.swap(tmp);
	tmp.clear();
	// TODO actually we don't need the vector any more at this point
	this->funcListMutex.unlock();
}
Esempio n. 5
0
bool ICFGBuilder::runOnModule(Module &M) {
  MicroBasicBlockBuilder &MBBB = getAnalysis<MicroBasicBlockBuilder>();

  forallbb(M, bb) {
    for (mbb_iterator mi = MBBB.begin(bb), E = MBBB.end(bb); mi != E; ++mi)
      getOrInsertMBB(mi);
  }

  forallbb(M, bb) {
    for (mbb_iterator mi = MBBB.begin(bb), E = MBBB.end(bb); mi != E; ++mi) {
      // The ICFG will not contain any inter-thread edge. 
      // It's also difficult to handle them. How to deal with the return
      // edges? They are supposed to go to the pthread_join sites. 
      if (mi->end() != bb->end() && !is_pthread_create(mi->end())) {
        FPCallGraph &CG = getAnalysis<FPCallGraph>();
        FuncList callees = CG.getCalledFunctions(mi->end());
        bool calls_decl = false;
        for (size_t i = 0; i < callees.size(); ++i) {
          Function *callee = callees[i];
          if (callee->isDeclaration()) {
            calls_decl = true;
          } else {
            MicroBasicBlock *entry_mbb = MBBB.begin(callee->begin());
            addEdge(mi, entry_mbb);
          }
        }
        if (calls_decl) {
          mbb_iterator next_mbb = mi; ++next_mbb;
          addEdge(mi, next_mbb);
        }
      } else {
        for (succ_iterator si = succ_begin(bb); si != succ_end(bb); ++si) {
          MicroBasicBlock *succ_mbb = MBBB.begin(*si);
          addEdge(mi, succ_mbb);
        }
        TerminatorInst *ti = bb->getTerminator();
        if (is_ret(ti)) {
          FPCallGraph &CG = getAnalysis<FPCallGraph>();
          InstList call_sites = CG.getCallSites(bb->getParent());
          for (size_t i = 0; i < call_sites.size(); ++i) {
            Instruction *call_site = call_sites[i];
            // Ignore inter-thread edges. 
            if (is_pthread_create(call_site))
              continue;
            MicroBasicBlock *next_mbb;
            if (isa<CallInst>(call_site)) {
              BasicBlock::iterator next = call_site;
              ++next;
              next_mbb = MBBB.parent(next);
            } else {
              assert(isa<InvokeInst>(call_site));
              InvokeInst *inv = dyn_cast<InvokeInst>(call_site);
              if (isa<ReturnInst>(ti)) {
                next_mbb = MBBB.begin(inv->getNormalDest());
              } else {
                next_mbb = MBBB.begin(inv->getUnwindDest());
              }
            }
            addEdge(mi, next_mbb);
          }
        }
      }
    }
  }
  return false;
}
void StructuredModuleEditor::instrumentCallsToFunction(Function *Callee) {
	if (Callee == NULL) {
		OS << "Function not found!\n";
		return;
	}

	InstList Calls = getCallsToFunction(Callee);

	FuncList Callers;
	for (InstList::iterator II = Calls.begin(), IE = Calls.end(); II != IE;
			++II) {
		Function *Caller = (*II)->getParent()->getParent();
		if (std::find(Callers.begin(), Callers.end(), Caller) == Callers.end())
			Callers.push_back(Caller);
	}

	OS << Callers.size() << " functions call '" << Callee->getName()
			<< "'...\n";
	OS << "=================================\n";
	for (FuncList::iterator FI = Callers.begin(), FE = Callers.end(); FI != FE;
			++FI) {
		OS << (*FI)->getName() << "\n";
	}
	OS << "=================================\n";

	std::vector<Value*> PreArgs;
	std::vector<Type*> PreArgTypes;
	for (Function::arg_iterator I = Callee->arg_begin(), E = Callee->arg_end();
			I != E; ++I) {
		PreArgTypes.push_back(I->getType());
		PreArgs.push_back(I);
	}

	std::vector<Type*> PostArgTypes;
	if (!Callee->getReturnType()->isVoidTy()) {
		PostArgTypes.push_back(Callee->getReturnType());
	}

	FuncList Clones;

	Clones.push_back(Callee);
	for (uint64_t i = 0; i < Callers.size() - 1; i++) {
		Function *Clone = cloneFunc(Callee);
		Clones.push_back(Clone);
	}

	for (uint64_t i = 0; i < Clones.size(); i++) {
		Constant *PreConst = M->getOrInsertFunction("",
				FunctionType::get(Type::getVoidTy(getGlobalContext()),
						PreArgTypes, false));
		Function *Pre = cast<Function>(PreConst);
		Pre->setName("pre");
		CG->getOrInsertFunction(Pre);

		Constant *PostConst = M->getOrInsertFunction("",
				FunctionType::get(Type::getVoidTy(getGlobalContext()),
						PostArgTypes, false));
		Function *Post = cast<Function>(PostConst);
		Post->setName("post");
		CG->getOrInsertFunction(Post);

		/*
		 OS << "\n";
		 OS << "Wrapping '" << Clones.at(i)->getName() << "'...\n\n";
		 OS << "Pre-invocation function = " << Pre->getName() << "\n";
		 OS << *Pre;
		 OS << "Post-invocation function = " << Post->getName() << "\n";
		 OS << *Post;
		 OS << "**************************************\n";*/

		Function *Wrapper = wrapFunc(Clones.at(i), Pre, Post);
		if (i == 0)
			Callee = Wrapper;

		Function *Caller = Callers.at(i);
		for (Function::iterator BBI = Caller->begin(), BBE = Caller->end();
				BBI != BBE; ++BBI) {
			for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end();
					II != IE; ++II) {
				CallSite CS(cast<Value>(II));
				// If this isn't a call, or it is a call to an intrinsic...
				if (!CS || isa<IntrinsicInst>(II))
					continue;

				if (Callee == CS.getCalledFunction()) {
					CS.setCalledFunction(Wrapper);

					// Creates an edge from the calling node to its new destination node
					CallGraphNode *CallingNode = (*CG)[CS.getCaller()];
					CallGraphNode *NewCalleeNode = (*CG)[Wrapper];
					CallingNode->replaceCallEdge(CS, CS, NewCalleeNode);
				}
			}
		}
	}

	OS << "Functions successfully wrapped!\n";
}
void StructuredModuleEditor::instrumentFunctionsThatCallFunction(
		Function *Callee) {
	if (Callee == NULL) {
		OS << "Function not found!\n";
		return;
	}

	InstList Calls = getCallsToFunction(Callee);

	FuncList Callers;
	for (InstList::iterator II = Calls.begin(), IE = Calls.end(); II != IE;
			++II) {
		Function *Caller = (*II)->getParent()->getParent();
		if (std::find(Callers.begin(), Callers.end(), Caller) == Callers.end())
			Callers.push_back(Caller);
	}

	OS << Callers.size() << " functions call '" << Callee->getName()
			<< "'...\n";
	OS << "=================================\n";
	for (FuncList::iterator FI = Callers.begin(), FE = Callers.end(); FI != FE;
			++FI) {
		OS << (*FI)->getName() << "\n";
	}
	OS << "=================================\n";

	for (FuncList::iterator FI = Callers.begin(), FE = Callers.end(); FI != FE;
			++FI) {
		std::vector<Value*> PreArgs;
		std::vector<Type*> PreArgTypes;

		Function *Caller = *FI;

		for (Function::arg_iterator AI = Caller->arg_begin(), AE =
				Caller->arg_end(); AI != AE; ++AI) {
			PreArgTypes.push_back(AI->getType());
			PreArgs.push_back(AI);
		}

		std::vector<Type*> PostArgTypes;
		if (!Caller->getReturnType()->isVoidTy()) {
			PostArgTypes.push_back(Caller->getReturnType());
		}

		Constant *PreConst = M->getOrInsertFunction("",
				FunctionType::get(Type::getVoidTy(getGlobalContext()),
						PreArgTypes, false));
		Function *Pre = cast<Function>(PreConst);
		Pre->setName("pre");
		CG->getOrInsertFunction(Pre);

		Constant *PostConst = M->getOrInsertFunction("",
				FunctionType::get(Type::getVoidTy(getGlobalContext()),
						PostArgTypes, false));
		Function *Post = cast<Function>(PostConst);
		Post->setName("post");
		CG->getOrInsertFunction(Post);

		Function *Wrapper = wrapFunc(Caller, Pre, Post);
		/*
		 OS << "\n";
		 OS << "Function '" << Caller->getName() << "'  returns "
		 << *(Caller->getReturnType()) << "\n";
		 int ArgCount = 0;
		 for (Function::arg_iterator AI = Caller->arg_begin(), AE =
		 Caller->arg_end(); AI != AE; ++AI) {
		 OS << "Arg #" << ArgCount++ << ": " << *AI << "\n";
		 }
		 OS << "\n";
		 OS << "Wrapping '" << Caller->getName() << "' with '" << Wrapper->getName()
		 << "'...\n\n";
		 OS << "Pre-invocation function = " << Pre->getName() << "\n";
		 OS << *Pre << "\n";
		 OS << "Post-invocation function = " << Post->getName() << "\n";
		 OS << *Post;
		 OS << "**************************************\n";*/
	}

	OS << "Functions successfully wrapped!\n";
}
Esempio n. 8
0
bool CallGraphChecker::runOnModule(Module &M) {
  unsigned NumMissingCallEdges = 0;

  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
    for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
      for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
        CallSite CS(Ins);
        if (CS && CS.getCalledFunction() == NULL) {
          Value *FP = CS.getCalledValue();

          // Get all the targets of <FP>.
          FuncList Callees;
#if 0
          // Use DynamicPointerAnalysis if not fine-grained.
          PointerAnalysis &PA = getAnalysis<DynamicPointerAnalysis>();
          ValueList Pointees;
          PA.getPointees(FP, Pointees);
          for (size_t j = 0; j < Pointees.size(); ++j) {
            assert(Pointees[j]);
            Callees.push_back(cast<Function>(Pointees[j]));
          }
#endif
          // Use DynamicAliasAnalysis if fine-grained.
          // <Callees> contains real callees in the execution.
          AliasAnalysis &AA = getAnalysis<DynamicAliasAnalysis>();
          for (Module::iterator PotentialCallee = M.begin();
               PotentialCallee != M.end(); ++PotentialCallee) {
            if (AA.alias(FP, PotentialCallee))
              Callees.push_back(PotentialCallee);
          }

          // Check whether these targets are captured in the call graph.
          for (size_t j = 0; j < Callees.size(); ++j) {
            Function *Callee = Callees[j];
            assert(Callee);
            if (!existsInCallGraph(Ins, Callee)) {
              ++NumMissingCallEdges;
              errs().changeColor(raw_ostream::RED);
              errs() << "Call edge does not exist in the call graph:\n";
              errs().resetColor();

              DynAAUtils::PrintValue(errs(), Ins); errs() << "\n";
              errs() << "  " << Callee->getName() << "\n";
            }
          }
        }
      }
    }
  }

  if (NumMissingCallEdges == 0) {
    errs().changeColor(raw_ostream::GREEN);
    errs() << "Congrats! You passed all the tests.\n";
    errs().resetColor();
  } else {
    errs().changeColor(raw_ostream::RED);
    errs() << "Detected " << NumMissingCallEdges << " missing call edges.\n";
    errs().resetColor();
  }

  return false;
}