Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file path.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817(**************************************************************************)(* 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). *)(* *)(**************************************************************************)exceptionUndefined=State.UndefinedexceptionUndeclared=State.UndeclaredexceptionUnknown=State.UnknownexceptionNon_mergeable=State.Non_mergeabletypetrilean=Basic_types.Ternary.ttype('state,'model)partition=|False|True|Falsishof'state|Trueishof'state|Splitof'state*'modellistmoduletypeS=sigtypettypestatetypevaluetypemodelvalid:t->intvalpc:t->Virtual_address.tvalsymbolize:t->Dba.Var.t->unitvalassign:t->Dba.Var.t->Dba.Expr.t->unitvalclobber:t->Dba.Var.t->unitvalload:t->Dba.Var.t->stringoption->addr:Dba.Expr.t->Machine.endianness->unitvalstore:t->stringoption->addr:Dba.Expr.t->Dba.Expr.t->Machine.endianness->unitvalmemcpy:t->stringoption->addr:Dba.Expr.t->int->Loader_types.buffer->unitvalpredicate:t->valuelistvalis_symbolic:t->Dba.Expr.t->boolvalis_zero:t->Dba.Expr.t->trileanvalassume:t->Dba.Expr.t->modeloptionvalcheck_sat_assuming:t->?retain:bool->Dba.Expr.t->modeloptionvalpartition:t->Dba.Expr.t->(state,model)partitionvalenumerate:t->?retain:bool->?n:int->?accumulator:modelBitvector.Map.t->?assuming:Dba.Expr.t->Dba.Expr.t->modelBitvector.Map.tvalcheck_model:t->?retain:bool->model->boolvaleval:t->Dba.Expr.t->Bitvector.tvalget_value:t->Dba.Expr.t->valuevallookup:t->Dba.Var.t->valuevalread:t->stringoption->addr:Dba.Expr.t->int->Machine.endianness->valuevalsymbols:t->valuelistDba_types.Var.Map.ttype'akeyvalget:t->'akey->'avalset:t->'akey->'a->unitmoduleValue:State.VALUEwithtypet=valuevalassign_v:t->Dba.Var.t->value->unitvalload_v:t->Dba.Var.t->stringoption->addr:value->Machine.endianness->unitvalstore_v:t->stringoption->addr:value->value->Machine.endianness->unitvalmemcpy_v:t->stringoption->addr:value->int->Loader_types.buffer->unitvalis_symbolic_v:t->value->boolvalis_zero_v:t->value->trileanvalassume_v:t->value->modeloptionvalcheck_sat_assuming_v:t->?retain:bool->value->modeloptionvalpartition_v:t->value->(state,model)partitionvalenumerate_v:t->?retain:bool->?n:int->?accumulator:modelBitvector.Map.t->?assuming:value->value->modelBitvector.Map.tvaleval_v:t->value->Bitvector.tvalread_v:t->stringoption->addr:value->int->Machine.endianness->valuemoduleModel:State.MODELwithtypet=modelandtypevalue:=valuemoduleState:State.Swithtypet=stateandtypeValue.t=valueandtypeModel.t=modelvalset_pc:t->Virtual_address.t->unitvalmodels:t->modellistvalset_models:t->modellist->unitvalstate:t->statevalset_state:t->state->unitvaltransform_state:t->(state->state)->unitendmoduleMake(Metrics:Metrics.S)(State:State.S):sigincludeSwithtypestate=State.tandtypevalue=State.Value.tandtypemodel=State.Model.tandmoduleState=Statevalcreate:unit->tvalcookie:t->State.Cookie.tvalfork:t->tvalmerge:t->t->toptionvaldeclare_field:?copy:('a->'a)->?merge:('a->'a->'aoption)->'a->'akeyend=structtypedatatypet=dataarraytype'afield=inttypemerge_handler=M:'afield*('a->'a->'aoption)->merge_handlertypecopy_handler=C:'afield*('a->'a)->copy_handlerletdefault_merge:typea.a->a->aoption=funxy->ifx==ythenSomexelseNonemoduleState=structincludeStateletcheck_sat:Cookie.t->t->Model.toption=funcookiestate->Metrics.Solver.Timer.start();matchcheck_satcookiestatewith|Some_asresult->Metrics.Solver.Timer.stop();Metrics.Solver.incrSat;result|None->Metrics.Solver.Timer.stop();Metrics.Solver.incrUnsat;None|exception(Unknownase)->Metrics.Solver.Timer.stop();Metrics.Solver.incrUnknown;raiseeletenumerate:Cookie.t->Value.t->?except:Bitvector.tlist->t->Enumeration.t=funcookietarget?exceptstate->Metrics.Solver.Timer.start();letresult=enumeratecookietarget?exceptstateinMetrics.Solver.Timer.stop();resultmoduleEnumeration=structincludeEnumerationletnext:t->(Bitvector.t*Model.t)option=funenum->Metrics.Solver.Timer.start();matchnextenumwith|Some_asresult->Metrics.Solver.Timer.stop();Metrics.Solver.incrSat;result|None->Metrics.Solver.Timer.stop();Metrics.Solver.incrUnsat;None|exception(Unknownase)->Metrics.Solver.Timer.stop();Metrics.Solver.incrUnknown;raiseeendendmoduleValue=State.ValuemoduleModel=State.Modeltypestate=State.tandvalue=Value.tandmodel=Model.tmoduleField=structtype'at=|Id:intt|Pc:Virtual_address.tt|Nid:State.Uid.tt|Symbols:Value.tlistDba_types.Var.Map.tt|State:State.tt|Cookie:State.Cookie.tt|Models:Model.tlistt|Last:unittexternalunsafe_of_int:int->'at="%identity"externalto_int:'at->int="%identity"letdefault:typea.at->a=function|Id->0|Pc->Virtual_address.zero|Nid->State.Uid.zero|Symbols->Dba_types.Var.Map.empty|State->State.empty()|Cookie->State.Cookie.default()|Models->[Model.empty()]|Last->assertfalseletmerge:typea.at->a->a->aoption=function|Id->funxy->Some(minxy)|Pc->default_merge|Nid->funxy->Some(maxxy)|Symbols->default_merge|State->(funxy->trySome(State.mergexy)withNon_mergeable->None)|Cookie->default_merge|Models->funxy->Some(List.appendxy)|Last->assertfalseletmerget=M(to_intt,merget)letiterf=fori=0toto_intLast-1dof(unsafe_of_inti)doneletlast=to_intLastendexternalget:t->'aField.t->'a="%obj_field"externalset:t->'aField.t->'a->unit="%obj_set_field"letidpath=getpathIdletpcpath=getpathPcletset_pcpathaddr=setpathPcaddrletsymbolspath=getpathSymbolsletstatepath=getpathStateletcookiepath=getpathCookieletmodelspath=getpathModelsletset_modelspathmodels=setpathModelsmodelsletset_statepathstate=setpathStatestatelettransform_statepathf=set_statepath(f(statepath))letsymbolize:t->Dba.Var.t->unit=funpathvar->letnid=getpathNidinsetpathNid(State.Uid.succnid);letvalue=Value.varnidvar.namevar.sizeinletsymbols=getpathSymbolsinletstream=tryDba_types.Var.Map.findvarsymbolswithNot_found->[]insetpathSymbols(Dba_types.Var.Map.addvar(value::stream)symbols);set_statepath(State.assignvarvalue(statepath))letclobber:t->Dba.Var.t->unit=funpathvar->letnid=getpathNidinsetpathNid(State.Uid.succnid);letvalue=Value.varnidvar.namevar.sizeinset_statepath(State.assignvarvalue(statepath))letreclookup:t->Dba.Var.t->Value.t=funpathvar->tryState.lookupvar(statepath)withUndefined_->symbolizepathvar;lookuppathvarletrecget_value:t->Dba.Expr.t->Value.t=letuope(o:Dba.Unary_op.t):Term.unaryTerm.operator=matchowith|Not->Not|UMinus->Minus|Sextn->Sext(n-Dba.Expr.size_ofe)|Uextn->Uext(n-Dba.Expr.size_ofe)|Restrictinterval->Restrictintervalinletbop(op:Dba.Binary_op.t):Term.binaryTerm.operator=matchopwith|Plus->Plus|Minus->Minus|Mult->Mul|DivU->Udiv|DivS->Sdiv|RemU->Urem|RemS->Srem|Eq->Eq|Diff->Diff|LeqU->Ule|LtU->Ult|GeqU->Uge|GtU->Ugt|LeqS->Sle|LtS->Slt|GeqS->Sge|GtS->Sgt|Xor->Xor|And->And|Or->Or|Concat->Concat|LShift->Lsl|RShiftU->Lsr|RShiftS->Asr|LeftRotate->Rol|RightRotate->Rorinfunpathe->matchewith|Cstbv|Var{info=Symbol(_,(lazybv));_}->Value.constantbv|Varvar->lookuppathvar|Load(len,dir,addr,array)->loadpathlenarray(get_valuepathaddr)dir|Unary(f,x)->Value.unary(uopxf)(get_valuepathx)|Binary(f,x,y)->Value.binary(bopf)(get_valuepathx)(get_valuepathy)|Ite(c,r,e)->(letc=get_valuepathcinmatchValue.is_zerocwith|True->get_valuepathe|False->get_valuepathr|Unknown->Value.itec(get_valuepathr)(get_valuepathe))andload:t->int->stringoption->Value.t->Machine.endianness->Value.t=funpathlenarrayaddrdir->tryletvalue,state=matcharraywith|None->State.read~addrlendir(statepath)|Somearray->State.selectarray~addrlendir(statepath)inset_statepathstate;valuewithUndeclaredarray->letstate=State.declare~array(Value.sizeofaddr)(statepath)inset_statepathstate;loadpathlenarrayaddrdirletread_v:t->stringoption->addr:value->int->Machine.endianness->Value.t=funpatharray~addrlendir->loadpathlenarrayaddrdirletread:t->stringoption->addr:Dba.Expr.t->int->Machine.endianness->Value.t=funpatharray~addrlendir->read_vpatharray~addr:(get_valuepathaddr)lendirletassign_v:t->Dba.Var.t->value->unit=funpathvarvalue->set_statepath(State.assignvarvalue(statepath))letassign:t->Dba.Var.t->Dba.Expr.t->unit=funpathvarexpr->assign_vpathvar(get_valuepathexpr)letload_v:t->Dba.Var.t->stringoption->addr:value->Machine.endianness->unit=funpathvararray~addrdir->letvalue=loadpath(var.sizelsr3)arrayaddrdirinset_statepath(State.assignvarvalue(statepath))letload:t->Dba.Var.t->stringoption->addr:Dba.Expr.t->Machine.endianness->unit=funpathvararray~addrdir->load_vpathvararray~addr:(get_valuepathaddr)dirletstore_v:t->stringoption->addr:value->value->Machine.endianness->unit=funpatharray~addrvaluedir->letstate=statepathinmatcharraywith|None->set_statepath(tryState.write~addrvaluedirstatewithUndeclaredarray->State.write~addrvaluedir(State.declare~array(Value.sizeofaddr)state))|Somename->set_statepath(tryState.storename~addrvaluedirstatewithUndeclaredarray->State.storename~addrvaluedir(State.declare~array(Value.sizeofaddr)state))letstore:t->stringoption->addr:Dba.Expr.t->Dba.Expr.t->Machine.endianness->unit=funpatharray~addrvaluedir->store_vpatharray~addr:(get_valuepathaddr)(get_valuepathvalue)dirletmemcpy_v:t->stringoption->addr:value->int->Loader_types.buffer->unit=funpatharray~addrlencontent->letstate=statepathinset_statepath(tryState.memcpyarray~addrlencontentstatewithUndeclaredarray->State.memcpyarray~addrlencontent(State.declare~array(Value.sizeofaddr)state))letmemcpy:t->stringoption->addr:Dba.Expr.t->int->Loader_types.buffer->unit=funpatharray~addrlencontent->memcpy_vpatharray~addr:(get_valuepathaddr)lencontentletpredicate:t->valuelist=funpath->State.predicate(statepath)letis_symbolic_v:t->value->bool=funpathvalue->State.is_symbolicvalue(statepath)letis_symbolic:t->Dba.Expr.t->bool=funpathe->is_symbolic_vpath(get_valuepathe)letis_zero_v:t->value->trilean=funpathvalue->State.is_zerovalue(statepath)letis_zero:t->Dba.Expr.t->trilean=funpathe->is_zero_vpath(get_valuepathe)letassume_v:t->value->Model.toption=funpathvalue->matchValue.is_zerovaluewith|True->None|False->Some(List.hd(modelspath))|Unknown->(Metrics.Preprocess.Timer.start();matchState.assumevalue(statepath)with|None->Metrics.Preprocess.Timer.stop();Metrics.Preprocess.incrUnsat;None|Somestate->(letmodels=List.fold_left(funmodelsmodel->ifBitvector.is_zero(Model.evalvaluemodel)thenmodelselsemodel::models)[](modelspath)inMetrics.Preprocess.Timer.stop();matchmodelswith|model::_->Metrics.Preprocess.incrSat;set_statepathstate;set_modelspathmodels;Somemodel|[]->(Metrics.Preprocess.incrUnknown;matchState.check_sat(cookiepath)statewith|None->None|Somemodel->set_statepathstate;set_modelspath[model];Somemodel)))letassume:t->Dba.Expr.t->Model.toption=funpathe->assume_vpath(get_valuepathe)letcheck_sat_assuming_v:t->?retain:bool->value->Model.toption=funpath?(retain=true)value->letmodels=modelspathinmatchValue.is_zerovaluewith|True->None|False->Some(List.hdmodels)|Unknown->(Metrics.Preprocess.Timer.start();matchList.find(funmodel->Bitvector.is_one(Model.evalvaluemodel))modelswith|model->Metrics.Preprocess.Timer.stop();Metrics.Preprocess.incrSat;Somemodel|exceptionNot_found->(matchState.assumevalue(statepath)with|None->Metrics.Preprocess.Timer.stop();Metrics.Preprocess.incrUnsat;None|Somestate->(Metrics.Preprocess.Timer.stop();Metrics.Preprocess.incrUnknown;matchState.check_sat(cookiepath)statewith|None->None|Somemodel->ifretainthenset_modelspath(model::models);Somemodel)))letcheck_sat_assuming:t->?retain:bool->Dba.Expr.t->Model.toption=funpath?retaine->check_sat_assuming_vpath?retain(get_valuepathe)letpartition_v:t->value->(state,model)partition=funpathvalue->matchValue.is_zerovaluewith|True->False|False->True|Unknown->(letstate=statepathandmodels=modelspathinMetrics.Preprocess.Timer.start();matchState.is_zerovaluestatewith|True->Metrics.Preprocess.Timer.stop();False|False->Metrics.Preprocess.Timer.stop();True|Unknown->(matchList.partition(funmodel->Bitvector.is_one(Model.evalvaluemodel))modelswith|[],_->(set_statepath(Option.get(State.assume(Value.unaryNotvalue)state));Metrics.Preprocess.incrSat;lettrue_state=State.assumevaluestateinMetrics.Preprocess.Timer.stop();matchtrue_statewith|None->Metrics.Preprocess.incrUnsat;False|Sometrue_state->Falsishtrue_state)|_,[]->(set_statepath(Option.get(State.assumevaluestate));Metrics.Preprocess.incrSat;letfalse_state=State.assume(Value.unaryNotvalue)stateinMetrics.Preprocess.Timer.stop();matchfalse_statewith|None->Metrics.Preprocess.incrUnsat;True|Somefalse_state->Trueishfalse_state)|true_models,false_models->set_statepath(Option.get(State.assumevaluestate));set_modelspathtrue_models;letfalse_state=Option.get(State.assume(Value.unaryNotvalue)state)inMetrics.Preprocess.Timer.stop();Metrics.Preprocess.incrSat;Metrics.Preprocess.incrUnsat;Split(false_state,false_models)))letpartition:t->Dba.Expr.t->(state,model)partition=funpathtest->partition_vpath(get_valuepathtest)letcheck_model:t->?retain:bool->Model.t->bool=funpath?(retain=true)model->letr=List.for_all(fune->Bitvector.is_one(Model.evalemodel))(State.predicate(statepath))inifretain&&rthenset_modelspath(model::modelspath);rletenumerate_v:t->?retain:bool->?n:int->?accumulator:Model.tBitvector.Map.t->?assuming:value->value->Model.tBitvector.Map.t=letdecr:intoption->intoption=function|None->None|Somen->Some(n-1)inletrecfold_enumeration:t->bool->intoption->State.Enumeration.t->Model.tBitvector.Map.t->Model.tBitvector.Map.t=funpathretainnenumresult->matchnwith|Some0->State.Enumeration.suspendenum;result|None|Some_->(matchState.Enumeration.nextenumwith|None->result|Some(bv,model)->ifretainthenset_modelspath(model::modelspath);fold_enumerationpathretain(decrn)enum(Bitvector.Map.addbvmodelresult))inletcheck_valid:Value.toption->Model.t->bool=funassumtpionmodel->matchassumtpionwith|None->true|Somecond->Bitvector.to_bool(Model.evalcondmodel)inletensure_valid:Value.toption->State.t->State.toption=funassumptionstate->matchassumptionwith|None->Somestate|Somecond->State.assumecondstateinletrecfold_models:t->bool->intoption->Value.toption->Value.t->Bitvector.tlist->Model.tBitvector.Map.t->Model.tlist->Model.tBitvector.Map.t=funpathretainnassumptionvalueexceptresultmodels->matchnwith|Some0->Metrics.Preprocess.Timer.stop();result|Some_|None->(matchmodelswith|[]->(matchensure_validassumption(statepath)with|None->Metrics.Preprocess.Timer.stop();Metrics.Preprocess.incrUnsat;result|Somestate->Metrics.Preprocess.Timer.stop();Metrics.Preprocess.incrUnknown;fold_enumerationpathretainn(State.enumerate(cookiepath)value~exceptstate)result)|model::models->ifcheck_validassumptionmodelthenletbv=Model.evalvaluemodelinifBitvector.Map.membvresultthenfold_modelspathretainnassumptionvalueexceptresultmodelselse(Metrics.Preprocess.incrSat;fold_modelspathretain(decrn)assumptionvalue(bv::except)(Bitvector.Map.addbvmodelresult)models)elsefold_modelspathretainnassumptionvalueexceptresultmodels)infunpath?(retain=true)?n?(accumulator=Bitvector.Map.empty)?assumingvalue->ifValue.is_symbolicvaluethen(Metrics.Preprocess.Timer.start();fold_modelspathretainnassumingvalue[]accumulator(modelspath))else(Metrics.Preprocess.incrSat;letmodel=List.hd(modelspath)inifcheck_validassumingmodelthenletbv=Model.evalvaluemodelinBitvector.Map.singletonbvmodelelseBitvector.Map.empty)letenumerate:t->?retain:bool->?n:int->?accumulator:Model.tBitvector.Map.t->?assuming:Dba.Expr.t->Dba.Expr.t->Model.tBitvector.Map.t=funpath?retain?n?accumulator?assuminge->enumerate_vpath?retain?n?accumulator?assuming:(Option.map(get_valuepath)assuming)(get_valuepathe)leteval_v:t->value->Bitvector.t=funpathvalue->Model.evalvalue(List.hd(modelspath))leteval:t->Dba.Expr.t->Bitvector.t=funpathe->eval_vpath(get_valuepathe)externalmake:int->int->dataarray="caml_obj_block"letsealed=reffalseletsize=refField.lastlettemplate:tref=ref(make0(2lslZ.numbits(Z.of_intField.last)))letmerge_handlers=Queue.create()letcopy_handlers=Queue.create()letn=ref0let()=Queue.add(C(0,fun_->incrn;!n))copy_handlers;Field.iter(funf->set!templatef(Field.defaultf);Queue.push(Field.mergef)merge_handlers)externalget:t->'afield->'a="%obj_field"externalset:t->'afield->'a->unit="%obj_set_field"letadd_fielddefault=if!sealedthenraise(Invalid_argument"sealed");letcapacity=Array.length!templateandfid=!sizeiniffid>=capacitythen(lettemplate'=make0(2*capacity)inArray.blit!template0template'0capacity;template:=template');set!templatefiddefault;incrsize;fidtype'akey='afieldletdeclare_field:?copy:('a->'a)->?merge:('a->'a->'aoption)->'a->'akey=fun?copy?(merge=default_merge)data->letfid=add_fielddatainQueue.add(M(fid,merge))merge_handlers;Option.iter(funcopy->Queue.add(C(fid,copy))copy_handlers)copy;fidletcreate:unit->t=fun()->sealed:=true;Array.sub!template0!sizeletfork:t->t=funpath->letpath'=Array.copypathinQueue.iter(fun(C(fid,copy))->setpath'fid(copy(getpath'fid)))copy_handlers;path'letmerge:t->t->toption=funpathpath'->letpath=Array.copypathintryQueue.iter(fun(M(fid,merge))->matchmerge(getpathfid)(getpath'fid)with|None->raise_notraceExit|Somedata->setpathfiddata)merge_handlers;SomepathwithExit->Noneend