From ed672d7a92b0e45fbb4915d0c26502262d60d9d3 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Fri, 25 Nov 2016 18:31:37 +0100 Subject: [PATCH] [kernel] compatibility between machdep and CPP options - Extend machdep information to include required CPP arguments (p.ex. -m32); - Check supported architecture options during configure; - Automatically apply options according to chosen machdep. Note: this may generate extra warnings when using old versions of GCC or compilers that do not support options -m32/-m64 and similar. --- Makefile.generating | 1 + configure.in | 33 +++++++++++++++++++++ share/Makefile.config.in | 1 + src/kernel_internals/runtime/config.ml.in | 2 ++ src/kernel_internals/runtime/config.mli | 7 +++++ src/kernel_internals/runtime/machdeps.ml | 5 ++++ src/kernel_services/ast_data/cil_types.mli | 2 ++ src/kernel_services/ast_queries/file.ml | 29 ++++++++++++++++-- tests/misc/custom_machdep/custom_machdep.ml | 1 + tests/syntax/machdep_char_unsigned.ml | 1 + 10 files changed, 80 insertions(+), 2 deletions(-) diff --git a/Makefile.generating b/Makefile.generating index 4bb84658c1e..063b2a11c93 100644 --- a/Makefile.generating +++ b/Makefile.generating @@ -85,6 +85,7 @@ $(CONFIG_FILE): $(CONFIG_FILE).in VERSION share/Makefile.config Makefile.generat -e "s|@FRAMAC_DEFAULT_CPP@|$(FRAMAC_DEFAULT_CPP)|" \ -e "s|@FRAMAC_GNU_CPP@|$(FRAMAC_GNU_CPP)|" \ -e "s|@DEFAULT_CPP_KEEP_COMMENTS@|$(DEFAULT_CPP_KEEP_COMMENTS)|" \ + -e "s|@DEFAULT_CPP_SUPPORTED_ARCH_OPTS@|$(DEFAULT_CPP_SUPPORTED_ARCH_OPTS)|" \ -e "s|@STATIC_PLUGINS@|$(STATIC_PLUGINS)|" \ -e "s|@STATIC_GUI_PLUGINS@|$(STATIC_GUI_PLUGINS)|" \ -e "s|@COMPILATION_UNITS@|$(COMPILATION_UNITS)|" \ diff --git a/configure.in b/configure.in index cbdd6db7736..5b1ec3eca26 100644 --- a/configure.in +++ b/configure.in @@ -528,6 +528,38 @@ AC_ARG_WITH( AC_MSG_RESULT(Default preprocessor is '$FRAMAC_DEFAULT_CPP'.) + +# Test if preprocessor supports options such as -m16/-m32/-m64 + +DEFAULT_CPP_SUPPORTED_ARCH_OPTS= + +rm -f conftest.i +CPPFLAGS="-m32" +AC_PREPROC_IFELSE( + [AC_LANG_SOURCE([/* Check if preprocessor supports option -m32 */])], + [if test -e conftest.i; then + DEFAULT_CPP_SUPPORTED_ARCH_OPTS+='\"-m32\"; '; + fi], []) + +rm -f conftest.i +CPPFLAGS="-m64" +AC_PREPROC_IFELSE( + [AC_LANG_SOURCE([/* Check if preprocessor supports option -m64 */])], + [if test -e conftest.i; then + DEFAULT_CPP_SUPPORTED_ARCH_OPTS+='\"-m64\"; '; + fi], []) + +rm -f conftest.i +CPPFLAGS="-m16" +AC_PREPROC_IFELSE( + [AC_LANG_SOURCE([/* Check if preprocessor supports option -m16 */])], + [if test -e conftest.i; then + DEFAULT_CPP_SUPPORTED_ARCH_OPTS+='\"-m16\"; '; + fi], []) + +AC_MSG_RESULT(Default preprocessor supported architecture-related options: $DEFAULT_CPP_SUPPORTED_ARCH_OPTS) + + ################# # Plugin wished # ################# @@ -954,6 +986,7 @@ AC_SUBST(CYCLES_PER_USEC) AC_SUBST(LOCAL_MACHDEP) AC_SUBST(datarootdir) AC_SUBST(FRAMAC_DEFAULT_CPP) +AC_SUBST(DEFAULT_CPP_SUPPORTED_ARCH_OPTS) AC_SUBST(FRAMAC_GNU_CPP) AC_SUBST(DEFAULT_CPP_KEEP_COMMENTS) AC_SUBST(CC) diff --git a/share/Makefile.config.in b/share/Makefile.config.in index e254ddc93d9..0f2a08ce440 100644 --- a/share/Makefile.config.in +++ b/share/Makefile.config.in @@ -50,6 +50,7 @@ EMACS_DATADIR ?=$(DATADIR)/emacs/site-lisp FRAMAC_DEFAULT_CPP ?=@FRAMAC_DEFAULT_CPP@ FRAMAC_GNU_CPP ?=@FRAMAC_GNU_CPP@ DEFAULT_CPP_KEEP_COMMENTS?=@DEFAULT_CPP_KEEP_COMMENTS@ +DEFAULT_CPP_SUPPORTED_ARCH_OPTS?=@DEFAULT_CPP_SUPPORTED_ARCH_OPTS@ CC =@CC@ ############### diff --git a/src/kernel_internals/runtime/config.ml.in b/src/kernel_internals/runtime/config.ml.in index 9fa1d0a2938..a44de6874d7 100644 --- a/src/kernel_internals/runtime/config.ml.in +++ b/src/kernel_internals/runtime/config.ml.in @@ -58,6 +58,8 @@ let preprocessor = let preprocessor_is_gnu_like = try ignore (Sys.getenv "CPP"); false with Not_found -> @FRAMAC_GNU_CPP@ +let preprocessor_supported_arch_options = [@DEFAULT_CPP_SUPPORTED_ARCH_OPTS@] + let preprocessor_keep_comments = try (ignore (Sys.getenv "CPP"); true) with Not_found -> @DEFAULT_CPP_KEEP_COMMENTS@ diff --git a/src/kernel_internals/runtime/config.mli b/src/kernel_internals/runtime/config.mli index bff595458dc..95a80251b1d 100644 --- a/src/kernel_internals/runtime/config.mli +++ b/src/kernel_internals/runtime/config.mli @@ -81,6 +81,13 @@ val preprocessor_is_gnu_like: bool @since Sodium-20150201 *) +val preprocessor_supported_arch_options: string list + (** architecture-related options (e.g. -m32) known to be supported by + the default preprocessor. Used to match preprocessor commands to + selected machdeps. + @since Frama-C+dev + *) + val preprocessor_keep_comments: bool (** [true] if the default preprocessor selected during compilation is able to keep comments (hence ACSL annotations) in its output. diff --git a/src/kernel_internals/runtime/machdeps.ml b/src/kernel_internals/runtime/machdeps.ml index a77f65ef77b..2af52070783 100644 --- a/src/kernel_internals/runtime/machdeps.ml +++ b/src/kernel_internals/runtime/machdeps.ml @@ -47,6 +47,7 @@ let x86_16 = { version = "x86 16 bits mode (gcc like compiler) with big or huge memory model"; compiler = "generic"; + cpp_arch_flags = ["-m16"]; sizeof_short = 2; sizeof_int = 2; sizeof_long = 4; @@ -86,6 +87,7 @@ let gcc_x86_16 = { x86_16 with compiler = "gcc" } let x86_32 = { version = "gcc 4.0.3 - X86-32bits mode"; compiler = "generic"; + cpp_arch_flags = ["-m32"]; sizeof_short = 2; sizeof_int = 4; sizeof_long = 4; @@ -123,6 +125,7 @@ let gcc_x86_32 = { x86_32 with compiler = "gcc" } let x86_64 = { version = "gcc 4.0.3 AMD64"; compiler = "generic"; + cpp_arch_flags = ["-m64"]; sizeof_short = 2; sizeof_int = 4; sizeof_long = 8; @@ -160,6 +163,7 @@ let gcc_x86_64 = { x86_64 with compiler = "gcc" } let ppc_32 = { version = "4.0.1 (Apple Computer, Inc. build 5367)"; compiler = "standard"; + cpp_arch_flags = ["-m32"]; sizeof_short = 2; sizeof_int = 4; sizeof_long = 4; @@ -195,6 +199,7 @@ let ppc_32 = { let msvc_x86_64 = { version = "MSVC - X86-64bits mode"; compiler = "msvc"; + cpp_arch_flags = ["-m64"]; sizeof_short = 2; sizeof_int = 4; sizeof_long = 4; diff --git a/src/kernel_services/ast_data/cil_types.mli b/src/kernel_services/ast_data/cil_types.mli index 331057aef90..27c1664773e 100644 --- a/src/kernel_services/ast_data/cil_types.mli +++ b/src/kernel_services/ast_data/cil_types.mli @@ -1765,6 +1765,8 @@ type mach = { __thread_is_keyword: bool (* Whether [__thread] is a keyword *); compiler: string; (* Compiler being used. Currently recognized names are 'gcc', 'msvc' and 'generic'. *) + cpp_arch_flags: string list; (* Architecture-specific flags to be given to + the preprocessor (if supported) *) version: string; (* Information on this machdep *) } diff --git a/src/kernel_services/ast_queries/file.ml b/src/kernel_services/ast_queries/file.ml index 05adaed0f21..ac7fb7ceca4 100644 --- a/src/kernel_services/ast_queries/file.ml +++ b/src/kernel_services/ast_queries/file.ml @@ -439,6 +439,25 @@ let parse_cabs = function else add_if_gnu "-nostdinc" in let define_args = "__FRAMAC__" :: define_args in + (* Hypothesis: the preprocessor does support the arch-related + options tested when 'configure' was run. *) + let required_cpp_arch_args = (get_machdep ()).cpp_arch_flags in + let supported_cpp_arch_args, unsupported_cpp_arch_args = + List.partition (fun arg -> + List.mem arg Config.preprocessor_supported_arch_options) + required_cpp_arch_args + in + if unsupported_cpp_arch_args <> [] then + Kernel.warning ~once:true + "your preprocessor is not known to handle option(s) `%a', \ + considered necessary for machdep `%s'. To ensure compatibility \ + between your preprocessor and the machdep, consider using \ + -cpp-command with the appropriate flags. \ + Your preprocessor is known to support these flags: %a" + (Pretty_utils.pp_list ~sep:" " Format.pp_print_string) + unsupported_cpp_arch_args (Kernel.Machdep.get ()) + (Pretty_utils.pp_list ~sep:" " Format.pp_print_string) + Config.preprocessor_supported_arch_options; let extra_args = if Kernel.ReadAnnot.get () then if Kernel.PreprocessAnnot.is_set () then @@ -459,7 +478,7 @@ let parse_cabs = function in let supp_args = string_of_supp_args include_args define_args - (extra_args @ Kernel.CppExtraArgs.get ()) + (extra_args @ Kernel.CppExtraArgs.get () @ supported_cpp_arch_args) in if Kernel.is_debug_key_enabled dkey_pp then Kernel.feedback ~dkey:dkey_pp @@ -485,8 +504,14 @@ preprocessor command or use the option \"-cpp-command\"." cpp_command "trying to preprocess annotation with an unknown \ preprocessor."; true)) then begin + let pp_annot_supp_args = + Format.asprintf "-nostdinc %a" + (Pretty_utils.pp_list ~sep:" " Format.pp_print_string) + supported_cpp_arch_args + in let ppf' = - try Logic_preprocess.file ".c" (build_cpp_cmd cmdl "-nostdinc") ppf + try Logic_preprocess.file ".c" + (build_cpp_cmd cmdl pp_annot_supp_args) ppf with Sys_error _ as e -> safe_remove_file ppf; Kernel.abort "preprocessing of annotations failed (%s)" diff --git a/tests/misc/custom_machdep/custom_machdep.ml b/tests/misc/custom_machdep/custom_machdep.ml index 3b50162d8a8..da8ee8cf9ba 100644 --- a/tests/misc/custom_machdep/custom_machdep.ml +++ b/tests/misc/custom_machdep/custom_machdep.ml @@ -4,6 +4,7 @@ let mach = { version = "foo"; compiler = "bar"; + cpp_arch_flags = []; sizeof_short = 2; sizeof_int = 3; sizeof_long = 4; diff --git a/tests/syntax/machdep_char_unsigned.ml b/tests/syntax/machdep_char_unsigned.ml index e23ac489ab3..494492e8be2 100644 --- a/tests/syntax/machdep_char_unsigned.ml +++ b/tests/syntax/machdep_char_unsigned.ml @@ -4,6 +4,7 @@ open Cil_types let md = { version = ""; compiler = "gcc"; + cpp_arch_flags = ["-m32"]; sizeof_short = 2; sizeof_int = 2; sizeof_long = 4; -- GitLab