123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904(**************************************************************************)(* *)(* This file is part of WP plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat a l'energie atomique et aux energies *)(* 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). *)(* *)(**************************************************************************)(* TODO DEVEL MODE *)[@@@warning"-32-37-60"](* -------------------------------------------------------------------------- *)(* --- Region Memory Model --- *)(* -------------------------------------------------------------------------- *)openCil_typesopenSigsopenDefinitionsmoduleWp=Wp_parametersmoduleF=Lang.FmoduleL=Qed.Logic(* -------------------------------------------------------------------------- *)(* --- Why-3 Region Theory --- *)(* -------------------------------------------------------------------------- *)letlibrary="region"letcluster_region()=Definitions.cluster~id:"Region"~title:"Region Index Constructors"()(* Index *)lett_addr=MemMemory.t_addrlett_index=L.Data(Lang.datatype~library"index",[])letf_addrof=Lang.extern_f~library~result:t_addr"addrof"letf_consistent=Lang.extern_fp~library"consistent"letf_consistent_range=Lang.extern_fp~library"consistent_range"leta_addrofl=F.e_funf_addrof[l]letp_consistentl=F.p_callf_consistent[l]letp_consistent_rangeln=F.p_callf_consistent_range[l;n]letp_rangeknps=F.(p_leqe_zerok::p_ltkn::ps)(* Null *)letf_inull=Lang.extern_f~library~result:t_index"inull"letl_inull=F.e_funf_inull[]leta_null=MemMemory.a_nullletp_inulll=F.p_equala_null(a_addrofl)(* Address *)letp_separatedpnqm=F.p_callMemMemory.p_separated[p;n;q;m](* Constructors *)letregion_ctor~result=Lang.extern_f~library~category:L.Constructor~result"%s"letf_addr_var=region_ctor~result:t_addr"addr_var"letf_addr_ref=region_ctor~result:t_addr"addr_ref"letf_base_var=region_ctor~result:L.Int"base_var"letf_base_ref=region_ctor~result:L.Int"base_ref"letf_index_var=region_ctor~result:t_index"index_var"letf_index_ref=region_ctor~result:t_index"index_ref"letf_index_mem=region_ctor~result:t_index"index_mem"leta_addr_varx=F.e_funf_addr_var[x]leta_addr_refp=F.e_funf_addr_ref[p]letl_index_varx=F.e_funf_index_var[F.e_intx]letl_index_memlkn=F.e_funf_index_ref[l;k;n]letl_index_refl=F.e_funf_index_ref[l](* Shifts *)leta_shift=MemMemory.a_shiftletf_shift_index=Lang.extern_f~library~result:t_index"shift_index"letl_shift_indexlp=F.e_funf_shift_index[l;p](* Bits *)lett_bits=L.Int(* -------------------------------------------------------------------------- *)(* --- Index Simplifiers --- *)(* -------------------------------------------------------------------------- *)typeindex_builtin={index:(Lang.lfun->F.termlist->F.term->F.term);addrof:(F.termlist->F.term);consistent:(F.termlist->F.pred);}moduleIndexBuiltin=WpContext.Static(structtypekey=Lang.lfuntypedata=index_builtinletname="MemRegion.INDEXER"includeLang.Funend)(* f enjoys shifting props:
- f(l,p,...)+k == f(l,p+k,...)
- &f(l,p,...) = &l+p
*)letis_shiftablef=(f==f_shift_index)||(f==f_index_mem)letphi_addrofindex=matchF.reprindexwith|L.Fun(f,[])whenf==f_inull->a_null|L.Fun(f,[x])whenf==f_index_var->a_addr_varx|L.Fun(f,[l])whenf==f_index_ref->a_addr_ref(a_addrofl)|L.Fun(f,l::p::_)whenis_shiftablef->a_shift(a_addrofl)p|L.Fun(f,es)->(IndexBuiltin.findf).addrofes|_->raiseNot_foundletphi_shift_indexlp=ifp==F.e_zerothenlelsematchF.reprlwith|L.Fun(f,l::q::w)whenis_shiftablef->F.e_funf(l::(F.e_addpq)::w)|L.Fun(f,es)->(IndexBuiltin.findf).indexfesp|_->raiseNot_foundletphi_consistentindex=matchF.reprindexwith|L.Fun(f,[])whenf==f_inull->F.e_false|L.Fun(f,[x])whenf==f_index_var->F.e_neqxF.e_zero|L.Fun(f,[l])whenf==f_index_ref->F.e_prop@@p_consistentl|L.Fun(f,[l;k;n])whenf==f_index_mem->F.e_prop@@F.p_conj@@p_rangekn[p_consistentl]|L.Fun(f,es)->F.e_prop@@(IndexBuiltin.findf).consistentes|_->raiseNot_foundletphi_consistent_rangeindexsizeof=matchF.reprindexwith|L.Fun(f,[l;k;n])whenf==f_index_mem->F.e_prop@@F.p_conj@@F.[p_leqe_zerosizeof;p_leqe_zerok;p_leq(e_addksizeof)n;p_consistentl;]|_->raiseNot_foundlet()=Context.registerbeginfun()->MemMemory.registerf_addr_var~base:(F.e_funf_base_var)~offset:(fun_->F.e_zero);MemMemory.registerf_addr_ref~base:(F.e_funf_base_ref);F.set_builtin_1f_addrofphi_addrof;F.set_builtin_1f_consistentphi_consistent;F.set_builtin_2f_shift_indexphi_shift_index;F.set_builtin_2f_consistent_rangephi_consistent_range;endletcid=ref0(* TODO: projectified *)letconstructor~basename~params~index~addrof~consistent=letid=incrcid;!cidinletlfun=Lang.generated_f~result:t_index"%s_%d"basenameidinletps=List.mapF.e_varparamsinletl=F.e_funlfunpsinletk=Lang.freshvar~basename:"k"L.Intinletofs=F.e_varkin(* Must compute properties before registering simplifiers *)letp_addrof=F.p_equal(a_addrofl)(addrofps)inletp_consistent=F.p_equiv(p_consistentl)(consistentps)inletp_index=F.p_equal(l_shift_indexlofs)(indexlfunpsofs)inIndexBuiltin.definelfun{index;addrof;consistent};funcluster->beginDefinitions.define_symbol{d_cluster=cluster;d_lfun=lfun;d_params=params;d_types=0;d_definition=Logict_index;};Definitions.define_lemma{l_cluster=cluster;l_kind=Admit;l_name=Printf.sprintf"addrof_%s_%d"basenameid;l_forall=params;l_triggers=[];l_lemma=p_addrof;};Definitions.define_lemma{l_cluster=cluster;l_kind=Admit;l_name=Printf.sprintf"consistent_%s_%d"basenameid;l_forall=params;l_triggers=[];l_lemma=p_consistent;};ifp_index!=F.p_truethenDefinitions.define_lemma{l_cluster=cluster;l_kind=Admit;l_name=Printf.sprintf"index_%s_%d"basenameid;l_forall=params@[k];l_triggers=[];l_lemma=p_index;};lfunend(* -------------------------------------------------------------------------- *)(* --- Field Index Constructors --- *)(* -------------------------------------------------------------------------- *)moduleFIELD=structtypet=intlist(* Overlay offsets *)letprettyfmt=function|[]->Format.fprintffmt"{}"|p::ps->beginFormat.fprintffmt"@[<hov 2>{%d"p;List.iter(funp->Format.fprintffmt",@,%d"p)ps;Format.fprintffmt"}@]";endletcompare=Stdlib.compare(* Extract constant offset *)letoffsetk=letrecwalksa=matchF.reprawith|L.Addes->List.fold_leftwalkses|L.Kintz->(trys+Integer.to_int_exnzwithZ.Overflow->s)|_->sinwalk0kletbuiltin_indexfesq=matcheswith|[l;p]->F.e_funf[l;F.e_addqp]|_->raiseNot_foundletbuiltin_addrof=function|[l;p]->a_shift(a_addrofl)p|_->raiseNot_foundletbuiltin_consistentfds=function|[l;p]->F.p_and(p_consistentl)(F.p_any(funfd->F.p_equal(F.e_intfd)p)fds)|_->raiseNot_foundend(* Model Independant Generators *)moduleFIELD_GEN=WpContext.StaticGenerator(FIELD)(structtypekey=FIELD.ttypedata=cluster->Lang.lfunletname="MemRegion.FIELD_GEN"letcompilefds=letl=Lang.freshvar~basename:"l"t_indexinletp=Lang.freshvar~basename:"p"L.Intinconstructor~basename:"field"~params:[l;p]~index:FIELD.builtin_index~addrof:FIELD.builtin_addrof~consistent:(FIELD.builtin_consistentfds)end)(* Model Dependent Definitions *)moduleFIELD_MODEL=WpContext.Generator(FIELD)(structtypekey=FIELD.ttypedata=Lang.lfunletname="MemRegion.FIELD_MODEL"letcompilefds=FIELD_GEN.getfds@@cluster_region()end)letl_fieldovllk=letfds=List.map(funrg->rg.Layout.ofs)ovlinF.e_fun(FIELD_MODEL.getfds)[l;k](* -------------------------------------------------------------------------- *)(* --- Array Index Constructors --- *)(* -------------------------------------------------------------------------- *)moduleARRAY=structtypet=int*intlistletcompare=Stdlib.compareletprettyfmt(s,ds)=Format.fprintffmt"%d%a"sLayout.Matrix.prettyds(* Coefficient from Matrix dimensions: c_i = \Pi_{i<j} d_j *)letcoefssds=letrecwalkcss=function|d::ds->walk(s::cs)(d*s)ds|[]->csinwalk[]sds(* All zeroes *)letzeroes=List.map(fun_->F.e_zero)(* Address shift with coefficient c_i for each index k_i *)letrecshiftacsks=matchcs,kswith|c::cs,k::ks->shift(a_shifta(F.e_factck))csks|_->a(* Address of an array index *)letbuiltin_addrofcs=function|l::ks->shift(a_addrofl)csks|_->raiseNot_found(* Add conditions (0 <= ki < ni) to [ps].
WARNING: ns = rev ds *)letrecadd_range_dimspsksns=matchks,nswith|k::ks,n::ns->add_range_dimsF.(p_rangek(e_intn)ps)ksns|k::ks,[]->add_range_dimsF.(p_equale_zerok::ps)ks[]|[],_->ps(* Consistent index.
WARNING: ns = rev ds *)letbuiltin_consistentns=function|l::ks->F.p_conj(add_range_dims[p_consistentl]ksns)|_->raiseNot_found(* Extract linear forms *)letrecget_linearpolya=matchF.reprawith|L.Addes->List.fold_leftget_linearpolyes|L.Kintz->(try(Integer.to_int_exnz,F.e_one)::polywithZ.Overflow->(1,a)::poly)|L.Times(c,e)->(try(Integer.to_int_exnc,e)::polywithZ.Overflow->(1,a)::poly)|_->(1,a)::poly(* Some of linear form *)letrecadd_linears=function|(k,e)::poly->add_linear(F.e_adds(F.e_factke))poly|[]->s(* Euclidian division *)(* euclid q r ci p = q',r' <-> p + ci.q + r = ci.q' + r' *)letreceuclidqrci=function|[]->q,r|(c,k)::poly->letq0=c/ciinletr0=cmodciineuclid(F.e_addq(F.e_factq0k))((r0,k)::r)cipoly(* Linear offset decomposed on each coefficient *)letrecadd_linear_indexcsksks'p=matchcs,kswith|c::cs,k::ks->letk',r=euclidk[]cpinadd_linear_indexcsks(k'::ks')r|_->List.rev_appendks'ks,p(* Linear offset and remainder delta *)letoffsetcsksp=letks',r=add_linear_indexcsks[](get_linear[]p)inks',add_linearF.e_zeror(* Builtin simplifier *)letbuiltin_indexcsfesp=matcheswith|l::ks->letks',r=offsetcskspinifQed.Hcons.equal_listF.equalksks'thenraiseNot_foundelseletl'=F.e_funf(l::ks)inl_shift_indexl'r|_->raiseNot_foundendmoduleARRAY_GEN=WpContext.StaticGenerator(ARRAY)(structtypekey=ARRAY.ttypedata=(cluster->Lang.lfun)letname="MemRegion.ARRAY_GEN"letcompile(s,ds)=letl=Lang.freshvar~basename:"l"t_indexinletks=List.map(fun_->Lang.freshvar~basename:"k"L.Int)dsinletcs=ARRAY.coefssdsinletns=List.revdsinconstructor~basename:"array"~params:(l::ks)~index:(ARRAY.builtin_indexcs)~addrof:(ARRAY.builtin_addrofcs)~consistent:(ARRAY.builtin_consistentns)end)moduleARRAY_MODEL=WpContext.Generator(ARRAY)(structtypekey=ARRAY.ttypedata=Lang.lfunletname="MemRegion.ARRAY_MODEL"letcompiledim=ARRAY_GEN.getdim@@cluster_region()end)letl_arraysdslks=F.e_fun(ARRAY_MODEL.get(s,ds))(l::ks)(* -------------------------------------------------------------------------- *)(* --- Model Context --- *)(* -------------------------------------------------------------------------- *)letdatatype="MemRegion"letconfigure()=beginletorig_pointer=Context.pushLang.pointert_indexinletorig_null=Context.pushCvalues.nullp_inullinletrollback()=Context.popLang.pointerorig_pointer;Context.popCvalues.nullorig_nullinrollbackendletconfigure_ia=letno_binder={bind=fun_fv->fv}infun_vertex->no_binderlethypothesesp=pleterrormsg=Warning.error~source:"Region Model"msg(* -------------------------------------------------------------------------- *)(* --- Region Maps --- *)(* -------------------------------------------------------------------------- *)letmap()=RegionAnalysis.getbeginmatchWpContext.get_scope()with|WpContext.Global->None|WpContext.Kfkf->Somekfend(* -------------------------------------------------------------------------- *)(* --- Locations --- *)(* -------------------------------------------------------------------------- *)openLayouttyperegion=Region.regiontypeindex=F.termletpp_index=F.pp_termletpp_region=Region.R.prettyletpp_value=Value.prettypp_regionletpp_argsfmt=function|[]->()|k::ks->F.pp_termfmtk;List.iter(funk->Format.fprintffmt"@,,%a"F.pp_termk)ksletpp_fieldfmtk=ifF.is_atomickthenFormat.fprintffmt"@,+%a"F.pp_termkelseFormat.fprintffmt"@,+(%a)"F.pp_termkletpp_deltafmtk=ifk!=F.e_zerothenpp_fieldfmtktypeloc=|GarbledMix(* any possible location *)|Indexofindex(* unqualified address *)|Lrefofregion*index*region|Lmemofregion*index*root*regionvalue|Lrawofregion*index*root*regionoption|Lfldofregion*index*F.term*regionoverlay|Larrofregion*index*F.term*F.termlist*int*intlist(* For Lxxx locations:
- index: start index inside the chunk
- term: additional shift index
- term list: array index from start *)(* -------------------------------------------------------------------------- *)(* --- Loc Basics --- *)(* -------------------------------------------------------------------------- *)letnull=Indexl_inullletvars=function|GarbledMix->F.Vars.empty|Indexl|Lref(_,l,_)|Lmem(_,l,_,_)|Lraw(_,l,_,_)->F.varsl|Lfld(_,l,k,_)->F.Vars.union(F.varsl)(F.varsk)|Larr(_,l,k,ks,_,_)->Qed.Hcons.fold_listF.Vars.unionF.varsF.Vars.empty(l::k::ks)letoccursx=function|GarbledMix->false|Indexl|Lref(_,l,_)|Lmem(_,l,_,_)|Lraw(_,l,_,_)->F.occursxl|Lfld(_,l,k,_)->F.occursxl||F.occursxk|Larr(_,l,k,ks,_,_)->List.exists(F.occursx)(l::k::ks)letprettyfmt=function|GarbledMix->Format.pp_print_stringfmt"garbled-mix"|Indexl->Format.fprintffmt"@[<hov 2>Index(%a)@]"pp_indexl|Lref(r,l,r')->Format.fprintffmt"@[<hov 2>Ref@,{%a->%a}@,(%a)@]"pp_regionrpp_regionr'pp_indexl|Lmem(r,l,_,v)->Format.fprintffmt"@[<hov 2>Mem@,{%a:@,%a}@,(%a)@]"pp_regionrpp_valuevpp_indexl|Lraw(r,l,_,None)->Format.fprintffmt"@[<hov 2>Raw@,{%a}@,(%a)"pp_regionrpp_indexl|Lraw(r,l,_,Somer')->Format.fprintffmt"@[<hov 2>Raw@,{%a->%a}@,(%a)"pp_regionrpp_regionr'pp_indexl|Lfld(r,l,k,_)->Format.fprintffmt"@[<hov 2>Field@,{%a}@,(%a%a)@]"pp_regionrpp_indexlpp_fieldk|Larr(r,l,k,ks,_,_)->Format.fprintffmt"@[<hov 2>Index@,{%a}@,@[<hov 2>(%a[%a]%a)@]@]"pp_regionrpp_indexlpp_argskspp_deltak(* -------------------------------------------------------------------------- *)(* --- Loc Constructors --- *)(* -------------------------------------------------------------------------- *)letrecindexmap(r:region)(l:index)(ofs:F.term)(len:int)=index_chunkmaprlofslen(Region.chunkmapr)andindex_chunkmap(r:region)lofslen=function|Mrefr'->Lref(r,l_shift_indexlofs,r')|Mraw(m,p)->Lraw(r,l_shift_indexlofs,m,p)|Mmem(m,v)->Lmem(r,l_shift_indexlofs,m,v)|Mcomp(_,[{ofs=0;reg;dim}])->index_dimmapreglofslendim|Mcomp(_,overlay)->index_fieldmaprlofslenoverlayandindex_fieldmaprlofslenoverlay=tryletk=FIELD.offsetofsinletrg=List.find(Layout.Range.includedklen)overlayinletfd=F.e_intkinletl'=l_fieldoverlaylfdinindex_dimmaprg.regl'(F.e_subofsfd)lenrg.dimwithNot_found->Lfld(r,l,ofs,overlay)andindex_dimmaprlofslen=function|Raws|Dim(s,[])->indexmapr(l_index_memlF.e_zero(F.e_ints))ofslen|Dim(s,ds)->index_arraymaprl(ARRAY.zeroesds)ofslensdsandindex_arraymaprlksofslensds=letcs=ARRAY.coefssdsinletks,ofs=ARRAY.offsetcsksofsiniflen<=sthenletl'=l_arraysdslksinindexmaprl'ofslenelseLarr(r,l,ofs,ks,s,ds)andshift_index_locmaplocofslen=matchlocwith|GarbledMix->GarbledMix|Indexl->Index(l_shift_indexlofs)|Lref(r,l,r')->Lref(r,l_shift_indexlofs,r')|Lmem(r,l,m,v)->Lmem(r,l_shift_indexlofs,m,v)|Lraw(r,l,m,p)->Lraw(r,l_shift_indexlofs,m,p)|Lfld(r,l,k,overlay)->index_fieldmaprl(F.e_addkofs)lenoverlay|Larr(r,l,k,ks,s,ds)->index_arraymaprlks(F.e_addkofs)lensdsletcvarx=letmap=map()inletregion=Region.of_cvarmapxinletid=ifCil.isConstTypex.vtypethen-x.videlsex.vidinindexmapregion(l_index_varid)F.e_zero(Cil.bitsSizeOfx.vtype)letfieldlocfd=letmap=map()inletofs,len=Region.field_offsetmapfdinshift_index_locmaploc(F.e_intofs)lenletshiftlocobjn=letmap=map()inlets=Ctypes.bits_sizeof_objectobjinshift_index_locmaploc(F.e_factsn)sletpointer_locl=Indexlletpointer_val=function|GarbledMix->error"Can not obtain address of Garbled-Mix location"|Indexl|Lref(_,l,_)|Lmem(_,l,_,_)|Lraw(_,l,_,_)->l|Lfld(_,l,k,overlay)->l_fieldoverlaylk|Larr(_,l,k,ks,s,ds)->l_shift_index(l_arraysdslks)kletloc_of_indexretyl=index(map())relF.e_zero(Cil.bitsSizeOfty)(* -------------------------------------------------------------------------- *)(* --- Chunks --- *)(* -------------------------------------------------------------------------- *)typechunk=|Mu_alloc|Mu_rawofregion*root|Mu_memofregion*root*regionvaluemoduleChunk=structtypet=chunkletself="region"letid=function|Mu_raw(r,_)|Mu_mem(r,_,_)->Region.idr|Mu_alloc->Region.noidlethashm=idmletcomparemm'=ifm==mthen0elseStdlib.compare(idm)(idm')letequalmm'=m==m'||(idm=idm')lettau_of_value=function|Int_->L.Int|Float_->L.Real|Pointer_->t_indexlettau_of_chunk=function|Mu_alloc->MemMemory.t_malloc|Mu_raw_->t_bits|Mu_mem(_,root,v)->letvalue=tau_of_valuevinifRoot.indexedrootthenL.Array(t_addr,value)elsevalueletbasename_of_chunk=function|Mu_raw_->"B"|Mu_mem(_,root,Int_)->ifRoot.indexedrootthen"M"else"V"|Mu_mem(_,root,Float_)->ifRoot.indexedrootthen"Mf"else"F"|Mu_mem(_,root,Pointer_)->ifRoot.indexedrootthen"Mp"else"M"|Mu_alloc->"A"letis_framed=function|Mu_raw(_,root)|Mu_mem(_,root,_)->Root.framedroot|Mu_alloc->falseletprettyfmtmu=Format.pp_print_stringfmt(basename_of_chunkmu)endmoduleHeap=structincludeQed.Collection.Make(Chunk)letempty=Set.emptyletof_rawrrt=Set.singleton(Mu_raw(r,rt))letof_memrrtv=Set.singleton(Mu_mem(r,rt,v))letrecof_regionmapr=matchRegion.chunkmaprwith|Mref_->Set.empty|Mraw(rt,_)->of_rawrrt|Mmem(rt,v)->of_memrrtv|Mcomp(_,overlay)->of_overlaymapoverlayandof_rangemap{reg}=of_regionmapregandof_overlaymapovl=Qed.Hcons.fold_listSet.union(of_rangemap)emptyovlendmoduleSigma=Sigma.Make(Chunk)(Heap)typesigma=Sigma.ttypedomain=Sigma.domainletvalue_footprint_obj=function|GarbledMix|Index_->error"Can not compute Garbled-mix domain"|Lref_->Heap.empty|Lraw(r,_,rt,_)->Heap.of_rawrrt|Lmem(r,_,rt,v)->Heap.of_memrrtv|Lfld(_,_,_,ovl)->Heap.of_overlay(map())ovl|Larr(r,_,_,_,_,_)->Heap.of_region(map())rletinit_footprint__=Heap.emptyletis_well_formed_s=Lang.F.p_trueletregion_of_loc=function|(GarbledMix|Index_)asl->error"Can not find region of %a"prettyl|Lref(r,_,_)|Lraw(r,_,_,_)|Lmem(r,_,_,_)|Lfld(r,_,_,_)|Larr(r,_,_,_,_,_)->r(* -------------------------------------------------------------------------- *)(* --- Loader --- *)(* -------------------------------------------------------------------------- *)moduleMODEL=structmoduleChunk=ChunkmoduleSigma=Sigmaletname="MemRegion.LOADER"typenonrecloc=locletfield=fieldletshift=shiftletsizeofobj=Lang.F.e_int(Ctypes.bits_sizeof_objectobj)letvalue_footprint=value_footprintletinit_footprint=init_footprintletframes___=[]letto_addrl=a_addrof(pointer_vall)letto_region_pointerl=Region.id(region_of_locl),pointer_vallletof_region_pointerrobjl=letmap=map()inindexmap(Region.regionmapr)lF.e_zero(Ctypes.bits_sizeof_objectobj)letload_memsigmarrtvl=letm=Sigma.valuesigma(Mu_mem(r,rt,v))inifRoot.indexedrtthenF.e_getm(a_addrofl)elsemletload_intsigmai=function|Lmem(r,l,rt,(Inti0asv))wheni=i0->load_memsigmarrtvl|l->error"Can not load %a value from %a"Ctypes.pp_intiprettylletload_floatsigmaf=function|Lmem(r,l,rt,(Floatf0asv))whenf=f0->load_memsigmarrtvl|l->error"Can not load %a value from %a"Ctypes.pp_floatfprettylletload_pointersigmaty=function|Lmem(r,l,rt,(Pointerr'asv))->loc_of_indexr'ty(load_memsigmarrtvl)|Lref(_,l,r')->loc_of_indexr'ty(l_index_refl)|l->error"Can not load pointer value from %a"prettyllethavocobjloc~length(chunk:chunk)~fresh~current=matchchunkwith|Mu_alloc->fresh|Mu_raw_->error"Can not havoc raw memories"|Mu_mem(_,root,_)->ifLayout.Root.indexedrootthenletaddr=to_addrlocinletoffset=F.e_fact(Ctypes.bits_sizeof_objectobj)lengthinF.e_funMemMemory.f_havoc[fresh;current;addr;offset]elsefreshleteqmemobjlocchunkm1m2=matchchunkwith|Mu_alloc->error"Can not compare allocation tables"|Mu_raw_->error"Can not compare raw memories"|Mu_mem(_,root,_)->ifLayout.Root.indexedrootthenletaddr=to_addrlocinletoffset=F.e_int(Ctypes.bits_sizeof_objectobj)inF.p_callMemMemory.p_eqmem[m1;m2;addr;offset]elseF.p_equalm1m2leteqmem_forallobjlocchunkm1m2=matchchunkwith|Mu_alloc->error"Can not compare allocation tables"|Mu_raw_->error"Can not compare raw memories"|Mu_mem(_,root,_)->ifLayout.Root.indexedrootthenletxp=Lang.freshvar~basename:"p"t_addrinletp=F.e_varxpinleta=to_addrlocinletn=F.e_int(Ctypes.bits_sizeof_objectobj)inletseparated=p_separatedpF.e_oneaninletequal=F.p_equal(F.e_getm1p)(F.e_getm2p)in[xp],separated,equalelse[],F.p_true,F.p_equalm1m2letlast_=error"Can not compute last valid index"letstore_memsigmarrtvlvalue=letc=Mu_mem(r,rt,v)inifRoot.indexedrtthenc,F.e_set(Sigma.valuesigmac)(a_addrofl)valueelsec,valueletstore_intsigmailocvalue=matchlocwith|Lmem(r,l,rt,(Inti0asv))wheni=i0->store_memsigmarrtvlvalue|_->error"Can not store %a value into %a"Ctypes.pp_intiprettylocletstore_floatsigmaflocvalue=matchlocwith|Lmem(r,l,rt,(Floatf0asv))whenf=f0->store_memsigmarrtvlvalue|_->error"Can not store %a value into %a"Ctypes.pp_floatfprettylocletstore_pointersigma_tylocvalue=matchlocwith|Lmem(r,l,rt,(Pointer_asv))->store_memsigmarrtvlvalue|_->error"Can not store pointer values into %a"prettylocletset_init_atom___=assertfalseletset_init_obj_loc~length_chunk~current=let_=lengthinlet_=currentinassertfalseletis_init_atom__=assertfalseletis_init_range____=assertfalseletmonotonic_init__=assertfalseendmoduleLOADER=MemLoader.Make(MODEL)letload=LOADER.loadletload_init=LOADER.load_initletload_value=LOADER.load_valueletstored=LOADER.storedletstored_init=LOADER.stored_initletcopied=LOADER.copiedletcopied_init=LOADER.copied_initletassigned=LOADER.assignedletinitialized=LOADER.initializedletdomain=LOADER.domain(* -------------------------------------------------------------------------- *)(* --- Loc Segments --- *)(* -------------------------------------------------------------------------- *)typesegment=locrlocletregion_of_sloc=functionRloc(_,l)|Rrange(l,_,_,_)->region_of_loclletdisjoint_regions1s2=letmap=map()inletc1=Region.chunksmap(region_of_slocs1)inletc2=Region.chunksmap(region_of_slocs2)innot(Qed.Intset.intersectc1c2)letaddrof=MODEL.to_addrletsizeof=MODEL.sizeofletincludeds1s2=ifdisjoint_regions1s2thenF.p_falseelseMemMemory.included~shift~addrof~sizeofs1s2letseparateds1s2=ifdisjoint_regions1s2thenF.p_trueelseMemMemory.separated~shift~addrof~sizeofs1s2(* -------------------------------------------------------------------------- *)(* --- TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO --- *)(* -------------------------------------------------------------------------- *)typestate=unitletstate_=()letiter__=()letlookup__=Mtermletupdates__=Bag.emptyletapply__=()letliteral~eid_=ignoreeid;GarbledMixletbase_addr_l=GarbledMixletbase_offsetl=MemMemory.a_offset(addrofl)letblock_length_s_obj_l=F.e_zeroletcast__l=GarbledMixletloc_of_int__=GarbledMixletint_of_loc__=F.e_zeroletnot_yet_pointer()=error"Pointer comparison not yet implemented"letis_null_=not_yet_pointer()letloc_eq__=not_yet_pointer()letloc_lt__=not_yet_pointer()letloc_leq__=not_yet_pointer()letloc_neq__=not_yet_pointer()letloc_diff___=not_yet_pointer()letframe_sigma=[]letallocsigma_xs=sigmaletscope_seq_s_xs=[]letvalid_sigma_acs_l=error"Validity not yet implemented"letinvalid_sigma_l=error"Validity not yet implemented"letglobal_sigma_p=F.p_true