StructuredModuleEditor::InstList StructuredModuleEditor::getCallsToFunction( Function * F) { InstList Calls; // Iterates over every basic block in the module and gathers a list of instructions // that call to the specified function for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) { for (Function::iterator BBI = FI->begin(), BBE = FI->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; Function *Callee = CS.getCalledFunction(); if (Callee == F) Calls.push_back(CS.getInstruction()); } } } return Calls; }
bool ExpandByVal::runOnModule(Module &M) { bool Modified = false; DataLayout DL(&M); for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) { AttributeSet NewAttrs = RemoveAttrs(Func->getContext(), Func->getAttributes()); Modified |= (NewAttrs != Func->getAttributes()); Func->setAttributes(NewAttrs); for (Function::iterator BB = Func->begin(), E = Func->end(); BB != E; ++BB) { for (BasicBlock::iterator Inst = BB->begin(), E = BB->end(); Inst != E; ++Inst) { if (CallInst *Call = dyn_cast<CallInst>(Inst)) { Modified |= ExpandCall(&DL, Call); } else if (InvokeInst *Call = dyn_cast<InvokeInst>(Inst)) { Modified |= ExpandCall(&DL, Call); } } } } return Modified; }
void GlobalMerge::setMustKeepGlobalVariables(Module &M) { // If we already processed a Module, UsedGlobalVariables may have been // populated. Reset the information for this module. MustKeepGlobalVariables.clear(); collectUsedGlobalVariables(M); for (Module::iterator IFn = M.begin(), IEndFn = M.end(); IFn != IEndFn; ++IFn) { for (Function::iterator IBB = IFn->begin(), IEndBB = IFn->end(); IBB != IEndBB; ++IBB) { // Follow the inwoke link to find the landing pad instruction const InvokeInst *II = dyn_cast<InvokeInst>(IBB->getTerminator()); if (!II) continue; const LandingPadInst *LPInst = II->getUnwindDest()->getLandingPadInst(); // Look for globals in the clauses of the landing pad instruction for (unsigned Idx = 0, NumClauses = LPInst->getNumClauses(); Idx != NumClauses; ++Idx) if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(LPInst->getClause(Idx) ->stripPointerCasts())) MustKeepGlobalVariables.insert(GV); } } }
/* * Build information about functions that store on pointer arguments * For simplification, we only consider a function to store on an argument * if it has exactly one StoreInst to that argument and the arg has no other use. */ int DeadStoreEliminationPass::getFnThatStoreOnArgs(Module &M) { int numStores = 0; DEBUG(errs() << "Getting functions that store on arguments...\n"); for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (F->arg_empty() || F->isDeclaration()) continue; // Get args std::set<Value*> args; for (Function::arg_iterator formalArgIter = F->arg_begin(); formalArgIter != F->arg_end(); ++formalArgIter) { Value *formalArg = formalArgIter; if (formalArg->getType()->isPointerTy()) { args.insert(formalArg); } } // Find stores on arguments for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { Instruction *inst = I; if (!isa<StoreInst>(inst)) continue; StoreInst *SI = dyn_cast<StoreInst>(inst); Value *ptrOp = SI->getPointerOperand(); if (args.count(ptrOp) && ptrOp->hasNUses(1)) { fnThatStoreOnArgs[F].insert(ptrOp); numStores++; DEBUG(errs() << " " << F->getName() << " stores on argument " << ptrOp->getName() << "\n"); } } } } DEBUG(errs() << "\n"); return numStores; }
void BlockFrequencyPruner::init() { freqSum = 0; std::vector<BasicBlock*> blocks; for (Module::iterator f = m->begin(); f != m->end(); f++) { if (!(*f).isDeclaration()) { BlockFrequencyInfo &bfi = mp->getAnalysis<BlockFrequencyInfo>(*f); for (Function::iterator b = f->begin(); b != f->end(); b++) { BasicBlock *block = b; unsigned freq = bfi.getBlockFreq(block).getFrequency(); freqSum += freq; blocks.push_back(block); _freqPredicate.freqs[block] = freq; } } } std::sort(blocks.begin(), blocks.end(), _freqPredicate); std::vector<double> dist = getBlockDistribution(blocks, (double)freqSum); double distSum = 0; for (unsigned i = 0; (i < blocks.size()) && (distSum < massThreshold); ++i, distSum += dist.at(i)) { prunedBlocks.push_back(blocks.at(i)); } }
bool MemoryInstrumenter::runOnModule(Module &M) { // Check whether there are unsupported language features. checkFeatures(M); // Setup scalar types. setupScalarTypes(M); // Find the main function. Main = M.getFunction("main"); assert(Main && !Main->isDeclaration() && !Main->hasLocalLinkage()); // Setup hook function declarations. setupHooks(M); // Hook global variable allocations. instrumentGlobals(M); // Hook memory allocations and memory accesses. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (F->isDeclaration()) continue; if (!IsWhiteListed(*F)) continue; // The second argument of main(int argc, char *argv[]) needs special // handling, which is done in instrumentMainArgs. // We should treat argv as a memory allocation instead of a regular // pointer. if (Main != F) instrumentPointerParameters(F); if (F->isVarArg()) instrumentVarArgFunction(F); for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { if (Diagnose) instrumentBasicBlock(BB); for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) instrumentInstructionIfNecessary(I); } instrumentEntry(*F); } // main(argc, argv) // argv is allocated by outside. instrumentMainArgs(M); // Lower global constructors. lowerGlobalCtors(M); #if 0 // Add HookGlobalsAlloc to the global_ctors list. addNewGlobalCtor(M); #endif // Call the memory hook initializer and the global variable allocation hook // at the very beginning. Instruction *OldEntry = Main->begin()->getFirstNonPHI(); CallInst::Create(MemHooksIniter, "", OldEntry); CallInst::Create(GlobalsAllocHook, "", OldEntry); return true; }
bool BlockExtractorPass::runOnModule(Module &M) { std::set<BasicBlock*> TranslatedBlocksToNotExtract; for (unsigned i = 0, e = BlocksToNotExtract.size(); i != e; ++i) { BasicBlock *BB = BlocksToNotExtract[i]; Function *F = BB->getParent(); // Map the corresponding function in this module. Function *MF = M.getFunction(F->getName()); assert(MF->getFunctionType() == F->getFunctionType() && "Wrong function?"); // Figure out which index the basic block is in its function. Function::iterator BBI = MF->begin(); std::advance(BBI, std::distance(F->begin(), Function::iterator(BB))); TranslatedBlocksToNotExtract.insert(&*BBI); } while (!BlocksToNotExtractByName.empty()) { // There's no way to find BBs by name without looking at every BB inside // every Function. Fortunately, this is always empty except when used by // bugpoint in which case correctness is more important than performance. std::string &FuncName = BlocksToNotExtractByName.back().first; std::string &BlockName = BlocksToNotExtractByName.back().second; for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) { Function &F = *FI; if (F.getName() != FuncName) continue; for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) { BasicBlock &BB = *BI; if (BB.getName() != BlockName) continue; TranslatedBlocksToNotExtract.insert(&*BI); } } BlocksToNotExtractByName.pop_back(); } // Now that we know which blocks to not extract, figure out which ones we WANT // to extract. std::vector<BasicBlock*> BlocksToExtract; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { SplitLandingPadPreds(&*F); for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) if (!TranslatedBlocksToNotExtract.count(&*BB)) BlocksToExtract.push_back(&*BB); } for (unsigned i = 0, e = BlocksToExtract.size(); i != e; ++i) { SmallVector<BasicBlock*, 2> BlocksToExtractVec; BlocksToExtractVec.push_back(BlocksToExtract[i]); if (const InvokeInst *II = dyn_cast<InvokeInst>(BlocksToExtract[i]->getTerminator())) BlocksToExtractVec.push_back(II->getUnwindDest()); CodeExtractor(BlocksToExtractVec).extractCodeRegion(); } return !BlocksToExtract.empty(); }
void Variables::updateMetadata(Module& module, Value* oldTarget, Value* newTarget, Type* newType) { vector<Instruction*> to_remove; if (newTarget) { errs() << "\tChanging metadata for: " << newTarget->getName() << "\n"; bool changed = false; for(Module::iterator f = module.begin(), fe = module.end(); f != fe; f++) { for(Function::iterator b = f->begin(), be = f->end(); b != be; b++) { for(BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; i++) { if (DbgDeclareInst *oldDeclare = dyn_cast<DbgDeclareInst>(i)) { if (Value *address = oldDeclare->getAddress()) { if (AllocaInst *allocaInst = dyn_cast<AllocaInst>(address)) { if (allocaInst == oldTarget) { // the alloca we are looking for DIVariable oldDIVar(oldDeclare->getVariable()); MDNode* newDIType = getTypeMetadata(module, oldDIVar, newType); // construct new DIVariable with new type descriptor vector<Value*> doperands; for(unsigned i = 0; i < oldDIVar->getNumOperands(); i++) { if (i == 5) { // the argument that corresponds to the type descriptor doperands.push_back(newDIType); } else { doperands.push_back(oldDIVar->getOperand(i)); // preserve other descriptors } } ArrayRef<Value*> *arrayRefDOperands = new ArrayRef<Value*>(doperands); MDNode* newMDNode = MDNode::get(module.getContext(), *arrayRefDOperands); DIVariable newDIVar(newMDNode); // insert new declare instruction DIBuilder* builder = new DIBuilder(module); Instruction *newDeclare = builder->insertDeclare(newTarget, newDIVar, oldDeclare); // make sure the declare instruction preserves its own metadata unsigned id = 0; if (oldDeclare->getMetadata(id)) { newDeclare->setMetadata(id, oldDeclare->getMetadata(id)); } to_remove.push_back(oldDeclare); // can't erase while iterating through instructions changed = true; } } } } } } } for(unsigned i = 0; i < to_remove.size(); i++) { to_remove[i]->eraseFromParent(); } if (!changed) { errs() << "\tNo metadata to change\n"; } } return; }
bool RaiseAsmPass::runOnModule(Module &M) { bool changed = false; #if LLVM_VERSION_CODE >= LLVM_VERSION(2, 9) std::string Err; std::string HostTriple = llvm::sys::getHostTriple(); const Target *NativeTarget = TargetRegistry::lookupTarget(HostTriple, Err); if (NativeTarget == 0) { llvm::errs() << "Warning: unable to select native target: " << Err << "\n"; TLI = 0; } else { #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 0) TargetMachine *TM = NativeTarget->createTargetMachine(HostTriple, "", ""); #else TargetMachine *TM = NativeTarget->createTargetMachine(HostTriple, ""); #endif TLI = TM->getTargetLowering(); } #endif for (Module::iterator fi = M.begin(), fe = M.end(); fi != fe; ++fi) { for (Function::iterator bi = fi->begin(), be = fi->end(); bi != be; ++bi) { for (BasicBlock::iterator ii = bi->begin(), ie = bi->end(); ii != ie;) { Instruction *i = ii; ++ii; changed |= runOnInstruction(M, i); } } } return changed; }
bool LdStCallCounter::runOnModule(Module &M) { if (flag == true) // if we have counted already -- structure of llvm means this could be called many times return false; // for all functions in module for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration()) { // for all blocks in the function for (Function::iterator BBB = I->begin(), BBE = I->end(); BBB != BBE; ++BBB) { // for all instructions in a block for (BasicBlock::iterator IB = BBB->begin(), IE = BBB->end(); IB != IE; IB++) { if (isa<LoadInst>(IB)) // count loads, stores, calls num_loads++; else if (isa<StoreInst>(IB)) num_stores++; // count only external calls, ignore declarations, etc else if (isa<CallInst>(IB) && ( (dyn_cast<CallInst>(IB)->getCalledFunction() == NULL) || (dyn_cast<CallInst>(IB)->getCalledFunction()->isDeclaration()))) num_calls++; } } } llvm::errs() << "Loads/Store/Calls:" << num_loads << " " << num_stores << " " << num_calls << "\n"; flag = true; return false; }
bool llvm::ValueCounter::runOnModule(Module& M) { std::set<Value*> values; for(Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; Fit++){ if (!values.count(Fit)) values.insert(Fit); for(Function::arg_iterator Arg = Fit->arg_begin(), aEnd = Fit->arg_end(); Arg != aEnd; Arg++) { if (!values.count(Arg)) values.insert(Arg); } for (Function::iterator BBit = Fit->begin(), BBend = Fit->end(); BBit != BBend; BBit++) { for (BasicBlock::iterator Iit = BBit->begin(), Iend = BBit->end(); Iit != Iend; Iit++) { if (!values.count(Iit)) values.insert(Iit); for(unsigned int i = 0; i < Iit->getNumOperands(); i++){ if (!values.count(Iit->getOperand(i))) values.insert(Iit->getOperand(i)); } } } } TotalValues = values.size(); //We don't modify anything, so we must return false; return false; }
bool OvershiftCheckPass::runOnModule(Module &M) { Function *overshiftCheckFunction = 0; LLVMContext &ctx = M.getContext(); bool moduleChanged = false; for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) { for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) { for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) { if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) { // find all shift instructions Instruction::BinaryOps opcode = binOp->getOpcode(); if (opcode == Instruction::Shl || opcode == Instruction::LShr || opcode == Instruction::AShr ) { std::vector<llvm::Value*> args; // Determine bit width of first operand uint64_t bitWidth=i->getOperand(0)->getType()->getScalarSizeInBits(); ConstantInt *bitWidthC = ConstantInt::get(Type::getInt64Ty(ctx), bitWidth, false); args.push_back(bitWidthC); CastInst *shift = CastInst::CreateIntegerCast(i->getOperand(1), Type::getInt64Ty(ctx), false, /* sign doesn't matter */ "int_cast_to_i64", &*i); args.push_back(shift); // Lazily bind the function to avoid always importing it. if (!overshiftCheckFunction) { Constant *fc = M.getOrInsertFunction("klee_overshift_check", Type::getVoidTy(ctx), Type::getInt64Ty(ctx), Type::getInt64Ty(ctx), NULL); overshiftCheckFunction = cast<Function>(fc); } // Inject CallInstr to check if overshifting possible CallInst *ci = CallInst::Create(overshiftCheckFunction, args, "", &*i); // set debug information from binary operand to preserve it ci->setDebugLoc(binOp->getDebugLoc()); moduleChanged = true; } } } } } return moduleChanged; }
void Constraints::SetupInstructionLabelMap(Module* M) { for (Module::iterator F = M->begin(), FE = M->end(); F != FE; F++) { for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; BB++) { for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; I++) { instrLabelMap.insert(InstrLabel_pair(I->label_instr, I)); } } } }
void MemoryInstrumenter::checkFeatures(Module &M) { // Check whether any memory allocation function can // potentially be pointed by function pointers. // Also, all intrinsic functions will be called directly, // i.e. not via function pointers. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) { for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) { User *Usr = *UI; assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr)); CallSite CS(cast<Instruction>(Usr)); for (unsigned i = 0; i < CS.arg_size(); ++i) assert(CS.getArgument(i) != F); } } } // Check whether memory allocation functions are captured. for (Module::iterator F = M.begin(); F != M.end(); ++F) { // 0 is the return, 1 is the first parameter. if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << "'s return value is marked noalias, "; errs() << "but the function is not treated as malloc.\n"; errs().resetColor(); } } // Global variables shouldn't be of the array type. for (Module::global_iterator GI = M.global_begin(), E = M.global_end(); GI != E; ++GI) { assert(!GI->getType()->isArrayTy()); } // A function parameter or an instruction can be an array, but we don't // instrument such constructs for now. Issue a warning on such cases. for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) { if (AI->getType()->isArrayTy()) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << ":" << *AI << " is an array\n"; errs().resetColor(); } } } 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) { if (Ins->getType()->isArrayTy()) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << ":" << *Ins << " is an array\n"; errs().resetColor(); } } } } }
bool AddStore::runOnModule(Module &M) { netDepGraph &mdg = getAnalysis<netDepGraph> (); depGraph = mdg.depGraph; for (Module::iterator F = M.begin(), eM = M.end(); F != eM; ++F) { Function *f = F; StringRef fname = f->getName(); int programID=1; if(fname.startswith("ttt_"))//Program #2 programID=2; else programID=1; for (Function::iterator BB = F->begin(), e = F->end(); BB != e; ++BB) { for (BasicBlock::iterator I = BB->begin(), ee = BB->end(); I != ee; ++I) { if (CallInst *CI = dyn_cast<CallInst>(I)) { Function *Callee = CI->getCalledFunction(); if (Callee) { StringRef Name = Callee->getName(); if ( Name.equals("memcpy") || Name.equals("ttt_memcpy") || Name.equals("strcpy") || Name.equals("ttt_strcpy") || Name.equals("memmove") || Name.equals("ttt_memmove") || Name.equals("memset") || Name.equals("ttt_memset") || Name.equals("strcat") || Name.equals("ttt_strcat") || Name.equals("strncat") || Name.equals("ttt_strncat") || Name.equals( "strncpy") || Name.equals( "strncpy")) { //src: arg1, dest: arg0 Value* src = CI->getArgOperand(1); Value* dest = CI->getArgOperand(0); if (dest->getType()->isPointerTy()) { GraphNode* srcN = depGraph->findNode(src,programID); OpNode* store = new OpNode(Instruction::Store); GraphNode* destN; destN = depGraph->findNode(dest,programID); depGraph->addEdge(programID, srcN, store); depGraph->addEdge(programID, store, destN); } } else if (Name.equals("sprintf")||Name.equals("ttt_sprintf")) { Value* dest = CI->getArgOperand(0); if (dest->getType()->isPointerTy()) { Value* src; GraphNode* destN = depGraph->findNode(dest,programID); for (unsigned i = 2, eee = CI->getNumArgOperands(); i != eee; ++i) { //skip format specifier src = CI->getArgOperand(i); GraphNode* srcN = depGraph->findNode(src,programID); OpNode* store = new OpNode(Instruction::Store); depGraph->addEdge(programID, srcN, store); depGraph->addEdge(programID, store, destN); } } } } } } } } return false; }
bool InterProceduralRA::runOnModule(Module& M) { //Build inter-procedural dependence graph moduleDepGraph& M_DepGraph = getAnalysis<moduleDepGraph>(); depGraph = M_DepGraph.depGraph; if(!RAFilename.empty()) { ModuleLookup& ML = getAnalysis<ModuleLookup>(); importInitialStates(ML); } loadIgnoredFunctions(RAIgnoredFunctions); addIgnoredFunction("malloc"); for(Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; Fit++){ //Skip functions without body (externally linked functions, such as printf) if (Fit->begin() == Fit->end()) continue; //Extract constraints from branch conditions BranchAnalysis& brAnalysis = getAnalysis<BranchAnalysis>(*Fit); std::map<const Value*, std::list<ValueSwitchMap*> > constraints = brAnalysis.getIntervalConstraints(); //Add branch information to the dependence graph. Here we add the future values addConstraints(constraints); } //Solve range analysis solve(); // errs() << "Computed ranges:\n"; // // for(Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; Fit++){ // // for (Function::iterator BBit = Fit->begin(), BBend = Fit->end(); BBit != BBend; BBit++){ // // for (BasicBlock::iterator Iit = BBit->begin(), Iend = BBit->end(); Iit != Iend; Iit++){ // // Instruction* I = Iit; // // Range R = getRange(I); // // errs() << I->getName() << " "; // R.print(errs()); // errs() << "\n"; // } // // } // } return false; }
// // Method: runOnModule() // // Description: // Entry point for this pass. // bool Dyncount::runOnModule (Module & M) { // // Create two global counters within the module. // TS = &getAnalysis<dsa::TypeSafety<TDDataStructures> >(); ConstantInt * Zero = ConstantInt::get (Type::getInt64Ty(M.getContext()), 0); GlobalVariable * Total = new GlobalVariable (M, Type::getInt64Ty(M.getContext()), false, GlobalValue::InternalLinkage, Zero, "Total"); GlobalVariable * Safe = new GlobalVariable (M, Type::getInt64Ty(M.getContext()), false, GlobalValue::InternalLinkage, Zero, "Safe"); for (Module::iterator F = M.begin(); F != M.end(); ++F){ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) { if(LoadInst *LI = dyn_cast<LoadInst>(I)) { instrumentLoad(Total, LI); if(TS->isTypeSafe(LI->getOperand(0),LI->getParent()->getParent())) instrumentLoad(Safe, LI); // check if safe } else if(StoreInst *SI = dyn_cast<StoreInst>(I)) { instrumentStore(Total, SI); if(TS->isTypeSafe(SI->getOperand(1),SI->getParent()->getParent())) instrumentStore(Safe, SI); // check if safe } } } } // // Add a call to main() that will record the values on exit(). // Function *MainFunc = M.getFunction("main") ? M.getFunction("main") : M.getFunction ("MAIN__"); BasicBlock & BB = MainFunc->getEntryBlock(); Constant * Setup = M.getOrInsertFunction ("DYN_COUNT_setup", Type::getVoidTy(M.getContext()), Total->getType(), Safe->getType(), NULL); std::vector<Value *> args; args.push_back (Total); args.push_back (Safe); CallInst::Create (Setup, args, "", BB.getFirstNonPHI()); return true; }
void ProgramCFG::findAllRetBlocks(Module &m){ for(Module::iterator f = m.begin(); f!= m.end(); f++){ if(f->getName() == "main") continue; for(Function::iterator bb = f->begin(); bb != f->end(); bb++){ TerminatorInst *terminator = bb->getTerminator(); if(isa<ReturnInst>(terminator) ){ ((*retBlocks)[f]).push_back(bb); } } } }
bool EnforcingLandmarks::runOnModule(Module &M) { if (EnforcingLandmarksFile == "") { const static size_t len = sizeof(DEFAULT_ENFORCING_LANDMARK_FUNCS) / sizeof(const char *[2]); for (size_t i = 0; i < len; ++i) { string func_name = DEFAULT_ENFORCING_LANDMARK_FUNCS[i][0]; string is_blocking = DEFAULT_ENFORCING_LANDMARK_FUNCS[i][1]; insert_enforcing_landmark_func(func_name, is_blocking); } } else { ifstream fin(EnforcingLandmarksFile.c_str()); string func_name, is_blocking; while (fin >> func_name >> is_blocking) insert_enforcing_landmark_func(func_name, is_blocking); } // Mark any function call to landmark functions as enforcing landmarks. for (Module::iterator f = M.begin(); f != M.end(); ++f) { if (f->getName() == "MyMalloc") continue; if (f->getName() == "MyFree") continue; if (f->getName() == "MyFreeNow") continue; if (f->getName() == "maketree") continue; 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.getInstruction()) { if (Function *callee = cs.getCalledFunction()) { StringRef callee_name = callee->getName(); if (enforcing_landmark_funcs.count(callee_name)) { if (OnlyMain && callee_name != "pthread_self" && f->getName() != "main") continue; if (callee_name.startswith("pthread_mutex") || callee_name.startswith("pthread_cond") || callee_name.startswith("pthread_barrier") || callee_name.startswith("pthread_rwlock") || callee_name.startswith("pthread_spin")) { if (rand() % 100 < PruningRate) continue; } enforcing_landmarks.insert(ins); } } } } } } return false; }
void MemoryInstrumenter::checkFeatures(Module &M) { // Check whether any memory allocation function can // potentially be pointed by function pointers. // Also, all intrinsic functions will be called directly, // i.e. not via function pointers. for (Module::iterator F = M.begin(); F != M.end(); ++F) { if (DynAAUtils::IsMalloc(F) || F->isIntrinsic()) { for (Value::use_iterator UI = F->use_begin(); UI != F->use_end(); ++UI) { User *Usr = *UI; assert(isa<CallInst>(Usr) || isa<InvokeInst>(Usr)); CallSite CS(cast<Instruction>(Usr)); for (unsigned i = 0; i < CS.arg_size(); ++i) assert(CS.getArgument(i) != F); } } } // Check whether memory allocation functions are captured. for (Module::iterator F = M.begin(); F != M.end(); ++F) { // 0 is the return, 1 is the first parameter. if (F->isDeclaration() && F->doesNotAlias(0) && !DynAAUtils::IsMalloc(F)) { errs().changeColor(raw_ostream::RED); errs() << F->getName() << "'s return value is marked noalias, "; errs() << "but the function is not treated as malloc.\n"; errs().resetColor(); } } // Sequential types except pointer types shouldn't be used as the type of // an instruction, a function parameter, or a global variable. for (Module::global_iterator GI = M.global_begin(), E = M.global_end(); GI != E; ++GI) { if (isa<SequentialType>(GI->getType())) assert(GI->getType()->isPointerTy()); } for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { for (Function::arg_iterator AI = F->arg_begin(); AI != F->arg_end(); ++AI) { if (isa<SequentialType>(AI->getType())) assert(AI->getType()->isPointerTy()); } } 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) { if (isa<SequentialType>(Ins->getType())) assert(Ins->getType()->isPointerTy()); } } } // We don't support multi-process programs for now. if (!HookFork) assert(M.getFunction("fork") == NULL); }
bool IntrinsicCleanerPass::runOnModule(Module &M) { bool dirty = false; for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) dirty |= runOnBasicBlock(*b, M); if (Function *Declare = M.getFunction("llvm.trap")) { Declare->eraseFromParent(); dirty = true; } return dirty; }
bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*> &Insts) { // Clone the program to try hacking it apart... ValueToValueMapTy VMap; Module *M = CloneModule(BD.getProgram(), VMap); // Convert list to set for fast lookup... SmallPtrSet<Instruction*, 64> Instructions; for (unsigned i = 0, e = Insts.size(); i != e; ++i) { assert(!isa<TerminatorInst>(Insts[i])); Instructions.insert(cast<Instruction>(VMap[Insts[i]])); } outs() << "Checking for crash with only " << Instructions.size(); if (Instructions.size() == 1) outs() << " instruction: "; else outs() << " instructions: "; for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI) for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) { Instruction *Inst = I++; if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst) && !isa<LandingPadInst>(Inst)) { if (!Inst->getType()->isVoidTy()) Inst->replaceAllUsesWith(UndefValue::get(Inst->getType())); Inst->eraseFromParent(); } } // Verify that this is still valid. PassManager Passes; Passes.add(createVerifierPass()); Passes.add(createDebugInfoVerifierPass()); Passes.run(*M); // Try running on the hacked up program... if (TestFn(BD, M)) { BD.setNewProgram(M); // It crashed, keep the trimmed version... // Make sure to use instruction pointers that point into the now-current // module, and that they don't include any deleted blocks. Insts.clear(); for (SmallPtrSet<Instruction*, 64>::const_iterator I = Instructions.begin(), E = Instructions.end(); I != E; ++I) Insts.push_back(*I); return true; } delete M; // It didn't crash, try something else. return false; }
bool IDTagger::runOnModule(Module &M) { IntegerType *IntType = IntegerType::get(M.getContext(), 32); for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) { for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { Constant *InsID = ConstantInt::get(IntType, NumInstructions); I->setMetadata("ins_id", MDNode::get(M.getContext(), InsID)); ++NumInstructions; } } } return true; }
// see if we can find label in any basic blocks of this program bool ModuloScheduler::find_legup_label(Module *M, std::string label) { for (Module::iterator F = M->begin(), FE = M->end(); F != FE; ++F) { for (Function::iterator BB = F->begin(), EE = F->end(); BB != EE; ++BB) { if (get_legup_label(BB) == label) { // errs() << "Found label: " << label << " in BB: " << // getLabel(BB) << "\n"; return true; } } } return false; }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. Search for insertvalue instructions // that can be simplified. // // Inputs: // M - A reference to the LLVM module to transform. // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool SimplifyIV::runOnModule(Module& M) { // Repeat till no change bool changed; do { changed = false; std::vector<StoreInst*> worklist; for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { InsertValueInst *IV = dyn_cast<InsertValueInst>(I++); if(!IV) continue; // Find all insert value instructions. if(!IV->hasOneUse()) continue; // Check that its only use is a StoreInst StoreInst *SI = dyn_cast<StoreInst>(*(IV->use_begin())); if(!SI) continue; // Check that it is the stored value if(SI->getOperand(0) != IV) continue; changed = true; numErased++; do { // replace by a series of gep/stores SmallVector<Value*, 8> Indices; Type *Int32Ty = Type::getInt32Ty(M.getContext()); Indices.push_back(Constant::getNullValue(Int32Ty)); for (InsertValueInst::idx_iterator I = IV->idx_begin(), E = IV->idx_end(); I != E; ++I) { Indices.push_back(ConstantInt::get(Int32Ty, *I)); } GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(SI->getOperand(1), Indices, SI->getName(), SI) ; new StoreInst(IV->getInsertedValueOperand(), GEP, SI); IV = dyn_cast<InsertValueInst>(IV->getAggregateOperand()); } while(IV); worklist.push_back(SI); } } } while(!worklist.empty()) { StoreInst *SI = worklist.back(); worklist.pop_back(); SI->eraseFromParent(); } } while(changed); return (numErased > 0); }
bool AdvancedInstCounter::runOnModule(Module &M) { unsigned NumIndirectCalls = 0; for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator B = F->begin(); B != F->end(); ++B) { for (BasicBlock::iterator I = B->begin(); I != B->end(); ++I) { CallSite CS(I); if (CS && CS.getCalledFunction() == NULL) { ++NumIndirectCalls; } } } } errs() << "# of indirect calls = " << NumIndirectCalls << "\n"; return false; }
bool moduleDepGraph::runOnModule(Module &M) { AliasSets* AS = NULL; if (USE_ALIAS_SETS) AS = &(getAnalysis<AliasSets> ()); //Making dependency graph depGraph = new Graph(AS); //Insert instructions in the graph for (Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; ++Fit) { for (Function::iterator BBit = Fit->begin(), BBend = Fit->end(); BBit != BBend; ++BBit) { for (BasicBlock::iterator Iit = BBit->begin(), Iend = BBit->end(); Iit != Iend; ++Iit) { depGraph->addInst(Iit); } } } //Connect formal and actual parameters and return values for (Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; ++Fit) { // If the function is empty, do not do anything // Empty functions include externally linked ones (i.e. abort, printf, scanf, ...) if (Fit->begin() == Fit->end()) continue; matchParametersAndReturnValues(*Fit); } //We don't modify anything, so we must return false return false; }
// // Method: preprocess() // // Description: // %p = bitcast %p1 to T1 // gep(%p) ... // -> // gep (bitcast %p1 to T1), ... // // Inputs: // M - A reference to the LLVM module to process // // Outputs: // M - The transformed LLVM module. // static void preprocess(Module& M) { for (Module::iterator F = M.begin(); F != M.end(); ++F){ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) { if(!(isa<GetElementPtrInst>(I))) continue; GetElementPtrInst *GEP = cast<GetElementPtrInst>(I); if(BitCastInst *BI = dyn_cast<BitCastInst>(GEP->getOperand(0))) { if(Constant *C = dyn_cast<Constant>(BI->getOperand(0))) { GEP->setOperand(0, ConstantExpr::getBitCast(C, BI->getType())); } } } } } }
void Preparer::replaceUndefsWithNull(Module &M) { ValueSet Replaced; for (Module::global_iterator GI = M.global_begin(); GI != M.global_end(); ++GI) { if (GI->hasInitializer()) { replaceUndefsWithNull(GI->getInitializer(), Replaced); } } 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) { replaceUndefsWithNull(Ins, Replaced); } } } }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. Search for insert/extractvalue instructions // that can be simplified. // // Inputs: // M - A reference to the LLVM module to transform. // // Outputs: // M - The transformed LLVM module. // // Return value: // true - The module was modified. // false - The module was not modified. // bool SimplifyLoad::runOnModule(Module& M) { // Repeat till no change bool changed; do { changed = false; for (Module::iterator F = M.begin(); F != M.end(); ++F) { for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) { LoadInst *LI = dyn_cast<LoadInst>(I++); if(!LI) continue; if(LI->hasOneUse()) { if(CastInst *CI = dyn_cast<CastInst>(*(LI->use_begin()))) { if(LI->getType()->isPointerTy()) { if(ConstantExpr *CE = dyn_cast<ConstantExpr>(LI->getOperand(0))) { if(const PointerType *PTy = dyn_cast<PointerType>(CE->getOperand(0)->getType())) if(PTy->getElementType() == CI->getType()) { LoadInst *LINew = new LoadInst(CE->getOperand(0), "", LI); CI->replaceAllUsesWith(LINew); } } } } } } } } } while(changed); return (numErased > 0); }