Пример #1
0
 bool
 canSpecialize(Function* f)
 {
   if (f->isDeclaration())
     return false;
   for (inst_iterator I = inst_begin(f), E = inst_end(f); I != E; ++I) {
     if (CallInst* ci = dyn_cast<CallInst>(&*I)) {
       if (ci->isInlineAsm()) {
         return false;
       }
     }
   }
   return true;
 }
Пример #2
0
    virtual bool runOnFunction(Function& F) {
        int num_changed = 0;
        for (inst_iterator inst_it = inst_begin(F), _inst_end = inst_end(F); inst_it != _inst_end; ++inst_it) {
            if (!isMallocCall(dyn_cast<CallInst>(&*inst_it)))
                continue;

            if (VERBOSITY("opt") >= 2) {
                errs() << "\nFound malloc call:\n" << *inst_it << '\n';
            }
            num_changed += ComparisonFinder(cast<CallInst>(&*inst_it)).elide_comparisons();
        }

        return num_changed > 0;
    }
Пример #3
0
void FIInstSelector::getInitFIInsts(Module &M, 
                                    std::set<Instruction*> *fiinsts) {
  for (Module::iterator m_it = M.begin(); m_it != M.end(); ++m_it) {
    if (!m_it->isDeclaration()) {
      //m_it is a function  
      for (inst_iterator f_it = inst_begin(m_it); f_it != inst_end(m_it);
           ++f_it) {
        Instruction *inst = &(*f_it);
        if (isInstFITarget(inst)) {
          fiinsts->insert(inst);
        }
      }
    }  
  }
}
Пример #4
0
std::string CodeGeneratorTest::GenerateCode() {
  // create worklist containing all instructions of the function
  std::vector<Instruction*> worklist;
  for (inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I)
    worklist.push_back(&*I);

  // remove parameter initialization from the instruction vector
  unsigned int paramCount = 0;
  for (std::vector<Instruction*>::iterator instrIt = worklist.begin(); instrIt != worklist.end(); ++instrIt)
    if (isa<AllocaInst>(*instrIt))
      paramCount++;
  worklist.erase(worklist.begin(), worklist.begin()+2*paramCount);

  // run C code generator
  return getCodeGenerator()->createCCode(*F, worklist);
}
Пример #5
0
void dumpPrettyIR(llvm::Function* f) {
    std::unique_ptr<llvm::Module> tmp_module(llvm::CloneModule(f->getParent()));
    // std::unique_ptr<llvm::Module> tmp_module(new llvm::Module("tmp", g.context));

    llvm::Function* new_f = tmp_module->begin();

    llvm::ValueToValueMapTy VMap;
    PrettifyingMaterializer materializer(tmp_module.get());
    for (llvm::Function::iterator I = new_f->begin(), E = new_f->end(); I != E; ++I) {
        VMap[I] = I;
    }
    for (llvm::inst_iterator it = inst_begin(new_f), end = inst_end(new_f); it != end; ++it) {
        llvm::RemapInstruction(&*it, VMap, llvm::RF_None, NULL, &materializer);
    }
    tmp_module->begin()->dump();
    // tmp_module->dump();
}
Пример #6
0
void DataDependence::getDataDependencies(Function &F, MemoryDependenceAnalysis &MDA,
    AliasAnalysis &AA) {
  // Since MemoryDependenceAnalysis is a function pass, we need to pass the
  // function we are looking at to the pass
  //MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>(F);

  for (inst_iterator i = inst_begin(F); i != inst_end(F); ++i) {
    Instruction *inst;
    inst = &*i;

    // skip non memory accesses
    if (!inst->mayReadFromMemory() && !inst->mayWriteToMemory())
      continue;

    processDepResult(inst, MDA, AA);

  } // end for (inst_iterator)
}
Пример #7
0
    unsigned int designScorer::getDesignSizeInGates(Function* F) {

        unsigned int totalGateSize = 0;

        map<string, unsigned int> resourceMap = 
            machineResourceConfig::getResourceTable();

        unsigned int mul_count = resourceMap["mul"];
        unsigned int div_count = resourceMap["div"];
        unsigned int shl_count = resourceMap["shl"];

        totalGateSize += mul_count*1088 + div_count*1500 + shl_count*1000;

        for (inst_iterator i = inst_begin(*F), e = inst_end(*F); i != e; ++i) {
            totalGateSize += getInstructionSize(&*i); 
        }
        return totalGateSize;
    }
Пример #8
0
void EncoderPass::initAssertCalls() {
    bool hasAsserts = false;
    inst_iterator ii0;
    for (ii0 = inst_begin(targetFun); ii0!=inst_end(targetFun); ii0++) {
        Instruction &I = *ii0;
        if (CallInst *C = dyn_cast<CallInst>(&I)) {
            StringRef calledFunName;
            Function *F = C->getCalledFunction();
            // Direct call
            if (F) {
                calledFunName = F->getName();
            }
            // Indirect function call
            else {
                F = dyn_cast<Function>(C->getCalledValue()->stripPointerCasts());
                if (F) {
                    calledFunName = F->getName();
                }
            }
            if (calledFunName==Frontend::SNIPER_ASSERT_FUN_NAME ||
                calledFunName=="sniper_reportAssert") {
                hasAsserts = true;
                if (MDNode *N = I.getMetadata("dbg")) {
                    DILocation Loc(N);
                    unsigned line = Loc.getLineNumber();
                    ctx->setAssertCallLine(line);
                }
            }
            // TODO: put assume line numbers in a differente vector
            else if (calledFunName==Frontend::SNIPER_ASSUME_FUN_NAME ||
                     calledFunName=="sniper_reportAssume") {
                if (MDNode *N = I.getMetadata("dbg")) {
                    DILocation Loc(N);
                    unsigned line = Loc.getLineNumber();
                    ctx->setAssertCallLine(line);
                }
            }
        }
    }
    // No post-condition and no oracle?
    assert((hasAsserts || !options->getGoldenOutputsFileName().empty()) &&
           "No call to assert function nor oracle!");
}
Пример #9
0
void getProgramExitInsts(Module &M, std::set<Instruction*> &exitinsts) {
  for (Module::iterator m_it = M.begin(); m_it != M.end(); ++m_it) {
    if (!m_it->isDeclaration()) {
      //m_it is a function  
      for (inst_iterator f_it = inst_begin(m_it); f_it != inst_end(m_it);
           ++f_it) {
        Instruction *inst = &(*f_it);
        if (CallInst *ci = dyn_cast<CallInst>(inst)) {
          Function *calledFunc = ci->getCalledFunction();
          if (calledFunc && calledFunc->hasName() && 
              calledFunc->getName().str() == "exit") {
            exitinsts.insert(inst);
          }
        }
      }
    }  
  }

  Function* mainfunc = M.getFunction("main");
  exitinsts.insert(getTermInstofFunction(mainfunc));
}
Пример #10
0
bool Frontend::inlineForProcessFct(Function* F) {
	for(inst_iterator i = inst_begin(F); i != inst_end(F); ++i) {
		Function* calledFunction = NULL;
		Instruction* currentInst = &*i;
		BasicBlock* bb = currentInst->getParent();
		bool isInvoke = false;
		if (CallInst *callInst = dyn_cast < CallInst > (currentInst)) {
			calledFunction =  callInst->getCalledFunction();
		} else if(InvokeInst *invokeInst = dyn_cast < InvokeInst > (currentInst)) {
			calledFunction =  invokeInst->getCalledFunction();
			isInvoke = true;
		} 

		if (! calledFunction) {
			TRACE_6("Encountered call to function pointer. Not parsing it.\n");
		} else if (! this->sccfactory->handlerExists(F, bb, currentInst, calledFunction)) {
			TRACE_6("CallInst : " << currentInst << "\n");
			TRACE_6("CalledFct : " << calledFunction << "\n");
			PRINT_6(currentInst->dump());
			TRACE_4("Call not handled : " << calledFunction->getName().str() << "\n");
			TRACE_4("Inlining function : " << calledFunction->getName().str() << "\n");
			bool isInlined = false;
			llvm::InlineFunctionInfo ifi;
			if (isInvoke) {
				isInlined = llvm::InlineFunction(dyn_cast<InvokeInst>(currentInst), ifi);
			} else {
				isInlined = llvm::InlineFunction(dyn_cast<CallInst>(currentInst), ifi);
			}
			// InlineFunction invalidates iterators => restart loop.
			if (isInlined) {
				return true;
			}
		}
	}

	return false;
}
Пример #11
0
void PointerTracking::print(raw_ostream &OS, const Module* M) const {
  // Calling some PT methods may cause caches to be updated, however
  // this should be safe for the same reason its safe for SCEV.
  PointerTracking &PT = *const_cast<PointerTracking*>(this);
  for (inst_iterator I=inst_begin(*FF), E=inst_end(*FF); I != E; ++I) {
    if (!isa<PointerType>(I->getType()))
      continue;
    Value *Base;
    const SCEV *Limit, *Offset;
    getPointerOffset(&*I, Base, Limit, Offset);
    if (!Base)
      continue;

    if (Base == &*I) {
      const SCEV *S = getAllocationElementCount(Base);
      OS << *Base << " ==> " << *S << " elements, ";
      OS << *Limit << " bytes allocated\n";
      continue;
    }
    OS << &*I << " -- base: " << *Base;
    OS << " offset: " << *Offset;

    enum SolverResult res = PT.checkLimits(Offset, Limit, I->getParent());
    switch (res) {
    case AlwaysTrue:
      OS << " always safe\n";
      break;
    case AlwaysFalse:
      OS << " always unsafe\n";
      break;
    case Unknown:
      OS << " <<unknown>>\n";
      break;
    }
  }
}
Пример #12
0
bool EscapeAnalysis::runOnFunction(Function& F) {
    return false; // This analysis is currently broken and not maintained

    if (VERBOSITY("opt") >= 1)
        outs() << "Running escape analysis on " << F.getName() << '\n';

    for (inst_iterator inst_it = inst_begin(F), _inst_end = inst_end(F); inst_it != _inst_end; ++inst_it) {
        CallInst* alloc = dyn_cast<CallInst>(&*inst_it);
        if (!alloc || !isAllocCall(alloc))
            continue;

        ChainInfo* chain = new ChainInfo(alloc);
        chains.push_back(chain);

        if (VERBOSITY("opt") >= 2) {
            errs() << "Found chain " << chain << " starting at " << *alloc;
        }

        // Calculating derived pointers, and finding escape points
        {
            // Instructions in the queue to be visited:
            std::deque<Instruction*> queue;
            // Instructions we've fully visited:
            std::unordered_set<Instruction*> checked;

            queue.push_back(alloc);

            while (queue.size()) {
                Instruction* next = queue.back();
                queue.pop_back();

                if (checked.count(next))
                    continue;

                checked.insert(next);

                for (User* user : next->users()) {
                    if (GetElementPtrInst* gep = dyn_cast<GetElementPtrInst>(user)) {
                        queue.push_back(gep);
                        chain->derived.insert(gep);
                        chain_by_pointer[gep] = chain;
                        continue;
                    }

                    if (CastInst* bc = dyn_cast<CastInst>(user)) {
                        queue.push_back(bc);
                        chain->derived.insert(bc);
                        chain_by_pointer[bc] = chain;
                        continue;
                    }

                    if (PHINode* phi = dyn_cast<PHINode>(user)) {
                        queue.push_back(phi);
                        chain->derived.insert(phi);
                        chain_by_pointer[phi] = chain;
                        continue;
                    }

                    if (isa<LoadInst>(user)) {
                        continue;
                    }

                    if (ReturnInst* ret = dyn_cast<ReturnInst>(user)) {
                        if (VERBOSITY() >= 2)
                            errs() << "Not dead; used here: " << *ret << '\n';
                        chain->escape_points.insert(ret);
                        continue;
                    }



                    if (StoreInst* si = dyn_cast<StoreInst>(user)) {
                        if (si->getPointerOperand() == next) {
                        } else {
                            assert(si->getValueOperand() == next);
                            if (VERBOSITY() >= 2)
                                errs() << "Escapes here: " << *si << '\n';
                            chain->escape_points.insert(si);
                        }
                        continue;
                    }

                    if (llvm::isa<CallInst>(user) || llvm::isa<InvokeInst>(user)) {
                        if (VERBOSITY() >= 2)
                            errs() << "Escapes here: " << *user << '\n';
                        chain->escape_points.insert(dyn_cast<Instruction>(user));
                        continue;
                    }



                    user->dump();
                    RELEASE_ASSERT(0, "");
                }
            }
        }

        // Calculating BB-level escape-ness
        {
            std::deque<const BasicBlock*> queue;

            for (const auto I : chain->escape_points) {
                chain->bb_escapes[I->getParent()] = BBPartialEscape;
                queue.insert(queue.end(), succ_begin(I->getParent()), succ_end(I->getParent()));
            }

            while (queue.size()) {
                const BasicBlock* bb = queue.back();
                queue.pop_back();

                if (chain->bb_escapes[bb] == BBFullEscape)
                    continue;

                chain->bb_escapes[bb] = BBFullEscape;
                queue.insert(queue.end(), succ_begin(bb), succ_end(bb));
            }

            for (BasicBlock& bb : F) {
                if (chain->bb_escapes.count(&bb) == 0)
                    chain->bb_escapes[&bb] = BBNoEscape;

                // outs() << bb.getName() << ' ' << chain->bb_escapes[&bb] << '\n';
            }
        }
    }


    return false;
}
Пример #13
0
/**
 * Finds those allocas that are only used to store some value from ebp and then
 * this value is stored back to ebp.
 */
bool StackPointerOpsRemove::removePreservationStores()
{
	bool changed = false;

	for (auto& f : _module->getFunctionList())
	{
		for (inst_iterator I = inst_begin(f), E = inst_end(f); I != E; ++I)
		{
			auto* a = dyn_cast<AllocaInst>(&*I);
			if (a == nullptr)
			{
				continue;
			}

			bool remove = true;
			Value* storedVal = nullptr;
			std::set<llvm::Instruction*> toRemove;
			for (auto* u : a->users())
			{
				if (auto* s = dyn_cast<StoreInst>(u))
				{
					auto* l = dyn_cast<LoadInst>(s->getValueOperand());
					if (l && storedVal == nullptr
							&& (l->getPointerOperand()->getName() == "ebp" || l->getPointerOperand()->getName() == "rbp"))
					{
						storedVal = l->getPointerOperand();
						toRemove.insert(s);
					}
					else if (l && l->getPointerOperand() == storedVal)
					{
						toRemove.insert(s);
					}
					else
					{
						remove = false;
						break;
					}
				}
				else if (isa<LoadInst>(u) || isa<CastInst>(u))
				{
					for (auto* uu : u->users())
					{
						auto* s = dyn_cast<StoreInst>(uu);
						if (s && storedVal == nullptr
								&& (s->getPointerOperand()->getName() == "ebp" || s->getPointerOperand()->getName() == "rbp"))
						{
							storedVal = s->getPointerOperand();
							toRemove.insert(s);
						}
						else if (s && s->getPointerOperand() == storedVal)
						{
							toRemove.insert(s);
						}
						else
						{
							remove = false;
							break;
						}
					}

					if (!remove)
					{
						break;
					}
				}
				else
				{
					remove = false;
					break;
				}
			}

			if (remove)
			{
				for (auto* i : toRemove)
				{
					i->eraseFromParent();
					changed = true;
				}
			}
		}
	}

	return changed;
}
Пример #14
0
  bool runOnFunction(Function &Func) override {
    if (Func.isDeclaration()) {
      return false;
    }
    vector<BranchInst *> BIs;
    for (inst_iterator I = inst_begin(Func); I != inst_end(Func); I++) {
      Instruction *Inst = &(*I);
      if (BranchInst *BI = dyn_cast<BranchInst>(Inst)) {
        BIs.push_back(BI);
      }
    } // Finish collecting branching conditions
    Value *zero =
        ConstantInt::get(Type::getInt32Ty(Func.getParent()->getContext()), 0);
    for (BranchInst *BI : BIs) {
      IRBuilder<> IRB(BI);
      vector<BasicBlock *> BBs;
      // We use the condition's evaluation result to generate the GEP
      // instruction  False evaluates to 0 while true evaluates to 1.  So here
      // we insert the false block first
      if (BI->isConditional()) {
        BBs.push_back(BI->getSuccessor(1));
      }
      BBs.push_back(BI->getSuccessor(0));
      ArrayType *AT = ArrayType::get(
          Type::getInt8PtrTy(Func.getParent()->getContext()), BBs.size());
      vector<Constant *> BlockAddresses;
      for (unsigned i = 0; i < BBs.size(); i++) {
        BlockAddresses.push_back(BlockAddress::get(BBs[i]));
      }
      GlobalVariable *LoadFrom = NULL;

      if (BI->isConditional() || indexmap.find(BI->getSuccessor(0))==indexmap.end()) {
        // Create a new GV
        Constant *BlockAddressArray =
            ConstantArray::get(AT, ArrayRef<Constant *>(BlockAddresses));
        LoadFrom = new GlobalVariable(*Func.getParent(), AT, false,
                                      GlobalValue::LinkageTypes::PrivateLinkage,
                                      BlockAddressArray);
      } else {
        LoadFrom =
            Func.getParent()->getGlobalVariable("IndirectBranchingGlobalTable",true);
      }
      Value *index = NULL;
      if (BI->isConditional()) {
        Value *condition = BI->getCondition();
        index = IRB.CreateZExt(
            condition, Type::getInt32Ty(Func.getParent()->getContext()));
      } else {
        index =
            ConstantInt::get(Type::getInt32Ty(Func.getParent()->getContext()),
                             indexmap[BI->getSuccessor(0)]);
      }
      Value *GEP = IRB.CreateGEP(LoadFrom, {zero, index});
      LoadInst *LI = IRB.CreateLoad(GEP, "IndirectBranchingTargetAddress");
      IndirectBrInst *indirBr = IndirectBrInst::Create(LI, BBs.size());
      for (BasicBlock *BB : BBs) {
        indirBr->addDestination(BB);
      }
      ReplaceInstWithInst(BI, indirBr);
    }
    return true;
  }
Пример #15
0
bool ProfilingPass::doInitialization(Module &M)
{
	LLVMContext& context = M.getContext();
	Function* mainFunc = M.getFunction("main");
	const string moduleName = M.getModuleIdentifier();
	if (mainFunc!=NULL) {
		//BasicBlock* entryBlock = &mainFunc->front();
		Constant* Init = ConstantArray::get(context,moduleName,true);	// Convert it to an LLVM Type
		GlobalVariable* nameStr = new GlobalVariable(Init->getType(), true, GlobalValue::InternalLinkage, Init, "NameStr" );
		M.getGlobalList().push_back( nameStr );						// Insert it into the list of globals for module
		std::vector<Constant*>IndicesC(2);
		IndicesC[0] = Constant::getNullValue(Type::getInt32Ty(context));
		IndicesC[1] = ConstantInt::get(Type::getInt32Ty(context),0);
		Constant *getElemExpr =  ConstantExpr::getGetElementPtr(nameStr, &IndicesC[0], IndicesC.size());
		vector<Value*> initInjectArgs;
		initInjectArgs.push_back( getElemExpr ); 
		FunctionType* initInjectionFuncType = FunctionType::get(Type::getVoidTy(context), 
		vector<const Type*>(1,  PointerType::get(Type::getInt8Ty(context),0)),0); 
		
		//BasicBlock *exitBlock = &mainFunc->back();
		Instruction *I;
		for (inst_iterator fi = inst_begin(mainFunc), fe = inst_end(mainFunc); fi!=fe; ++fi){
			I = &*fi;
			if(isa<ReturnInst>(I))
				break;
		}
		BasicBlock *retblock = I->getParent(); //*retpred = retblock->getSinglePredecessor();
		
		Instruction *term = retblock->getTerminator();
		Constant *endFunc = M.getOrInsertFunction("endProfiling", initInjectionFuncType);
		vector<Value*> countArgs(1);
		//const IntegerType* itype = IntegerType::get(context,32);
		//Value* branchVal = ConstantInt::get(itype, BRANCH );
		CallInst::Create(endFunc, initInjectArgs.begin(), initInjectArgs.end(), "", term);
	}
	else
	{
		Constant* Init = ConstantArray::get(context,moduleName,true);	// Convert it to an LLVM Type
		GlobalVariable* nameStr = new GlobalVariable(Init->getType(), true, GlobalValue::InternalLinkage, Init, "NameStr" );
		M.getGlobalList().push_back( nameStr );
	}

	//***********************************************************************************************************
	//code for loading configure file should be here
	ifstream config ("llfi_configure.txt");
	if (config.is_open())
	{
		// we need to extract information from config file here Qining
		// this loop is used to know if the file is end
		while ( config.good() )
    	{
    		string line;
      		getline (config,line);
      		if(line.empty())	continue;
      		//if the line is empty, just skip.
      		//Any block of configure is started with one specific function
      		unsigned found = line.find("FUNCTION_NAME:");
      		if (found < line.length())
      		{
    			//std::cout << "\nfound FUNCTION_NAME at " << found << '\n';
    			std::string func_name = line.substr (found + string("FUNCTION_NAME:").length(),line.length() - found - string("FUNCTION_NAME:").length());
    			//first, I need to trim it
    			while(func_name[0] == ' ')
    			{
    				func_name.erase(0, 1);
    			}
    			while(func_name[func_name.length() - 1] == ' ')
    			{
    				func_name.erase(func_name.length() - 1, 0);
    			}
    			//so now I've got the name of the function
    			if(func_name.empty())	continue;
				std::cout << "The func_name is " << func_name << "\n";
				map_func_argu[func_name] = set<unsigned int>(); // create entry
				//map_func_fault_type[func_name] = set<unsigned int>(); 
				//second, I need to load argument set and type set
				do
				{
					line.clear();
					getline(config,line); // get the next line
					if(!config.good())	break; // if the new line is the end of file, our job is done.
					if(line.find("ARGUMENT:") < line.length())
					{
						//insert argument id to argument set
						std::string arg_set = line.substr(line.find("ARGUMENT:")+string("ARGUMENT:").length(), line.length() - line.find("ARGUMENT:")-string("ARGUMENT:").length());
						std::string arg;
						while(!arg_set.empty())
						{
							while(arg_set[0] <= '9' && arg_set[0] >= '0')
							{
								arg.append(arg_set.substr(0,1));
								if(!arg_set.empty())	arg_set.erase(0,1);
							}
							if(!arg.empty())
							{
								unsigned int arg_num = atoi(arg.c_str()) - 1;
								map_func_argu[func_name].insert(arg_num);
								std::cout << "\tinclude arg: " << arg_num+1 << "\n";
							}
							arg.clear();
							if(!arg_set.empty())	arg_set.erase(0,1);

						}
					}

				}while(line.find("FUNC_DEF_END") != 0);

    		}

    	}
    	// The file is end, we should have already finished our work, now close the file
    	config.close();
	}
	else errs()<<"Unable to open config file, use default config: all instructions, one bit flip\n";
	//***********************************************************************************************************

     return FunctionPass::doInitialization(M);
}
// =============================================================================
// replaceCallsInProcess
// 
// Replace indirect calls to write() or read() by direct calls 
// in the given process.
// =============================================================================
void TLMBasicPassImpl::replaceCallsInProcess(sc_core::sc_module *initiatorMod,
                                         sc_core::sc_process_b *proc) {
    
    // Get associate function
    std::string fctName = proc->func_process;
	std::string modType = typeid(*initiatorMod).name();
	std::string mainFctName = "_ZN" + modType + 
    utostr(fctName.size()) + fctName + "Ev";
	Function *oldProcf = this->llvmMod->getFunction(mainFctName);
    if (oldProcf==NULL)
        return;
    
    // We do not modifie the original function
    // Instead, we create a clone.
    Function *procf = createProcess(oldProcf, initiatorMod);
    void *funPtr = this->engine->getPointerToFunction(procf); 
    sc_core::SC_ENTRY_FUNC_OPT scfun = 
    reinterpret_cast<sc_core::SC_ENTRY_FUNC_OPT>(funPtr);
    proc->m_semantics_p = scfun;
    std::string procfName = procf->getName();
    MSG("      Replace in the process's function : "+procfName+"\n");
    
    std::ostringstream oss;
    sc_core::sc_module *targetMod;
    std::vector<CallInfo*> *work = new std::vector<CallInfo*>;
    
    inst_iterator ii;
    for (ii = inst_begin(procf); ii!=inst_end(procf); ii++) {
        Instruction &i = *ii;
        CallSite cs(&i);
        if (cs.getInstruction()) {
            // Candidate for a replacement
            Function *oldfun = cs.getCalledFunction();
            if (oldfun!=NULL && !oldfun->isDeclaration()) {
                std::string name = oldfun->getName();
                // === Write ===
                if (!strcmp(name.c_str(), wFunName.c_str())) {
                    
                    CallInfo *info = new CallInfo();
                    info->oldcall = dyn_cast<CallInst>(cs.getInstruction());
                    MSG("       Checking adress : ");
                    // Retrieve the adress argument by executing 
                    // the appropriated piece of code
                    SCJit *scjit = new SCJit(this->llvmMod, this->elab);
                    Process *irProc = this->elab->getProcess(proc);
                    scjit->setCurrentProcess(irProc);                    
                    bool jitErr = false;
                    info->addrArg = cs.getArgument(1);
                    int value = 
                    scjit->jitInt(procf, info->oldcall, info->addrArg, &jitErr);
                    if(jitErr) {
                        std::cout << "       cannot get the address value!" 
                          << std::endl;
                    } else {
                    oss.str("");  oss << std::hex << value;
                    MSG("0x"+oss.str()+"\n");
                    basic::addr_t a = static_cast<basic::addr_t>(value);            
                    
                    // Checking address alignment
                    if(value % sizeof(basic::data_t)) {
                        std::cerr << "  unaligned write : " <<
                        std::hex << value << std::endl;
                        abort();
                    }

                    // Retreive the target module using the address
                    targetMod =  getTargetModule(initiatorMod, a);
                                    
                    // Save informations to build a new call later
                    FunctionType *writeFunType = 
                        this->basicWriteFun->getFunctionType();  
                    info->targetType = writeFunType->getParamType(0);
                    LLVMContext &context = getGlobalContext();
                    IntegerType *intType;
                    if (this->is64Bit) {
                        intType = Type::getInt64Ty(context);
                    } else {
                        intType = Type::getInt32Ty(context);
                    }
                    info->targetModVal = ConstantInt::getSigned(intType,
                                        reinterpret_cast<intptr_t>(targetMod));
                    info->dataArg = cs.getArgument(2);
                    work->push_back(info);
                    }
   
                } else
                    
                // === Read ===
                if (!strcmp(name.c_str(), rFunName.c_str())) {
                    
                    // Not yet supported
                                        
                }
            }  
        }
    
    }
        
    // Before
    //procf->dump();
    
    // Replace calls
    std::vector<CallInfo*>::iterator it;
    for (it = work->begin(); it!=work->end(); ++it) {
        CallInfo *i = *it;
        
        LLVMContext &context = getGlobalContext();
        FunctionType *writeFunType = 
        this->writeFun->getFunctionType();
        IntegerType *i64 = Type::getInt64Ty(context);
        // Get a pointer to the target module
        basic::target_module_base *tmb = 
        dynamic_cast<basic::target_module_base*>(targetMod);
        Value *ptr = 
        ConstantInt::getSigned(i64, reinterpret_cast<intptr_t>(tmb));
        IntToPtrInst *modPtr = new IntToPtrInst(ptr, 
                                                writeFunType->getParamType(0),
                                                "myitp", i->oldcall);
        // Get a the address value
        LoadInst *addr = new LoadInst(i->addrArg, "", i->oldcall);
        
        // Create the new call
        Value *args[] = {modPtr, addr, i->dataArg};
        i->newcall = CallInst::Create(this->writeFun, ArrayRef<Value*>(args, 3));
        
        // Replace the old call
        BasicBlock::iterator it(i->oldcall);
        ReplaceInstWithInst(i->oldcall->getParent()->getInstList(), it, i->newcall);
        i->oldcall->replaceAllUsesWith(i->newcall);
        
        // Inline the new call
        DataLayout *td = new DataLayout(this->llvmMod);
        InlineFunctionInfo ifi(NULL, td);
        bool success = InlineFunction(i->newcall, ifi);
        if(!success) {
            MSG("       The call cannot be inlined (it's not an error :D)");
        }
        
        MSG("       Call optimized (^_-)\n");
        callOptCounter++;
    }
    
    //std::cout << "==================================\n";
    // Run preloaded passes on the function to propagate constants
    funPassManager->run(*procf);
    // After
    //procf->dump();        
    // Check if the function is corrupt
    verifyFunction(*procf);
    this->engine->recompileAndRelinkFunction(procf);
}
Пример #17
0
//
// Method: addGetActualValues()
//
// Description:
//  Search for comparison or pointer to integer cast instructions which will
//  need to turn an OOB pointer back into the original pointer value.  Insert
//  calls to getActualValue() to do the conversion.
//
// Inputs:
//  M - The module in which to add calls to getActualValue().
//
// Return value:
//  true  - The module was modified.
//  false - The module was not modified.
//
bool
RewriteOOB::addGetActualValues (Module & M) {
  // Assume that we don't modify anything
  bool modified = false;

  // Worklist of instructions to modify
  std::vector<Instruction *> Worklist;
  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
    //
    // Clear the worklist.
    //
    Worklist.clear();

    //
    // Scan through all the instructions in the given function for those that
    // need to be modified.  Add them to the worklist.
    //
    for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
      //
      // Integer comparisons need to be processed.
      //
      if (ICmpInst *CmpI = dyn_cast<ICmpInst>(&*I)) {
        CmpInst::Predicate Pred = CmpI->getUnsignedPredicate();
        if ((Pred >= CmpInst::FIRST_ICMP_PREDICATE) &&
            (Pred <= CmpInst::LAST_ICMP_PREDICATE)) {
          Worklist.push_back (CmpI);
        }
      }

      //
      // Casts from pointers to integers must also be processed.
      //
      if (PtrToIntInst * CastInst = dyn_cast<PtrToIntInst>(&*I)) {
        Worklist.push_back (CastInst);
      }
    }

    //
    // Now scan through the worklist and process each instruction.  Note that,
    // since we're using a worklist, we won't pick up casts introduced by
    // addGetActualValue().
    //
    for (unsigned index = 0; index < Worklist.size(); ++index) {
      //
      // Get the proper element from the worklist.
      //
      Instruction * I = Worklist[index];

      if (ICmpInst *CmpI = dyn_cast<ICmpInst>(I)) {
        //
        // Replace all pointer operands with a call to getActualValue().
        // This will convert an OOB pointer back into the real pointer value.
        //
        if (isa<PointerType>(CmpI->getOperand(0)->getType())) {
          // Rewrite both operands and flag that we modified the code
          addGetActualValue(CmpI, 0);
          modified = true;
        }

        if (isa<PointerType>(CmpI->getOperand(1)->getType())) {
          // Rewrite both operands and flag that we modified the code
          addGetActualValue(CmpI, 1);
          modified = true;
        }
      }

      if (PtrToIntInst * CastInst = dyn_cast<PtrToIntInst>(&*I)) {
        //
        // Replace all pointer operands with a call to getActualValue().
        // This will convert an OOB pointer back into the real pointer value.
        //
        if (isa<PointerType>(CastInst->getOperand(0)->getType())) {
          // Rewrite both operands and flag that we modified the code
          addGetActualValue(CastInst, 0);
          modified = true;
        }
      }
    }
  }

  // Return whether we modified anything
  return modified;
}
Пример #18
0
bool ProfilingPass::runOnFunction(Function &F)
{
	LLVMContext& context = F.getContext();
    Module *m = F.getParent();
	string funcname = F.getNameStr();
	string injectfunc("injectFault");
	if((profileoption == 'p' || profileoption == 'c' || profileoption == 'i') && (funcname.find(injectfunc) != string::npos))
		return false;
	std::vector<Instruction*> insert_worklist;
	for (inst_iterator In = inst_begin(F), E = inst_end(F); In != E; ++In)
    {     
		Instruction *I = dyn_cast<Instruction>(&*In);
		//errs()<<*I<<"\n";
		if(profileoption == 'b')
		{
			if(CmpInst *ci = dyn_cast<CmpInst>(I))
				if(is_used_by_branch(ci)){
					vector<const Type*> argTypes(1);
					argTypes[0] = Type::getInt32Ty(context);	// enum for the options
					FunctionType* countFuncType = FunctionType::get( Type::getVoidTy(context), argTypes, 0 );
					Constant* countFunc = m->getOrInsertFunction("doProfiling", countFuncType);			// get the injection function
					vector<Value*> countArgs(1);
					const IntegerType* itype = IntegerType::get(context,32);
					Value* branchVal = ConstantInt::get(itype, BRANCH );

					countArgs[0] = branchVal; //enum for branch
					CallInst::Create( countFunc, countArgs.begin(),countArgs.end(), "", I); 
				}
		}
		else if(profileoption == 'd')
		{
			//see if the current instruction is a cmp instruction that leads to a conditional branch
			//add the instrumentation to the defs of this cmp instruction
			//--> Static time deduction since branch not known if executed or not
			CmpInst *ci = dyn_cast<CmpInst>(I);
			//errs() <<"reached here:\n";
			if(!ci)
				continue;
	
			//traverse def-use chain
			//int is_used_by_branch = 0;    
	
			if(!is_used_by_branch(I))
				continue;
			//the defines of this instruction I --> would be injectFaultCalls.   
			for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) 
			{    
				Instruction *v = dyn_cast<Instruction>(*i);
				if(!v)
					continue;
				//errs() <<"reached here:"<< *v << "\n"; 
				//do profiling for the def
				vector<const Type*> argTypes(1);
				argTypes[0] = Type::getInt32Ty(context);	// enum for the options
				FunctionType* countFuncType = FunctionType::get( Type::getVoidTy(context), argTypes, 0 );
				Constant* countFunc = m->getOrInsertFunction("doProfiling", countFuncType);			// get the injection function
				vector<Value*> countArgs(1);
				const IntegerType* itype = IntegerType::get(context,32);
				Value* defVal = ConstantInt::get(itype, DEF );
				countArgs[0] = defVal; //enum for branch
				Instruction *beforeInst;
				if(isa<PHINode>(v))
				{	BasicBlock *bb = v->getParent();
					beforeInst = bb->getFirstNonPHI(); 
				}
				else
					beforeInst = v;
				CallInst::Create( countFunc, countArgs.begin(),countArgs.end(), "", beforeInst); 	// insert the profiling call before the def:v

			}
		}
		else if(profileoption == 'a' )
		{
			Instruction *beforeInst;
			//consider all instructions profiling
			vector<const Type*> argTypes(1);
			argTypes[0] = Type::getInt32Ty(context);	// enum for the options
			FunctionType* countFuncType = FunctionType::get( Type::getVoidTy(context), argTypes, 0 );
			Constant* countFunc = m->getOrInsertFunction("doProfiling", countFuncType);			// get the injection function
			vector<Value*> countArgs(1);
			const IntegerType* itype = IntegerType::get(context,32);
			Value* allVal = ConstantInt::get(itype, ALL );
			if(isa<PHINode>(I))
			{	BasicBlock *bb = I->getParent();
				beforeInst = bb->getFirstNonPHI(); 
			}
			else
				beforeInst = I;
			countArgs[0] = allVal; //enum for All inst
			CallInst::Create( countFunc, countArgs.begin(),countArgs.end(), "", beforeInst); 	// Insert the inject call before the instruction
		}
		//in fact, here we only use backwardslice ('s')
		else if(profileoption == 's')
		{
			const Type* returnType = I->getType();
			if (returnType->isVoidTy() || !filter(I))//Here we can insert a new filter ///////////////////////////////////////////////
			{
				//errs()<<"filter not passed\n";
				continue;
			}
//for injection into all instructions except invoke instructions (these are same as unconditional branch instructions with exception handling mechanism)
		  if((isa<InvokeInst>(I)) 
#ifdef EXCLUDE_CASTINST
|| (isa<CastInst>(I))
#endif
) // cast instruction added by Jiesheng
        continue;
			
			//errs()<<"filter passed\n";
			Instruction *beforeInst;
			if(isa<PHINode>(I))
			{	BasicBlock *bb = I->getParent();
				beforeInst = bb->getFirstNonPHI(); 
			}
			else
				beforeInst = I;
			insert_worklist.push_back(beforeInst);
		}

    }

    while(!insert_worklist.empty())
    {
    	Instruction* beforeInst = insert_worklist.back();
    	insert_worklist.pop_back();
    	vector<const Type*> argTypes(1);
			argTypes[0] = Type::getInt32Ty(context);	// enum for the options
			FunctionType* countFuncType = FunctionType::get( Type::getVoidTy(context), argTypes, 0 );
    	Constant* countFunc = m->getOrInsertFunction("doProfiling", countFuncType);
    	vector<Value*> countArgs(1);
    		const IntegerType* itype = IntegerType::get(context,32);
			Value* allVal = ConstantInt::get(itype, BACKWARD_SLICE );
    		countArgs[0] = allVal; //enum for All inst

    	CallInst::Create( countFunc, countArgs.begin(),countArgs.end(), "", beforeInst);

    }
    return true;
}
  bool NullDerefProtectionTransformer::runOnFunction(llvm::Function &F) {

    std::vector<llvm::Instruction*> WorkList;
    for (llvm::inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
      llvm::Instruction* I = &*i;
      if (llvm::isa<llvm::LoadInst>(I))
        WorkList.push_back(I);
    }

    for (std::vector<llvm::Instruction*>::iterator i = WorkList.begin(), 
           e = WorkList.end(); i != e; ++i) {
      Inst = *i;
      Builder->SetInsertPoint(Inst);
      llvm::LoadInst* I = llvm::cast<llvm::LoadInst>(*i);

      // Find all the instructions that uses the instruction I.
      for (llvm::Value::use_iterator UI = I->use_begin(), UE = I->use_end();
           UI != UE; ++UI) {

        // Check whether I is used as the first argument for a load instruction.
        // If it is, then instrument the load instruction.
        if (llvm::LoadInst* LI = llvm::dyn_cast<llvm::LoadInst>(*UI)) {
          llvm::Value* Arg = LI->getOperand(0);
          if (Arg == I)
            instrumentInst(LI, Arg);
        }

        // Check whether I is used as the second argument for a store
        // instruction. If it is, then instrument the store instruction.
        else if (llvm::StoreInst* SI = llvm::dyn_cast<llvm::StoreInst>(*UI)) {
          llvm::Value* Arg = SI->getOperand(1);
          if (Arg == I)
            instrumentInst(SI, Arg);
        }

        // Check whether I is used as the first argument for a GEP instruction.
        // If it is, then instrument the GEP instruction.
        else if (llvm::GetElementPtrInst* GEP = llvm::dyn_cast<
               llvm::GetElementPtrInst>(*UI)) {
          llvm::Value* Arg = GEP->getOperand(0);
          if (Arg == I)
            instrumentInst(GEP, Arg);
        }

        else {
          // Check whether I is used as the first argument for a call instruction.
          // If it is, then instrument the call instruction.
          llvm::CallSite CS(*UI);
          if (CS) {
            llvm::CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end();
            if (i != e) {
              llvm::Value *Arg = *i;
              if (Arg == I)
               instrumentInst(CS.getInstruction(), Arg);
            }
          }
        }
      }
    }
    return true;
  }
Function * futamurize( const Function * orig_func, DenseMap<const Value*, Value*> &argmap, std::set<const unsigned char *> &constant_addresses_set )
{
	LLVMContext &context = getGlobalContext();
	
	
	// Make a copy of the function, removing constant arguments
	Function * specialized_func = CloneFunction( orig_func, argmap );
	specialized_func->setName( orig_func->getNameStr() + "_1" );
	
	// add it to our module
	LLVM_Module->getFunctionList().push_back( specialized_func );
	
	printf("\nspecialized_func = %p <%s>\n", specialized_func, specialized_func->getName().data());
	//~ specialized_func->dump();

	// Optimize it
	FunctionPassManager PM( LLVM_Module );
	createStandardFunctionPasses( &PM, 3 );
	
	PM.add(createScalarReplAggregatesPass());  // Break up aggregate allocas
	PM.add(createInstructionCombiningPass());  // Cleanup for scalarrepl.
	PM.add(createJumpThreadingPass());         // Thread jumps.
	PM.add(createCFGSimplificationPass());     // Merge & remove BBs
	PM.add(createInstructionCombiningPass());  // Combine silly seq's
	PM.add(createTailCallEliminationPass());   // Eliminate tail calls
	PM.add(createCFGSimplificationPass());     // Merge & remove BBs
	PM.add(createReassociatePass());           // Reassociate expressions
	PM.add(createLoopRotatePass());            // Rotate Loop
	PM.add(createLICMPass());                  // Hoist loop invariants
	PM.add(createLoopUnswitchPass( false ));
	PM.add(createInstructionCombiningPass());
	PM.add(createIndVarSimplifyPass());        // Canonicalize indvars
	PM.add(createLoopDeletionPass());          // Delete dead loops
	PM.add(createLoopUnroll2Pass());            // Unroll small loops
	PM.add(createInstructionCombiningPass());  // Clean up after the unroller
	PM.add(createGVNPass());                   // Remove redundancies
	PM.add(createMemCpyOptPass());             // Remove memcpy / form memset
	PM.add(createSCCPPass());                  // Constant prop with SCCP
	PM.add(createPromoteMemoryToRegisterPass()); 
	PM.add(createConstantPropagationPass());            
	PM.add(createDeadStoreEliminationPass());            
	PM.add(createAggressiveDCEPass());            
	PM.add(new MemoryDependenceAnalysis());            
	//~ PM.add(createAAEvalPass());              
	
	const PassInfo * pinfo = Pass::lookupPassInfo( "print-alias-sets" );
	if( !pinfo ) { printf( "print-alias-sets not found\n" ); exit(-1); }
	PM.add( pinfo->createPass() );
	
	FunctionPassManager PM_Inline( LLVM_Module );
	PM_Inline.add(createSingleFunctionInliningPass());            
	
	bool Changed = false;
	int iterations = 2;
	int inline_iterations = 6;
	
	do
	{
		Changed = false;
		
		// first do some optimizations
		PM.doInitialization();
		PM.run( *specialized_func );
		PM.doFinalization();
		
		// Load from Constant Memory detection
		const TargetData *TD = LLVM_EE->getTargetData();
		
		for (inst_iterator I = inst_begin(specialized_func), E = inst_end(specialized_func); I != E; ++I) 
		{
			Instruction * inst = (Instruction *) &*I;

			// get all Load instructions
			LoadInst * load = dyn_cast<LoadInst>( inst );
			if( !load ) continue;
			if( load->isVolatile() ) continue;

			if (load->use_empty()) continue;        // Don't muck with dead instructions...

			// get the address loaded by load instruction
			Value *ptr_value = load->getPointerOperand();
			
			// we're only interested in constant addresses
			ConstantExpr * ptr_constant_expr =  dyn_cast<ConstantExpr>( ptr_value );
			if( !ptr_constant_expr ) continue;			
			ptr_constant_expr->dump();
			
			// compute real address of constant pointer expression
			Constant * ptr_constant = ConstantFoldConstantExpression( ptr_constant_expr, TD );
			if( !ptr_constant ) continue;
			ptr_constant->dump();
			
			// convert to int constant
			ConstantInt *int_constant =  dyn_cast<ConstantInt>( ConstantExpr::getPtrToInt( ptr_constant, Type::getInt64Ty( context )));
			if( !int_constant ) continue;
			int_constant->dump();
			
			// get data size
			int data_length = TD->getTypeAllocSize( load->getType() );
			ptr_value->getType()->dump();
			
			// get real address (at last !)
			const unsigned char * c_ptr = (const unsigned char *) int_constant->getLimitedValue();
			
			printf( "%ld %d %d\n", c_ptr, constant_addresses_set.count( c_ptr ), data_length );
			
			// check what's in this address	
			int isconst = 1;
			for( int offset=0; offset<data_length; offset++ )
				isconst &= constant_addresses_set.count( c_ptr + offset );
			
			if( !isconst ) continue;
			printf( "It is constant.\n" );
			
			// make a LLVM const with the data
			Constant *new_constant = NULL;
			switch( data_length )
			{
				case 1:	new_constant = ConstantInt::get( Type::getInt8Ty( context ),  *(uint8_t*)c_ptr, false /* signed */ );	break;
				case 2:	new_constant = ConstantInt::get( Type::getInt16Ty( context ), *(uint16_t*)c_ptr, false /* signed */ );	break;
				case 4:	new_constant = ConstantInt::get( Type::getInt32Ty( context ), *(uint32_t*)c_ptr, false /* signed */ );	break;
				case 8:	new_constant = ConstantInt::get( Type::getInt64Ty( context ), *(uint64_t*)c_ptr, false /* signed */ );	break;
				default:
				{
					StringRef const_data ( (const char *) c_ptr, data_length );
					new_constant = ConstantArray::get( context, const_data, false /* dont add terminating null */ );
				}
			}
			
			if( !new_constant ) continue;
			
			new_constant->dump();
							
			//~ // get the type that is loaded
			const Type *Ty = load->getType();
			
			// do we need a cast ?
			if( load->getType() != new_constant->getType() )
			{
				new_constant = ConstantExpr::getBitCast( new_constant, Ty );
				new_constant->dump();
			}
			
			// zap the load and replace with constant address
			load->replaceAllUsesWith( new_constant );
			printf( "\nREPLACED :...\n" );
			load->dump();
			new_constant->dump();
			
			Changed = true;
		}	
		
		if( Changed )
			continue;	// re-optimize and do another pass of constant load elimination
		
		// if we can't do anything else, do an inlining pass
		if( inline_iterations > 0 )
		{
			inline_iterations --;
			
			PM_Inline.doInitialization();
			Changed |= PM_Inline.run( *specialized_func );
			PM_Inline.doFinalization();

			//~ for( int i=0; i<3; i++ )
			{
				PM.doInitialization();
				Changed |= PM.run( *specialized_func );
				PM.doFinalization();
			}
		}
		
		if( iterations>0 && !Changed ) 
			iterations--;
	} while( Changed || iterations>0 );
	
	return specialized_func;
}