123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* 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). *)(* *)(**************************************************************************)(** This module deals with the action management.
* It consists of the definitions of the different kinds of actions,
* and the management of the action list.
*)(**/**)openPdg_typestypeselect=SlicingTypes.sl_markPdgMarks.selecttypen_or_d_marks=(SlicingInternals.node_or_dpds*SlicingInternals.pdg_mark)list(**/**)(*============================================================================*)(** {2 Build} *)(** {3 How the elements will be selected} *)(** Build a description to tell that the associated nodes have to be marked
* with the given mark, and than the same one will be propagated through
* their dependencies. (see also {!build_node_and_dpds_selection}) *)letbuild_simple_node_selection?(nd_marks=[])mark=(SlicingInternals.CwNode,mark)::nd_marks(** Only the control dependencies of the nodes will be marked *)letbuild_addr_dpds_selection?(nd_marks=[])mark=(SlicingInternals.CwAddrDpds,mark)::nd_marks(** Only the control dependencies of the nodes will be marked *)letbuild_data_dpds_selection?(nd_marks=[])mark=(SlicingInternals.CwDataDpds,mark)::nd_marks(** Only the control dependencies of the nodes will be marked *)letbuild_ctrl_dpds_selection?(nd_marks=[])mark=(SlicingInternals.CwCtrlDpds,mark)::nd_marks(** Build a description to tell how the selected PDG nodes and their
* dependencies will have to be marked
* (see {!type:SlicingTypes.Internals.node_or_dpds}).
* This description depend on the mark that has been asked for.
* First of all, whatever the mark is, the node is selected as [spare],
* so that it will be visible, and so will its dependencies. Then,
* if [is_ctrl mark] propagate a m1 control mark through the control dependencies
* and do a similar thing for [addr] and [data] *)letbuild_node_and_dpds_selection?(nd_marks=[])mark=letm_spare=SlicingMarks.mk_user_spareinletnd_marks=build_simple_node_selection~nd_marks:nd_marksm_spareinletnd_marks=ifSlicingMarks.is_ctrl_markmarkthenletm_ctrl=SlicingMarks.mk_user_mark~ctrl:true~data:false~addr:falseinbuild_ctrl_dpds_selection~nd_marks:nd_marksm_ctrlelsend_marksinletnd_marks=ifSlicingMarks.is_addr_markmarkthenletm_addr=SlicingMarks.mk_user_mark~ctrl:false~data:false~addr:trueinbuild_addr_dpds_selection~nd_marks:nd_marksm_addrelsend_marksinletnd_marks=ifSlicingMarks.is_data_markmarkthenletm_data=SlicingMarks.mk_user_mark~ctrl:false~data:true~addr:falseinbuild_data_dpds_selection~nd_marks:nd_marksm_dataelsend_marksinnd_marks(** {3 Translations to a mapping between marks and program elements} *)lettranslate_crit_to_selectpdg?(to_select=[])list_crit=lettranslateacc(nodes,nd_mark)=letadd_pdg_markacc(nd,mark)=letadd_nodesmaccnodes=letaddmaccnodepart=PdgMarks.add_node_to_selectaccnodepartminList.fold_left(addm)accnodesinletadd_node_dpdsdpd_markf_dpdsacc(node,_node_z_part)=letnodes=f_dpdsnodeinadd_nodesdpd_markaccnodesinletacc=matchndwith|SlicingInternals.CwNode->add_nodesmarkaccnodes|SlicingInternals.CwAddrDpds->letf=PdgTypes.Pdg.get_x_direct_dpdsPdgTypes.Dpd.AddrpdginList.fold_left(add_node_dpdsmarkf)accnodes|SlicingInternals.CwCtrlDpds->letf=PdgTypes.Pdg.get_x_direct_dpdsPdgTypes.Dpd.CtrlpdginList.fold_left(add_node_dpdsmarkf)accnodes|SlicingInternals.CwDataDpds->letf=PdgTypes.Pdg.get_x_direct_dpdsPdgTypes.Dpd.DatapdginList.fold_left(add_node_dpdsmarkf)accnodesinaccinList.fold_leftadd_pdg_markaccnd_markinList.fold_lefttranslateto_selectlist_crit(** {3 Function criteria} *)(** build an action to apply the criteria to the persistent selection of the
* function. It means that it will be applied to all slices. *)letmk_fct_critficrit=SlicingInternals.CrFct{SlicingInternals.cf_fct=SlicingInternals.FctSrcfi;SlicingInternals.cf_info=crit}letmk_fct_user_critficrit=mk_fct_critfi(SlicingInternals.CcUserMarkcrit)letmk_crit_fct_topfim=mk_fct_user_critfi(SlicingInternals.CuTopm)letmk_crit_fct_user_selectfiselect=mk_fct_user_critfi(SlicingInternals.CuSelectselect)letmk_crit_prop_persit_marksfinode_marks=mk_fct_critfi(SlicingInternals.CcPropagatenode_marks)(** build an action to apply the criteria to the given slice. *)letmk_ff_critffcrit=SlicingInternals.CrFct{SlicingInternals.cf_fct=SlicingInternals.FctSlicedff;SlicingInternals.cf_info=crit}letmk_ff_user_selectffcrit=mk_ff_critff(SlicingInternals.CcUserMark(SlicingInternals.CuSelectcrit))letmk_crit_choose_callffcall=mk_ff_critff(SlicingInternals.CcChooseCallcall)letmk_crit_change_callffcallf=mk_ff_critff(SlicingInternals.CcChangeCall(call,f))letmk_crit_missing_inputsffcall(input_marks,more_inputs)=mk_ff_critff(SlicingInternals.CcMissingInputs(call,input_marks,more_inputs))letmk_crit_missing_outputsffcall(output_marks,more_outputs)=mk_ff_critff(SlicingInternals.CcMissingOutputs(call,output_marks,more_outputs))letmk_crit_examines_callsffcall_out_marks=mk_ff_critff(SlicingInternals.CcExamineCallscall_out_marks)letmk_appli_select_callsfi=SlicingInternals.CrAppli(SlicingInternals.CaCallfi)(** {3 Shortcut functions for previous things} *)letmk_crit_mark_callsfi_callerto_callmark=letselect=tryletcaller=SlicingMacros.get_fi_kffi_callerinletpdg_caller=Pdg.Api.getcallerinletcall_stmts=Pdg.Api.find_call_stmts~callerto_callinletstmt_markstmt=letstmt_ctrl_node=Pdg.Api.find_call_ctrl_nodepdg_callerstmtin(PdgMarks.mk_select_nodestmt_ctrl_node,mark)inletselect=List.mapstmt_markcall_stmtsinSlicingInternals.CuSelectselectwithPdgTypes.Pdg.Top->SlicingInternals.CuTopmarkinmk_fct_user_critfi_callerselectletmk_crit_add_output_marksffselect=(*
let pdg = SlicingMacros.get_ff_pdg ff in
let add acc (out, m) =
let nd_m = build_simple_node_selection m in
let node = out in
mk_mark_nodes pdg ~marks:acc [node] nd_m
in let select = List.fold_left add [] output_marks in
*)mk_ff_user_selectffselect(*
let mk_crit_add_all_outputs_mark ff mark =
let pdg = SlicingMacros.get_ff_pdg ff in
let nodes = Pdg.Api.find_all_outputs_nodes pdg in
let nd_m = build_simple_node_selection mark in
let select = mk_mark_nodes nodes nd_m in
mk_ff_user_crit ff select
*)(*============================================================================*)(** {2 Print} *)letprint_nd_and_markf(nd,m)=letstr=matchndwith|SlicingInternals.CwNode->""|SlicingInternals.CwAddrDpds->"addr->"|SlicingInternals.CwDataDpds->"data->"|SlicingInternals.CwCtrlDpds->"ctrl->"inFormat.fprintff"%s%a"strSlicingMarks.pretty_markmletrecprint_nd_and_mark_listfmtndm_list=matchndm_listwith|[]->()|x::ndm_list->print_nd_and_markfmtx;print_nd_and_mark_listfmtndm_listletprint_nodesfmtnodes=letprintn=Format.fprintffmt"%a "(Pdg.Api.pretty_nodetrue)ninList.iterprintnodesletprint_node_markfmtnzm=Format.fprintffmt"(%a ,%a)"(PdgTypes.Node.pretty_with_part)(n,z)SlicingMarks.pretty_markmletprint_sel_marks_listfmtto_select=letprint_sel(s,m)=matchswith|PdgMarks.SelNode(n,z)->print_node_markfmtnzm|PdgMarks.SelInl->Format.fprintffmt"(UndefIn %a:%a)"Locations.Zone.prettylSlicingMarks.pretty_markminmatchto_selectwith[]->Format.fprintffmt"<empty>"|_->List.iterprint_selto_selectlet_print_ndmfmt(nodes,ndm_list)=Format.fprintffmt"(%a,%a)"print_nodesnodesprint_nd_and_mark_listndm_listletprint_f_critfmtf_crit=matchf_critwith|SlicingInternals.CuTopm->Format.fprintffmt"top(%a)"SlicingMarks.pretty_markm|SlicingInternals.CuSelectto_select->print_sel_marks_listfmtto_selectletprint_critfmtcrit=matchcritwith|SlicingInternals.CrFctfct_crit->letfct=fct_crit.SlicingInternals.cf_fctinletname=SlicingMacros.f_namefctinFormat.fprintffmt"[%s = "name;let_=matchfct_crit.SlicingInternals.cf_infowith|SlicingInternals.CcUserMarkinfo->print_f_critfmtinfo|SlicingInternals.CcMissingInputs(call,_input_marks,more_inputs)->Format.fprintffmt"missing_inputs for call %d (%s)"call.Cil_types.sid(ifmore_inputsthen"more_inputs"else"marks only")|SlicingInternals.CcMissingOutputs(call,_output_marks,more_outputs)->Format.fprintffmt"missing_outputs for call %d (%s)"call.Cil_types.sid(ifmore_outputsthen"more_outputs"else"marks only")|SlicingInternals.CcChooseCallcall->Format.fprintffmt"choose_call for call %d"call.Cil_types.sid|SlicingInternals.CcChangeCall(call,f)->letfname=matchfwith|SlicingInternals.CallSliceff->SlicingMacros.ff_nameff|SlicingInternals.CallSrc(Somefi)->("(src:"^(SlicingMacros.fi_namefi)^")")|SlicingInternals.CallSrcNone->"(src)"inFormat.fprintffmt"change_call for call %d -> %s"call.Cil_types.sidfname|SlicingInternals.CcPropagatenl->Format.fprintffmt"propagate %a"print_sel_marks_listnl|SlicingInternals.CcExamineCalls_->Format.fprintffmt"examine_calls"inFormat.fprintffmt"]"|SlicingInternals.CrAppli(SlicingInternals.CaCallfi)->letname=SlicingMacros.fi_namefiinFormat.fprintffmt"[Appli : calls to %s]"name|_->SlicingParameters.not_yet_implemented"Printing this slicing criterion "letprint_list_critfmtlist_crit=List.iter(print_critfmt)list_crit(*============================================================================*)