123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207(**************************************************************************)(* *)(* This file is part of Aorai plug-in of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* INRIA (Institut National de Recherche en Informatique et en *)(* Automatique) *)(* INSA (Institut National des Sciences Appliquees) *)(* *)(* 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). *)(* *)(**************************************************************************)(* [VP] Need to get rid of those global references at some point. *)letc_file=refFilepath.Normalized.emptyletdot_file=refFilepath.Normalized.empty(* Performs some checks before calling [open_in f], reporting ["errmsg: <f>"]
in case of error. *)letcheck_and_open_in(f:Filepath.Normalized.t)errmsg=ifnot(Filepath.Normalized.is_filef)thenAorai_option.abort"%s: %a"errmsgFilepath.Normalized.prettyf;open_in(f:>string)letload_ya_filefilename=letchannel=check_and_open_infilename"invalid Ya file"inletlexbuf=Lexing.from_channelchannelinLexing.(lexbuf.lex_curr_p<-{lexbuf.lex_curr_pwithpos_fname=(filename:>string)});tryletautomata=Yaparser.mainYalexer.tokenlexbufinclose_inchannel;Data_for_aorai.setAutomataautomatawith|Parsing.Parse_error->Utils_parser.abort_currentlexbuf"syntax error"letdisplay_status()=ifAorai_option.verbose_atleast2thenbeginAorai_option.feedback"\n";Aorai_option.feedback"C file: '%a'\n"Filepath.Normalized.pretty!c_file;Aorai_option.feedback"Entry point: '%a'\n"Kernel_function.pretty(fst(Globals.entry_point()));ifAorai_option.Dot.get()thenAorai_option.feedback"Dot file: '%a'\n"Filepath.Normalized.pretty!dot_file;endletinit_file_names()=letfreshname?opt_suffilesuf=letname=(file:Filepath.Normalized.t:>string)inletpre=Filename.remove_extensionnameinletpre=matchopt_sufwithNone->pre|Somes->pre^sinletrecfnpsn=ifnot(Sys.file_exists(p^(string_of_intn)^s))then(p^(string_of_intn)^s)elsefnps(n+1)inletname=ifnot(Sys.file_exists(pre^suf))thenpre^sufelsefnpresuf0inFilepath.Normalized.of_stringnameinifAorai_option.Ya.is_empty()thenAorai_option.abort"empty Ya file name";ifAorai_option.Dot.get()thendot_file:=freshname(Aorai_option.Ya.get())".dot";display_status()letprintverbs=Aorai_option.feedback~level:2"%s"sletoutput()=(* Dot file *)if(Aorai_option.Dot.get())thenbeginPretty_automaton.Typed.output_dot_automata(Data_for_aorai.getAutomata())(!dot_file:>string);printverb"Generating dot file : done\n"endletwork()=letfile=Ast.get()inAorai_utils.initFilefile;printverb"C file loading : done\n";ifnot(Aorai_option.Ya.is_empty())thenload_ya_file(Aorai_option.Ya.get());letroot=fst(Globals.entry_point())inletaxiomatization=Aorai_option.Axiomatization.get()inifaxiomatizationthenbegin(* Step 5 : incrementing pre/post
conditions with states and transitions information *)printverb"Refining pre/post : \n";Aorai_dataflow.compute();(* Step 6 : Removing transitions never crossed *)letautomaton_has_states=if(Aorai_option.AutomataSimplification.get())thenbeginprintverb"Removing unused trans : done\n";tryData_for_aorai.removeUnusedTransitionsAndStates();truewithData_for_aorai.Empty_automaton->Aorai_option.warning"No state of the automaton is reachable. \
Program and specification are incompatible, \
instrumentation will not be generated.";falseendelse(printverb"Removing unused trans : skipped\n";true)inifautomaton_has_statesthenbegin(* Step 7 : Labeling abstract file *)(* Finally the information is added into the Cil automata. *)Aorai_utils.initGlobalsrootaxiomatization;Aorai_visitors.add_sync_with_buchfile;ifAorai_option.GenerateAnnotations.get()thenAorai_visitors.add_pre_post_from_buchfile(Aorai_option.advance_abstract_interpretation())elseifAorai_option.ConsiderAcceptance.get()thenbeginletkf,_=Globals.entry_point()inletbhv=Aorai_utils.mk_acceptance_bhv()inAnnotations.add_behaviorsAorai_option.emitterkf[bhv]end;Aorai_eva_analysis.setup();printverb"Annotation of Cil : done\n";endendelsebegin(* Step 4': Computing the set of possible pre-states and post-states of each function *)(* And so for pre/post transitions *)printverb"Abstracting pre/post : skipped\n";(* Step 5': incrementing pre/post conditions with states and transitions information *)printverb"Refining pre/post : skipped\n";(* Step 6 : Removing transitions never crossed *)printverb"Removing unused trans : skipped\n";(* Step 7 : Labeling abstract file *)(* Finally the information is added into the Cil automata. *)Aorai_utils.initGlobalsrootaxiomatization;Aorai_visitors.add_sync_with_buchfile;printverb"Annotation of Cil : partial\n"end;(* Step 8 : clearing tables whose information has been
invalidated by our transformations.
*)Ast.mark_as_changed();Cfg.clearFileCFG~clear_id:falsefile;Cfg.computeFileCFGfile;Ast.clear_last_decl();ifKernel.Check.get()thenFilecheck.check_ast"aorai";output()letrun()=(* Step 1 : Capture files names *)init_file_names();(* Step 2 : Work in our own project, initialized by a copy of the main
one. *)letwork_prj=File.create_project_from_visitor"aorai"(funprj->newVisitor.frama_c_copyprj)inProject.copy~selection:(Parameter_state.get_selection())work_prj;Project.onwork_prjwork()(* Plugin registration *)letrun=Dynamic.register~plugin:"Aorai""run"(Datatype.funcDatatype.unitDatatype.unit)runletrun,_=State_builder.apply_once"Aorai"(letmoduleO=Aorai_optionin[O.Ya.self;O.Axiomatization.self;O.ConsiderAcceptance.self;O.AutomataSimplification.self;O.AbstractInterpretation.self;O.AddingOperationNameAndStatusInSpecification.self])runletmain()=ifAorai_option.is_on()thenrun()let()=Db.Main.extendmain(*
Local Variables:
compile-command: "make -C ../../.."
End:
*)