Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file smt2_solver.ml
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297(**************************************************************************)(* 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). *)(* *)(**************************************************************************)letbyte_size=Natural.to_intBasic_types.Constants.bytesizemoduleSession=structletn=ref0typestate=Dead|Assert|Sat|Unsattypesession={solver:Prover.t;mutablestate:state;pid:Subprocess.t;stdin:out_channel;stdout:in_channel;stderr:in_channel;stdlog:out_channeloption;fdlog:out_channeloption;formatter:Format.formatter;}letcloset=ift.state<>Deadthen(t.state<-Dead;ignore@@Subprocess.closet.pid;matcht.fdlogwithNone->()|Somefd->close_outfd)letstart?stdlogsolver=Options.Logger.debug"Openning session %d"!n;letfdlog=matchSmt_options.SMT_dir.get_opt()with|None->None|Somedir->ifnot(Sys.file_existsdir)thenUnix.mkdirdir0o777;letfilename=Filename.concatdir(Printf.sprintf"query_%d.smt2"!n)inSome(open_outfilename)inincrn;letcmd=Prover.command~incremental:true0solverinletpid=Subprocess.spawn~pdeathsig:Sys.sigkillcmdinletstdin=Subprocess.stdinpidandstdout=Subprocess.stdoutpidandstderr=Subprocess.stderrpidinletformatter=match(stdlog,fdlog)with|None,None->Format.formatter_of_out_channelstdin|Somestdlog,None->letoutputstrposlen=output_substringstdlogstrposlen;output_substringstdinstrposlenandflush()=flushstdlog;flushstdininFormat.make_formatteroutputflush|None,Somefdlog->letoutputstrposlen=output_substringfdlogstrposlen;output_substringstdinstrposlenandflush()=flushfdlog;flushstdininFormat.make_formatteroutputflush|Somestdlog,Somefdlog->letoutputstrposlen=output_substringstdlogstrposlen;output_substringfdlogstrposlen;output_substringstdinstrposlenandflush()=flushstdlog;flushfdlog;flushstdininFormat.make_formatteroutputflushinFormat.fprintfformatter"@[<v 0>(set-option :print-success false)@ (set-info :smt-lib-version \
2.5)@ (set-logic QF_ABV)@ @]";{solver;state=Assert;pid;stdin;stdout;stderr;stdlog;fdlog;formatter;}letrecparse_check_with_deadlinetfddeadline:Libsolver.status=matchdeadlinewith|None->parse_check_linetfddeadlineFloat.minus_one|Somedeadline'->lettimeout=deadline'-.Unix.gettimeofday()inifFloat.sign_bittimeoutthen(closet;Unknown)elseparse_check_linetfddeadlinetimeoutandparse_check_linetfddeadlinetimeout:Libsolver.status=matchUnix.select[fd][][]timeoutwith|[_],_,_->(Unix.set_nonblockfd;matchinput_linet.stdoutwith|"sat"->Unix.clear_nonblockfd;t.state<-Sat;Sat|"unsat"->Unix.clear_nonblockfd;t.state<-Unsat;Unsat|"unknown"->Unix.clear_nonblockfd;t.state<-Assert;Unknown|""->parse_check_with_deadlinetfddeadline|s->Options.Logger.error"Solver returned: %s"s;closet;Unknown|exceptionSys_blocked_io->parse_check_with_deadlinetfddeadline|exceptionEnd_of_file->closet;Unknown)|_->closet;Unknownletparse_checkt~timeout=parse_check_with_deadlinet(Unix.descr_of_in_channelt.stdout)(Option.map(funtimeout->Unix.gettimeofday()+.timeout)timeout)letcheck_satt~timeout=Format.fprintft.formatter"(check-sat)@.";parse_checkt~timeoutletcheck_sat_assumingt~timeoute=Format.fprintft.formatter"(check-sat-assuming (%s))@."e;parse_checkt~timeoutletvalue_of_constantcst=letopenSmtlibinmatchcstwith|CstBoolfalse->Z.zero|CstBooltrue->Z.one|CstBinaryb->Z.of_string_base2b|CstDecimald|CstDecimalSize(d,_)->Z.of_string_base10d|CstHexadecimalx->Z.of_string_base16x|CstNumeral_|CstString_->Options.Logger.fatal"Model construction: unexpected constant %a as bitvector value"Smtlib_pp.pp_spec_constantcstletget_valuetppx=assert(t.state=Sat);Format.fprintft.formatter"(get-value (%a))@."ppx;letlexbuf=Lexing.from_channelt.stdoutinletopenSmtlibinmatchSmtlib_parser.ivalueSmtlib_lexer.tokenlexbufwith|[(_,{term_desc=TermSpecConstantcst;_})]->value_of_constantcst|_->assertfalseend(* utils *)letpp_int_as_bvppfx=function|1->Format.fprintfppf"#b%d"(xland1)|4->Format.fprintfppf"#x%01x"(xland0xf)|8->Format.fprintfppf"#x%02x"(xland0xff)|12->Format.fprintfppf"#x%03x"(xland0xfff)|16->Format.fprintfppf"#x%04x"(xland0xffff)|20->Format.fprintfppf"#x%05x"(xland0xfffff)|24->Format.fprintfppf"#x%06x"(xland0xffffff)|28->Format.fprintfppf"#x%07x"(xland0xfffffff)|32->Format.fprintfppf"#x%08x"(xland0xffffffff)|szwhenx<0->Format.fprintfppf"(_ bv%a %d)"Z.pp_print(Z.extract(Z.of_intx)0sz)sz|sz->Format.fprintfppf"(_ bv%d %d)"xszletpp_bvppfvaluesize=trypp_int_as_bvppf(Z.to_intvalue)sizewithZ.Overflow->Format.fprintfppf"(_ bv%a %d)"Z.pp_print(ifZ.ltvalueZ.zerothenZ.extractvalue0sizeelsevalue)sizemodulePrinter=structopenSexprtypeterm=stringtypeaccess=Selectofterm*int|Storeofterm*intanddef=BlofExpr.t|BvofExpr.t|AxofMemory.t|Declofstringandt={fvariables:Expr.tStTbl.t;farrays:Memory.tStTbl.t;mutableid:Suid.t;bl_cons:stringBvTbl.t;bv_cons:stringBvTbl.t;ax_cons:stringAxTbl.t;ax_root:Memory.tAxTbl.t;ordered_defs:defQueue.t;ordered_mem:accessQueue.tAxTbl.t;word_size:int;debug:name:string->label:string->string;}letcreate?(word_size=Kernel_options.Machine.word_size())?(debug=fun~name~label:_->name)~next_id()=letbv_cons=BvTbl.create128andbl_cons=BvTbl.create32inBvTbl.addbl_consExpr.zero"false";BvTbl.addbv_consExpr.zero"#b0";BvTbl.addbl_consExpr.one"true";BvTbl.addbv_consExpr.one"#b1";{fvariables=StTbl.create16;farrays=StTbl.create4;id=next_id;bl_cons;bv_cons;ax_cons=AxTbl.create64;ax_root=AxTbl.create64;ordered_defs=Queue.create();ordered_mem=AxTbl.create4;word_size;debug;}letcopy{fvariables;farrays;id;bl_cons;bv_cons;ax_cons;ax_root;ordered_defs;ordered_mem;word_size;debug;}=letordered_mem=AxTbl.fold(funaxhistorytbl->AxTbl.addtblax(Queue.copyhistory);tbl)ordered_mem(AxTbl.create(AxTbl.lengthordered_mem))in{fvariables=StTbl.copyfvariables;farrays=StTbl.copyfarrays;id;bl_cons=BvTbl.copybl_cons;bv_cons=BvTbl.copybv_cons;ax_cons=AxTbl.copyax_cons;ax_root;ordered_defs=Queue.copyordered_defs;ordered_mem;word_size;debug;}letpp_int_as_offsetsizeppfi=pp_bvppfisizeletonce=""andevicted="\\"letrecvisit_blctxbl=matchBvTbl.findctx.bl_consblwith|exceptionNot_found->visit_and_mark_blctxblBvTbl.addonce|label->iflabel==oncethen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;BvTbl.replacectx.bl_consblname)elseiflabel==evictedthen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;visit_and_mark_blctxblBvTbl.replacename)andvisit_and_mark_blctx(bl:Expr.t)setlabel=matchblwith|Cst_->()|Load_(* cannot be a bl<1> *)->assertfalse|Unary{f=Not;x;_}->setctx.bl_consbllabel;visit_blctxx;Queue.push(Blbl)ctx.ordered_defs|Binary{f=And|Or;x;y;_}->setctx.bl_consbllabel;visit_blctxx;visit_blctxy;Queue.push(Blbl)ctx.ordered_defs|Binary{f=Eq|Diff|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt;x;y;_;}->setctx.bl_consbllabel;visit_bvctxx;visit_bvctxy;Queue.push(Blbl)ctx.ordered_defs|Ite{c;t;e;_}->setctx.bl_consbllabel;visit_blctxc;visit_blctxt;visit_blctxe;Queue.push(Blbl)ctx.ordered_defs|Var_|Unary_|Binary_->visit_bvctxblandvisit_bvctxbv=matchBvTbl.findctx.bv_consbvwith|exceptionNot_found->visit_and_mark_bvctxbvBvTbl.addonce|label->iflabel==oncethen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;BvTbl.replacectx.bv_consbvname)elseiflabel==evictedthen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;visit_and_mark_bvctxbvBvTbl.replacename)andvisit_and_mark_bvctxbvsetlabel'=matchbvwith|Var{name;size;label;_}->StTbl.addctx.fvariablesnamebv;letname=ctx.debug~name~labelinBvTbl.addctx.bv_consbvname;ifsize=1thenBvTbl.addctx.bl_consbv(Printf.sprintf"(= %s #b1)"name);Queue.push(Decl(Format.sprintf"(declare-fun %s () (_ BitVec %d))"namesize))ctx.ordered_defs|Load{len;addr;label;_}->setctx.bv_consbvlabel';visit_bvctxaddr;visit_bvctxaddr;visit_axctxlabel;iflen>1thenvisit_axctxlabel;Queue.push(Bvbv)ctx.ordered_defs;letroot=AxTbl.findctx.ax_rootlabelinletordered_mem=AxTbl.findctx.ordered_memrootinQueue.push(Select(BvTbl.findctx.bv_consaddr,len))ordered_mem|Cst_->setctx.bv_consbvlabel';Queue.push(Bvbv)ctx.ordered_defs|Unary{x;_}->setctx.bv_consbvlabel';visit_bvctxx;Queue.push(Bvbv)ctx.ordered_defs|Binary{f=Eq|Diff|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt;_}->setctx.bv_consbvlabel';visit_blctxbv;Queue.push(Bvbv)ctx.ordered_defs|Binary{f=Rol|Ror;x;y=(Load_|Unary_|Binary_|Ite_)asy;_}->setctx.bv_consbvlabel';visit_bvctxx;visit_bvctxx;visit_bvctxy;visit_bvctxy;Queue.push(Bvbv)ctx.ordered_defs|Binary{x;y;_}->setctx.bv_consbvlabel';visit_bvctxx;visit_bvctxy;Queue.push(Bvbv)ctx.ordered_defs|Ite{c;t;e;_}->setctx.bv_consbvlabel';visit_blctxc;visit_bvctxt;visit_bvctxe;Queue.push(Bvbv)ctx.ordered_defsandvisit_axctx(ax:Memory.t)=matchAxTbl.findctx.ax_consaxwith|exceptionNot_found->visit_and_mark_axctxaxAxTbl.addonce|label->iflabel==oncethen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;AxTbl.replacectx.ax_consaxname)elseiflabel==evictedthen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;visit_and_mark_axctxaxAxTbl.replacename)andvisit_and_mark_axctx(ax:Memory.t)setlabel=matchaxwith|Root->AxTbl.addctx.ax_consax(ctx.debug~name:Suid.(to_stringzero)~label:"memory");AxTbl.addctx.ax_rootaxax;AxTbl.addctx.ordered_memax(Queue.create());Queue.push(Decl(Format.sprintf"(declare-fun %s () (Array (_ BitVec %d) (_ BitVec %d)))"(ctx.debug~name:Suid.(to_stringzero)~label:"memory")ctx.word_sizebyte_size))ctx.ordered_defs|Symbolname->StTbl.addctx.farraysnameax;AxTbl.addctx.ax_consaxname;AxTbl.addctx.ax_rootaxax;AxTbl.addctx.ordered_memax(Queue.create());Queue.push(Decl(Format.sprintf"(declare-fun %s () (Array (_ BitVec %d) (_ BitVec %d)))"namectx.word_sizebyte_size))ctx.ordered_defs|Layer{addr=Cst_;store;over;_}->setctx.ax_consaxlabel;Store.iter_term(fun_bv->visit_bvctxbv;ifExpr.sizeofbv<>8thenvisit_bvctxbv)store;visit_axctxover;letroot=AxTbl.findctx.ax_rootoverinAxTbl.addctx.ax_rootaxroot;Queue.push(Axax)ctx.ordered_defs;letordered_mem=AxTbl.findctx.ordered_memrootinStore.iter_term(funibv->letindex=Format.asprintf"%a"(pp_int_as_offsetctx.word_size)iinQueue.push(Store(index,Expr.sizeofbvlsr3))ordered_mem)store|Layer{addr;store;over;_}->setctx.ax_consaxlabel;visit_bvctxaddr;visit_bvctxaddr;Store.iter_term(fun_bv->visit_bvctxbv;ifExpr.sizeofbv<>8thenvisit_bvctxbv)store;visit_axctxover;letroot=AxTbl.findctx.ax_rootoverinAxTbl.addctx.ax_rootaxroot;Queue.push(Axax)ctx.ordered_defs;letordered_mem=AxTbl.findctx.ordered_memrootinletindex=BvTbl.findctx.bv_consaddrinStore.iter_term(funibv->letindex=Format.asprintf"(bvadd %s %a)"index(pp_int_as_offsetctx.word_size)iinQueue.push(Store(index,Expr.sizeofbvlsr3))ordered_mem)storeletpp_unopppf(op:Term.unaryTerm.operator)=matchopwith|Not->Format.pp_print_stringppf"bvnot"|Minus->Format.pp_print_stringppf"bvneg"|Uextn->Format.fprintfppf"(_ zero_extend %d)"n|Sextn->Format.fprintfppf"(_ sign_extend %d)"n|Restrict{Interval.hi;lo}->Format.fprintfppf"(_ extract %d %d)"hiloletpp_binop=letstring_of_binop(op:Term.binaryTerm.operator)=matchopwith|Plus->"bvadd"|Minus->"bvsub"|Mul->"bvmul"|Udiv->"bvudiv"|Sdiv->"bvsdiv"|Umod->"bvurem"|Smod->"bvsrem"|Or->"bvor"|And->"bvand"|Xor->"bvxor"|Concat->"concat"|Lsl->"bvshl"|Lsr->"bvlshr"|Asr->"bvashr"|Rol->"rotate_left"|Ror->"rotate_right"|Eq->"="|Diff->assertfalse|Ule->"bvule"|Ult->"bvult"|Uge->"bvuge"|Ugt->"bvugt"|Sle->"bvsle"|Slt->"bvslt"|Sge->"bvsge"|Sgt->"bvsgt"infunppff->Format.pp_print_stringppf(string_of_binopf)letrecprint_blctxppfbl=tryletname=BvTbl.findctx.bl_consblinifname==once||name==evictedthenprint_bl_no_consctxppfblelseFormat.pp_print_stringppfnamewithNot_found->Format.pp_print_stringppf"(= ";Format.pp_print_spaceppf();print_bvctxppfbl;Format.pp_print_stringppf" #b1)"andprint_bl_no_consctxppfbl=matchblwith|Cst_(* true and false should already be in the cache *)|Load_(* cannot be a bl<1> *)->assertfalse|Unary{f=Not;x;_}->Format.pp_print_stringppf"(not";Format.pp_print_spaceppf();print_blctxppfx;Format.pp_print_charppf')'|Binary{f=(And|Or)asf;x;y;_}->Format.pp_print_charppf'(';(Format.pp_print_stringppf@@matchfwithAnd->"and"|Or->"or"|_->assertfalse);Format.pp_print_spaceppf();print_blctxppfx;Format.pp_print_spaceppf();print_blctxppfy;Format.pp_print_charppf')'|Binary{f=Diff;x;y;_}->Format.pp_print_stringppf"(not";Format.pp_print_spaceppf();Format.pp_print_stringppf"(=";Format.pp_print_spaceppf();print_bvctxppfx;Format.pp_print_spaceppf();print_bvctxppfy;Format.pp_print_stringppf"))"|Binary{f=(Eq|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt)asf;x;y;_;}->Format.pp_print_charppf'(';pp_binopppff;Format.pp_print_spaceppf();print_bvctxppfx;Format.pp_print_spaceppf();print_bvctxppfy;Format.pp_print_charppf')'|Ite{c;t;e;_}->Format.pp_print_stringppf"(ite";Format.pp_print_spaceppf();print_blctxppfc;Format.pp_print_spaceppf();print_blctxppft;Format.pp_print_spaceppf();print_blctxppfe;Format.pp_print_charppf')'|Var_|Unary_|Binary_->Format.pp_print_stringppf"(=";Format.pp_print_spaceppf();print_bvctxppfbl;Format.pp_print_spaceppf();Format.pp_print_stringppf"#b1)"andprint_bvctxppfbv=letname=BvTbl.findctx.bv_consbvinifname==once||name==evictedthenprint_bv_no_consctxppfbvelseFormat.pp_print_stringppfnameandprint_bv_no_consctxppfbv=matchbvwith|Var{name;_}->Format.pp_print_stringppfname|Load{len=1;addr;label;_}->Format.pp_print_stringppf"(select";Format.pp_print_spaceppf();print_axctxppflabel;Format.pp_print_spaceppf();print_bvctxppfaddr;Format.pp_print_charppf')'|Load{len;dir;addr;label;_}->Format.pp_print_stringppf"(concat";print_multi_selectdirppflen(AxTbl.findctx.ax_conslabel)(BvTbl.findctx.bv_consaddr)(Expr.sizeofaddr);Format.pp_print_charppf')'|Cstbv->letsize=Bv.size_ofbvandvalue=Bv.value_ofbvinpp_bvppfvaluesize|Unary{f;x;_}->Format.pp_print_charppf'(';pp_unopppff;Format.pp_print_spaceppf();print_bvctxppfx;Format.pp_print_charppf')'|Binary{f=Eq|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt;_}->Format.pp_print_stringppf"(ite";Format.pp_print_spaceppf();print_blctxppfbv;Format.pp_print_spaceppf();Format.pp_print_stringppf"#b1";Format.pp_print_spaceppf();Format.pp_print_stringppf"#b0)"|Binary{f=Diff;x;y;_}->Format.pp_print_stringppf"(ite (=";Format.pp_print_spaceppf();print_bvctxppfx;Format.pp_print_spaceppf();print_bvctxppfy;Format.pp_print_charppf')';Format.pp_print_spaceppf();Format.pp_print_stringppf"#b0";Format.pp_print_spaceppf();Format.pp_print_stringppf"#b1)"|Binary{f=(Rol|Ror)asf;x;y=Cstbv;_}->Format.pp_print_stringppf"((_";Format.pp_print_spaceppf();pp_binopppff;Format.pp_print_spaceppf();Z.pp_printppf(Bv.value_ofbv);Format.pp_print_charppf')';Format.pp_print_spaceppf();print_bvctxppfx;Format.pp_print_charppf')'|Binary{f=(Rol|Ror)asf;x;y;_}->Format.pp_print_stringppf"(bvor";Format.pp_print_spaceppf();Format.pp_print_charppf'(';pp_binopppf(matchfwithRol->Lsl|Ror->Lsr|_->assertfalse);Format.pp_print_spaceppf();Format.pp_print_stringppf(BvTbl.findctx.bv_consx);Format.pp_print_spaceppf();Format.pp_print_stringppf(BvTbl.findctx.bv_consy);Format.pp_print_charppf')';Format.pp_print_spaceppf();Format.pp_print_charppf'(';pp_binopppf(matchfwithRol->Lsr|Ror->Lsl|_->assertfalse);Format.pp_print_spaceppf();Format.pp_print_stringppf(BvTbl.findctx.bv_consx);Format.pp_print_spaceppf();Format.pp_print_stringppf"(bvsub";Format.pp_print_spaceppf();pp_int_as_bvppf(Expr.sizeofx)(Expr.sizeofx);Format.pp_print_spaceppf();Format.pp_print_stringppf(BvTbl.findctx.bv_consy);Format.pp_print_stringppf")))"|Binary{f;x;y;_}->Format.pp_print_charppf'(';pp_binopppff;Format.pp_print_spaceppf();print_bvctxppfx;Format.pp_print_spaceppf();print_bvctxppfy;Format.pp_print_charppf')'|Ite{c;t;e;_}->Format.pp_print_stringppf"(ite";Format.pp_print_spaceppf();print_blctxppfc;Format.pp_print_spaceppf();print_bvctxppft;Format.pp_print_spaceppf();print_bvctxppfe;Format.pp_print_charppf')'andprint_axctxppfax=letname=AxTbl.findctx.ax_consaxinifname==once||name==evictedthenprint_ax_no_consctxppfaxelseFormat.pp_print_stringppfnameandprint_ax_no_consctxppf(ax:Memory.t)=matchaxwith|Root->Suid.ppppfSuid.zero|Symbol_->assertfalse|Layer{addr;store;over;_}->Store.iter_term(fun_value->for_=1toExpr.sizeofvaluelsr3doFormat.pp_print_stringppf"(store";Format.pp_print_spaceppf()done)store;print_axctxppfover;letaddr_space=ctx.word_sizeinletrebase,idx=matchaddrwith|Cst_->(false,"")|_->(true,BvTbl.findctx.bv_consaddr)inletrecunroll_storeloibv=Format.pp_print_spaceppf();ifrebasethenifZ.zero=ithen(Format.pp_print_stringppfidx;Format.pp_print_spaceppf())else(Format.pp_print_stringppf"(bvadd";Format.pp_print_spaceppf();Format.pp_print_stringppfidx;Format.pp_print_spaceppf();pp_bvppfiaddr_space;Format.pp_print_charppf')')elsepp_bvppfiaddr_space;Format.pp_print_spaceppf();letsize=Expr.sizeofbvinifsize>8then(Format.fprintfppf"((_ extract %d %d)"(lo+7)lo;Format.pp_print_spaceppf();print_bvctxppfbv;Format.pp_print_stringppf"))";letlo'=lo+8iniflo'<sizethenunroll_storelo'(Z.succi)bv)else(print_bvctxppfbv;Format.pp_print_charppf')')inStore.iter_term(unroll_store0)storeandprint_multi_select=letrecprint_multi_select_leppflenaxbvsize=iflen=1thenFormat.fprintfppf" (select@ %s@ %s)"axbvelseletlen=len-1inFormat.fprintfppf" (select@ %s@ (bvadd@ %s@ "axbv;pp_int_as_bvppflensize;Format.pp_print_stringppf"))";print_multi_select_leppflenaxbvsizeinletrecprint_multi_select_beippflenaxbvsize=ifi=0then(Format.fprintfppf"@ (select@ %s@ %s)"axbv;print_multi_select_be1ppflenaxbvsize)elseifi<lenthen(Format.fprintfppf" (select@ %s@ (bvadd@ %s@ "axbv;pp_int_as_bvppfisize;Format.pp_print_stringppf"))";print_multi_select_be(i+1)ppflenaxbvsize)infunction|LittleEndian->print_multi_select_le|BigEndian->print_multi_select_be0letpp_print_defsppfctx=Queue.iter(function|Blbl->letname=BvTbl.findctx.bl_consblinifname==oncethenBvTbl.replacectx.bl_consblevictedelseifname==evictedthen()else(Format.fprintfppf"@[<h>(define-fun %s () Bool "name;print_bl_no_consctxppfbl;Format.fprintfppf")@]@ ")|Bvbv->letname=BvTbl.findctx.bv_consbvinifname==oncethenBvTbl.replacectx.bv_consbvevictedelseifname==evictedthen()else(Format.fprintfppf"@[<h>(define-fun %s () (_ BitVec %d) "name(Expr.sizeofbv);print_bv_no_consctxppfbv;Format.fprintfppf")@]@ ")|Axax->letname=AxTbl.findctx.ax_consaxinifname==oncethenAxTbl.replacectx.ax_consaxevictedelseifname==evictedthen()else(Format.fprintfppf"@[<h>(define-fun %s () (Array (_ BitVec %d) (_ BitVec %d)) "name(Kernel_options.Machine.word_size())byte_size;print_ax_no_consctxppfax;Format.fprintfppf")@]@ ")|Decldl->Format.pp_print_stringppfdl;Format.pp_print_spaceppf())ctx.ordered_defsletpp_flush_defsppfctx=pp_print_defsppfctx;Queue.clearctx.ordered_defsletpp_print_bl=print_blletpp_print_bv=print_bvletpp_print_ax=print_axendmoduleCross=structopenSexprtypek=|BlofExpr.t|BvofExpr.t|AxofMemory.t|AssertofExpr.t|BvDefineofFormula.bv_var*Expr.t|AxDefineofFormula.ax_var*Memory.tandt={mutableid:Suid.t;bv_decl:Formula.declBvTbl.t;ax_decl:Formula.declAxTbl.t;bl_cons:Formula.bl_varBvTbl.t;bv_cons:Formula.bv_varBvTbl.t;ax_cons:Formula.ax_varAxTbl.t;ordered:kQueue.t;word_size:int;debug:name:string->label:string->string;}letcreate?(word_size=Kernel_options.Machine.word_size())?(debug=fun~name~label:_->name)~next_id()={id=next_id;bv_decl=BvTbl.create16;ax_decl=AxTbl.create1;bl_cons=BvTbl.create32;bv_cons=BvTbl.create128;ax_cons=AxTbl.create64;ordered=Queue.create();word_size;debug;}letbl_once=Formula.bl_var"!"letbv_once=Formula.bv_var"!"1letax_once=Formula.ax_var"!"11letrecvisit_blctxbl=tryifBvTbl.findctx.bl_consbl==bl_oncethen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;BvTbl.replacectx.bl_consbl(Formula.bl_varname))withNot_found->(matchblwith|Cst_->()|Load_(* cannot be a bl<1> *)->assertfalse|Unary{f=Not;x;_}->BvTbl.addctx.bl_consblbl_once;visit_blctxx;Queue.push(Blbl)ctx.ordered|Binary{f=And|Or;x;y;_}->BvTbl.addctx.bl_consblbl_once;visit_blctxx;visit_blctxy;Queue.push(Blbl)ctx.ordered|Binary{f=Eq|Diff|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt;x;y;_;}->BvTbl.addctx.bl_consblbl_once;visit_bvctxx;visit_bvctxy;Queue.push(Blbl)ctx.ordered|Ite{c;t;e;_}->BvTbl.addctx.bl_consblbl_once;visit_blctxc;visit_blctxt;visit_blctxe;Queue.push(Blbl)ctx.ordered|Var_|Unary_|Binary_->visit_bvctxbl)andvisit_bvctxbv=tryifBvTbl.findctx.bv_consbv==bv_oncethen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;BvTbl.replacectx.bv_consbv(Formula.bv_varname(Expr.sizeofbv)))withNot_found->(matchbvwith|Var{name;size;label;_}->letname=ctx.debug~name~labelinletvar=Formula.bv_varnamesizeinBvTbl.addctx.bv_consbvvar;BvTbl.addctx.bv_declbv(Formula.mk_bv_declvar[])|Load{addr;label;_}->BvTbl.addctx.bv_consbvbv_once;visit_bvctxaddr;visit_axctxlabel;Queue.push(Bvbv)ctx.ordered|Cst_->BvTbl.addctx.bv_consbvbv_once;Queue.push(Bvbv)ctx.ordered|Unary{x;_}->BvTbl.addctx.bv_consbvbv_once;visit_bvctxx;Queue.push(Bvbv)ctx.ordered|Binary{f=Eq|Diff|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt;_}->BvTbl.addctx.bv_consbvbv_once;visit_blctxbv;Queue.push(Bvbv)ctx.ordered|Binary{x;y;_}->BvTbl.addctx.bv_consbvbv_once;visit_bvctxx;visit_bvctxy;Queue.push(Bvbv)ctx.ordered|Ite{c;t;e;_}->BvTbl.addctx.bv_consbvbv_once;visit_blctxc;visit_bvctxt;visit_bvctxe;Queue.push(Bvbv)ctx.ordered)andvisit_axctxax=tryifAxTbl.findctx.ax_consax==ax_oncethen(letname=Suid.to_stringctx.idinctx.id<-Suid.incrctx.id;AxTbl.replacectx.ax_consax(Formula.ax_varnamectx.word_size8))withNot_found->(matchaxwith|Memory.Root->letvar=Formula.ax_var(ctx.debug~name:Suid.(to_stringzero)~label:"memory")ctx.word_size8inAxTbl.addctx.ax_consaxvar;AxTbl.addctx.ax_declax(Formula.mk_ax_declvar[])|Memory.Symbolname->letvar=Formula.ax_var(ctx.debug~name~label:"")ctx.word_size8inAxTbl.addctx.ax_consaxvar;AxTbl.addctx.ax_declax(Formula.mk_ax_declvar[])|Memory.Layer{addr;store;over;_}->AxTbl.addctx.ax_consaxax_once;visit_bvctxaddr;Store.iter_term(fun_bv->visit_bvctxbv)store;visit_axctxover;Queue.push(Axax)ctx.ordered)letassert_blctxbl=visit_blctxbl;Queue.push(Assertbl)ctx.orderedletdefine_bvctxnamebv=visit_bvctxbv;letvar=Formula.bv_varname(Expr.sizeofbv)inQueue.push(BvDefine(var,bv))ctx.orderedletdefine_axctxnameax=visit_axctxax;letvar=Formula.ax_varnamectx.word_size8inQueue.push(AxDefine(var,ax))ctx.orderedletmk_unop(op:Term.unaryTerm.operator)=matchopwith|Not->Formula.BvNot|Minus->Formula.BvNeg|Uextn->Formula.BvZeroExtendn|Sextn->Formula.BvSignExtendn|Restricti->Formula.BvExtractiletmk_comp(op:Term.binaryTerm.operator)=matchopwith|Eq->Formula.BvEqual|Diff->Formula.BvDistinct|Uge->Formula.BvUge|Ule->Formula.BvUle|Ugt->Formula.BvUgt|Ult->Formula.BvUlt|Sge->Formula.BvSge|Sle->Formula.BvSle|Sgt->Formula.BvSgt|Slt->Formula.BvSlt|Plus|Minus|Mul|Udiv|Sdiv|Umod|Smod|Or|And|Xor|Concat|Lsl|Lsr|Asr|Rol|Ror->assertfalseletmk_bnop(op:Term.binaryTerm.operator)=matchopwith|Eq|Diff|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt->assertfalse|Plus->Formula.BvAdd|Minus->Formula.BvSub|Mul->Formula.BvMul|Udiv->Formula.BvUdiv|Sdiv->Formula.BvSdiv|Umod->Formula.BvUrem|Smod->Formula.BvSmod|Or->Formula.BvOr|And->Formula.BvAnd|Xor->Formula.BvXor|Concat->Formula.BvConcat|Lsl->Formula.BvShl|Lsr->Formula.BvLshr|Asr->Formula.BvAshr|Rol|Ror->assertfalseletrecmk_blctxbl=tryletvar=BvTbl.findctx.bl_consblinifvar==bl_oncethenmk_bl_no_consctxblelseFormula.mk_bl_varvarwithNot_found->Formula.mk_bv_equal(mk_bvctxbl)Formula.mk_bv_oneandmk_bl_no_consctxbl=matchblwith|Cstbv->ifBitvector.is_onebvthenFormula.mk_bl_trueelseFormula.mk_bl_false|Load_(* cannot be a bl<1> *)->assertfalse|Unary{f=Not;x;_}->Formula.mk_bl_not(mk_blctxx)|Binary{f=And;x;y;_}->Formula.mk_bl_and(mk_blctxx)(mk_blctxy)|Binary{f=Or;x;y;_}->Formula.mk_bl_or(mk_blctxx)(mk_blctxy)|Binary{f=(Eq|Diff|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt)asf;x;y;_;}->Formula.mk_bv_comp(mk_compf)(mk_bvctxx)(mk_bvctxy)|Ite{c;t;e;_}->Formula.mk_bl_ite(mk_blctxc)(mk_blctxt)(mk_blctxe)|Var_|Unary_|Binary_->Formula.mk_bv_equal(mk_bvctxbl)Formula.mk_bv_oneandmk_bvctxbv=letvar=BvTbl.findctx.bv_consbvinifvar==bv_oncethenmk_bv_no_consctxbvelseFormula.mk_bv_varvarandmk_bv_no_consctxbv=matchbvwith|Var_->assertfalse|Load{len;dir=LittleEndian;addr;label;_}->Formula.mk_selectlen(mk_axctxlabel)(mk_bvctxaddr)|Load{len;dir=BigEndian;addr;label;_}->mk_select_belen(mk_axctxlabel)(mk_bvctxaddr)|Cstbv->Formula.mk_bv_cstbv|Unary{f;x;_}->Formula.mk_bv_unop(mk_unopf)(mk_bvctxx)|Binary{f=Eq|Diff|Uge|Ule|Ugt|Ult|Sge|Sle|Sgt|Slt;_}->Formula.mk_bv_ite(mk_blctxbv)Formula.mk_bv_oneFormula.mk_bv_zero|Binary{f=Rol;x;y=Cstbv;_}->Formula.mk_bv_rotate_left(Bv.to_uintbv)(mk_bvctxx)|Binary{f=Ror;x;y=Cstbv;_}->Formula.mk_bv_rotate_right(Bv.to_uintbv)(mk_bvctxx)|Binary{f=Rol;x;y;_}->Formula.mk_bv_or(Formula.mk_bv_shl(mk_bvctxx)(mk_bvctxy))(Formula.mk_bv_lshr(mk_bvctxx)(Formula.mk_bv_sub_int(mk_bvctxy)(Expr.sizeofx)))|Binary{f=Ror;x;y;_}->Formula.mk_bv_or(Formula.mk_bv_lshr(mk_bvctxx)(mk_bvctxy))(Formula.mk_bv_shl(mk_bvctxx)(Formula.mk_bv_sub_int(mk_bvctxy)(Expr.sizeofx)))|Binary{f;x;y;_}->Formula.mk_bv_bnop(mk_bnopf)(mk_bvctxx)(mk_bvctxy)|Ite{c;t;e;_}->Formula.mk_bv_ite(mk_blctxc)(mk_bvctxt)(mk_bvctxe)andmk_axctxax=letvar=AxTbl.findctx.ax_consaxinifvar==ax_oncethenmk_ax_no_consctxaxelseFormula.mk_ax_varvarandmk_ax_no_consctxax=matchaxwith|Memory.Root|Memory.Symbol_->assertfalse|Memory.Layer{addr;store;over;_}->letaddr=mk_bvctxaddrinStore.fold_term(funibvstore->Formula.mk_store(Expr.sizeofbvlsr3)store(Formula.mk_bv_addaddr(Formula.mk_bv_cst(Bitvector.createictx.word_size)))(mk_bvctxbv))(mk_axctxover)storeandmk_select_be=letrecmk_select_belenaxbvsel=iflen=0thenselelseletlen=len-1inmk_select_belenaxbv(Formula.mk_bv_concatsel(Formula.mk_select1ax(Formula.mk_bv_add_intbvlen)))infunlenaxbv->letlen=len-1inmk_select_belenaxbv(Formula.mk_select1ax(Formula.mk_bv_add_intbvlen))letto_formulactx=Queue.fold(funformula->function|Blbl->letvar=BvTbl.findctx.bl_consblinifvar!=bl_oncethenFormula.push_front_define(Formula.mk_bl_defvar[](mk_bl_no_consctxbl))formulaelseformula|Bvbv->letvar=BvTbl.findctx.bv_consbvinifvar!=bv_oncethenFormula.push_front_define(Formula.mk_bv_defvar[](mk_bv_no_consctxbv))formulaelseformula|Axax->letvar=AxTbl.findctx.ax_consaxinifvar!=ax_oncethenFormula.push_front_define(Formula.mk_ax_defvar[](mk_ax_no_consctxax))formulaelseformula|Assertbl->Formula.push_front_assert(mk_blctxbl)formula|BvDefine(var,bv)->Formula.push_front_define(Formula.mk_bv_defvar[](mk_bvctxbv))formula|AxDefine(var,ax)->Formula.push_front_define(Formula.mk_ax_defvar[](mk_axctxax))formula)(BvTbl.fold(fun_declformula->Formula.push_front_declaredeclformula)ctx.bv_decl(AxTbl.fold(fun_declformula->Formula.push_front_declaredeclformula)ctx.ax_declFormula.empty))ctx.orderedendmoduleSolver():Solver.S=structopenSexprletsession=Session.start(* ~stdlog:stderr *)(Formula_options.Solver.get())letctx=ref[Printer.create~next_id:Suid.zero()]lettop()=List.hd!ctxletvisit_formula=List.iter(Printer.visit_bl(top()))letiter_free_variablesf=StTbl.iterf(top()).fvariablesletiter_free_arraysf=StTbl.iterf(top()).farraysletpush()=ctx:=Printer.copy(List.hd!ctx)::!ctx;Format.pp_print_stringsession.formatter"(push 1)"letpop()=ctx:=List.tl!ctx;Format.pp_print_stringsession.formatter"(pop 1)"letflush_bl(ctx:Printer.t)x=matchBvTbl.findctx.bl_consxwith|exceptionNot_found->Printer.visit_blctxx;Printer.visit_blctxx;Printer.pp_flush_defssession.formatterctx;BvTbl.findctx.bl_consx|name->ifname==Printer.once||name==Printer.evictedthen(Printer.visit_blctxx;Printer.pp_flush_defssession.formatterctx;BvTbl.findctx.bl_consx)elsenameletassert_formulabl=letctx=top()inFormat.pp_open_hovboxsession.formatter0;(* print declarations *)letbl=flush_blctxblin(* print assertion *)Format.pp_print_stringsession.formatter"(assert ";Format.pp_print_stringsession.formatterbl;Format.pp_print_charsession.formatter')';Format.pp_print_spacesession.formatter();Format.pp_close_boxsession.formatter()letflush_bv(ctx:Printer.t)x=matchBvTbl.findctx.bv_consxwith|exceptionNot_found->Printer.visit_bvctxx;Printer.visit_bvctxx;Printer.pp_flush_defssession.formatterctx;BvTbl.findctx.bv_consx|name->ifname==Printer.once||name==Printer.evictedthen(Printer.visit_bvctxx;Printer.pp_flush_defssession.formatterctx;BvTbl.findctx.bv_consx)elsenameletget_valuex=letctx=top()inletbv=flush_bvctxxinSession.get_valuesessionFormat.pp_print_stringbvletget_atnamexs=Session.get_valuesession(funppfx->Format.pp_print_stringppf"(select ";Format.pp_print_stringppfname;Format.pp_print_charppf' ';pp_bvppfxs;Format.pp_print_charppf')')xletfold_array_valuesfarx=letctx=top()inmatchAxTbl.findctx.ordered_memarwith|exceptionNot_found->x|history->ifQueue.is_emptyhistorythenxelseletdirty=BiTbl.create(Queue.lengthhistory)inletname=Format.asprintf"%a"(Printer.pp_print_axctx)arandaddr_space=ctx.word_sizeinQueue.fold(funx(access:Printer.access)->matchaccesswith|Select(index,len)->letindex=Session.get_valuesessionFormat.pp_print_stringindexinletrecfoldindexlenx=iflen=0thenxelseifBiTbl.memdirtyindexthenfold(Z.succindex)(len-1)xelseletk=get_atnameindexaddr_spaceinfold(Z.succindex)(len-1)(findexkx)infoldindexlenx|Store(index,len)->letindex=Session.get_valuesessionFormat.pp_print_stringindexinletrecloopindexlen=iflen<>0then(BiTbl.replacedirtyindex();loop(Z.succindex)(len-1))inloopindexlen;x)xhistoryletcheck_sat?timeout():Libsolver.status=Session.check_satsession~timeoutletcheck_sat_assuming?timeoutbl:Libsolver.status=letctx=top()inPrinter.visit_blctxbl;Printer.visit_blctxbl;Printer.pp_flush_defssession.formatterctx;Session.check_sat_assumingsession~timeout(BvTbl.findctx.bl_consbl)letclose()=Session.closesessionend