123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283(**************************************************************************)(* 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). *)(* *)(**************************************************************************)moduleObj=structtypet=..endtype'aloc='a*Lexing.positionletlocaposition=(a,position)letpp_rangeppf{Interval.hi;lo}=ifhi=lothenFormat.fprintfppf"{%d}"hielseFormat.fprintfppf"{%d..%d}"hilomoduleSymbol=structtypet=string*Dba.Var.Tag.attributeletcreate?(attr=Dba.Var.Tag.Value)name=(name,attr)letppppf(name,attr)=Format.fprintfppf"<%s%a>"nameDba.Var.Tag.Attribute.ppattrendmodulerecSize:sigtypet=|Implicit|Explicitofint|SizeofofLoc.tloc|EvalofExpr.tlocvalnone:tvalsome:int->tvalsizeof:Loc.tloc->tvaleval:Expr.tloc->tvalpp:Format.formatter->t->unitend=structtypet=|Implicit|Explicitofint|SizeofofLoc.tloc|EvalofExpr.tlocletnone=Implicitletsomesize=Explicitsizeletsizeoflval=Sizeoflvalletevalexpr=Evalexprletppppf=function|Implicit->()|Explicitn->Format.fprintfppf"<%d>"n|Sizeof(lval,_)->Format.fprintfppf"<sizeof(%a)>"Loc.pplval|Eval(expr,_)->Format.fprintfppf"<%a>"Expr.ppexprendandLoc:sigtypet=|Varofstring*Size.t|Loadofint*Machine.endiannessoption*Expr.tloc*stringoption|SubofintInterval.t*tlocvalvar:?size:Size.t->string->tvalload:?array:string->int->?endianness:Machine.endianness->Expr.tloc->tvalrestrict:hi:int->lo:int->tloc->tvalpp:Format.formatter->t->unitend=structtypet=|Varofstring*Size.t|Loadofint*Machine.endiannessoption*Expr.tloc*stringoption|SubofintInterval.t*tlocletvar?(size=Size.none)name=Var(name,size)letload?arraylen?endiannessaddr=Load(len,endianness,addr,array)letrestrict~hi~lot=Sub({hi;lo},t)letrecppppflval=matchlvalwith|Var(name,size)->Format.fprintfppf"%s%a"nameSize.ppsize|Load(len,endianness,(addr,_),array)->Format.fprintfppf"%a[%a%a, %d]"(Format.pp_print_option~none:(funppf()->Format.pp_print_charppf'@')(funppfname->Format.pp_print_stringppfname))arrayExpr.ppaddr(Format.pp_print_option(funppf(e:Machine.endianness)->matchewith|LittleEndian->Format.pp_print_stringppf", <-"|BigEndian->Format.pp_print_stringppf", ->"))endiannesslen|Sub(r,(lval,_))->Format.fprintfppf"%a%a"pplvalpp_rangerendandExpr:sigtypet=|IntofZ.t*stringoption|BvofBitvector.t|SymbolofSymbol.tloc|LocofLoc.tloc|UnaryofDba.Unary_op.t*tloc|BinaryofDba.Binary_op.t*tloc*tloc|Iteoftloc*tloc*tlocvalzero:tvalone:tvalsucc:tloc->tvalinteger:?src:string->Z.t->tvalconstant:Bitvector.t->tvalsymbol:Symbol.tloc->tvalloc:Loc.tloc->tvaladd:tloc->tloc->tvalsub:tloc->tloc->tvalmul:tloc->tloc->tvalneg:tloc->t(* Unsigned operations *)valudiv:tloc->tloc->tvalurem:tloc->tloc->t(* Signed operations *)valsdiv:tloc->tloc->tvalsrem:tloc->tloc->tvallogand:tloc->tloc->tvallogor:tloc->tloc->tvallognot:tloc->tvallogxor:tloc->tloc->tincludeSigs.COMPARISONwithtypet:=tlocandtypeboolean:=tvalshift_left:tloc->tloc->tvalshift_right:tloc->tloc->tvalshift_right_signed:tloc->tloc->tvalrotate_left:tloc->tloc->tvalrotate_right:tloc->tloc->tvalsext:int->tloc->tvaluext:int->tloc->tvalrestrict:hi:int->lo:int->tloc->tvalappend:tloc->tloc->tvalite:tloc->tloc->tloc->tvalpp:Format.formatter->t->unitend=structtypet=|IntofZ.t*stringoption|BvofBitvector.t|SymbolofSymbol.tloc|LocofLoc.tloc|UnaryofDba.Unary_op.t*tloc|BinaryofDba.Binary_op.t*tloc*tloc|Iteoftloc*tloc*tlocletzero=BvBitvector.zeroletone=BvBitvector.oneletsuccx=Binary(Plus,x,(Int(Z.one,None),Lexing.dummy_pos))letinteger?srcz=Int(z,src)letconstantbv=Bvbvletsymbolsym=Symbolsymletloclval=Loclvalletbinaryopxy=Binary(op,x,y)letnegx=Unary(UMinus,x)letadd=binaryPlusletsub=binaryMinusletmul=binaryMultletsrem=binaryRemSleturem=binaryRemUletudiv=binaryDivUletsdiv=binaryDivSletlognotx=Unary(Not,x)letlogor=binaryOrletlogxor=binaryXorletlogand=binaryAndletequal=binaryEqletdiff=binaryDiffletule=binaryLeqUletsle=binaryLeqSletult=binaryLtUletslt=binaryLtSletuge=binaryGeqUletsge=binaryGeqSletugt=binaryGtUletsgt=binaryGtSletshift_left=binaryLShiftletshift_right=binaryRShiftUletshift_right_signed=binaryRShiftSletrotate_left=binaryLeftRotateletrotate_right=binaryRightRotateletsextnx=Unary(Sextn,x)letuextnx=Unary(Uextn,x)letrestrict~hi~lox=Unary(Restrict{hi;lo},x)letappend=binaryConcatletitetxy=Ite(t,x,y)letrecppppfe=matchewith|Int(_,Somestr)->Format.pp_print_stringppfstr|Int(z,None)->Z.pp_printppfz|Bvbv->Bitvector.pp_hex_or_binppfbv|Symbol(sym,_)->Symbol.ppppfsym|Loc(lval,_)->Loc.ppppflval|Unary(Uextn,(x,_))->Format.fprintfppf"(uext%d %a)"nppx|Unary(Sextn,(x,_))->Format.fprintfppf"(sext%d %a)"nppx|Unary(Restrictr,(x,_))->Format.fprintfppf"%a%a"ppxpp_ranger|Unary(op,(x,_))->Format.fprintfppf"%a (%a)"Dba_printer.Ascii.pp_unary_opopppx|Binary(op,(x,_),(y,_))->Format.fprintfppf"(%a %a %a)"ppxDba_printer.Ascii.pp_binary_opopppy|Ite((t,_),(x,_),(y,_))->Format.fprintfppf"%a ? %a : %a"pptppxppyendmoduleInstr=structtypet=..typet+=|Nop|Labelofstring(** [label]: *)|AssignofLoc.tloc*Expr.tloc(** [lval] := [rval] *)|UndefofLoc.tloc(** [lval] := undef *)|NondetofLoc.tloc(** [lval] := nondet *)|AssumeofExpr.tloc(** assume [rval] *)|AssertofExpr.tloc(** assert [rval] *)|IfofExpr.tloc*string(** if [rval] then goto [label] *)|Gotoofstring(** goto [label] *)|JumpofExpr.tloc(** jump at [rval] *)|Haltletnop=Nopletlabelname=Labelnameletassignlvalrval=Assign(lval,rval)letundeflval=Nondetlvalletnondetlval=Nondetlvalletassumerval=Assumervalletdynamic_assertrval=Assertrvalletconditional_jumprvallabel=If(rval,label)letdynamic_jumprval=Jumprvalletgotolabel=Gotolabellethalt=Haltletprinters=ref[]letregister_ppf=printers:=f::!printersletrecresolve_ppppfinst=function|[]->Format.pp_print_stringppf"unknown"|pp::printers->ifnot(ppppfinst)thenresolve_ppppfinstprintersletppppfinst=matchinstwith|Nop->Format.pp_print_stringppf"nop"|Labelname->Format.fprintfppf"%s:"name|Assign((lval,_),(rval,_))->Format.fprintfppf"%a := %a"Loc.pplvalExpr.pprval|Undef(lval,_)->Format.fprintfppf"%a := undef"Loc.pplval|Nondet(lval,_)->Format.fprintfppf"%a := nondet"Loc.pplval|Assume(rval,_)->Format.fprintfppf"assume %a"Expr.pprval|Assert(rval,_)->Format.fprintfppf"assert %a"Expr.pprval|If((rval,_),label)->Format.fprintfppf"if %a then goto %s"Expr.pprvallabel|Gotolabel->Format.fprintfppf"goto %s"label|Jump(rval,_)->Format.fprintfppf"jump at %a"Expr.pprval|Halt->Format.pp_print_stringppf"halt"|_->resolve_ppppfinst!printersendtypet=..