Ejemplo n.º 1
0
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";
}