From 37e9e05119008fba8b85cb4bc72adb0df6b3a6ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 18 Jul 2022 20:45:04 +0200 Subject: [PATCH] [Eva] Utils: new function to compute direct and indirect dependencies. Needed by the From plugin. --- src/plugins/eva/Eva.mli | 11 +++++++++ src/plugins/eva/utils/eva_utils.ml | 37 +++++++++++++++++++++-------- src/plugins/eva/utils/eva_utils.mli | 11 +++++++++ src/plugins/eva/utils/results.ml | 9 +++++++ src/plugins/eva/utils/results.mli | 11 +++++++++ 5 files changed, 69 insertions(+), 10 deletions(-) diff --git a/src/plugins/eva/Eva.mli b/src/plugins/eva/Eva.mli index 98c8fc246b5..998cd2b8400 100644 --- a/src/plugins/eva/Eva.mli +++ b/src/plugins/eva/Eva.mli @@ -276,6 +276,17 @@ module Results: sig evaluate the given lvalue, excluding the lvalue zone itself. *) val address_deps : Cil_types.lval -> request -> Locations.Zone.t + (** Memory dependencies of an expression. *) + type deps = Function_Froms.Deps.deps = { + data: Locations.Zone.t; + (** Memory zone directly required to evaluate the given expression. *) + indirect: Locations.Zone.t; + (** Memory zone read to compute data addresses. *) + } + + (** Computes (an overapproximation of) the memory dependencies of an + expression. *) + val expr_dependencies : Cil_types.exp -> request -> deps (** Evaluation *) diff --git a/src/plugins/eva/utils/eva_utils.ml b/src/plugins/eva/utils/eva_utils.ml index a1ea4f6e298..7717dfaf3db 100644 --- a/src/plugins/eva/utils/eva_utils.ml +++ b/src/plugins/eva/utils/eva_utils.ml @@ -274,41 +274,58 @@ let dump_garbled_mix () = (Pretty_utils.pp_list ~pre:"" ~suf:"" ~sep:"@ " pp_one) l +type deps = Function_Froms.Deps.deps = { + data: Locations.Zone.t; + indirect: Locations.Zone.t; +} + +let bottom_deps = + { data = Locations.Zone.bottom; indirect = Locations.Zone.bottom } + +let join_deps a b = + { data = Locations.Zone.join a.data b.data; + indirect = Locations.Zone.join a.indirect b.indirect; } + +let deps_to_zone deps = Locations.Zone.join deps.data deps.indirect + (* Computation of the inputs of an expression. *) -let rec zone_of_expr find_loc expr = +let rec deps_of_expr find_loc expr = let rec process expr = match expr.enode with | Lval lval -> (* Dereference of an lvalue. *) - zone_of_lval find_loc lval + deps_of_lval find_loc lval | UnOp (_, e, _) | CastE (_, e) -> (* Unary operators. *) process e | BinOp (_, e1, e2, _) -> (* Binary operators. *) - Locations.Zone.join (process e1) (process e2) + join_deps (process e1) (process e2) | StartOf lv | AddrOf lv -> (* computation of an address: the inputs of the lvalue whose address is computed are read to compute said address. *) - indirect_zone_of_lval find_loc lv + { data = indirect_zone_of_lval find_loc lv; + indirect = Locations.Zone.bottom; } | Const _ | SizeOf _ | AlignOf _ | SizeOfStr _ | SizeOfE _ | AlignOfE _ -> (* static constructs, nothing is read to evaluate them. *) - Locations.Zone.bottom + bottom_deps in process expr +and zone_of_expr find_loc expr = deps_to_zone (deps_of_expr find_loc expr) + (* dereference of an lvalue: first, its address must be computed, then its contents themselves are read *) -and zone_of_lval find_loc lval = +and deps_of_lval find_loc lval = let ploc = find_loc lval in let zone = Precise_locs.enumerate_valid_bits Read ploc in - Locations.Zone.join zone - (indirect_zone_of_lval find_loc lval) + { data = zone; + indirect = indirect_zone_of_lval find_loc lval; } (* Computations of the inputs of a lvalue : union of the "host" part and the offset. *) and indirect_zone_of_lval find_loc (lhost, offset) = - (Locations.Zone.join - (zone_of_lhost find_loc lhost) (zone_of_offset find_loc offset)) + Locations.Zone.join + (zone_of_lhost find_loc lhost) (zone_of_offset find_loc offset) (* Computation of the inputs of a host. Nothing for a variable, and the inputs of [e] for a dereference [*e]. *) diff --git a/src/plugins/eva/utils/eva_utils.mli b/src/plugins/eva/utils/eva_utils.mli index be3385152b0..7f665f05f26 100644 --- a/src/plugins/eva/utils/eva_utils.mli +++ b/src/plugins/eva/utils/eva_utils.mli @@ -107,6 +107,17 @@ val indirect_zone_of_lval: on which the offset and the pointer expression (if any) of an lvalue depend. *) + +type deps = Function_Froms.Deps.deps = { + data: Locations.Zone.t; + indirect: Locations.Zone.t; +} + +val deps_of_expr: + (lval -> Precise_locs.precise_location) -> exp -> deps +(** Given a function computing the location of lvalues, computes the memory + dependencies of an expression. *) + (** Computes the height of an expression, that is the maximum number of nested operations in this expression. *) val height_expr: exp -> int diff --git a/src/plugins/eva/utils/results.ml b/src/plugins/eva/utils/results.ml index db4af18ba2c..40a6ce93b06 100644 --- a/src/plugins/eva/utils/results.ml +++ b/src/plugins/eva/utils/results.ml @@ -699,6 +699,15 @@ let address_deps lval request = let lval_to_loc lv = eval_address lv request |> as_precise_loc in Eva_utils.indirect_zone_of_lval lval_to_loc lval +type deps = Function_Froms.Deps.deps = { + data: Locations.Zone.t; + indirect: Locations.Zone.t; +} + +let expr_dependencies expr request = + let lval_to_loc lv = eval_address lv request |> as_precise_loc in + Eva_utils.deps_of_expr lval_to_loc expr + (* Reachability *) let is_empty rq = diff --git a/src/plugins/eva/utils/results.mli b/src/plugins/eva/utils/results.mli index e18f41a0325..007a99c6319 100644 --- a/src/plugins/eva/utils/results.mli +++ b/src/plugins/eva/utils/results.mli @@ -181,6 +181,17 @@ val lval_deps : Cil_types.lval -> request -> Locations.Zone.t evaluate the given lvalue, excluding the lvalue zone itself. *) val address_deps : Cil_types.lval -> request -> Locations.Zone.t +(** Memory dependencies of an expression. *) +type deps = Function_Froms.Deps.deps = { + data: Locations.Zone.t; + (** Memory zone directly required to evaluate the given expression. *) + indirect: Locations.Zone.t; + (** Memory zone read to compute data addresses. *) +} + +(** Computes (an overapproximation of) the memory dependencies of an + expression. *) +val expr_dependencies : Cil_types.exp -> request -> deps (** Evaluation *) -- GitLab