123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187(**************************************************************************)(* *)(* 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). *)(* *)(**************************************************************************)openCil_typesopenFormat_typesopenVa_typesopenOptionsmoduleTyp=Extends.Typ(* ************************************************************************ *)(* Variadic classes builders *)(* ************************************************************************ *)letfind_functionenvs=trySome(Environment.find_functionenvs)withNot_found->Self.warning~wkey:wkey_libc_framac"Unable to locate function %s which should be in the Frama-C LibC."s;Noneletmk_overloadenvnames=letvis=List.filter_map(find_functionenv)namesinletoverload=List.map(funvi->Typ.params_typesvi.vtype,vi)visinOverloadoverloadletmk_aggregatorenvfun_namea_pospnamea_type=matchfind_functionenvfun_namewith|None->Misc|Somevi->try(* Get the list of arguments *)letparams=Typ.paramsvi.vtypein(* Check that pos is a valid position in the list *)assert(a_pos>=0);ifa_pos>=List.lengthparamsthenbeginSelf.warning~current:true~wkey:wkey_libc"The standard function %s should have at least %d parameters."fun_name(a_pos+1);raiseExitend;(* Get the aggregate type of elements *)let_,ptyp,_=List.nthparamsa_posinleta_param=pname,matchptypwith|TArray(typ,_,_)|TPtr(typ,_)->typ|_->Self.warning~current:true~wkey:wkey_libc"The parameter %d of standard function %s should be \
of array type."(a_pos+1)fun_name;raiseExitinAggregator{a_target=vi;a_pos;a_type;a_param}(* In case of failure return Misc (apply generic translation) *)withExit->Miscletmk_format_funvif_kindf_buffer~format_pos=letbuffer_arguments=matchf_bufferwith|StdIO|Syslog->[]|Filei|Streami|Arg(i,None)->[i]|Arg(i,Somej)->[i;j]inletexpected_args=buffer_arguments@[format_pos]inletn_expected_args=(List.fold_leftmax(-1)expected_args)+1andn_actual_args=List.length(Typ.paramsvi.vtype)inifn_actual_args<n_expected_argsthenbeginSelf.warning~current:true~wkey:wkey_libc"The standard function %s was expected to have at least %d fixed \
parameters but only has %d.@ \
No variadic translation will be performed."vi.vnamen_expected_argsn_actual_args;MiscendelseFormatFun{f_kind;f_buffer;f_format_pos=format_pos}(* ************************************************************************ *)(* Classification *)(* ************************************************************************ *)letis_frama_c_builtinname=Ast_info.is_frama_c_builtinname||Cil_builtins.Builtin_functions.memname||String.starts_with~prefix:"__FRAMAC_"name(* Mthread prefixes *)letva_builtins=["__builtin_va_start";"__builtin_va_copy";"__builtin_va_arg";"__builtin_va_end";]letis_va_builtins=List.memsva_builtinsletclassify_stdenvvi=matchvi.vnamewith(* fcntl.h - Overloads of functions *)|"fcntl"->mk_overloadenv["__va_fcntl_void";"__va_fcntl_int";"__va_fcntl_flock"]|"open"->mk_overloadenv["__va_open_void";"__va_open_mode_t"]|"openat"->mk_overloadenv["__va_openat_void";"__va_openat_mode_t"](* unistd.h *)|"execl"->mk_aggregatorenv"execv"1"argv"EndedByNull|"execle"->mk_aggregatorenv"execve"1"argv"EndedByNull|"execlp"->mk_aggregatorenv"execvp"1"argv"EndedByNull|"syscall"->Misc(* stdio.h *)|"fprintf"->mk_format_funviPrintfLike~format_pos:1(Stream0)|"printf"->mk_format_funviPrintfLike~format_pos:0(StdIO)|"sprintf"->mk_format_funviPrintfLike~format_pos:1(Arg(0,None))|"snprintf"->mk_format_funviPrintfLike~format_pos:2(Arg(0,Some1))|"dprintf"->mk_format_funviPrintfLike~format_pos:1(File0)|"fscanf"->mk_format_funviScanfLike~format_pos:1(Stream0)|"scanf"->mk_format_funviScanfLike~format_pos:0(StdIO)|"sscanf"->mk_format_funviScanfLike~format_pos:1(Arg(0,None))(* syslog.h *)|"syslog"->mk_format_funviPrintfLike~format_pos:1(Syslog)(* wchar.h *)|"fwprintf"->mk_format_funviPrintfLike~format_pos:1(Stream0)|"swprintf"->mk_format_funviPrintfLike~format_pos:2(Arg(0,Some1))|"wprintf"->mk_format_funviPrintfLike~format_pos:0(StdIO)|"fwscanf"->mk_format_funviScanfLike~format_pos:1(Stream0)|"swscanf"->mk_format_funviScanfLike~format_pos:1(Arg(0,None))|"wscanf"->mk_format_funviScanfLike~format_pos:0(StdIO)(* stropts.h *)|"ioctl"->mk_overloadenv["__va_ioctl_void";"__va_ioctl_int";"__va_ioctl_ptr"]|nwhenString.starts_with~prefix:"__sync_"n->Misc|nwhenis_va_builtinn->Misc|nwhenis_frama_c_builtinn->Builtin(* Anything else *)|_->Unknownletis_variadic_functionvi=matchCil.unrollTypevi.vtypewith|TFun(_,_,b,_)->b|_->falseletclassifyenvvi=ifis_variadic_functionvithenbeginSelf.result~level:2~current:true"Declaration of variadic function %s."vi.vname;Some{vf_decl=vi;vf_original_type=vi.vtype;vf_class=ifvi.vdefinedthenDefinedelseclassify_stdenvvi;vf_specialization_count=0}endelseNone