123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-2022 *)(* 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). *)(* *)(**************************************************************************)openSmt_optionsletbyte_size=Natural.to_intBasic_types.Constants.bytesizemoduleF=structletfullnameindex=name^"_"^string_of_intindexletmemory="__memory"letfull_mem=fullmemoryletmemory_typeword_size=Formula.ax_sortword_sizebyte_sizeletpc="__pc"letfull_pc=fullpcletvarname=letopenFormulainfunction|BlSort->BlVar(bl_varname)|BvSorti->BvVar(bv_varnamei)|AxSort(i,j)->AxVar(ax_varnameij)letdecl=letopenFormulainfunction|BlVarv->mk_bl_declv[]|BvVarv->mk_bv_declv[]|AxVarv->mk_ax_declv[]letdefvaluevar=letopenFormulainmatch(value.term_desc,var)with|BlTermvalue,BlVarv->mk_bl_defv[]value|BvTermvalue,BvVarv->mk_bv_defv[]value|AxTermvalue,AxVarv->mk_ax_defv[]value|_->failwith"F.def has incompatible types"end(* global mutable state to assign unique indices *)letnext_index=ref0letmk_index()=next_index:=!next_index+1;!next_index(* variable bindings but one per branch *)moduleState=structmoduleS=Basic_types.String.MapmoduleB=Bitvector.Collection.Maptypeinfos=int*Formula.sort(* index, type *)typet={fml:Formula.formula;var_infos:infosS.t;initialisation:intB.t;(* list of memory locations to read *)uncontrolled:Formula.VarSet.t;}letadd_entryentrystate=letfml=Formula.push_frontentrystate.fmlin{statewithfml}letadd_uncontrolledvarst={stwithuncontrolled=Formula.VarSet.addvarst.uncontrolled}lethavoc?(wild=false)namevar_typestate=letopenFormulainletindex=mk_index()inletvar=F.var(F.fullnameindex)var_typeinletdeclaration=F.declvarinletvar_infos=S.addname(index,var_type)state.var_infosinletstate'=add_entry(mk_declaredeclaration){statewithvar_infos}inifwildthenadd_uncontrolledvarstate'elsestate'letdeclare?wildnamevar_typestate=ifS.memnamestate.var_infosthenfailwith"variable already declared";havoc?wildnamevar_typestateletassign?(wild=false)namevar_typevaluestate=letopenFormulain(matchS.findnamestate.var_infoswith|_,vtypewhenvtype<>var_type->failwith"Store.get_last_index with wrong type"|_->()|exceptionNot_found->());letindex=mk_index()inletvar=F.var(F.fullnameindex)var_typeinletdefinition=F.defvaluevarinletvar_infos=S.addname(index,var_type)state.var_infosinletstate'=add_entry(mk_definedefinition){statewithvar_infos}inifwildthenadd_uncontrolledvarstate'elsestate'letcreate()=letopenFormulainletfml=Formula.emptyandvar_infos=S.singletonF.memory(0,F.memory_type(Kernel_options.Machine.word_size()))inletinitialisation=B.emptyinletuncontrolled=Formula.VarSet.emptyinletself={fml;var_infos;initialisation;uncontrolled}inassignF.pcbl_sort(mk_bl_termmk_bl_true)selfletinitializationsst=st.initialisationletcommentcmtstate=add_entry(Formula.mk_commentcmt)stateletppppfstate=letopenFormatinfprintfppf"@[<v 0># State var_infos @ @[<hov 0>%a@]@]"(funppfm->S.iter(funname(n,_)->fprintfppf"%s:%d;@ "namen)m)state.var_infosletget_last_indexstatenamevar_type=matchS.findnamestate.var_infoswith|_,vwhenv<>var_type->failwith"State.get_last_index with wrong type"|n,_->nletget_memorystate=letword_size=Kernel_options.Machine.word_size()inletindex=get_last_indexstateF.memory(F.memory_typeword_size)inletname=F.full_memindexinFormula.(mk_ax_var(ax_varnameword_sizebyte_size))letget_path_constraintstate=letindex=get_last_indexstateF.pcFormula.bl_sortinletname=F.full_pcindexinFormula.(mk_bl_var(bl_varname))letconstraincondstate=letopenFormulainletcurrent_pc=get_path_constraintstateinletpc=mk_bl_andcurrent_pccondinassignF.pcbl_sort(mk_bl_termpc)stateletget_bvnamesizestate=letsort=Formula.bv_sort(Size.Bit.to_intsize)inletindex,state''=matchget_last_indexstatenamesortwith|n->(n,state)|exceptionNot_found->letstate'=declare(*FIXME wild ? *)namesortstatein(get_last_indexstate'namesort,state')inletname=F.fullnameindexinletvalue=Formula.(mk_bv_var(bv_varname(Size.Bit.to_intsize)))in(value,state'')letinit_mem_at~addr~sizestate={statewithinitialisation=B.addaddrsizestate.initialisation}letget_entriesstate=letopenFormulainletword_size=Kernel_options.Machine.word_size()inletvar=F.(varmemory(memory_typeword_size))inletdeclaration=F.declvarinletsymbolic_memory=mk_ax_var(ax_varF.memoryword_sizebyte_size)inletread_bitvectoraddrsz=letb=Buffer.create(2*sz)in(* The loop below is little-endian *)letrecloopoffset=ifoffset<0then(letv=Z.of_string("0x"^Buffer.contentsb)inletbv=Bitvector.createv(byte_size*sz)inLogger.debug~level:5"[sse] C bitvector %s (%d): %a"(Z.to_stringv)szBitvector.pp_hexbv;bv)elseletoff_bv=Bitvector.of_int~size:word_sizeoffsetinletload_addr=Bitvector.addaddroff_bvinletimg=Kernel_functions.get_img()inletbyte=Loader_utils.get_byte_atimgload_addrinletbyte_str=Format.sprintf"%02x"byteinBuffer.add_stringbbyte_str;loop(offset-1)inloop(sz-1)inletload_ataddrsizemem=assert(word_size=Bitvector.size_ofaddr);mk_storesizemem(mk_bv_cstaddr)(mk_bv_cst(read_bitvectoraddrsize))inletinitial_memory_value=mk_ax_term(B.foldload_atstate.initialisationsymbolic_memory)inletdefinition=F.var(F.full_mem0)(F.memory_typeword_size)|>F.definitial_memory_valueinstate.fml|>Formula.push_back_definedefinition|>Formula.push_back_declaredeclarationletformulastate=Formula.push_front_assert(get_path_constraintstate)(get_entriesstate)letuncontrolledst=st.uncontrolledletmemory_termfml=(F.memory,F.memory_type(Kernel_options.Machine.word_size()),Formula.mk_ax_termfml)end