123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194(**************************************************************************)(* 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). *)(* *)(**************************************************************************)openGeneric_decoder_sigmoduleDecode_Expr(I:Expr_Input)=structopenDbaopenBinary_opopenIlet(>>=)=M.bindletrecexpr:Dba.Expr.t->I.binaryM.m=fune->(* Logger.result "Expressions %a" Dba_printer.Ascii.pp_bl_term e; *)matchewith|Expr.Cstbv->letsize=Bitvector.size_ofbvinI.Binary.biconst~size(Bitvector.value_ofbv)|Expr.Binary(bop,e1,e2)->(letsize=Dba.Expr.size_ofe1inexpre1>>=funv1->expre2>>=funv2->matchbopwith(* Binary operations. *)|Plus->I.Binary.biadd~sizev1v2|Minus->I.Binary.bisub~sizev1v2|Mult->I.Binary.bimul~sizev1v2|DivU->I.Binary.biudiv~sizev1v2|DivS->I.Binary.bisdiv~sizev1v2|RemU->I.Binary.biurem~sizev1v2|RemS->I.Binary.bisrem~sizev1v2|Or->I.Binary.bor~sizev1v2|And->I.Binary.band~sizev1v2|Xor->I.Binary.bxor~sizev1v2|Concat->I.Binary.bconcat~size1:(Dba.Expr.size_ofe1)v1~size2:(Dba.Expr.size_ofe2)v2|LShift->I.Binary.bshl~sizev1v2|RShiftU->I.Binary.blshr~sizev1v2|RShiftS->I.Binary.bashr~sizev1v2|LeftRotate->I.Binary.bv_left_rotate~sizev1v2|RightRotate->I.Binary.bv_right_rotate~sizev1v2(* Predicates. *)|Eq->I.Binary.beq~sizev1v2>>=funbool->I.bin_of_boolbool|Diff->I.Binary.beq~sizev1v2>>=funbool->I.Boolean.notbool>>=funnbool->I.bin_of_boolnbool|LeqU->I.Binary.biule~sizev1v2>>=funbool->I.bin_of_boolbool|GeqU->I.Binary.biule~sizev2v1>>=funbool->I.bin_of_boolbool|LeqS->I.Binary.bisle~sizev1v2>>=funbool->I.bin_of_boolbool|GeqS->I.Binary.bisle~sizev2v1>>=funbool->I.bin_of_boolbool|LtU->I.Binary.biult~sizev1v2>>=funbool->I.bin_of_boolbool|GtU->I.Binary.biult~sizev2v1>>=funbool->I.bin_of_boolbool|LtS->I.Binary.bislt~sizev1v2>>=funbool->I.bin_of_boolbool|GtS->I.Binary.bislt~sizev2v1>>=funbool->I.bin_of_boolbool)|Expr.Unary(op,e1)ase->(letsize=Dba.Expr.size_ofeinexpre1>>=funv1->matchopwith|Unary_op.UMinus->I.Binary.biconst~sizeZ.zero>>=funvz->I.Binary.bisub~sizevzv1|Unary_op.Not->I.Binary.biconst~sizeZ.minus_one>>=funffff->I.Binary.bxor~sizeffffv1|Unary_op.Uextn->I.Binary.buext~size:n~oldsize:(Dba.Expr.size_ofe1)v1|Unary_op.Sextn->I.Binary.bsext~size:n~oldsize:(Dba.Expr.size_ofe1)v1|Unary_op.Restrict{Interval.lo;Interval.hi}->I.Binary.bextract~lo~hi~oldsize:(Dba.Expr.size_ofe1)v1)|Expr.Var{name=var;size;_}->I.get_var~sizevar|Expr.Load(size,endianness,e,None)->expre>>=funaddress->I.load~size:(size*8)endiannessaddress|Expr.Load_->assertfalse|Expr.Ite(c,e1,e2)->condc>>=funvc->expre1>>=funv1->expre2>>=funv2->I.itevcv1v2andcond:Dba.Expr.t->I.booleanM.m=fune->assert(Dba.Expr.size_ofe==1);letopenDba.Exprinmatchewith|CstxwhenBitvector.is_onex->I.Boolean.true_|CstxwhenBitvector.is_zerox->I.Boolean.false_|Cst_->assertfalse|Unary(Unary_op.Not,x)->condx>>=funv->I.Boolean.notv|Unary(Unary_op.UMinus,x)->condx|Binary(And,a,b)->conda>>=funva->condb>>=funvb->I.Boolean.(&&)vavb|Binary(Or,a,b)->conda>>=funva->condb>>=funvb->I.Boolean.(||)vavb|e->expre>>=funv->I.bool_of_binvendmoduleDecode_Instr(S:Instr_Input):sigvalinstruction:S.State.t->Dba.Instr.t->(S.boolean,S.binary)Generic_decoder_sig.jump_kind*S.State.tend=structmoduleEDecode=Decode_Expr(structincludeSmoduleM=State_Monad(S.State)end)openDbaletwrite_lhsstatevalue=function|LValue.Var{name;size;_}->S.set_var~sizenamevaluestate|LValue.Restrict({name;size;_},{Interval.lo;Interval.hi})->letvalue_size=sizeinletold,state=S.get_var~sizenamestateinletwritten_size=1+hi-loinletv,state=iflo==0then(value,state)elseletpold,state=S.Binary.bextract~oldsize:value_size~lo:0~hi:(lo-1)oldstateinS.Binary.bconcat~size1:written_size~size2:lovaluepoldstateinletv,state=ifhi==size-1then(v,state)elseletpold,state=S.Binary.bextract~oldsize:value_size~lo:(hi+1)~hi:(size-1)oldstateinS.Binary.bconcat~size1:(size-hi)~size2:hipoldvstateinS.set_var~sizenamevstate|LValue.Store(size,endianness,address,None)->letvaddress,state=EDecode.expraddressstateinS.store~size:(size*8)endiannessvaddressvaluestate|LValue.Store_->assertfalseletinstructionstateinstr=letopen!Generic_decoder_siginletopenInstrin(* Logger.result "Instruction %a" Dba_printer.Ascii.pp_instruction instr; *)matchinstrwith|Assign(lhs,expr,id)->letv,state=EDecode.exprexprstateinletstate=write_lhsstatevlhsin(JKJump(Static(JInnerid)),state)|SJump(target,_)->(JKJump(Statictarget),state)|DJump(target,_)->letv,state=EDecode.exprtargetstatein(JKJump(Dynamicv),state)|If(Dba.Expr.Cstbv,target,id)->ifBitvector.is_onebvthen(JKJump(Statictarget),state)else(JKJump(Static(JInnerid)),state)|If(cond,target,id)->letv,state=EDecode.condcondstatein(JKIf(v,Statictarget,Static(JInnerid)),state)|Stop_->(JKStop,state)|Assume(cond,id)|Assert(cond,id)->letv,state=EDecode.condcondstatein(JKAssume(v,Static(JInnerid)),state)|Nondet(lhs,id)->letsize=assertfalseinletv,state=S.unknown~sizestateinletstate=write_lhsstatevlhsin(JKJump(Static(JInnerid)),state)|Undef(lhs,id)->letsize=Dba_types.LValue.unsafe_bitsizelhsinletv,state=S.undef~sizestateinletstate=write_lhsstatevlhsin(JKJump(Static(JInnerid)),state)end