// // Method: typeFieldsOverlap() // // Description: // Determine if any of the type fields can overlap within the DSNode. // // Notes: // o) We take advantage of the fact that a std::map keeps its elements sorted // by key. // template<class dsa> bool TypeSafety<dsa>::typeFieldsOverlap (const DSNode * N) { // // There are no overlapping fields if the DSNode has no fields. // if (N->type_begin() == N->type_end()) return false; // // Iterate through the DSNode to see if the previous fields overlaps with the // current field. // DSNode::const_type_iterator tn = N->type_begin(); bool overlaps = false; while (!overlaps) { // // Get the information about the current field. // unsigned offset = tn->first; SuperSet<Type*>::setPtr TypeSet = tn->second; // // If there are multiple types in the current field, then the node is type-unsafe. // if (TypeSet) { svset<Type*>::const_iterator tb = TypeSet->begin(); if (++tb != TypeSet->end()) { overlaps = true; break; } } // // If this is the last field, then we are done searching. // if ((++tn) == N->type_end()) { break; } // // Get the offset of the next field. // unsigned next_offset = tn->first; // // Check to see if any of the types in the current field extend into the // next field. // if (TypeSet) { for (svset<Type*>::const_iterator ni = TypeSet->begin(), ne = TypeSet->end(); ni != ne; ++ni) { unsigned field_length = TD->getTypeStoreSize (*ni); if ((offset + field_length) > next_offset) { overlaps = true; if(TypeInferenceOptimize) { if(const ArrayType *AT = dyn_cast<ArrayType>(*ni)) { Type *ElemTy = AT->getElementType(); while(ArrayType *AT1 = dyn_cast<ArrayType>(ElemTy)) ElemTy = AT1->getElementType(); if(next_offset < (TD->getTypeStoreSize(ElemTy) + offset)) { assert(isa<StructType>(ElemTy) && "Array Not of Struct Type??"); overlaps = false; } } } if(overlaps) { DEBUG(errs() << " Found overlap at " << offset << " with " << next_offset << "\n"); break; } } } } } // // Return the result. // return overlaps; }
/* * Reduce this module with respect to the given interface. * - The interface suggests some of the uses of the functions, * so here we can generate special versions of those functions. * Generate a ComponentInterfaceTransform for clients to rewrite their * code to use the new API */ bool SpecializeComponent(Module& M, ComponentInterfaceTransform& T, SpecializationPolicy &policy, std::list<Function*>& to_add) { errs() << "SpecializeComponent()\n"; int rewrite_count = 0; const ComponentInterface& I = T.getInterface(); // TODO: What needs to be done? // - Should try to handle strings & arrays // Iterate through all functions in the interface of T for (ComponentInterface::FunctionIterator ff = I.begin(), fe = I.end(); ff != fe; ++ff) { StringRef name = ff->first(); Function* func = resolveFunction(M, name); if (func == NULL || func->isDeclaration()) { // We don't specialize declarations because we don't own them continue; } // Now iterate through all calls to func in the interface of T for (ComponentInterface::CallIterator cc = I.call_begin(name), ce = I.call_end(name); cc != ce; ++cc) { const CallInfo* const call = *cc; const unsigned arg_count = call->args.size(); if (func->isVarArg()) { // TODO: I don't know how to specialize variable argument functions yet continue; } if (arg_count != func->getArgumentList().size()) { // Not referring to this function? // NOTE: I can't assert this equality because of the way that approximations occur continue; } /* should we specialize? if yes then each bit in slice will indicate whether the argument is a specializable constant */ SmallBitVector slice(arg_count); bool shouldSpecialize = policy.specializeOn(func, call->args.begin(), call->args.end(), slice); if (!shouldSpecialize) continue; std::vector<Value*> args; std::vector<unsigned> argPerm; args.reserve(arg_count); argPerm.reserve(slice.count()); for (unsigned i = 0; i < arg_count; i++) { if (slice.test(i)) { Type * paramType = func->getFunctionType()->getParamType(i); Value *concreteArg = call->args[i].concretize(M, paramType); args.push_back(concreteArg); assert(concreteArg->getType() == paramType && "Specializing function with concrete argument of wrong type!"); } else { args.push_back(NULL); argPerm.push_back(i); } } /* args is a list of pointers to values -- if the pointer is NULL then that argument is not specialized -- if the pointer is not NULL then the argument will be/has been specialized to that value argsPerm is a list on integers; the indices of the non-special arguments args[i] = NULL iff i is in argsPerm for i < arg_count. */ Function* nfunc = specializeFunction(func, args); nfunc->setLinkage(GlobalValue::ExternalLinkage); FunctionHandle rewriteTo = nfunc->getName(); T.rewrite(name, call, rewriteTo, argPerm); to_add.push_back(nfunc); errs() << "Specialized " << name << " to " << rewriteTo << "\n"; #if 0 for (unsigned i = 0; i < arg_count; i++) { errs() << "i = " << i << ": slice[i] = " << slice[i] << " args[i] = " << args.at(i) << "\n"; } errs() << " argPerm = ["; for (unsigned i = 0; i < argPerm.size(); i++) { errs() << argPerm.at(i) << " "; } errs() << "]\n"; #endif rewrite_count++; } } if (rewrite_count > 0) { errs() << rewrite_count << " pending rewrites\n"; } return rewrite_count > 0; }
inline void enqueue(Q& queue, QE e) { DSE_LOG(errs() << "\tEnqueued " << e << "\n"); queue.push_back(e); }
int TableGenMain(char *argv0, TableGenAction &Action) { RecordKeeper Records; try { // Parse the input file. OwningPtr<MemoryBuffer> File; if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), File)) { errs() << "Could not open input file '" << InputFilename << "': " << ec.message() <<"\n"; return 1; } MemoryBuffer *F = File.take(); // Tell SrcMgr about this buffer, which is what TGParser will pick up. SrcMgr.AddNewSourceBuffer(F, SMLoc()); // Record the location of the include directory so that the lexer can find // it later. SrcMgr.setIncludeDirs(IncludeDirs); TGParser Parser(SrcMgr, Records); if (Parser.ParseFile()) return 1; std::string Error; tool_output_file Out(OutputFilename.c_str(), Error); if (!Error.empty()) { errs() << argv0 << ": error opening " << OutputFilename << ":" << Error << "\n"; return 1; } if (!DependFilename.empty()) { if (OutputFilename == "-") { errs() << argv0 << ": the option -d must be used together with -o\n"; return 1; } tool_output_file DepOut(DependFilename.c_str(), Error); if (!Error.empty()) { errs() << argv0 << ": error opening " << DependFilename << ":" << Error << "\n"; return 1; } DepOut.os() << OutputFilename << ":"; const std::vector<std::string> &Dependencies = Parser.getDependencies(); for (std::vector<std::string>::const_iterator I = Dependencies.begin(), E = Dependencies.end(); I != E; ++I) { DepOut.os() << " " << (*I); } DepOut.os() << "\n"; DepOut.keep(); } if (Action(Out.os(), Records)) return 1; // Declare success. Out.keep(); return 0; } catch (const TGError &Error) { PrintError(Error); } catch (const std::string &Error) { PrintError(Error); } catch (const char *Error) { PrintError(Error); } catch (...) { errs() << argv0 << ": Unknown unexpected exception occurred.\n"; } return 1; }
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); }
template <> void dumpSet(const BlockSet &toDump) { for (auto element : toDump) errs() << element->getName() << " "; errs() << "\n"; }
// Template specialization for BasicBlock. template <> void dumpVector(const BlockVector &toDump) { errs() << "Size: " << toDump.size() << "\n"; for (auto element : toDump) errs() << element->getName() << " -- "; errs() << "\n"; }
static bool fillRanges(MemoryBuffer *Code, std::vector<tooling::Range> &Ranges) { IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem( new vfs::InMemoryFileSystem); FileManager Files(FileSystemOptions(), InMemoryFileSystem); DiagnosticsEngine Diagnostics( IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), new DiagnosticOptions); SourceManager Sources(Diagnostics, Files); FileID ID = createInMemoryFile("<irrelevant>", Code, Sources, Files, InMemoryFileSystem.get()); if (!LineRanges.empty()) { if (!Offsets.empty() || !Lengths.empty()) { errs() << "error: cannot use -lines with -offset/-length\n"; return true; } for (unsigned i = 0, e = LineRanges.size(); i < e; ++i) { unsigned FromLine, ToLine; if (parseLineRange(LineRanges[i], FromLine, ToLine)) { errs() << "error: invalid <start line>:<end line> pair\n"; return true; } if (FromLine > ToLine) { errs() << "error: start line should be less than end line\n"; return true; } SourceLocation Start = Sources.translateLineCol(ID, FromLine, 1); SourceLocation End = Sources.translateLineCol(ID, ToLine, UINT_MAX); if (Start.isInvalid() || End.isInvalid()) return true; unsigned Offset = Sources.getFileOffset(Start); unsigned Length = Sources.getFileOffset(End) - Offset; Ranges.push_back(tooling::Range(Offset, Length)); } return false; } if (Offsets.empty()) Offsets.push_back(0); if (Offsets.size() != Lengths.size() && !(Offsets.size() == 1 && Lengths.empty())) { errs() << "error: number of -offset and -length arguments must match.\n"; return true; } for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { if (Offsets[i] >= Code->getBufferSize()) { errs() << "error: offset " << Offsets[i] << " is outside the file\n"; return true; } SourceLocation Start = Sources.getLocForStartOfFile(ID).getLocWithOffset(Offsets[i]); SourceLocation End; if (i < Lengths.size()) { if (Offsets[i] + Lengths[i] > Code->getBufferSize()) { errs() << "error: invalid length " << Lengths[i] << ", offset + length (" << Offsets[i] + Lengths[i] << ") is outside the file.\n"; return true; } End = Start.getLocWithOffset(Lengths[i]); } else { End = Sources.getLocForEndOfFile(ID); } unsigned Offset = Sources.getFileOffset(Start); unsigned Length = Sources.getFileOffset(End) - Offset; Ranges.push_back(tooling::Range(Offset, Length)); } return false; }
// Returns true on error. static bool format(StringRef FileName) { ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr = MemoryBuffer::getFileOrSTDIN(FileName); if (std::error_code EC = CodeOrErr.getError()) { errs() << EC.message() << "\n"; return true; } std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get()); if (Code->getBufferSize() == 0) return false; // Empty files are formatted correctly. std::vector<tooling::Range> Ranges; if (fillRanges(Code.get(), Ranges)) return true; StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName; FormatStyle FormatStyle = getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer()); if (SortIncludes.getNumOccurrences() != 0) FormatStyle.SortIncludes = SortIncludes; unsigned CursorPosition = Cursor; Replacements Replaces = sortIncludes(FormatStyle, Code->getBuffer(), Ranges, AssumedFileName, &CursorPosition); auto ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces); if (!ChangedCode) { llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n"; return true; } // Get new affected ranges after sorting `#includes`. Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); bool IncompleteFormat = false; Replacements FormatChanges = reformat(FormatStyle, *ChangedCode, Ranges, AssumedFileName, &IncompleteFormat); Replaces = Replaces.merge(FormatChanges); if (OutputXML) { outs() << "<?xml version='1.0'?>\n<replacements " "xml:space='preserve' incomplete_format='" << (IncompleteFormat ? "true" : "false") << "'>\n"; if (Cursor.getNumOccurrences() != 0) outs() << "<cursor>" << FormatChanges.getShiftedCodePosition(CursorPosition) << "</cursor>\n"; outputReplacementsXML(Replaces); outs() << "</replacements>\n"; } else { IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem( new vfs::InMemoryFileSystem); FileManager Files(FileSystemOptions(), InMemoryFileSystem); DiagnosticsEngine Diagnostics( IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), new DiagnosticOptions); SourceManager Sources(Diagnostics, Files); FileID ID = createInMemoryFile(AssumedFileName, Code.get(), Sources, Files, InMemoryFileSystem.get()); Rewriter Rewrite(Sources, LangOptions()); tooling::applyAllReplacements(Replaces, Rewrite); if (Inplace) { if (FileName == "-") errs() << "error: cannot use -i when reading from stdin.\n"; else if (Rewrite.overwriteChangedFiles()) return true; } else { if (Cursor.getNumOccurrences() != 0) outs() << "{ \"Cursor\": " << FormatChanges.getShiftedCodePosition(CursorPosition) << ", \"IncompleteFormat\": " << (IncompleteFormat ? "true" : "false") << " }\n"; Rewrite.getEditBuffer(ID).write(outs()); } } return false; }
void ComputeSSO::PrintTainted(std::set<GraphNode*> tainted) { // errs()<<"\n\n Tainted Nodes: "<<tainted.size(); for(set<GraphNode*>::iterator taintNode = tainted.begin();taintNode != tainted.end();++taintNode) { //errs()<<"\n Node Label : "<<(*taintNode)->getLabel(); // errs()<<"--"; if(isa<MemNode>(*taintNode)) { // errs()<<"\n is mem node"; //string nodeLab = (*taintNode)->getLabel(); // string str = "sub_42BC4"; // std::size_t found = nodeLab.find(str); // if (found!=std::string::npos || 1) { MemNode * memNew = dyn_cast<MemNode>(*taintNode); Value * val = memNew->defLocation.second; std::set<Value*> aliases = memNew->getAliases(); if(val) { errs()<<"\n Sink Node Tainted : "<<(*taintNode)->getLabel(); if(isa<Instruction>(val)) { Instruction * inst = dyn_cast<Instruction>(val); string funcName = inst->getParent()->getParent()->getName(); errs()<<"\n Function: "<<funcName; } val->dump(); } if(aliases.size()>0) errs()<<"\n Sink Node Tainted : "<<(*taintNode)->getLabel(); for(set<Value*>::iterator alVal = aliases.begin(); alVal != aliases.end();++alVal) { if(isa<Instruction>(*alVal)) { Instruction * inst = dyn_cast<Instruction>(*alVal); string funcName = inst->getParent()->getParent()->getName(); errs()<<"\n Function: "<<funcName; } (*alVal)->dump(); } } } if(isa<VarNode>(*taintNode)) { VarNode * varNew = dyn_cast<VarNode>(*taintNode); Value * val = varNew->getValue(); //->defLocation.second; if(val) { errs()<<"\n Sink Node Tainted : "<<(*taintNode)->getLabel(); if(isa<Instruction>(val)) { Instruction * inst = dyn_cast<Instruction>(val); string funcName = inst->getParent()->getParent()->getName(); errs()<<"\n Function: "<<funcName; } val->dump(); } } //if } }
/// dbgs - Return errs(). raw_ostream &dbgs() { return errs(); }
void ComputeSSO::HandleQueries(Module& M) { for(set<QueryInput*>::iterator qit = queryinputs.begin();qit!=queryinputs.end();++qit) { bool constCheck; errs()<<"\n\n\n\n*******************************************************Query "; errs()<<"\nOperation : "<<(*qit)->operation; errs()<<"\nConstCheck : "<<(*qit)->constcheck; string operation = (*qit)->operation; set<string> labels = (*qit)->labels; set<Value*> vals = (*qit)->labVals; std::set<GraphNode*> taintedA; std::set<GraphNode*> taintedB; std::set<GraphNode*> intersectGraph; for(set<string>::iterator label = labels.begin();label != labels.end();++label) errs()<<" - "<<*label; errs()<<"\n*******************************************************\n "; constCheck = (*qit)->constcheck; if(constCheck) { for(set<Value*>::iterator val = vals.begin();val != vals.end();++val) { taintedA = taintGraphMap[*val]; } intersectGraph = taintedA; } else { for(set<Value*>::iterator val = vals.begin();val != vals.end();++val) { taintedA = taintGraphMap[*val]; ++val; if(val!=vals.end()) taintedB = taintGraphMap[*val]; } if(strcmp(operation.c_str(),"intersect")==0) { // intersectGraph = getIntersect(taintedA,taintedB); for(set<GraphNode*>::iterator gnode = taintedA.begin();gnode != taintedA.end();++gnode) { if(taintedB.count(*gnode) > 0) { GraphNode* interNode = (*gnode)->clone(); intersectGraph.insert(interNode); } } } } int branches =0; errs()<<"\n Intersect graph size :"<<intersectGraph.size(); //print intersect graph nodes: // PrintTainted(intersectGraph); // for(set<GraphNode*>::iterator gnode = intersectGraph.begin();gnode != intersectGraph.end();++gnode) // { // errs()<<"\n Node: "<<(*gnode)->getLabel(); // } //Print appropriate vals....: for (Module::iterator F = M.begin(), endF = M.end(); F != endF; ++F) { string funcName = F->getName(); // errs()<<"\nTaints in function: "<<funcName; for (Function::iterator BB = F->begin(), endBB = F->end(); BB != endBB; ++BB) { string bbName ="noName"; if(BB->hasName()) { bbName = BB->getName(); } // errs()<<" - block: "<<bbName; for (BasicBlock::iterator I = BB->begin(), endI = BB->end(); I != endI; ++I) { GraphNode* g = depGraph->findNode(I); if (intersectGraph.count(g)) { errs()<<"\n Node found..:"; I->dump(); errs()<<"Taint in function : "<<funcName<<" :"; I->dump(); if (BranchInst *BI = dyn_cast<BranchInst>(I)) { if(constCheck) { Value* conditional = BI->getCondition(); for (unsigned int i = 0; i < cast<User> (conditional)->getNumOperands(); i++) { Value *v1 = cast<User> (conditional)->getOperand(i); if(isa<ConstantInt>(v1)) { errs()<<"Branch Inst tainted in func : "<<funcName<<" :"; BI->dump(); branches++; } } } else { // BI->getCondition()->dump(); errs()<<"Branch Inst tainted : "; BI->dump(); branches++; } } } } } } errs()<<"\n Number of conditionals tainted : " <<branches; } errs()<<"\n*******************************************************\n "; }
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; }
bool RaceDetector::runOnModule(Module &M) { ShareAnalysis& sa = getAnalysis<ShareAnalysis>(); LockDomAnalysis& lda = getAnalysis<LockDomAnalysis>(); FlowtoAnalysis& fta = getAnalysis<FlowtoAnalysis>(); for (auto pr : sa.sharingLocation) { Value *placep = pr.first; auto instList = pr.second; std::set<Value*> lockset; lockset.insert(NULL); // universal set for (auto instp : instList) { Function* funcp = instp->getParent()->getParent(); std::vector<CallSite*> csList = getCallSiteList(funcp, M); for (auto csp : csList) { // if (csp != NULL) { // errs() << "[RD] CallSite from " << csp->getInstruction()->getParent()->getParent()->getName(); // errs() << " to " << funcp->getName() << "\n"; // } else { // errs() << "[RD] Entry point of main\n"; // } // first check if the current context will access the place Value *pp = NULL; if (isa<LoadInst>(instp)) { LoadInst* loadp = cast<LoadInst>(instp); pp = loadp->getPointerOperand(); } else { StoreInst* storep = cast<StoreInst>(instp); pp = storep->getPointerOperand(); } PTNode* node = fta.c2g[csp]->findValue(pp); // skip this context if the instruction will not access the place if (std::find_if(node->next.begin(), node->next.end(), [&](const PTNode* x)->bool { return x->getValue() == placep && x->isLocation(); }) == node->next.end()) continue; auto idom = lda.analyzeCallSite(csp, M); auto it = idom.find(instp); if (it == idom.end()) { errs() << "[RD] inst: " << *instp << "\nidom:\n"; for (auto pr: idom) { errs() << *pr.first << "\n"; } } assert(it != idom.end() && "inst should be found in idom map"); int oldsize = lockset.size(); lockset = intersection(lockset, it->second); if (oldsize != 0 && lockset.size() == 0) { errs() << "[RD] oops, please check " << *instp << "in func "; errs() << instp->getParent()->getParent()->getName() << "\n"; } } } if (lockset.size() == 0) { errs() << "[RD] value " << *placep << " may be accessed without proper lock\n"; errs() << "[RD] Check for the following instruciton: \n"; for (auto instp : instList) errs() << "[RD]" << *instp << "in func " << instp->getParent()->getParent()->getName() << "\n"; errs() << "\n"; } } return false; }
void DebugMap::dump() const { print(errs()); }
std::vector<FlowRecord> NoFlows::process(const ContextID ctxt, const ImmutableCallSite cs) const { DEBUG(errs() << "Using no flows signature...\n"); return std::vector<FlowRecord>(); }
//------------------------------------------------------------------------------ void dumpV2V(const V2VMap &map) { errs() << "==== Map ====\n"; for (auto iter : map) errs() << iter.first->getName() << " -> " << iter.second->getName() << "\n"; errs() << "=============\n"; }
BlockFlow::BlockFlow(BasicBlock *b, std::vector<BoundsCheck*> *chks, ConstraintGraph *graph, std::map<BasicBlock*,BlockFlow*> *f) { blk = b; flows = f; checks = chks; cg = graph; numInsts = 0; isEntry = false; outSet.allChecks = true; killAll = false; killAllLoc = 0; for (BasicBlock::iterator i = blk->begin(), e = blk->end(); i != e; ++i) { Instruction *inst = &*i; numInsts++; instructions.push_back(inst); instLoc[&*i] = numInsts; StoreInst *SI = dyn_cast<StoreInst>(inst); if (isa<CallInst>(inst)) { killAll = true; killAllLoc = numInsts; } if (SI != NULL) { storeSet.insert(SI->getPointerOperand()); Value *to = SI->getPointerOperand(); Type* T = to->getType(); bool isPointer = T->isPointerTy() && T->getContainedType(0)->isPointerTy(); if (isPointer) { killAll = true; killAllLoc = numInsts; } lastStoreLoc[to] = numInsts; } } #if DEBUG_GLOBAL errs() << "Identifying Downward Exposed Bounds Checks:" << blk->getName() << "\n"; #endif for (std::vector<BoundsCheck*>::iterator it = checks->begin(), et = checks->end(); it != et; it++) { BoundsCheck *chk = *it; if (!chk->stillExists()) continue; // May require fixing later? unsigned int loc = instLoc[chk->getInsertPoint()]; Value *var = chk->getVariable(); if (var == NULL) { var = chk->getIndex(); if (var == NULL) { errs() << "Could not identify index value for following check:\n"; chk->print(); continue; } } /** bool downwardExposed = true; // Find downward exposed checks // Inefficient, basically go through the remaining instructions // and see if there is a store to the same location for (unsigned int i = loc; i <= numInsts; i++) { Instruction *inst = instructions.at(i-1); StoreInst *SI = dyn_cast<StoreInst>(inst); if (isa<CallInst>(inst)) { downwardExposed = false; #if DEBUG_GLOBAL errs() << "Following Check is not downward exposed\n"; chk->print(); #endif break; } if (SI != NULL) { if (var == SI->getPointerOperand()) { downwardExposed = false; #if DEBUG_GLOBAL errs() << "Following Check is not downward exposed\n"; chk->print(); #endif break; } else { Value *to = SI->getPointerOperand(); Type* T = to->getType(); bool isPointer = T->isPointerTy() && T->getContainedType(0)->isPointerTy(); if (isPointer) { downwardExposed = false; #if DEBUG_GLOBAL errs() << "Following Check is not downward exposed\n"; chk->print(); #endif break; } } } } if (!downwardExposed) continue; **/ if (loc < killAllLoc) { continue; } bool blkHasStore = false; if (lastStoreLoc.find(var) != lastStoreLoc.end()) { blkHasStore = true; } GlobalCheck *gCheck; // Insert lower bounds check if downward exposed, and index <= to variable it references if (chk->hasLowerBoundsCheck()){ if (chk->comparisonKnown && chk->comparedToVar <= 0) { bool add = true; ConstraintGraph::CompareEnum varChange = cg->identifyMemoryChange(var); // Check if there is a store instruction after the check if (blkHasStore && (lastStoreLoc[var] > loc)) { // If index variable becomes smaller across basic block, can't add lower bounds check if (varChange == ConstraintGraph::LESS_THAN || varChange == ConstraintGraph::UNKNOWN) { add = false; } } for (std::vector<GlobalCheck*>::iterator gi = globalChecks.begin(), ge = globalChecks.end(); gi != ge; gi++) { GlobalCheck *c = *gi; if (!c->isUpper && (c->var == var)) { add = false; } } if (add) { #if DEBUG_GLOBAL errs() << "==============================" << "\n"; errs() << "Adding Lower-Bound Check to GEN set:\n"; chk->print(); #endif gCheck = new GlobalCheck(chk, var, NULL, false, loc); globalChecks.push_back(gCheck); } } } // Insert upper bounds check if downward exposed, and index >= variable it references if (chk->hasUpperBoundsCheck()){ if (chk->comparisonKnown && chk->comparedToVar >= 0) { bool add = true; ConstraintGraph::CompareEnum varChange = cg->identifyMemoryChange(var); // Check if there is a store instruction after the check if (blkHasStore && (lastStoreLoc[var] > loc)) { // If index variable becomes bigger across basic block, can't add upper bounds check if (varChange == ConstraintGraph::GREATER_THAN || varChange == ConstraintGraph::UNKNOWN) { add = false; } } for (std::vector<GlobalCheck*>::iterator gi = globalChecks.begin(), ge = globalChecks.end(); gi != ge; gi++) { GlobalCheck *c = *gi; if (c->isUpper && (c->var == var)) { add = false; } } if (add) { #if DEBUG_GLOBAL errs() << "==============================" << "\n"; errs() << "Adding Exposed Upper-Bound Check to GEN set:\n"; chk->print(); #endif gCheck = new GlobalCheck(chk, var, chk->getUpperBound(), true, loc); globalChecks.push_back(gCheck); } } } } }
//------------------------------------------------------------------------------ template <class type> void dumpVector(const std::vector<type *> &toDump) { errs() << "Size: " << toDump.size() << "\n"; for (auto element : toDump) element->dump(); }
void BlockFlow::identifyInSet() { #if DEBUG_GLOBAL errs() << "Generating In-Set: " << blk->getName() << "\n"; #endif inSet.checks.clear(); std::vector<GlobalCheck*> inChecks; bool foundChecks = false; for (pred_iterator PI = pred_begin(blk), E = pred_end(blk); PI != E; ++PI) { BasicBlock *pred = *PI; BlockFlow *pred_flow = (*flows)[pred]; if (!pred_flow->outSet.allChecks) { #if DEBUG_GLOBAL errs() << "Adding checks from predecessor: " << pred->getName() << "\n"; #endif foundChecks = true; for (std::vector<GlobalCheck*>::iterator i = pred_flow->outSet.checks.begin(), e = pred_flow->outSet.checks.end(); i != e; i++) { inChecks.push_back(*i); } break; } } if (inChecks.empty() && foundChecks) { inSet.allChecks = false; return; } else if (inChecks.empty()) { inSet.allChecks = true; return; } inSet.allChecks = false; for (std::vector<GlobalCheck*>::iterator i = inChecks.begin(), e = inChecks.end(); i != e; i++) { GlobalCheck* chk = *i; bool existsInAllPreds = true; for (pred_iterator PI = pred_begin(blk), E = pred_end(blk); PI != E; ++PI) { BasicBlock *pred = *PI; BlockFlow *pred_flow = (*flows)[pred]; bool found = false; if (!pred_flow->outSet.allChecks) { for (std::vector<GlobalCheck*>::iterator pred_i = pred_flow->outSet.checks.begin(), pred_e = pred_flow->outSet.checks.end(); pred_i != pred_e; pred_i++) { GlobalCheck *predCheck = *pred_i; ConstantInt *const1 = dyn_cast<ConstantInt>(chk->var); ConstantInt *const2 = dyn_cast<ConstantInt>(predCheck->var); if (chk->isUpper && predCheck->isUpper) { // Both upper bounds checks if (const1 != NULL && const2 != NULL) { // If both constants, replace with the less strict version if (const1->getSExtValue() > const2->getSExtValue()) { chk = predCheck; } found = true; break; } else if (const1 == NULL && const2 == NULL) { if (chk->var == predCheck->var) { ConstantInt *bound1 = dyn_cast<ConstantInt>(chk->bound); ConstantInt *bound2 = dyn_cast<ConstantInt>(predCheck->bound); if (bound1 != NULL && bound2 != NULL) { if (bound1->getZExtValue() < bound2->getZExtValue()) { // Replace with larger upper bound chk = predCheck; } found = true; break; } else if (bound1 == NULL && bound2 == NULL) { if (bound1 == bound2) { found = true; break; } } } } } else if (!chk->isUpper && !predCheck->isUpper) { // Both lower bounds checks if (const1 != NULL && const2 != NULL) { // If both constants, replace with the less strict version if (const1->getSExtValue() < const2->getSExtValue()) { chk = predCheck; } found = true; break; } else if (const1 == NULL && const2 == NULL) { if (chk->var == predCheck->var) { found = true; break; } } } } } else { found = true; } if (!found) { existsInAllPreds = false; break; } } // If we found the check in all predecessors if (existsInAllPreds) { inSet.addCheck(chk); } } }
void dumpIntVector(const std::vector<int> &toDump) { for (auto element : toDump) { errs() << element << ", "; } }
bool BlockFlow::identifyOutSet() { bool MadeChange = false; std::vector<GlobalCheck*> outChecks; if (!isEntry && !killAll) { identifyInSet(); #if DEBUG_GLOBAL errs() << "Generating Out-Set: " << blk->getName() << "\n"; #endif // Identify checks from inSet that should be killed for (std::vector<GlobalCheck*>::iterator i = inSet.checks.begin(), e = inSet.checks.end(); i != e; i++) { // For each global check, see if it survives past block, or if we can tell how variable changes GlobalCheck *chk = *i; std::set<Value*>::iterator it = storeSet.find(chk->var); if (it == storeSet.end()) { outChecks.push_back(chk); } else { ConstraintGraph::CompareEnum change = cg->identifyMemoryChange(chk->var); if (chk->isUpper) { // Upper-bound check switch (change) { case ConstraintGraph::EQUALS: case ConstraintGraph::LESS_THAN: outChecks.push_back(chk); break; default: break; } } else { // Lower-bound check switch (change) { case ConstraintGraph::EQUALS: case ConstraintGraph::GREATER_THAN: outChecks.push_back(chk); break; default: break; } } } } } #if DEBUG_GLOBAL else { errs() << "Generating Out-Set: " << blk->getName() << "\n"; } #endif // Just identify checks that are live at the end of set for (std::vector<GlobalCheck*>::iterator i = globalChecks.begin(), e = globalChecks.end(); i != e; i++) { GlobalCheck *chk = *i; bool add = true; for (unsigned int o = 0; o < outChecks.size(); o++) { GlobalCheck *oCheck = outChecks.at(o); ConstantInt *const1 = dyn_cast<ConstantInt>(chk->var); ConstantInt *const2 = dyn_cast<ConstantInt>(oCheck->var); if (chk->isUpper && oCheck->isUpper) { // Both upper bounds checks if (const1 != NULL && const2 != NULL) { // If both constants, replace with the more strict version if (const1->getSExtValue() > const2->getSExtValue()) { outChecks.at(o) = chk; } add = false; break; } else if (const1 == NULL && const2 == NULL) { if (chk->var == oCheck->var) { ConstantInt *bound1 = dyn_cast<ConstantInt>(chk->bound); ConstantInt *bound2 = dyn_cast<ConstantInt>(oCheck->bound); if (bound1 != NULL && bound2 != NULL) { if (bound1->getZExtValue() < bound2->getZExtValue()) { outChecks.at(o) = chk; } add = false; break; } else if (bound1 == NULL && bound2 == NULL) { if (bound1 == bound2) { add = false; break; } } } } } else if (!chk->isUpper && !oCheck->isUpper) { // Both lower bounds checks if (const1 != NULL && const2 != NULL) { // If both constants, replace with the more strict version if (const1->getSExtValue() < const2->getSExtValue()) { outChecks.at(o) = chk; } add = false; break; } else if (const1 == NULL && const2 == NULL) { if (chk->var == oCheck->var) { add = false; break; } } } } if (add) { outChecks.push_back(chk); } } if (isEntry && outChecks.empty()) { outSet.allChecks = false; return true; } if (outChecks.empty()) { if (inSet.allChecks) { bool oldState = outSet.allChecks; outSet.checks.clear(); outSet.allChecks = true; return oldState != true; } else { outSet.allChecks = false; if (outSet.checks.empty()) { return false; } else { outSet.checks.clear(); return true; } } } for (std::vector<GlobalCheck*>::iterator i = outChecks.begin(), e = outChecks.end(); i != e; i++) { #if DEBUG_GLOBAL errs() << "Adding Check to Out Set:\n"; (*i)->print(); #endif MadeChange |= outSet.addAvailableCheck(*i); } return MadeChange; }
InChain = CopyFromHi.getValue(1); InGlue = CopyFromHi.getValue(2); } CurDAG->RemoveDeadNode(N); // We need to clear R1. This is currently done (dirtily) // using a custom inserter. return true; } void AVRDAGToDAGISel::Select(SDNode *N) { // Dump information about the Node being selected DEBUG(errs() << "Selecting: "; N->dump(CurDAG); errs() << "\n"); // If we have a custom node, we already have selected! if (N->isMachineOpcode()) { DEBUG(errs() << "== "; N->dump(CurDAG); errs() << "\n"); N->setNodeId(-1); return; } // See if subclasses can handle this node. if (trySelect(N)) return; // Select the default instruction SelectCode(N); }
void BlockFlow::print() { errs() << "==============================" << "\n"; errs() << "Basic Block: " << blk->getName() << "\n"; errs() << "In Set: "; if (inSet.checks.empty()) { errs() << "EMPTY" << "\n"; } else { for (std::vector<GlobalCheck*>::iterator i = inSet.checks.begin(), e = inSet.checks.end(); i != e; i++) { GlobalCheck *chk = *i; if (chk->isUpper) { errs() << "(" << chk->var->getName() << "< " << *(chk->bound) << ") "; } else { errs() << "(0 < " << chk->var->getName() << ") "; } } errs() << "\n"; } errs() << "Out Set: "; if (outSet.checks.empty()) { if (outSet.allChecks) { errs() << "ALL CHECKS" << "\n"; } else { errs() << "EMPTY" << "\n"; } } else { for (std::vector<GlobalCheck*>::iterator i = outSet.checks.begin(), e = outSet.checks.end(); i != e; i++) { GlobalCheck *chk = *i; if (chk->isUpper) { errs() << "(" << chk->var->getName() << " < " << *(chk->bound) << ") "; } else { errs() << "(0 < " << chk->var->getName() << ") "; } } errs() << "\n"; } }
LLVM_ATTRIBUTE_NORETURN void reportError(Twine Msg) { errs() << "\nError reading file: " << Msg << ".\n"; errs().flush(); exit(1); }
static bool error(error_code ec) { if (!ec) return false; errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n"; return true; }
/* * Remove all code from the given module that is not necessary to * implement the given interface. */ bool MinimizeComponent(Module& M, const ComponentInterface& I) { errs() << "InternalizePass::runOnModule: " << M.getModuleIdentifier() << "\n"; bool modified = false; int hidden = 0; int internalized = 0; std::set<std::string> keep_external; if (KeepExternalFile != "") { std::ifstream infile(KeepExternalFile); if (infile.is_open()) { std::string line; while (std::getline(infile, line)) { keep_external.insert(line); } infile.close(); } else { errs() << "Warning: ignored whitelist because something failed.\n"; } } // Set all functions that are not in the interface to internal linkage only for (auto &f: M) { if (keep_external.count(f.getName())) { errs() << "Did not internalize " << f.getName() << " because it is whitelisted.\n"; continue; } if (!f.isDeclaration() && f.hasExternalLinkage() && I.calls.find(f.getName()) == I.calls.end() && I.references.find(f.getName()) == I.references.end()) { errs() << "Hiding '" << f.getName() << "'\n"; f.setLinkage(GlobalValue::InternalLinkage); hidden++; modified = true; } } // Set all initialized global variables that are not referenced in // the interface to "localized linkage" only for (auto &gv: M.globals()) { if (gv.hasName() && keep_external.count(gv.getName())) { errs() << "Did not internalize " << gv.getName() << " because it is whitelisted.\n"; continue; } if ((gv.hasExternalLinkage() || gv.hasCommonLinkage()) && gv.hasInitializer() && I.references.find(gv.getName()) == I.references.end()) { errs() << "internalizing '" << gv.getName() << "'\n"; gv.setLinkage(localizeLinkage(gv.getLinkage())); internalized++; modified = true; } } if (!modified) { // We don't run DCE if we didn't modify any linkage return false; } // Perform global dead code elimination until fixpoint or // threshold is reached. legacy::PassManager dceMgr, mcMgr; ModulePass* modulePassDCE = createGlobalDCEPass(); ModulePass* constantMergePass = createConstantMergePass(); dceMgr.add(modulePassDCE); mcMgr.add(constantMergePass); bool moreToDo = true; bool change_dce = false; bool change_mc = false; unsigned int iters = 0; while (moreToDo && iters < FixpointTreshold) { change_dce = dceMgr.run(M); change_mc = mcMgr.run(M); moreToDo = (change_dce || change_mc); ++iters; } if (change_dce) { errs() << "GlobalDCE still had more to do\n"; } if (change_mc) { errs() << "MergeConstants still had more to do\n"; } errs() << "Progress: hidden = " << hidden << " internalized " << internalized << "\n"; return true; }
void DebugMapObject::dump() const { print(errs()); }
bool LoopBogusCF::runOnLoop(Loop *loop, LPPassManager &LPM) { if (disableLoopBcf) return false; ++NumLoops; DEBUG(errs() << "LoopBogusCF: Dumping loop info\n"); // DEBUG(loop->dump()); BasicBlock *header = loop->getHeader(); BranchInst *branch = dyn_cast<BranchInst>(header->getTerminator()); if (!branch || !branch->isConditional()) { DEBUG(errs() << "\t Not trivial loop -- skipping\n"); return false; } if (!loop->isLoopSimplifyForm()) { DEBUG(errs() << "\t Not simplified loop -- skipping\n"); return false; } BasicBlock *exitBlock = loop->getUniqueExitBlock(); if (!exitBlock) { DEBUG(errs() << "\t No unique exit block -- skipping\n"); return false; } if (branch->getSuccessor(0) != exitBlock && branch->getSuccessor(1) != exitBlock) { DEBUG(errs() << "\t Not trivial loop -- skipping\n"); return false; } ++NumLoopsObf; // DEBUG(header->getParent()->viewCFG()); DEBUG(errs() << "\tCreating dummy block\n"); LoopInfo &info = getAnalysis<LoopInfo>(); // Split header block BasicBlock *dummy = header->splitBasicBlock(header->getTerminator()); loop->addBasicBlockToLoop(dummy, info.getBase()); BasicBlock *trueBlock, *falseBlock = exitBlock; if (branch->getSuccessor(0) == exitBlock) { trueBlock = branch->getSuccessor(1); branch->setSuccessor(1, dummy); } else { trueBlock = branch->getSuccessor(0); branch->setSuccessor(0, dummy); } branch->moveBefore(header->getTerminator()); header->getTerminator()->eraseFromParent(); OpaquePredicate::createStub(dummy, trueBlock, falseBlock, OpaquePredicate::PredicateTrue, false); // DEBUG(header->getParent()->viewCFG()); return true; }
// // Method: fieldMapUpdate() // // Description: // Update the fieldmap // template<class dsa> void TypeSafety<dsa>::fieldMapUpdate (const DSNode * N) { FieldMap fmap; // // There are no overlapping fields if the DSNode has no fields. // if (N->type_begin() == N->type_end()) return; // // Iterate through the DSNode to see if the previous fields overlaps with the // current field. // DSNode::const_type_iterator tn = N->type_begin(); while (true) { // // If this is the last field, then we are done updating. // if (tn == N->type_end()) { break; } // // Get the information about the current field. // unsigned offset = tn->first; SuperSet<Type*>::setPtr TypeSet = tn->second; // // If there are multiple types in the current field, then the field is type-unsafe. // if (TypeSet) { svset<Type*>::const_iterator tb = TypeSet->begin(); if (++tb != TypeSet->end()) { fmap[offset] = true; DEBUG(errs() << "Multiple fields at " << offset << "\n"); } } for (DSNode::const_type_iterator ti = ++tn; ti != N->type_end(); ++ti) { // // Get the offset of the next field. // unsigned next_offset = ti->first; assert((next_offset >= offset) && "next offset should be larger than offset."); // // Check to see if any of the types in the current field extend into the // next field. // if (TypeSet) { bool overlaps = false; for (svset<Type*>::const_iterator ni = TypeSet->begin(), ne = TypeSet->end(); ni != ne; ++ni) { unsigned field_length = TD->getTypeStoreSize (*ni); if ((offset + field_length) > next_offset) { if(TypeInferenceOptimize) { if(const ArrayType *AT = dyn_cast<ArrayType>(*ni)) { Type *ElemTy = AT->getElementType(); while(ArrayType *AT1 = dyn_cast<ArrayType>(ElemTy)) ElemTy = AT1->getElementType(); if(next_offset < (TD->getTypeStoreSize(ElemTy) + offset)) { assert(isa<StructType>(ElemTy) && "Array Not of Struct Type??"); //overlaps = false; //fmap[next_offset] = false; continue; } } } fmap[offset] = true; fmap[next_offset] = true; overlaps = true; if(overlaps) { DEBUG(errs() << "Found overlap at " << offset << " with " << next_offset << "\n"); break; } } } if (!overlaps) break; } } if (fmap.find(offset) == fmap.end()) fmap[offset] = false; } // // Return the result. // NodeInfo[N] = fmap; return; }