123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-2026 *)(* 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). *)(* *)(**************************************************************************)typestatus=|Halt|Cut|Merged|Stashed|Unsatisfiable_assumption|Assertion_failure|Max_depth|Enumeration_limit|Unresolved_formula|Non_executable_code|Errorofstringletstatus_to_string:status->string=function|Halt->"halt"|Cut->"cut"|Merged->"merged"|Stashed->"stashed"|Unsatisfiable_assumption->"unsatisfiable_assumption"|Assertion_failure->"assertion_failure"|Max_depth->"max_depth"|Enumeration_limit->"enumeration_limit"|Unresolved_formula->"unresolved_formula"|Non_executable_code->"non_executable_code"|Error_->"error"letpp_status:Format.formatter->status->unit=funppfstatus->Format.pp_print_stringppf(status_to_stringstatus)moduletypeTIMER=sigtypetvalget:t->floatvalstart:t->unitvalstop:t->unitendmoduletypeASPECT=sigtypetvalget:t->intvalincr:t->unitmoduleTimer:TIMERwithtypet:=unitvalpp:Format.formatter->unit->unitvalto_toml:unit->Toml.Types.tableendmoduletypeQUERY=sigmodulePreprocess:ASPECTwithtypet:=Binsec_smtlib.Solver.statusmoduleSolver:ASPECTwithtypet:=Binsec_smtlib.Solver.statusvalreset:unit->unitvalpp:Format.formatter->unit->unitvalto_toml:unit->Toml.Types.tableendmoduletypeBUFFER=sigtypettypeeltvalcreate:int->tvalfill:t->int->int->elt->unitvalget:t->int->eltvalset:t->int->elt->unitendmoduletypeBACKEND=sigmoduleInt:BUFFERwithtypeelt:=intmoduleFloat:BUFFERwithtypeelt:=floatendmoduleArrayBackend:BACKEND=structmoduleInt=structtypet=intarrayletcreate:int->t=funsize->Array.makesize0letfill:t->int->int->int->unit=Array.fillletget:t->int->int=Array.unsafe_getletset:t->int->int->unit=Array.unsafe_setendmoduleFloat=structtypet=floatarrayletcreate:int->t=funsize->Float.Array.makesize0.letfill:t->int->int->float->unit=Float.Array.fillletget:t->int->float=Float.Array.unsafe_getletset:t->int->float->unit=Float.Array.unsafe_setendendmoduleTimer(B:BACKEND):sigincludeTIMERwithtypet:=unitvalreset:unit->unitend=structletis_active,set_active=letcell=B.Int.create1in((fun()->B.Int.getcell0<>0),funb->B.Int.setcell0(Bool.to_intb))letget_time,set_time,get_since,set_since=letcells=B.Float.create2in((fun()->B.Float.getcells0),(funx->B.Float.setcells0x),(fun()->B.Float.getcells1),funx->B.Float.setcells1x)letget()=ifis_active()thenget_time()+.(Unix.gettimeofday()-.get_since())elseget_time()letstart()=set_since(Unix.gettimeofday());set_activetrueletstop()=set_activefalse;set_time(get_time()+.(Unix.gettimeofday()-.get_since()))letreset()=set_time0.;set_activefalseendmoduleMake_query(B:BACKEND):QUERY=structtypestatus=Binsec_smtlib.Solver.statusletto_int:status->int=functionSat->0|Unsat->1|Unknown->2moduleCommon()=structletcounters=B.Int.create3letgets=B.Int.getcounters(to_ints)letincrs=B.Int.setcounters(to_ints)(B.Int.getcounters(to_ints)+1)moduleTimer=Timer(B)letreset()=B.Int.fillcounters030;Timer.reset()endmodulePreprocess=structincludeCommon()letppppf()=letsat=getSatandunsat=getUnsatinFormat.fprintfppf"@[<v 2>@[<h>Preprocessing simplifications@]@,\
@[<h>total %d@]@,\
@[<h>sat %d@]@,\
@[<h>unsat %d@]@,\
@[<h>time %.2f@]@]"(sat+unsat)satunsat(Timer.get())letto_toml()=Toml.Min.of_key_values[(Toml.Min.key"sat",Toml.Types.TInt(getSat));(Toml.Min.key"unsat",Toml.Types.TInt(getUnsat));(Toml.Min.key"time",Toml.Types.TFloat(Timer.get()));]endmoduleSolver=structincludeCommon()letppppf()=letsat=getSatandunsat=getUnsatandunknown=getUnknownandtime=Timer.get()inlettotal=sat+unsat+unknowninFormat.fprintfppf"@[<v 2>@[<h>Satisfiability queries@]@,\
@[<h>total %d@]@,\
@[<h>sat %d@]@,\
@[<h>unsat %d@]@,\
@[<h>unknown %d@]@,\
@[<h>time %.2f@]@,\
@[<h>average %.2f@]@]"totalsatunsatunknowntime(time/.floattotal)letto_toml()=Toml.Min.of_key_values[(Toml.Min.key"sat",Toml.Types.TInt(getSat));(Toml.Min.key"unsat",Toml.Types.TInt(getUnsat));(Toml.Min.key"unknown",Toml.Types.TInt(getUnknown));(Toml.Min.key"time",Toml.Types.TFloat(Timer.get()));]endletreset()=Preprocess.reset();Solver.reset()letppppf()=letopenFormatinfprintfppf"@[<v 0>%a@,@,%a@,@]"Preprocess.pp()Solver.pp()letto_toml()=Toml.Min.of_key_values[(Toml.Min.key"preprocess",Toml.Types.TTable(Preprocess.to_toml()));(Toml.Min.key"solver",Toml.Types.TTable(Solver.to_toml()));]endmoduleQuery():QUERY=Make_query(ArrayBackend)moduletypeEXPLORATION=sigmodulePaths:sigtypet=Total|Pending|Completed|Discontinuedvalget:t->intvalstatus:status->intvalincr:unit->unitvalresume:unit->unitvalsignal:status->unitendmoduleTopology:sigtypet=Branch|Jump|Assertvalget:t->intvalincr:t->unitendmoduleMax_depth:sigvalget:unit->intvalupdate:int->unitendmoduleAddresses:sigvalunique:unit->intvalregister:Virtual_address.t->unitendmoduleInstructions:sigvalget:unit->intvalincr:int->unitendmoduleTimer:TIMERwithtypet:=unitvalreset:unit->unitvalpp:Format.formatter->unit->unitvalto_toml:unit->Toml.Types.tableendmoduleMake_exploration(B:BACKEND):EXPLORATION=structmodulePaths=structtypet=Total|Pending|Completed|Discontinuedletstatus_to_int:status->int=function|Halt->0|Cut->1|Merged->2|Stashed->3|Unsatisfiable_assumption->4|Assertion_failure->5|Max_depth->6|Enumeration_limit->7|Unresolved_formula->8|Non_executable_code->9|Error_->10letto_int:t->int=function|Total->11|Pending->12|Completed->13|Discontinued->14letstatus_to_t:status->t=function|Halt->Completed|Cut->Completed|Merged->Completed|Stashed->Pending|Unsatisfiable_assumption->Completed|Assertion_failure->Completed|Max_depth->Discontinued|Enumeration_limit->Discontinued|Unresolved_formula->Discontinued|Non_executable_code->Discontinued|Error_->Discontinuedletcounters=B.Int.create15letincrx=B.Int.setcounters(to_intx)(B.Int.getcounters(to_intx)+1)letgetc=B.Int.getcounters(to_intc)letstatuss=B.Int.getcounters(status_to_ints)letsignals=B.Int.setcounters(status_to_ints)(B.Int.getcounters(status_to_ints)+1);B.Int.setcounters(to_intPending)(B.Int.getcounters(to_intPending)-1);incr(status_to_ts)letresume()=B.Int.setcounters(status_to_intStashed)(B.Int.getcounters(status_to_intStashed)-1)letincr()=incrTotal;incrPendingletreset()=B.Int.fillcounters0150letto_toml()=letcompleted,discontinued=List.fold_left(fun(completed,discontinued)s->letentry=(Toml.Min.key(status_to_strings),Toml.Types.TInt(statuss))inmatchstatus_to_tswith|Total|Pending->(completed,discontinued)|Completed->(entry::completed,discontinued)|Discontinued->(completed,entry::discontinued))([],[])[Halt;Cut;Stashed;Unsatisfiable_assumption;Assertion_failure;Max_depth;Enumeration_limit;Unresolved_formula;Non_executable_code;Error"";]inToml.Min.of_key_values[(Toml.Min.key"total",Toml.Types.TInt(getTotal));(Toml.Min.key"pending",Toml.Types.TInt(getPending));(Toml.Min.key"completed",Toml.Types.TTable(Toml.Min.of_key_valuescompleted));(Toml.Min.key"discontinued",Toml.Types.TTable(Toml.Min.of_key_valuesdiscontinued));]endmoduleTopology=structtypet=Branch|Jump|Assertletto_int:t->int=functionBranch->0|Jump->1|Assert->2letcounters=B.Int.create3letgete=B.Int.getcounters(to_inte)letincre=B.Int.setcounters(to_inte)(B.Int.getcounters(to_inte)+1)letreset()=B.Int.fillcounters030letto_toml()=Toml.Min.of_key_values[(Toml.Min.key"branches",Toml.Types.TInt(getBranch));(Toml.Min.key"jumps",Toml.Types.TInt(getJump));(Toml.Min.key"assertions",Toml.Types.TInt(getAssert));]endmoduleMax_depth=structletcounter=B.Int.create1letget()=B.Int.getcounter0letupdaten=B.Int.setcounter0(maxn(B.Int.getcounter0))letreset()=B.Int.setcounter00endmoduleAddresses=structlettbl=Virtual_address.Htbl.create1024letcounter=B.Int.create1letunique()=B.Int.getcounter0letregisteraddr=Virtual_address.Htbl.replacetbladdr();B.Int.setcounter0(Virtual_address.Htbl.lengthtbl)letreset()=Virtual_address.Htbl.resettbl;B.Int.setcounter00endmoduleInstructions=structletcounter=B.Int.create1letget()=B.Int.getcounter0letincrn=B.Int.setcounter0(B.Int.getcounter0+n)letreset()=B.Int.setcounter00endmoduleTimer=Timer(B)letreset()=Paths.reset();Topology.reset();Max_depth.reset();Addresses.reset();Instructions.reset();Timer.reset()letppppf()=Format.fprintfppf"@[<v 0>@[<h>total paths %d@]@,\
@[<h>completed/cut paths %d@]@,\
@[<h>pending paths %d@]@,\
@[<h>discontinued paths %d@]@,\
@[<h>failed assertions %d@]@,\
@[<h>branching points %d@]@,\
@[<h>max path depth %d@]@,\
@[<h>visited instructions (unrolled) %d@]@,\
@[<h>visited instructions (static) %d@]@,\
@]"(Paths.getTotal)(Paths.getCompleted)(Paths.getPending)(Paths.getDiscontinued)(Paths.statusAssertion_failure)(Topology.getBranch)(Max_depth.get())(Instructions.get())(Addresses.unique())letto_toml()=Toml.Min.of_key_values[(Toml.Min.key"paths",Toml.Types.TTable(Paths.to_toml()));(Toml.Min.key"topology",Toml.Types.TTable(Topology.to_toml()));(Toml.Min.key"max_depth",Toml.Types.TInt(Max_depth.get()));(Toml.Min.key"instructions",Toml.Types.TInt(Instructions.get()));(Toml.Min.key"unique_insts",Toml.Types.TInt(Addresses.unique()));(Toml.Min.key"time",Toml.Types.TFloat(Timer.get()));]endmoduleExploration():EXPLORATION=Make_exploration(ArrayBackend)