void PatchMgr::getExitSites(Scope &scope, ExitSites &sites) { // All sites in whatever functions we want Functions funcs; getFuncs(scope, funcs); for (Functions::iterator iter = funcs.begin(); iter != funcs.end(); ++iter) { const PatchFunction::Blockset &e = (*iter)->exitBlocks(); for (PatchFunction::Blockset::const_iterator iter2 = e.begin(); iter2 != e.end(); ++iter2) { if (!scope.block || (scope.block == *iter2)) sites.push_back(ExitSite_t(*iter, *iter2)); } } }
void PatchMgr::getFuncCandidates(Scope &scope, Point::Type types, Candidates &ret) { // We can either have a scope of PatchObject and be looking for all // the functions it contains, a scope of a Function, or be looking // for every single function we know about. Functions funcs; getFuncs(scope, funcs); for (Functions::iterator iter = funcs.begin(); iter != funcs.end(); ++iter) { if (types & Point::FuncDuring) ret.push_back(Candidate(Location::Function(*iter), Point::FuncDuring)); if (types & Point::FuncEntry) ret.push_back(Candidate(Location::EntrySite(*iter, (*iter)->entry(), true), Point::FuncEntry)); } }
void PatchMgr::getBlockInstances(Scope &scope, BlockInstances &blocks) { Functions funcs; getFuncs(scope, funcs); for (Functions::iterator iter = funcs.begin(); iter != funcs.end(); ++iter) { const PatchFunction::Blockset &b = (*iter)->blocks(); for (PatchFunction::Blockset::const_iterator iter2 = b.begin(); iter2 != b.end(); ++iter2) { // TODO FIXME: make this more efficient to avoid iunnecessary iteration if (scope.block && scope.block != *iter2) continue; blocks.push_back(BlockInstance(*iter, *iter2)); } } }
// Detect functions that are semantically similar by running multiple iterations of partition_functions(). void analyze() { RTS_Message *m = thread->tracing(TRACE_MISC); Functions functions = find_functions(m, thread->get_process()); PointerDetectors pointers = detect_pointers(m, thread, functions); PartitionForest partition; while (partition.nlevels()<MAX_ITERATIONS) { InputValues inputs = choose_inputs(3, 3); size_t level = partition.new_level(inputs); m->mesg("####################################################################################################"); m->mesg("%s: fuzz testing %zu function%s at level %zu", name, functions.size(), 1==functions.size()?"":"s", level); m->mesg("%s: using these input values:\n%s", name, inputs.toString().c_str()); if (0==level) { partition_functions(m, partition, functions, pointers, inputs, NULL); } else { const PartitionForest::Vertices &parent_vertices = partition.vertices_at_level(level-1); for (PartitionForest::Vertices::const_iterator pvi=parent_vertices.begin(); pvi!=parent_vertices.end(); ++pvi) { PartitionForest::Vertex *parent_vertex = *pvi; if (parent_vertex->functions.size()>MAX_SIMSET_SIZE) partition_functions(m, partition, parent_vertex->functions, pointers, inputs, parent_vertex); } } // If the new level doesn't contain any vertices then we must not have needed to repartition anything and we're all // done. if (partition.vertices_at_level(level).empty()) break; } m->mesg("=========================================================================================="); m->mesg("%s: The entire partition forest follows...", name); m->mesg("%s", StringUtility::prefixLines(partition.toString(), std::string(name)+": ").c_str()); m->mesg("=========================================================================================="); m->mesg("%s: Final function similarity sets are:", name); PartitionForest::Vertices leaves = partition.get_leaves(); size_t setno=0; for (PartitionForest::Vertices::iterator vi=leaves.begin(); vi!=leaves.end(); ++vi, ++setno) { PartitionForest::Vertex *leaf = *vi; const Functions &functions = leaf->get_functions(); m->mesg("%s: set #%zu at level %zu has %zu function%s:", name, setno, leaf->get_level(), functions.size(), 1==functions.size()?"":"s"); for (Functions::const_iterator fi=functions.begin(); fi!=functions.end(); ++fi) m->mesg("%s: 0x%08"PRIx64" <%s>", name, (*fi)->get_entry_va(), (*fi)->get_name().c_str()); } m->mesg("%s: dumping final similarity sets to clones.sql", name); partition.dump("clones.sql", "NO_USER", "NO_PASSWD"); }
void PatchMgr::getInsnInstances(Scope &scope, InsnInstances &insns) { Functions funcs; getFuncs(scope, funcs); for (Functions::iterator iter = funcs.begin(); iter != funcs.end(); ++iter) { const PatchFunction::Blockset &b = (*iter)->blocks(); for (PatchFunction::Blockset::const_iterator iter2 = b.begin(); iter2 != b.end(); ++iter2) { // TODO FIXME: make this more efficient to avoid iunnecessary iteration if (scope.block && scope.block != *iter2) continue; PatchBlock::Insns i; (*iter2)->getInsns(i); for (PatchBlock::Insns::iterator iter3 = i.begin(); iter3 != i.end(); ++iter3) { insns.push_back(InsnInstance(*iter, InsnLoc_t(*iter2, iter3->first, iter3->second))); } } } }
// Run each function from the specified set of functions in order to produce an output set for each function. Then insert // the functions into the bottom of the specified PartitionForest. This runs one iteration of partitioning. void partition_functions(RTS_Message *m, PartitionForest &partition, const Functions &functions, PointerDetectors &pointers, InputValues &inputs, PartitionForest::Vertex *parent) { for (Functions::const_iterator fi=functions.begin(); fi!=functions.end(); ++fi) { PointerDetectors::iterator ip = pointers.find(*fi); assert(ip!=pointers.end()); CloneDetection::Outputs<RSIM_SEMANTICS_VTYPE> *outputs = fuzz_test(*fi, inputs, ip->second); #if 1 /*DEBUGGING [Robb Matzke 2013-01-14]*/ std::ostringstream output_values_str; OutputValues output_values = outputs->get_values(); for (OutputValues::iterator ovi=output_values.begin(); ovi!=output_values.end(); ++ovi) output_values_str <<" " <<*ovi; m->mesg("%s: function output values are {%s }", name, output_values_str.str().c_str()); #endif partition.insert(*fi, output_values, parent); } }
ScriptingService::Functions ScriptingService::loadFunctions( const string& code, const string& filename, bool mrethrow ) { Logger::In in("ScriptingService::loadFunctions"); Parser p; Functions exec; Functions ret; try { Logger::log() << Logger::Info << "Parsing file "<<filename << Logger::endl; ret = p.parseFunction(code, mowner, filename); } catch( const file_parse_exception& exc ) { #ifndef ORO_EMBEDDED Logger::log() << Logger::Error << filename<<" :"<< exc.what() << Logger::endl; if ( mrethrow ) throw; #endif return Functions(); } if ( ret.empty() ) { Logger::log() << Logger::Debug << "No Functions executed from "<< filename << Logger::endl; Logger::log() << Logger::Info << filename <<" : Successfully parsed." << Logger::endl; return Functions(); } else { // Load all listed functions in the TaskContext's Processor: for( Parser::ParsedFunctions::iterator it = ret.begin(); it != ret.end(); ++it) { Logger::log() << "Queueing Function "<< (*it)->getName() << Logger::endl; if ( mowner->engine()->runFunction( it->get() ) == false) { Logger::log() << Logger::Error << "Could not run Function '"<< (*it)->getName() <<"' :" << Logger::nl; Logger::log() << "Processor not accepting or function queue is full." << Logger::endl; } else exec.push_back( *it ); // is being executed. } } return exec; }
PointerDetectors detect_pointers(RTS_Message *m, RSIM_Thread *thread, const Functions &functions) { // Choose an SMT solver. This is completely optional. Pointer detection still seems to work fairly well (and much, // much faster) without an SMT solver. SMTSolver *solver = NULL; #if 0 // optional code if (YicesSolver::available_linkage()) solver = new YicesSolver; #endif PointerDetectors retval; CloneDetection::InstructionProvidor *insn_providor = new CloneDetection::InstructionProvidor(thread->get_process()); for (Functions::iterator fi=functions.begin(); fi!=functions.end(); ++fi) { m->mesg("%s: performing pointer detection analysis for \"%s\" at 0x%08"PRIx64, name, (*fi)->get_name().c_str(), (*fi)->get_entry_va()); CloneDetection::PointerDetector pd(insn_providor, solver); pd.initial_state().registers.gpr[x86_gpr_sp] = SYMBOLIC_VALUE<32>(thread->policy.INITIAL_STACK); pd.initial_state().registers.gpr[x86_gpr_bp] = SYMBOLIC_VALUE<32>(thread->policy.INITIAL_STACK); //pd.set_debug(stderr); pd.analyze(*fi); retval.insert(std::make_pair(*fi, pd)); #if 1 /*DEBUGGING [Robb P. Matzke 2013-01-24]*/ if (m->get_file()) { const CloneDetection::PointerDetector::Pointers plist = pd.get_pointers(); for (CloneDetection::PointerDetector::Pointers::const_iterator pi=plist.begin(); pi!=plist.end(); ++pi) { std::ostringstream ss; if (pi->type & BinaryAnalysis::PointerAnalysis::DATA_PTR) ss <<"data "; if (pi->type & BinaryAnalysis::PointerAnalysis::CODE_PTR) ss <<"code "; ss <<"pointer at " <<pi->address; m->mesg(" %s", ss.str().c_str()); } } #endif } return retval; }
double kantorovich (const T &densityT, const Functions &densityF, const Matrix &X, const Vector &weights, Vector &g, SparseMatrix &h) { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Polygon_2<K> Polygon; typedef K::FT FT; typedef CGAL::Regular_triangulation_filtered_traits_2<K> RT_Traits; typedef CGAL::Regular_triangulation_vertex_base_2<RT_Traits> Vbase; typedef CGAL::Triangulation_vertex_base_with_info_2 <size_t, RT_Traits, Vbase> Vb; typedef CGAL::Regular_triangulation_face_base_2<RT_Traits> Cb; typedef CGAL::Triangulation_data_structure_2<Vb,Cb> Tds; typedef CGAL::Regular_triangulation_2<RT_Traits, Tds> RT; typedef RT::Vertex_handle Vertex_handle_RT; typedef RT::Weighted_point Weighted_point; typedef typename CGAL::Point_2<K> Point; size_t N = X.rows(); assert(weights.rows() == N); assert(weights.cols() == 1); assert(X.cols() == 2); // insert points with indices in the regular triangulation std::vector<std::pair<Weighted_point,size_t> > Xw(N); for (size_t i = 0; i < N; ++i) { Xw[i] = std::make_pair(Weighted_point(Point(X(i,0), X(i,1)), weights(i)), i); } RT dt (Xw.begin(), Xw.end()); dt.infinite_vertex()->info() = -1; // compute the quadratic part typedef MA::Voronoi_intersection_traits<K> Traits; typedef typename MA::Tri_intersector<T,RT,Traits> Tri_isector; typedef typename Tri_isector::Pgon Pgon; typedef Eigen::Triplet<FT> Triplet; std::vector<Triplet> htri; FT total(0), fval(0), total_area(0); g = Vector::Zero(N); MA::voronoi_triangulation_intersection_raw (densityT,dt, [&] (const Pgon &pgon, typename T::Face_handle f, Vertex_handle_RT v) { Tri_isector isector; Polygon p; std::vector<Vertex_handle_RT> adj; for (size_t i = 0; i < pgon.size(); ++i) { size_t ii = (i==0)?(pgon.size()-1):(i-1); //size_t ii = (i+1)%pgon.size(); p.push_back(isector.vertex_to_point(pgon[i], pgon[ii])); adj.push_back((pgon[i].type == Tri_isector::EDGE_DT) ? pgon[i].edge_dt.second : 0); } size_t idv = v->info(); auto fit = densityF.find(f); assert(fit != densityF.end()); auto fv = fit->second; // function to integrate // compute hessian for (size_t i = 0; i < p.size(); ++i) { if (adj[i] == 0) continue; Vertex_handle_RT w = adj[i]; size_t idw = w->info(); FT r = MA::integrate_1<FT>(p.edge(i), fv); FT d = 2*sqrt(CGAL::squared_distance(v->point(), w->point())); htri.push_back(Triplet(idv, idw, -r/d)); htri.push_back(Triplet(idv, idv, +r/d)); } // compute value and gradient FT warea = MA::integrate_1<FT>(p, FT(0), fv); FT intg = MA::integrate_3<FT>(p, FT(0), [&](Point p) { return fv(p) * CGAL::squared_distance(p, v->point()); }); fval = fval + warea * weights[idv] - intg; g[idv] = g[idv] + warea; total += warea; total_area += p.area(); }); h = SparseMatrix(N,N); h.setFromTriplets(htri.begin(), htri.end()); h.makeCompressed(); return fval; }