123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330(**************************************************************************)(* 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). *)(* *)(**************************************************************************)typedirection=Graph.Fixpoint.direction=Forward|BackwardmoduletypeS=sigtypeaddrtypeinsttypesymbtypetmoduleV:sigtypetvalcompare:t->t->intvalhash:t->intvalequal:t->t->boolvalof_addr:addr->tvalof_inst:addr->inst->tvalof_symb:addr->symb->tvaladdr:t->addrvalinst:t->instoptionvalsymb:t->symboptionendtypevertex=V.tmoduleE:sigtypettypelabelvalcompare:t->t->intvallabel:t->labelvalsrc:t->vertexvaldst:t->vertexvalcreate:vertex->label->vertex->tendtypeedge=E.tmoduleFixpoint(X:sigtypedatavaldirection:directionvaljoin:data->data->datavalequal:data->data->boolvalanalyze:E.t->data->dataend):sigvalanalyze:(V.t->X.data)->t->V.t->X.dataendtypetrace=vertexSequence.tvalis_directed:boolvalcreate:int->tvalclear:t->unitvalcopy:t->tvaladd_vertex:t->vertex->unitvaladd_addr:t->addr->unitvaladd_inst:t->addr->inst->unitvaladd_symb:t->addr->symb->unitvalremove_vertex:t->vertex->unitvalremove_addr:t->addr->unitvalremove_inst:t->addr->unitvalremove_symb:t->addr->unitvaladd_edge:t->vertex->vertex->unitvaladd_edge_a:t->addr->addr->unitvaladd_edge_e:t->edge->unitvalremove_edge:t->vertex->vertex->unitvalremove_edge_a:t->addr->addr->unitvalremove_edge_e:t->edge->unitvalis_empty:t->boolvalnb_vertex:t->intvalnb_edges:t->intvalout_degree:t->vertex->intvalin_degree:t->vertex->intvalmem_vertex:t->vertex->vertexoptionvalmem_vertex_a:t->addr->vertexoptionvalmem_edge:t->vertex->vertex->edgeoptionvalmem_edge_a:t->addr->addr->edgeoptionvalmem_edge_e:t->edge->edgeoptionvalsucc:t->vertex->vertexlistvalpred:t->vertex->vertexlistvalsucc_e:t->vertex->edgelistvalpred_e:t->vertex->edgelistvaliter_vertex:(vertex->unit)->t->unitvaliter_edges:(vertex->vertex->unit)->t->unitvalfold_vertex:(vertex->'a->'a)->t->'a->'avalfold_edges:(vertex->vertex->'a->'a)->t->'a->'avaliter_edges_e:(edge->unit)->t->unitvalfold_edges_e:(edge->'a->'a)->t->'a->'avaliter_succ:(vertex->unit)->t->vertex->unitvaliter_pred:(vertex->unit)->t->vertex->unitvalfold_succ:(vertex->'a->'a)->t->vertex->'a->'avalfold_pred:(vertex->'a->'a)->t->vertex->'a->'avaliter_succ_e:(edge->unit)->t->vertex->unitvalfold_succ_e:(edge->'a->'a)->t->vertex->'a->'avaliter_pred_e:(edge->unit)->t->vertex->unitvalfold_pred_e:(edge->'a->'a)->t->vertex->'a->'aendmoduleMake(A:Graph.Sig.COMPARABLE)(I:Graph.Sig.HASHABLE)(S:Graph.Sig.HASHABLE):Swithtypeaddr=A.tandtypeinst=I.tandtypesymb=S.t=structmoduleWA=Weak.Make(A)moduleWI=Weak.Make(I)moduleWS=Weak.Make(S)letweak_addr=WA.create17letweak_inst=WI.create17letweak_symb=WS.create17moduleElt:sigtypet=private{addr:A.t;mutableinst:I.toption;mutablesymb:S.toption;}valcompare:t->t->intvalhash:t->intvalequal:t->t->boolvalof_addr:A.t->tvalof_inst:A.t->I.t->tvalof_symb:A.t->S.t->tvalupdate_inst:t->I.toption->unitvalupdate_symb:t->S.toption->unitend=structtypet={addr:A.t;mutableinst:I.toption;mutablesymb:S.toption;}letcomparet1t2=A.comparet1.addrt2.addrlethasht=A.hasht.addrletequalt1t2=A.equalt1.addrt2.addrletof_addraddr=letaddr=WA.mergeweak_addraddrinletinst=Noneinletsymb=Nonein{addr;inst;symb}letof_instaddrinst=letaddr=WA.mergeweak_addraddrinletinst=Some(WI.mergeweak_instinst)inletsymb=Nonein{addr;inst;symb}letof_symbaddrsymb=letaddr=WA.mergeweak_addraddrinletinst=Noneinletsymb=Some(WS.mergeweak_symbsymb)in{addr;inst;symb}letupdate_insteinst=e.inst<-instletupdate_symbesymb=e.symb<-symbendmoduleH=Hashtbl.Make(A)moduleG=Graph.Imperative.Digraph.ConcreteBidirectional(Elt)typeaddr=A.ttypeinst=I.ttypesymb=S.ttypet={graph:G.t;htbl:Elt.tH.t}moduleV=structincludeG.Vletof_addraddr=Elt.of_addraddrletof_instaddrinst=Elt.of_instaddrinstletof_symbaddrsymb=Elt.of_symbaddrsymbletaddrv=v.Elt.addrletinstv=v.Elt.instletsymbv=v.Elt.symbendtypevertex=V.tmoduleE=structincludeG.Eletcreatev1lv2=createv1lv2endtypeedge=E.tmoduleFixpoint(X:sigtypedatavaldirection:directionvaljoin:data->data->datavalequal:data->data->boolvalanalyze:E.t->data->dataend)=structincludeGraph.Fixpoint.Make(G)(structincludeXtypeg=G.ttypevertex=V.ttypeedge=E.tend)letanalyzeft=analyzeft.graphendtypetrace=vertexSequence.tletis_directed=trueletcreatesize=letgraph=G.create~size()inlethtbl=H.createsizein{graph;htbl}letcleart=G.cleart.graph;H.cleart.htblletcopyt=letgraph=G.copyt.graphinlethtbl=H.copyt.htblin{graph;htbl}letfindtv=tryH.findtv.Elt.addrwithNot_found->H.addtv.Elt.addrv;vletmergetv=lete=findtvin(matchv.Elt.instwith|Some_->Elt.update_instev.Elt.inst|None->());(matchv.Elt.symbwith|Some_->Elt.update_symbev.Elt.symb|None->());eletadd_vertextv=G.add_vertext.graph(merget.htblv)letadd_addrtaddr=add_vertext(Elt.of_addraddr)letadd_insttaddrinst=add_vertext(Elt.of_instaddrinst)letadd_symbtaddrsymb=add_vertext(Elt.of_symbaddrsymb)letremove_vertextv=G.remove_vertext.graphv;H.removet.htblv.Elt.addrletremove_addrtaddr=remove_vertext(Elt.of_addraddr)letremove_insttaddr=Elt.update_inst(findt.htbl(Elt.of_addraddr))Noneletremove_symbtaddr=Elt.update_symb(findt.htbl(Elt.of_addraddr))Noneletadd_edgetv1v2=G.add_edget.graph(merget.htblv1)(merget.htblv2)letadd_edge_ata1a2=add_edget(Elt.of_addra1)(Elt.of_addra2)letadd_edge_ete=add_edget(E.srce)(E.dste)letremove_edgetv1v2=G.remove_edget.graphv1v2letremove_edge_ata1a2=G.remove_edget.graph(Elt.of_addra1)(Elt.of_addra2)letremove_edge_ete=G.remove_edge_et.grapheletis_emptyt=G.is_emptyt.graphletnb_vertext=G.nb_vertext.graphletnb_edgest=G.nb_edgest.graphletout_degreetv=G.out_degreet.graphvletin_degreetv=G.in_degreet.graphvletmem_vertextv=ifG.mem_vertext.graphvthenSome(H.findt.htblv.Elt.addr)elseNoneletmem_vertex_ata=mem_vertext(Elt.of_addra)letmem_edgetv1v2=matchG.find_edget.graphv1v2with|e->letlabel=E.labeleinSome(E.create(H.findt.htblv1.Elt.addr)label(H.findt.htblv2.Elt.addr))|exceptionNot_found->Noneletmem_edge_ata1a2=mem_edget(Elt.of_addra1)(Elt.of_addra2)letmem_edge_ete=mem_edget(E.srce)(E.dste)letsucctv=G.succt.graphvletpredtv=G.predt.graphvletsucc_etv=G.succ_et.graphvletpred_etv=G.succ_et.graphvletiter_vertexft=G.iter_vertexft.graphletiter_edgesft=G.iter_edgesft.graphletiter_edges_eft=G.iter_edges_eft.graphletfold_vertexftacc=G.fold_vertexft.graphaccletfold_edgesftacc=G.fold_edgesft.graphaccletfold_edges_eftacc=G.fold_edges_eft.graphaccletiter_succftv=G.iter_succft.graphvletiter_predftv=G.iter_predft.graphvletfold_succftvacc=G.fold_succft.graphvaccletfold_predftvacc=G.fold_predft.graphvaccletiter_succ_eftv=G.iter_succ_eft.graphvletiter_pred_eftv=G.iter_pred_eft.graphvletfold_succ_eftvacc=G.fold_succ_eft.graphvaccletfold_pred_eftvacc=G.fold_pred_eft.graphvaccend