From 15cc714e98e4231622e46d434e6c389f7e679b1a Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Tue, 24 Sep 2019 15:28:04 +0200 Subject: [PATCH] [Override Std] Adds memmove --- headers/header_spec.txt | 2 + src/plugins/override_std/Makefile.in | 2 +- src/plugins/override_std/memmove.ml | 136 +++++++++++++++++++++++++++ src/plugins/override_std/memmove.mli | 21 +++++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/plugins/override_std/memmove.ml create mode 100644 src/plugins/override_std/memmove.mli diff --git a/headers/header_spec.txt b/headers/header_spec.txt index 571583ba263..c047a396060 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -938,6 +938,8 @@ src/plugins/override_std/memcmp.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/override_std/memcmp.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/override_std/memcpy.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/override_std/memcpy.mli: CEA_LGPL_OR_PROPRIETARY +src/plugins/override_std/memmove.ml: CEA_LGPL_OR_PROPRIETARY +src/plugins/override_std/memmove.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/override_std/options.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/override_std/options.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/override_std/override_table.ml: CEA_LGPL_OR_PROPRIETARY diff --git a/src/plugins/override_std/Makefile.in b/src/plugins/override_std/Makefile.in index a70f414e48e..9d9ab06f2db 100644 --- a/src/plugins/override_std/Makefile.in +++ b/src/plugins/override_std/Makefile.in @@ -37,7 +37,7 @@ PLUGIN_DIR ?= . PLUGIN_ENABLE := @ENABLE_OVERRIDE_STD@ PLUGIN_NAME := OverrideStd PLUGIN_CMI := -PLUGIN_CMO := options transform override_table basic_blocks memcpy memcmp register +PLUGIN_CMO := options transform override_table basic_blocks memcpy memcmp memmove register PLUGIN_DISTRIBUTED := $(PLUGIN_ENABLE) PLUGIN_DISTRIB_EXTERNAL:= Makefile.in configure.ac configure #PLUGIN_NO_DEFAULT_TEST := no diff --git a/src/plugins/override_std/memmove.ml b/src/plugins/override_std/memmove.ml new file mode 100644 index 00000000000..ea35d100a61 --- /dev/null +++ b/src/plugins/override_std/memmove.ml @@ -0,0 +1,136 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2019 *) +(* 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). *) +(* *) +(**************************************************************************) + +open Cil_types +open Logic_const +open Basic_blocks + +let function_name = "memmove" + +let pmoved_memmove ?loc dest src len = + let j = Cil_const.make_logic_var_quant "j" Linteger in + let tj = tvar j in + let geq_0 = prel ?loc (Rle, (tinteger 0), tj) in + let lt_len = prel ?loc (Rlt, tj, len) in + let bounds = pand ?loc (geq_0, lt_len) in + let dest_j = tplus ?loc dest tj in + let dest_acc = term ?loc (TLval(TMem(dest_j), TNoOffset)) (ttype_of_pointed dest.term_type) in + let src_j = tplus ?loc src tj in + let src_acc = term ?loc (TLval(TMem(src_j), TNoOffset)) (ttype_of_pointed dest.term_type) in + let src_acc = tat ?loc (src_acc, pre_label) in + let eq = prel ?loc (Req, dest_acc, src_acc) in + pforall ?loc ([j], (pimplies ?loc (bounds, eq))) + +let pmoved_len_bytes ?loc dest src bytes_len = + plet_len_div_size ?loc dest.term_type bytes_len (pmoved_memmove ?loc dest src) + +let generate_requires loc dest src len = + List.map new_predicate [ + { (pcorrect_len_bytes ~loc dest.term_type len) with pred_name = ["aligned_end"] } ; + { (pvalid_len_bytes ~loc here_label dest len) with pred_name = ["valid_dest"] } ; + { (pvalid_read_len_bytes ~loc here_label src len) with pred_name = ["valid_read_src"] } ; + ] + +let generate_assigns loc t dest src len = + let dest_range = new_identified_term (tunref_range ~loc dest len) in + let src_range = new_identified_term(tunref_range ~loc src len) in + let copy = dest_range, From [src_range] in + let result = new_identified_term (tresult t) in + let dest = new_identified_term dest in + let res = result, From [dest] in + Writes [ copy ; res ] + +let generate_ensures loc dest src len = + List.map (fun p -> Normal, new_predicate p) [ + { (pmoved_len_bytes ~loc dest src len) with pred_name = [ "moved"] } + ] + +let generate_spec vi loc = + let (cdest, csrc, clen) = match Cil.getFormalsDecl vi with + | [ dest ; src ; len ] -> dest, src, len + | _ -> assert false + in + let t = cdest.vtype in + let dest = cvar_to_tvar cdest in + let src = cvar_to_tvar csrc in + let len = cvar_to_tvar clen in + let requires = generate_requires loc dest src len in + let assigns = generate_assigns loc t dest src len in + let ensures = generate_ensures loc dest src len in + make_funspec [make_behavior ~requires ~assigns ~ensures ()] () + +let generate_prototype t = + let name = function_name ^ "_" ^ (string_of_typ t) in + let dt = ptr_of (restrict_of t) in + let st = ptr_of (restrict_of (const_of t)) in + let params = [ + ("dest", dt, []) ; + ("src", st, []) ; + ("len", size_t (), []) + ] in + let fun_t = TFun(dt, Some params, false, []) in + let vi = Cil.makeGlobalVar ~referenced:true name fun_t in + Cil.setFormalsDecl vi fun_t ; + vi + +module Table = Override_table.Make(struct + let function_name = function_name + let build_prototype = generate_prototype + let build_spec = generate_spec + end) + +let type_from_parameter x = + let x = Cil.stripCasts x in + let xt = Cil.unrollTypeDeep (Cil.typeOf x) in + let xt = Cil.type_remove_qualifier_attributes_deep xt in + Cil.typeOf_pointed xt + +let well_typed_parameters dest src = + let dt = type_from_parameter dest in + let st = type_from_parameter src in + Cil_datatype.Typ.equal dt st + +let create_call fct (dest, src, len) = + if well_typed_parameters dest src then + let typ = type_from_parameter dest in + let fct = Table.get_override typ in + let dest = Cil.stripCasts dest in + let src = Cil.stripCasts src in + fct, (dest, src, len) + else + fct, (dest, src, len) + +let replace_call = function + | Call(r, ({ enode = Lval((Var fct), NoOffset) } as e), [ dest ; src ; len ], loc) -> + let fct, (dest, src, len) = create_call fct (dest, src, len) in + Call(r, { e with enode = Lval((Var fct), NoOffset) }, [ dest ; src ; len ], loc) + | Local_init(r, ConsInit(fct, [ dest ; src ; len ], Plain_func), loc) -> + let fct, (dest, src, len) = create_call fct (dest, src, len) in + Local_init(r, ConsInit(fct, [ dest ; src ; len ], Plain_func), loc) + | _ -> assert false + +let () = Transform.register (module struct + let function_name = function_name + let replace_call = replace_call + let get_globals = Table.get_globals + let mark_as_computed = Table.mark_as_computed + end) diff --git a/src/plugins/override_std/memmove.mli b/src/plugins/override_std/memmove.mli new file mode 100644 index 00000000000..fa8f3783c35 --- /dev/null +++ b/src/plugins/override_std/memmove.mli @@ -0,0 +1,21 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2019 *) +(* 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). *) +(* *) +(**************************************************************************) -- GitLab