Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file solver.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-2024 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)openSexprexceptionUnknown=Types.UnknownmoduletypeS=sigvalvisit_formula:Expr.tlist->unitvaliter_free_variables:(string->Expr.t->unit)->unitvaliter_free_arrays:(string->Memory.t->unit)->unitvalassert_formula:Expr.t->unitvalcheck_sat:?timeout:float->unit->Libsolver.statusvalcheck_sat_assuming:?timeout:float->Expr.t->Libsolver.statusvalget_value:Expr.t->Z.tvalfold_array_values:(Z.t->Z.t->'a->'a)->Memory.t->'a->'avalpush:unit->unitvalpop:unit->unitvalclose:unit->unitendmoduletypeOPEN=functor()->Stypelazy_memory={addr_space:int;content:(Z.t*Loader_buf.t)Imap.t;mutablelemmas:Expr.tlist;}typeresult=SatofModel.t|Unsat|Unknownletdeadline_of_timeout=Option.map(funtimeout->Unix.gettimeofday()+.timeout)lettimeout_of_deadline=Option.map(fundeadline->deadline-.Unix.gettimeofday())letextract_memorysolverlmem=letmoduleSolver=(valsolver:S)inletmemory=BiTbl.create64inletalocs=Solver.fold_array_values(funaddrvaluealocs->matchImap.findaddrlmem.contentwith|exceptionNot_found->BiTbl.addmemoryaddr(Char.unsafe_chr(Z.to_intvalue));alocs|base,img->letoffset=Z.to_int(Z.subaddrbase)inletvalue'=Z.of_int(ifoffset<Bigarray.Array1.dimimgthenBigarray.Array1.getimgoffsetelse0)inifvalue<>value'thenExpr.equal(Expr.load1LittleEndian(Expr.constant(Bv.createaddrlmem.addr_space))Memory.root)(Expr.constant(Bv.createvalue'8))::alocselsealocs)Memory.rootlmem.lemmasin(memory,alocs)letextract_arraysolvername=letmoduleSolver=(valsolver:S)inletarray=BiTbl.create64inSolver.fold_array_values(funaddrvaluearray->BiTbl.addarrayaddr(Char.unsafe_chr(Z.to_intvalue));array)namearrayletextract_arrayssolver=letmoduleSolver=(valsolver:S)inletarrays=StTbl.create5inSolver.iter_free_arrays(funnamesymbol->StTbl.addarraysname(extract_arraysolversymbol));arraysletextract_varssolver=letmoduleSolver=(valsolver:S)inletvars=StTbl.create8andvalues=BvTbl.create32inSolver.iter_free_variables(funnamebv->StTbl.addvarsnamebv;BvTbl.addvaluesbv(Bitvector.create(Solver.get_valuebv)(Expr.sizeofbv)));(vars,values)letrecassert_lazy_lemmassolverlmemlemmas=letmoduleSolver=(valsolver:S)iniflemmas!=lmem.lemmasthenmatchlemmaswith|[]->()|e::lemmas->Solver.assert_formulae;assert_lazy_lemmassolverlmemlemmasletassert_lazy_lemmassolverlmemlemmas=assert_lazy_lemmassolverlmemlemmas;lmem.lemmas<-lemmasmoduleCommon(QS:Types.QUERY_STATISTICS)=structletreccheck_satsolverdeadlinelmem=letmoduleSolver=(valsolver:S)inmatchSolver.check_sat?timeout:(timeout_of_deadlinedeadline)()with|Unknown->QS.Solver.incr_err();Unknown|Unsat->QS.Solver.incr_unsat();Unsat|Sat->QS.Solver.incr_sat();letmemory,lemmas=extract_memorysolverlmeminiflemmas!=lmem.lemmasthen(assert_lazy_lemmassolverlmemlemmas;check_satsolverdeadlinelmem)elseletvars,values=extract_varssolverinSat(vars,values,memory,extract_arrayssolver,lmem.addr_space)letreccheck_sat_assumingsolverdeadlinelmeme=letmoduleSolver=(valsolver:S)inmatchSolver.check_sat_assuming?timeout:(timeout_of_deadlinedeadline)ewith|Unknown->QS.Solver.incr_err();Unknown|Unsat->QS.Solver.incr_unsat();Unsat|Sat->QS.Solver.incr_sat();letmemory,lemmas=extract_memorysolverlmeminiflemmas!=lmem.lemmasthen(assert_lazy_lemmassolverlmemlemmas;check_sat_assumingsolverdeadlinelmeme)elseletvars,values=extract_varssolverinSat(vars,values,memory,extract_arrayssolver,lmem.addr_space)letrecfold_valuessolverdeadlinelmemesizenfacc=ifn=0thenaccelseletmoduleSolver=(valsolver:S)inmatchSolver.check_sat?timeout:(timeout_of_deadlinedeadline)()with|Unknown->QS.Solver.incr_err();raiseUnknown|Unsat->QS.Solver.incr_unsat();acc|Sat->QS.Solver.incr_sat();letmemory,lemmas=extract_memorysolverlmeminiflemmas!=lmem.lemmasthen(assert_lazy_lemmassolverlmemlemmas;fold_valuessolverdeadlinelmemesizenfacc)elseletx=Solver.get_valueeinletbv=Bv.createxsizeinletvars,values=extract_varssolverinletmodel=(vars,values,memory,extract_arrayssolver,lmem.addr_space)inSolver.assert_formula(Expr.diffe(Expr.constantbv));fold_valuessolverdeadlinelmemesize(n-1)f(fbvmodelacc)endmoduletypeGET_MODEL=sigvalcheck_sat:?timeout:float->lazy_memory->Expr.tlist->resultvalfold_values:?timeout:float->lazy_memory->Expr.tlist->Expr.t->n:int->except:Bv.tlist->(Bv.t->Model.t->'a->'a)->'a->'aendmoduletypeGET_MODEL_WITH_STATS=functor(QS:Types.QUERY_STATISTICS)->GET_MODELmoduleOnce(Session:OPEN)(QS:Types.QUERY_STATISTICS):GET_MODEL=structincludeCommon(QS)letcheck_sat?timeoutlmemformula=letmoduleSolver=Session()inSolver.visit_formulaformula;List.iterSolver.assert_formulaformula;List.iterSolver.assert_formulalmem.lemmas;letr=check_sat(moduleSolver:S)(deadline_of_timeouttimeout)lmeminSolver.close();rletfold_values?timeoutlmemformulae~n~exceptfacc=letmoduleSolver=Session()inSolver.visit_formulaformula;List.iterSolver.assert_formulaformula;List.iterSolver.assert_formulalmem.lemmas;List.iter(funbv->Solver.assert_formula(Expr.diffe(Expr.constantbv)))except;matchfold_values(moduleSolver:S)(deadline_of_timeouttimeout)lmeme(Expr.sizeofe)nfaccwith|exceptionUnknown->Solver.close();raiseUnknown|acc->Solver.close();accendmoduleMultiChecks(Session:OPEN)(QS:Types.QUERY_STATISTICS):GET_MODEL=structincludeCommon(QS)letclosesolver=letmoduleSolver=(valsolver:S)inSolver.close()typecache={mutableassertions:Expr.tlist;mutablelemmas:Expr.tlist;mutablesolver:(moduleS)option;}letcache={assertions=[];lemmas=[];solver=None}letreset()=cache.assertions<-[];cache.lemmas<-[];Option.iterclosecache.solver;cache.solver<-Noneletassert_formulasolverformula=letmoduleSolver=(valsolver:S)inSolver.visit_formulaformula;List.iterSolver.assert_formulaformulaletopen_solverlemmasformula=Option.iterclosecache.solver;letmoduleSolver=Session()inletsolver=(moduleSolver:S)incache.solver<-Somesolver;assert_formulasolverformula;List.iterSolver.assert_formulalemmas;solverletrecupdate_lemmassolverlemmas=iflemmas=cache.lemmasthen()elsematchlemmaswith|[]->assertfalse|e::lemmas->letmoduleSolver=(valsolver:S)inSolver.assert_formulae;update_lemmassolverlemmasletrecsearch_prefixsolverlemmasformulato_assert=ifformula==cache.assertionsthen(assert_formulasolverto_assert;update_lemmassolverlemmas;solver)elsematchformulawith|[]->open_solverlemmasto_assert|e::formula->search_prefixsolverlemmasformula(e::to_assert)letset_contextlemmasformula=letsolver=matchcache.solverwith|None->open_solverlemmasformula|Somesolver->search_prefixsolverlemmasformula[]incache.assertions<-formula;cache.lemmas<-lemmas;solverletcheck_sat?timeout(lmem:lazy_memory)formula=matchformulawith|[]->Sat(Model.emptylmem.addr_space)|e::formula->letsolver=set_contextlmem.lemmasformulainletmoduleSolver=(valsolver)incheck_sat_assuming(moduleSolver:S)(deadline_of_timeouttimeout)lmemeletfold_values?timeout(lmem:lazy_memory)formulae~n~exceptfacc=letsolver=set_contextlmem.lemmasformulainletmoduleSolver=(valsolver)inSolver.push();List.iter(funbv->Solver.assert_formula(Expr.diffe(Expr.constantbv)))except;matchfold_values(moduleSolver:S)(deadline_of_timeouttimeout)lmeme(Expr.sizeofe)nfaccwith|exceptionUnknown->reset();raiseUnknown|acc->Solver.pop();accend