bool LLPE::runOnModule(Module &M) {
  
	vector<int> argv = readInputFile();

	for (Module::iterator F = M.begin(), F_end = M.end(); F != F_end; ++F) {

		for (Function::arg_iterator A = F->arg_begin(), A_end = F->arg_end(); A != A_end; ++A) {
		
			//Search for variables referencing argv
			if (A->getName() == "argv") {
				
				//Iterate through uses of argv
				for (Value::use_iterator U = A->use_begin(), U_end = A->use_end(); U != U_end; ++U) {
					Instruction *User = dyn_cast<Instruction>(*U);
					
					StoreInst *SI = dyn_cast<StoreInst>(User);
					AllocaInst *OrigAlloca = dyn_cast<AllocaInst>(SI->getOperand(1));
					
					for (Value::use_iterator U2 = OrigAlloca->use_begin(), U2_end = OrigAlloca->use_end(); U2 != U2_end; ++U2) {
						Instruction *User2 = dyn_cast<Instruction>(*U2);

						for (Value::use_iterator U3 = User2->use_begin(), U3_end = OrigAlloca->use_end(); U3 != U3_end; ++U3) {
							searchForStoreInstruction(dyn_cast<Instruction>(*U3)->getParent(), argv);
						}
					}

				}
			}
			
		}

	}
   
	return true;
}
/*
 * 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;
}
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;
}
Exemple #4
0
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();
                }
            }
        }
    }
}
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);
}
Exemple #6
0
void IntrinsicLowering::AddPrototypes(Module &M) {
  LLVMContext &Context = M.getContext();
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (I->isDeclaration() && !I->use_empty())
      switch (I->getIntrinsicID()) {
      default: break;
      case Intrinsic::setjmp:
        EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(),
                             Type::getInt32Ty(M.getContext()));
        break;
      case Intrinsic::longjmp:
        EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(),
                             Type::getVoidTy(M.getContext()));
        break;
      case Intrinsic::siglongjmp:
        EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(),
                             Type::getVoidTy(M.getContext()));
        break;
      case Intrinsic::memcpy:
        M.getOrInsertFunction("memcpy",
          Type::getInt8PtrTy(Context),
                              Type::getInt8PtrTy(Context), 
                              Type::getInt8PtrTy(Context), 
                              DL.getIntPtrType(Context), nullptr);
        break;
      case Intrinsic::memmove:
        M.getOrInsertFunction("memmove",
          Type::getInt8PtrTy(Context),
                              Type::getInt8PtrTy(Context), 
                              Type::getInt8PtrTy(Context), 
                              DL.getIntPtrType(Context), nullptr);
        break;
      case Intrinsic::memset:
        M.getOrInsertFunction("memset",
          Type::getInt8PtrTy(Context),
                              Type::getInt8PtrTy(Context), 
                              Type::getInt32Ty(M.getContext()), 
                              DL.getIntPtrType(Context), nullptr);
        break;
      case Intrinsic::sqrt:
        EnsureFPIntrinsicsExist(M, I, "sqrtf", "sqrt", "sqrtl");
        break;
      case Intrinsic::sin:
        EnsureFPIntrinsicsExist(M, I, "sinf", "sin", "sinl");
        break;
      case Intrinsic::cos:
        EnsureFPIntrinsicsExist(M, I, "cosf", "cos", "cosl");
        break;
      case Intrinsic::pow:
        EnsureFPIntrinsicsExist(M, I, "powf", "pow", "powl");
        break;
      case Intrinsic::log:
        EnsureFPIntrinsicsExist(M, I, "logf", "log", "logl");
        break;
      case Intrinsic::log2:
        EnsureFPIntrinsicsExist(M, I, "log2f", "log2", "log2l");
        break;
      case Intrinsic::log10:
        EnsureFPIntrinsicsExist(M, I, "log10f", "log10", "log10l");
        break;
      case Intrinsic::exp:
        EnsureFPIntrinsicsExist(M, I, "expf", "exp", "expl");
        break;
      case Intrinsic::exp2:
        EnsureFPIntrinsicsExist(M, I, "exp2f", "exp2", "exp2l");
        break;
      }
}
Exemple #7
0
/*!
 *  This method identify which is value sym and which is object sym
 */
void SymbolTableInfo::buildMemModel(llvm::Module& module) {
    analysisUtil::increaseStackSize();

    prePassSchedule(module);

    mod = &module;

    maxFieldLimit = maxFieldNumLimit;

    // Object #0 is black hole the object that may point to any object
    assert(totalSymNum == BlackHole && "Something changed!");
    symTyMap.insert(std::make_pair(totalSymNum++, BlackHole));
    createBlkOrConstantObj(BlackHole);

    // Object #1 always represents the constant
    assert(totalSymNum == ConstantObj && "Something changed!");
    symTyMap.insert(std::make_pair(totalSymNum++, ConstantObj));
    createBlkOrConstantObj(ConstantObj);

    // Pointer #2 always represents the pointer points-to black hole.
    assert(totalSymNum == BlkPtr && "Something changed!");
    symTyMap.insert(std::make_pair(totalSymNum++, BlkPtr));

    // Pointer #3 always represents the null pointer.
    assert(totalSymNum == NullPtr && "Something changed!");
    symTyMap.insert(std::make_pair(totalSymNum, NullPtr));

    // Add symbols for all the globals .
    for (Module::global_iterator I = module.global_begin(), E =
                module.global_end(); I != E; ++I) {
        collectSym(&*I);
    }

    // Add symbols for all the global aliases
    for (Module::alias_iterator I = module.alias_begin(), E =
                module.alias_end(); I != E; I++) {
        collectSym(&*I);
    }

    // Add symbols for all of the functions and the instructions in them.
    for (Module::iterator F = module.begin(), E = module.end(); F != E; ++F) {
        collectSym(&*F);
        collectRet(&*F);
        if (F->getFunctionType()->isVarArg())
            collectVararg(&*F);

        // Add symbols for all formal parameters.
        for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
                I != E; ++I) {
            collectSym(&*I);
        }

        // collect and create symbols inside the function body
        for (inst_iterator II = inst_begin(&*F), E = inst_end(&*F); II != E; ++II) {
            const Instruction *inst = &*II;
            collectSym(inst);

            // initialization for some special instructions
            //{@
            if (const StoreInst *st = dyn_cast<StoreInst>(inst)) {
                collectSym(st->getPointerOperand());
                collectSym(st->getValueOperand());
            }

            else if (const LoadInst *ld = dyn_cast<LoadInst>(inst)) {
                collectSym(ld->getPointerOperand());
            }

            else if (const PHINode *phi = dyn_cast<PHINode>(inst)) {
                for (u32_t i = 0; i < phi->getNumIncomingValues(); ++i) {
                    collectSym(phi->getIncomingValue(i));
                }
            }

            else if (const GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(
                    inst)) {
                collectSym(gep->getPointerOperand());
            }

            else if (const SelectInst *sel = dyn_cast<SelectInst>(inst)) {
                collectSym(sel->getTrueValue());
                collectSym(sel->getFalseValue());
            }

            else if (const CastInst *cast = dyn_cast<CastInst>(inst)) {
                collectSym(cast->getOperand(0));
            }
            else if (const ReturnInst *ret = dyn_cast<ReturnInst>(inst)) {
                if(ret->getReturnValue())
                    collectSym(ret->getReturnValue());
            }
            else if (isCallSite(inst) && isInstrinsicDbgInst(inst)==false) {

                CallSite cs = analysisUtil::getLLVMCallSite(inst);
                callSiteSet.insert(cs);
                for (CallSite::arg_iterator it = cs.arg_begin();
                        it != cs.arg_end(); ++it) {
                    collectSym(*it);
                }
                // Calls to inline asm need to be added as well because the callee isn't
                // referenced anywhere else.
                const Value *Callee = cs.getCalledValue();
                collectSym(Callee);

                //TODO handle inlineAsm
                ///if (isa<InlineAsm>(Callee))

            }
            //@}
        }
    }
}
Exemple #8
0
bool
StdLibDataStructures::runOnModule (Module &M) {
  //
  // Get the results from the local pass.
  //
  init (&getAnalysis<LocalDataStructures>(), true, true, false, false);
  AllocWrappersAnalysis = &getAnalysis<AllocIdentify>();

  //
  // Fetch the DSGraphs for all defined functions within the module.
  //
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 
    if (!I->isDeclaration())
      getOrCreateGraph(&*I);

  //
  // Erase direct calls to functions that don't return a pointer and are marked
  // with the readnone annotation.
  //
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 
    if (I->isDeclaration() && I->doesNotAccessMemory() &&
        !isa<PointerType>(I->getReturnType()))
      eraseCallsTo(I);

  //
  // Erase direct calls to external functions that are not varargs, do not
  // return a pointer, and do not take pointers.
  //
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) 
    if (I->isDeclaration() && !I->isVarArg() &&
        !isa<PointerType>(I->getReturnType())) {
      bool hasPtr = false;
      for (Function::arg_iterator ii = I->arg_begin(), ee = I->arg_end();
           ii != ee;
           ++ii)
        if (isa<PointerType>(ii->getType())) {
          hasPtr = true;
          break;
        }
      if (!hasPtr)
        eraseCallsTo(I);
    }

  if(!DisableStdLib) {

    //
    // Scan through the function summaries and process functions by summary.
    //
    for (int x = 0; recFuncs[x].name; ++x) 
      if (Function* F = M.getFunction(recFuncs[x].name))
        if (F->isDeclaration()) {
          processFunction(x, F);
        }

    std::set<std::string>::iterator ai = AllocWrappersAnalysis->alloc_begin();
    std::set<std::string>::iterator ae = AllocWrappersAnalysis->alloc_end();
    int x;
    for (x = 0; recFuncs[x].name; ++x) {
      if(recFuncs[x].name == std::string("malloc"))
        break;
    }

    for(;ai != ae; ++ai) {
      if(Function* F = M.getFunction(*ai))
        processFunction(x, F);
    }

    ai = AllocWrappersAnalysis->dealloc_begin();
    ae = AllocWrappersAnalysis->dealloc_end();
    for (x = 0; recFuncs[x].name; ++x) {
      if(recFuncs[x].name == std::string("free"))
        break;
    }

    for(;ai != ae; ++ai) {
      if(Function* F = M.getFunction(*ai))
        processFunction(x, F);
    }

    //
    // Merge return values and checked pointer values for SAFECode run-time
    // checks.
    //
    processRuntimeCheck (M, "boundscheck", 2);
    processRuntimeCheck (M, "boundscheckui", 2);
    processRuntimeCheck (M, "exactcheck2", 1);

    processRuntimeCheck (M, "boundscheck_debug", 2);
    processRuntimeCheck (M, "boundscheckui_debug", 2);
    processRuntimeCheck (M, "exactcheck2_debug", 1);

    processRuntimeCheck (M, "pchk_getActualValue", 1);
  }

  //
  // In the Local DSA Pass, we marked nodes passed to/returned from 'StdLib'
  // functions as External because, at that point, they were.  However, they no
  // longer are necessarily External, and we need to update accordingly.
  //
  GlobalsGraph->maskIncompleteMarkers();

  GlobalsGraph->computeExternalFlags(DSGraph::ResetExternal);
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration()) {
      DSGraph * G = getDSGraph(*I);
      unsigned EFlags = 0
        | DSGraph::ResetExternal
        | DSGraph::DontMarkFormalsExternal
        | DSGraph::ProcessCallSites;
      G->maskIncompleteMarkers();
      G->markIncompleteNodes(DSGraph::MarkFormalArgs
                             |DSGraph::IgnoreGlobals);
      G->computeExternalFlags(EFlags);
      DEBUG(G->AssertGraphOK());
    }
  GlobalsGraph->markIncompleteNodes(DSGraph::MarkFormalArgs
                                    |DSGraph::IgnoreGlobals);
  GlobalsGraph->computeExternalFlags(DSGraph::ProcessCallSites);
  DEBUG(GlobalsGraph->AssertGraphOK());
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
    if (!I->isDeclaration()) {
      DSGraph *Graph = getOrCreateGraph(I);
      Graph->maskIncompleteMarkers();
      cloneGlobalsInto(Graph, DSGraph::DontCloneCallNodes |
                       DSGraph::DontCloneAuxCallNodes);
      Graph->markIncompleteNodes(DSGraph::MarkFormalArgs
                                 |DSGraph::IgnoreGlobals);
    }

  return false;
}