123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133(****************************************************************************)(* *)(* This file is part of MOPSA, a Modular Open Platform for Static Analysis. *)(* *)(* Copyright (C) 2017-2019 The MOPSA Project. *)(* *)(* This program is free software: 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, either version 3 of the License, or *)(* (at your option) any later version. *)(* *)(* This program 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. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this program. If not, see <http://www.gnu.org/licenses/>. *)(* *)(****************************************************************************)(** Runner - main entry point of the analysis *)openMopsa_utilsopenCore.AllopenParams.Optionslet()=Sys.catch_breaktrue(** {2 Command-line options} *)(** ************************ *)letopt_interactive=ref"automatic"let()=register_builtin_option{key="-engine";category="Debugging";doc="selects analysis mode";spec=ArgExt.Symbol(["automatic";"interactive";"dap"],(funs->matchswith|"automatic"->opt_interactive:="automatic"|"interactive"->opt_interactive:="interactive"|"dap"->opt_interactive:="dap"|_->()));default="automatic";}(** Parse command line arguments and apply [f] on the list of target
source files *)letparse_optionspassed_argsf()=letfiles=ref[]inletargs=refNoneinArgExt.parsepassed_args(Params.Options.get_options())(funfilename->files:=filename::!files)(funrest->args:=Somerest)"Modular Open Platform for Static Analysis"Params.Options.help;f!files!args(** {2 Parsing} *)(** *********** *)(** Call the appropriate frontend to parse the input sources *)letparse_programlangfiles=letfront=tryfind_language_frontendlangwithNot_found->Exceptions.panic"No front-end found for language %s"langinfront.parsefiles(** {2 Entry points} *)(** **************** *)letanalyze_files(files:stringlist)(args:stringlistoption):int=lett=Timing.start()intryletconfig=Params.Paths.resolve_config_file!Params.Config.Parser.opt_configinletabstraction=Params.Config.Parser.parseconfiginletdomain=Params.Config.Builder.from_jsonabstraction.domaininletprog=parse_programabstraction.languagefilesin(* Top layer analyzer *)letmoduleDomain=(valdomain)inletmoduleToplevel=Toplevel.Make(Domain)inletmoduleEngine=(valmatch!opt_interactivewith|"interactive"->letmoduleE=Engines.Interactive.Engine.Make(Toplevel)(Engines.Interactive.Terminal.Make)in(moduleE)|"dap"->letmoduleE=Engines.Interactive.Engine.Make(Toplevel)(Engines.Interactive.Dap.Make)in(moduleE)|"automatic"->letmoduleE=Engines.Automatic.Make(Toplevel)in(moduleE)|x->Exceptions.panic"unknown engine '%s'"x:Engines.Engine_sig.ENGINEwithtypet=Domain.t)inletflow=Engine.initproginletstmt=mk_stmt(S_program(prog,args))prog.prog_rangeinletres=tryEngine.analyzestmtflowwithToplevel.SysBreakflow->(* let () = warn "Early termination, hooks will yield partial information only" in *)let()=Hook.on_finishEngine.manflowinraise(Toplevel.SysBreakflow)inlett=Timing.stoptinHook.on_finishEngine.manres;Output.Factory.reportEngine.manres~time:t~fileswith|Exit->exit1|e->lett=tryTiming.stoptwith_->0.inOutput.Factory.panic~btrace:(Printexc.get_backtrace())e~time:t~filesletrun()=exit@@parse_optionsSys.argvanalyze_files()