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; }