123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101(**************************************************************************)(* *)(* SPDX-License-Identifier LGPL-2.1 *)(* Copyright (C) *)(* CEA (Commissariat à l'énergie atomique et aux énergies alternatives) *)(* *)(**************************************************************************)(** Variables from mthread.c used by the cvalue domain to represent
threads, mutexes and queues during the analysis. *)letfind_mthread_global_varname=tryGlobals.Vars.find_from_astinfonameGlobalwithNot_found->letmthread_c=Mt_self.Share.get_file"mthread.c"inMt_self.abort"Variable %S not found. \
It should be in file %a, required for the Mthread analysis. \
Use parameter -mt-threads-lib to include this file in the parsing phase."nameFilepath.prettymthread_cletmthread_global_varname=letmoduleInfo=structletname="Eva.Mt_lib."^nameletdependencies=[Ast.self]endinletmoduleRef=State_builder.Option_ref(Cil_datatype.Varinfo)(Info)infun()->Ref.memo(fun()->find_mthread_global_varname)letarray_threads=mthread_global_var"__fc_mthread_threads"letarray_mutexes=mthread_global_var"__fc_mthread_mutexes"letarray_queues=mthread_global_var"__fc_mthread_queues"letvar_thread_created=mthread_global_var"__fc_mthread_threads_running"letcheck_mthread_library()=ignore(array_threads());ignore(array_mutexes());ignore(array_queues());ignore(var_thread_created());(** Load files used to stub threads library. *)typethreads_lib=|BuiltinsOnly|Pthreadsletpp_threads_libfmtlib=matchlibwith|BuiltinsOnly->Format.pp_print_stringfmt"builtins only"|Pthreads->Format.pp_print_stringfmt"lib pthreads"letthreads_lib_fileslib=letmthread_c=Mt_self.Share.get_file"mthread.c"inmatchlibwith|BuiltinsOnly->Filepath.Set.singletonmthread_c|Pthreads->letmthread_pthread_c=Mt_self.Share.get_file"mthread_pthread.c"inFilepath.Set.of_list[mthread_c;mthread_pthread_c]letload_threads_librarylib=Mt_self.feedback"Preparing sources for Mthread with %a"pp_threads_liblib;(* Add MThread folder to the include path. *)letmt_include_dir=Format.asprintf"-I%a"Filepath.pretty_abs(Mt_self.Share.get_dir".")inKernel.CppExtraArgs.addmt_include_dir;(* Add the stubbed library files to the list of files to parse. *)threads_lib_fileslib|>Filepath.Set.iter(funf->letf=File.from_filenamefinFile.pre_registerf)letis_pthread_functionkf=letloc=Kernel_function.get_locationkfinletpath=(fstloc).pos_pathinFilepath.basenamepath="pthread.h"lethas_been_parsedlib=letlib_files=threads_lib_fileslibinletcabs_files=Ast.UntypedFiles.get()inletparsed_files=List.mapfstcabs_files|>Filepath.Set.of_listinFilepath.Set.subsetlib_filesparsed_filesletwarn_on_unsupported_library_functionkf=ifis_pthread_functionkfthenifhas_been_parsedPthreadsthenMt_self.error~current:true~once:true"Unsupported function %a from the pthreads library: \
its analysis is probably unsound."Kernel_function.prettykfelseMt_self.abort~current:true"Call to %a from the pthreads library, whose Mthread files are missing. \
Use '-mt-threads-lib pthreads' to enable the support of pthreads, \
or write a C stub for this function using Mthread primitives."Kernel_function.prettykf