/// fixupLineNumbers - Update inlined instructions' line numbers to /// to encode location where these instructions are inlined. static void fixupLineNumbers(Function *Fn, Function::iterator FI, Instruction *TheCall) { DebugLoc TheCallDL = TheCall->getDebugLoc(); if (TheCallDL.isUnknown()) return; for (; FI != Fn->end(); ++FI) { for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI) { DebugLoc DL = BI->getDebugLoc(); if (!DL.isUnknown()) { BI->setDebugLoc(updateInlinedAtInfo(DL, TheCallDL, BI->getContext())); if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(BI)) { LLVMContext &Ctx = BI->getContext(); MDNode *InlinedAt = BI->getDebugLoc().getInlinedAt(Ctx); DVI->setOperand(2, createInlinedVariable(DVI->getVariable(), InlinedAt, Ctx)); } } } } }
/// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(Module &M) { if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) addCompileUnit(DICompileUnit(CU_Nodes->getOperand(i))); for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) for (Function::iterator FI = (*I).begin(), FE = (*I).end(); FI != FE; ++FI) for (BasicBlock::iterator BI = (*FI).begin(), BE = (*FI).end(); BI != BE; ++BI) { if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI)) processDeclare(DDI); DebugLoc Loc = BI->getDebugLoc(); if (Loc.isUnknown()) continue; LLVMContext &Ctx = BI->getContext(); DIDescriptor Scope(Loc.getScope(Ctx)); if (Scope.isCompileUnit()) addCompileUnit(DICompileUnit(Scope)); else if (Scope.isSubprogram()) processSubprogram(DISubprogram(Scope)); else if (Scope.isLexicalBlock()) processLexicalBlock(DILexicalBlock(Scope)); if (MDNode *IA = Loc.getInlinedAt(Ctx)) processLocation(DILocation(IA)); } if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.gv")) { for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { DIGlobalVariable DIG(cast<MDNode>(NMD->getOperand(i))); if (addGlobalVariable(DIG)) { if (DIG.getVersion() <= LLVMDebugVersion10) addCompileUnit(DIG.getCompileUnit()); processType(DIG.getType()); } } } if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) processSubprogram(DISubprogram(NMD->getOperand(i))); }
void Matcher::processInst(Function *F) { for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; FI++) { /** Get each instruction's scope information **/ for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; BI++) { DebugLoc Loc = BI->getDebugLoc(); if (Loc.isUnknown()) continue; LLVMContext & Ctx = BI->getContext(); DIDescriptor Scope(Loc.getScope(Ctx)); if (Scope.isLexicalBlock()) { DILexicalBlock DILB(Scope); errs() << "Block :" << DILB.getLineNumber() << ", " << DILB.getColumnNumber() << "\n"; } } } }
// bypassSlowDivision - This optimization identifies DIV instructions that can // be profitably bypassed and carried out with a shorter, faster divide. bool llvm::bypassSlowDivision(Function &F, Function::iterator &I, const DenseMap<unsigned int, unsigned int> &BypassWidths) { DivCacheTy DivCache; bool MadeChange = false; for (BasicBlock::iterator J = I->begin(); J != I->end(); J++) { // Get instruction details unsigned Opcode = J->getOpcode(); bool UseDivOp = Opcode == Instruction::SDiv || Opcode == Instruction::UDiv; bool UseRemOp = Opcode == Instruction::SRem || Opcode == Instruction::URem; bool UseSignedOp = Opcode == Instruction::SDiv || Opcode == Instruction::SRem; // Only optimize div or rem ops if (!UseDivOp && !UseRemOp) continue; // Skip division on vector types, only optimize integer instructions if (!J->getType()->isIntegerTy()) continue; // Get bitwidth of div/rem instruction IntegerType *T = cast<IntegerType>(J->getType()); unsigned int bitwidth = T->getBitWidth(); // Continue if bitwidth is not bypassed DenseMap<unsigned int, unsigned int>::const_iterator BI = BypassWidths.find(bitwidth); if (BI == BypassWidths.end()) continue; // Get type for div/rem instruction with bypass bitwidth IntegerType *BT = IntegerType::get(J->getContext(), BI->second); MadeChange |= reuseOrInsertFastDiv(F, I, J, BT, UseDivOp, UseSignedOp, DivCache); } return MadeChange; }
/// SimplifyDivRemOfSelect - Try to fold a divide or remainder of a select /// instruction. bool InstCombiner::SimplifyDivRemOfSelect(BinaryOperator &I) { SelectInst *SI = cast<SelectInst>(I.getOperand(1)); // div/rem X, (Cond ? 0 : Y) -> div/rem X, Y int NonNullOperand = -1; if (Constant *ST = dyn_cast<Constant>(SI->getOperand(1))) if (ST->isNullValue()) NonNullOperand = 2; // div/rem X, (Cond ? Y : 0) -> div/rem X, Y if (Constant *ST = dyn_cast<Constant>(SI->getOperand(2))) if (ST->isNullValue()) NonNullOperand = 1; if (NonNullOperand == -1) return false; Value *SelectCond = SI->getOperand(0); // Change the div/rem to use 'Y' instead of the select. I.setOperand(1, SI->getOperand(NonNullOperand)); // Okay, we know we replace the operand of the div/rem with 'Y' with no // problem. However, the select, or the condition of the select may have // multiple uses. Based on our knowledge that the operand must be non-zero, // propagate the known value for the select into other uses of it, and // propagate a known value of the condition into its other users. // If the select and condition only have a single use, don't bother with this, // early exit. if (SI->use_empty() && SelectCond->hasOneUse()) return true; // Scan the current block backward, looking for other uses of SI. BasicBlock::iterator BBI = &I, BBFront = I.getParent()->begin(); while (BBI != BBFront) { --BBI; // If we found a call to a function, we can't assume it will return, so // information from below it cannot be propagated above it. if (isa<CallInst>(BBI) && !isa<IntrinsicInst>(BBI)) break; // Replace uses of the select or its condition with the known values. for (Instruction::op_iterator I = BBI->op_begin(), E = BBI->op_end(); I != E; ++I) { if (*I == SI) { *I = SI->getOperand(NonNullOperand); Worklist.Add(BBI); } else if (*I == SelectCond) { *I = NonNullOperand == 1 ? ConstantInt::getTrue(BBI->getContext()) : ConstantInt::getFalse(BBI->getContext()); Worklist.Add(BBI); } } // If we past the instruction, quit looking for it. if (&*BBI == SI) SI = 0; if (&*BBI == SelectCond) SelectCond = 0; // If we ran out of things to eliminate, break out of the loop. if (SelectCond == 0 && SI == 0) break; } return true; }
bool ComputeSSO::runOnModule(Module &M) { //Get the timing information for the analysis..done using -time-passes // if (Input.getValue() == llvm::cl::BOU_UNSET || Input.getValue() // == llvm::cl::BOU_TRUE) { // errs()<<"---getting from InputValues--------------\n"; // InputValues &IV = getAnalysis<InputValues> (); // inputDepValues = IV.getInputDepValues(); // //TODO:need to add the function to get the target functions here // } else { errs()<<"---getting from InputDep--------------\n"; InputDep &IV = getAnalysis<InputDep> (); inputDepValues = IV.getInputDepValues(); targetFunctions = IV.getTargetFunctions(); targetBlocks = IV.getTargetBlock(); sourceTypes = IV.getSourceTypes(); ValLabelmap = IV.getValueLabelMap(); mediatorFunctions = IV.getMediators(); queryinputs = IV.getQueryVals(); // targetVal = IV.getTargetValue(); // PostDominatorTree &pdt = getAnalysis<PostDominatorTree>(); // DominatorTree &DT = getAnalysis<DominatorTree>(); // } blockAssign &bssa = getAnalysis<blockAssign> (); depGraph = bssa.newGraph; //DEBUG( // display dependence graph string Error; std::string tmp = M.getModuleIdentifier(); replace(tmp.begin(), tmp.end(), '\\', '_'); std::string Filename = "/tmp/" + tmp + ".dot"; //Print dependency graph (in dot format) depGraph->toDot(M.getModuleIdentifier(), "depGraphtest.dot"); // depGraph->toDotLines(M.getModuleIdentifier(), "depGraphtestlines.dot"); // sys::Path Filename_path(Filename); // llvm::DisplayGraph(Filename_path, true, GraphProgram::DOT); // ); int inputDepVal_count = 0; std::string appendVal ="a"; std::set<Value*> inputDepValuespart; set<Instruction*> LoopupInsts; set<Value*> SecSensitiveObjs; errs()<<"----------------------Taint Flow Analysis-----------------\n"; for(std::set<Value*>::iterator tv = inputDepValues.begin(); tv != inputDepValues.end(); ++tv) { int branches = 0; errs()<<**tv <<"\n"; //std::string appendVal = (**tv).getName(); inputDepValuespart.clear(); errs()<<"----------------------Input deps above-----------------\n"; //tainted = depGraph->getDepValues(inputDepValues); Value* currentTaintVal = *tv; std::string appendVal = ValLabelmap[currentTaintVal]; inputDepValuespart.insert(currentTaintVal); errs()<<"\n\nInputDep Values for "<<*currentTaintVal; tainted = depGraph->getDepValues(inputDepValuespart); //Graph * subGraph = depGraph->generateSubGraph(currentTaintVal,) //To print strings used with this taint... std::string ErrorInfo; bool writeStrings = true; string stringfileName = tmp+"_"+ appendVal + ".txt"; raw_fd_ostream FileS(stringfileName.c_str(), ErrorInfo,sys::fs::F_None); if (!ErrorInfo.empty()) { errs() << "Error opening file " << stringfileName << " for writing! Error Info: " << ErrorInfo << " \n"; writeStrings = false; } taintGraphMap[currentTaintVal] = tainted; // PrintTainted(tainted); errs()<<"\n---------------------\n"; //TODO: Memory error in the insert... verify and solve... std::set<GraphNode *>::iterator G; std::set<GraphNode *>::iterator endG; // for (G = tainted.begin(), endG = tainted.end(); G != endG; ++G) // { // // errs()<<" The tainted graph node : "<<(*G)->getName()<<"\n"; // } // errs()<<" \n \n"; //DEBUG( // If debug mode is enabled, add metadata to easily identify tainted values in the llvm IR for (Module::iterator F = M.begin(), endF = M.end(); F != endF; ++F) { for (Function::iterator BB = F->begin(), endBB = F->end(); BB != endBB; ++BB) { for (BasicBlock::iterator I = BB->begin(), endI = BB->end(); I != endI; ++I) { GraphNode* g = depGraph->findNode(I); if (tainted.count(g)) { g->taintSet.insert(appendVal); if (BranchInst *BI = dyn_cast<BranchInst>(I)) { // errs()<<"Branch Inst tainted : "; BI->dump(); branches++; } if(CallInst *CI = dyn_cast<CallInst>(I)) { Function* func = CI->getCalledFunction(); if(func && !func->isDeclaration()) { for(set<string>::iterator med = mediatorFunctions.begin(); med != mediatorFunctions.end();med++) { string medfunc = (*med); string funcName = func->getName(); if(strcmp(medfunc.c_str(),funcName.c_str())==0) { g->taintSet.erase(appendVal); errs()<<"\n+++++++++++ Med func : function name : "<<funcName; appendVal = appendVal+"_Med"; g->taintSet.insert(appendVal); } } } } //Print all the lookup instructions with tainted values..: if(GetElementPtrInst *GI = dyn_cast<GetElementPtrInst>(I)) { moduleDepGraph* mdG = new moduleDepGraph(); mdG->CheckifRelevantField(GI,depGraph); LoopupInsts.insert(I); Value* sensitiveObject = GI->getPointerOperand(); SecSensitiveObjs.insert(sensitiveObject); } //check if any operand is global string.. if(writeStrings) { for (unsigned int i = 0; i < cast<User> (I)->getNumOperands(); i++) { Value *v1 = cast<User> (I)->getOperand(i); if(isa<GlobalVariable> (v1)) { if(isa<Constant> (v1)) { //string sName = v1->getName() v1->print(FileS); (FileS) << "\n"; } } } } LLVMContext& C = I->getContext(); MDNode* N = MDNode::get(C, MDString::get(C, "ComputeSSO")); // char numstr[21]; // enough to hold all numbers up to 64-bits //sprintf(numstr, "%d", inputDepVal_count); //appendVal = () std::string taintVal = "TAINT_"+appendVal; // if(debug) errs()<<"\nFunction : "<< F->getName()<<" Tainted Val " << *I <<" val: " << appendVal; //For the given tainted Val try priniting all the uses of it. // errs()<<"\nUsed in :: "<<I->getNumUses(); // std::string taintVal = std::strcat("tainted",numstr); I->setMetadata(taintVal, N); } /* if (GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(&*I)) { // Dump the GEP instruction // gep->dump(); Value* firstOperand = gep->getOperand(0); Type* type = firstOperand->getType(); // Figure out whether the first operand points to an array if (PointerType *pointerType = dyn_cast<PointerType>(type)) { Type* elementType = pointerType->getElementType(); //errs() << "The element type is: " << *elementType << "\n"; if (elementType->isArrayTy()) { errs() << "\n .. points to an array!\n"; errs()<< "First op ..: "<< firstOperand <<" full def :"; gep->dump(); } else if(elementType->isStructTy ()) { errs() << "\n *** points to a Struct !\n"; errs()<< "First op ..: "<< firstOperand <<" full def :"; gep->dump(); } } } */ } } } //Print how many source types added //errs()<<"\nSource Types added :"<<sourceTypes.size(); inputDepVal_count++; //appendVal = appendVal+ 1; errs()<<"\n Branch Inst tainted : "<<branches; } //closing the loop for inputdepVal errs()<<"\n\n --- toal loookup instss.------: "<<LoopupInsts.size()<<"\n"; errs()<<"\n\n --- toal sensitve objects .------: "<<SecSensitiveObjs.size()<<"\n"; for(set<Value*>::iterator secVal = SecSensitiveObjs.begin(); secVal != SecSensitiveObjs.end();++secVal) { (*secVal)->dump(); } updateTaintLabels(); tainted = depGraph->getDepValues(inputDepValues); //Add taint labels in metadata: for (Module::iterator F = M.begin(), endF = M.end(); F != endF; ++F) { for (Function::iterator BB = F->begin(), endBB = F->end(); BB != endBB; ++BB) { for (BasicBlock::iterator I = BB->begin(), endI = BB->end(); I != endI; ++I) { GraphNode* g = depGraph->findNode(I); if (tainted.count(g)) { LLVMContext& C = I->getContext(); MDNode* N = MDNode::get(C, MDString::get(C, "ComputeSSO")); for(set<string>::iterator label = g->taintSet.begin();label!=g->taintSet.end();++label) { std::string taintVal = *label; I->setMetadata(taintVal, N); } } } } } // // M.dump(); // getSinkSourceBlockDependence(); // getSinkSourceDependence(); // getHookLocation(); //testProcessing(); // ); // HandleQueries(M); //errs()<<"\n\n\n\n********* Source Types ******************"; for(std::set<SourceType*>::iterator st = sourceTypes.begin(); st!=sourceTypes.end();++st) { (*st)->Print(); } //errs()<<"\n\n\n\n********* Derived Types ******************"; for(std::set<SourceType*>::iterator st = sourceTypesDerived.begin(); st!=sourceTypesDerived.end();++st) { (*st)->Print(); } return false; }