Newer
Older
(** Eva public API.
The main modules are:
- Analysis: run the analysis.
- Results: access analysis results, especially the values of expressions
and memory locations of lvalues at each program point.
The following modules allow configuring the Eva analysis:
- Value_parameters: change the configuration of the analysis.
- Eva_annotations: add local annotations to guide the analysis.
- Builtins: register ocaml builtins to be used by the cvalue domain
instead of analysing the body of some C functions.
Other modules are for internal use only. *)
(* This file is generated. Do not edit. *)
module Analysis: sig
val compute : unit -> unit
(** Computes the Eva analysis, if not already computed, using the entry point
of the current project. You may set it with {!Globals.set_entry_point}.
@raise Globals.No_such_entry_point if the entry point is incorrect
@raise Db.Value.Incorrect_number_of_arguments if some arguments are
specified for the entry point using {!Db.Value.fun_set_args}, and
an incorrect number of them is given.
@plugin development guide *)
val is_computed : unit -> bool
(** Return [true] iff the Eva analysis has been done. *)
val self : State.t
(** Internal state of Eva analysis from projects viewpoint. *)
(** Eva's result API is a work-in-progress interface to allow accessing the
analysis results once its completed. It is experimental and is very likely
to change in the future. It aims at replacing [Db.Value] but does not
completely covers all its usages yet. As for now, this interface has some
- evaluations uses every available domains and not only Cvalue;
- the caller may distinguish failure cases when a request is unsucessful;
- working with callstacks is easy;
- some common shortcuts are provided (e.g. for extracting ival directly);
- overall, individual functions are simpler.
The idea behind this API is that requests must be decomposed in several
steps. For instance, to evaluate an expression :
1. first, you have to state where you want to evaluate it,
2. optionally, you may specify in which callstack,
3. you choose the expression to evaluate,
4. you require a destination type to evaluate into.
Eva.Results.(
before stmt |> in_callstack cs |>
eval_var vi |> as_int |> default 0)
Eva.Results.(
default O (as_int (eval_var vi (in_callstack cs (before stmt))))
type callstack = (Cil_types.kernel_function * Cil_types.kinstr) list
type value
type address
type 'a evaluation
type error = Bottom | Top | DisabledDomain
type 'a result = ('a,error) Result.t
(** Translates an error to a human readable string. *)
val string_of_error : error -> string
(** Pretty printer for errors. *)
val pretty_error : Format.formatter -> error -> unit
(** Pretty printer for API's results. *)
val pretty_result : (Format.formatter -> 'a -> unit) ->
Format.formatter -> 'a result -> unit
(** [default d r] extracts the value of [r] if [r] is Ok,
or use the default value [d] otherwise.
Equivalent to [Result.value ~default:d r] *)
val default : 'a -> 'a result -> 'a
(** At the start of the analysis, but after the initialization of globals. *)
(** At the end of the analysis, after the main function has returned. *)
(** At the start of the given function. *)
val at_start_of : Cil_types.kernel_function -> request
(** At the end of the given function. *)
val at_end_of : Cil_types.kernel_function -> request
(** Just before a statement is executed. *)
val before : Cil_types.stmt -> request
(** Just after a statement is executed. *)
val after : Cil_types.stmt -> request
(** Just before a statement or at the start of the analysis. *)
val before_kinstr : Cil_types.kinstr -> request
(** Only consider the given callstack.
Replaces previous calls to [in_callstack] or [in_callstacks]. *)
val in_callstack : callstack -> request -> request
(** Only consider the callstacks from the given list.
Replaces previous calls to [in_callstack] or [in_callstacks]. *)
val in_callstacks : callstack list -> request -> request
(** Only consider callstacks satisfying the given predicate. Several filters
can be added. If callstacks are also selected with [in_callstack] or
[in_callstacks], only the selected callstacks will be filtered. *)
val filter_callstack : (callstack -> bool) -> request -> request
(** Returns the list of reachable callstacks from the given request. *)
val callstacks : request -> callstack list
(** Returns a list of subrequests for each reachable callstack from
val by_callstack : request -> (callstack * request) list
(** Iterates on the reachable callstacks from the request. *)
val iter_callstacks : (callstack -> request -> unit) -> request -> unit
(** Folds on the reachable callstacks from the request. *)
val fold_callstacks : (callstack -> request -> 'a -> 'a) -> 'a -> request -> 'a
(** Returns the list of expressions which have been inferred to be equal to
the given expression by the Equality domain. *)
val equality_class : Cil_types.exp -> request -> Cil_types.exp list result
(** Returns the Cvalue model. *)
val as_cvalue_model : request -> Cvalue.Model.t result
(** Computes (an overapproximation of) the memory zones that must be read to
evaluate the given expression, including all adresses computations. *)
val expr_deps : Cil_types.exp -> request -> Locations.Zone.t
(** Computes (an overapproximation of) the memory zones that must be read to
evaluate the given lvalue, including the lvalue zone itself. *)
val lval_deps : Cil_types.lval -> request -> Locations.Zone.t
(** Computes (an overapproximation of) the memory zones that must be read to
evaluate the given lvalue, excluding the lvalue zone itself. *)
val address_deps : Cil_types.lval -> request -> Locations.Zone.t
(** Returns (an overapproximation of) the possible values of the variable. *)
val eval_var : Cil_types.varinfo -> request -> value evaluation
(** Returns (an overapproximation of) the possible values of the lvalue. *)
val eval_lval : Cil_types.lval -> request -> value evaluation
(** Returns (an overapproximation of) the possible values of the expression. *)
val eval_exp : Cil_types.exp -> request -> value evaluation
(** Returns (an overapproximation of) the possible addresses of the lvalue. *)
val eval_address : Cil_types.lval -> request -> address evaluation
(** Returns the kernel functions into which the given expression may evaluate.
If the callee expression doesn't always evaluate to a function, those
spurious values are ignored. If it always evaluate to a non-function value
then the returned list is empty.
Raises [Stdlib.Invalid_argument] if the callee expression is not an lvalue
without offset.
Also see [callee] for a function which applies directly on Call
statements. *)
val eval_callee : Cil_types.exp -> request -> Kernel_function.t list result
(** Evaluated values conversion *)
(** In all functions below, if the abstract value inferred by Eva does not fit
in the required type, [Error Top] is returned, as Top is the only possible
over-approximation of the request. *)
(** Converts the value into a singleton ocaml int. *)
val as_int : value evaluation -> int result
(** Converts the value into a singleton unbounded integer. *)
val as_integer : value evaluation -> Integer.t result
(** Converts the value into a floating point number. *)
val as_float : value evaluation -> float result
(** Converts the value into a C number abstraction. *)
val as_ival : value evaluation -> Ival.t result
(** Converts the value into a floating point abstraction. *)
val as_fval : value evaluation -> Fval.t result
(** Converts the value into a Cvalue abstraction. *)
val as_cvalue : value evaluation -> Cvalue.V.t result
(** Converts into a C location abstraction. *)
val as_location : address evaluation -> Locations.location result
David Bühler
committed
(** Converts into a Zone. Error cases are converted into bottom or top zones
accordingly. *)
val as_zone: ?access:Locations.access -> address evaluation ->
Locations.Zone.t
David Bühler
committed
(** Converts into a Zone result. *)
val as_zone_result : ?access:Locations.access -> address evaluation ->
Locations.Zone.t result
(** Returns whether the evaluated value is initialized or not. If the value have
been evaluated from a Cil expression, it is always initialized. *)
val is_initialized : value evaluation -> bool
(** Returns the set of alarms emitted during the evaluation. *)
val alarms : 'a evaluation -> Alarms.t list
(** Returns true if there are no reachable states for the given request. *)
val is_empty : request -> bool
(** Returns true if an evaluation leads to bottom, i.e. if the given expression
or lvalue cannot be evaluated to a valid result for the given request. *)
val is_bottom : 'a evaluation -> bool
(** Returns true if the function has been analyzed. *)
val is_called : Cil_types.kernel_function -> bool
(** Returns true if the statement has been reached by the analysis. *)
val is_reachable : Cil_types.stmt -> bool
(** Returns true if the statement has been reached by the analysis, or if
the main function has been analyzed for [Kglobal]. *)
val is_reachable_kinstr : Cil_types.kinstr -> bool
(*** Callers / Callees / Callsites *)
(** Returns the list of inferred callers of the given function. *)
val callers : Cil_types.kernel_function -> Cil_types.kernel_function list
(** Returns the list of inferred callers, and for each of them, the list
of callsites (the call statements) inside. *)
val callsites : Cil_types.kernel_function ->
(Cil_types.kernel_function * Cil_types.stmt list) list
(** Returns the kernel functions called in the given statement.
If the callee expression doesn't always evaluate to a function, those
spurious values are ignored. If it always evaluate to a non-function value
then the returned list is empty.
Raises [Stdlib.Invalid_argument] if the statement is not a [Call]
instruction or a [Local_init] with [ConsInit] initializer. *)
val callee : Cil_types.stmt -> Kernel_function.t list
module Value_parameters: sig
(** Configuration of the analysis. *)
(** Returns the list (name, descr) of currently enabled abstract domains. *)
val enabled_domains: unit -> (string * string) list
(** [use_builtin kf name] instructs the analysis to use the builtin [name]
to interpret calls to function [kf].
Raises [Not_found] if there is no builtin of name [name]. *)
val use_builtin: Cil_types.kernel_function -> string -> unit
(** [use_global_value_partitioning vi] instructs the analysis to use
value partitioning on the global variable [vi]. *)
val use_global_value_partitioning: Cil_types.varinfo -> unit
end
module Eva_annotations: sig
(** Register special annotations to locally guide the Eva analysis:
- slevel annotations: "slevel default", "slevel merge" and "slevel i"
- loop unroll annotations: "loop unroll term"
- value partitioning annotations: "split term" and "merge term"
- subdivision annotations: "subdivide i"
(** Annotations tweaking the behavior of the -eva-slevel parameter. *)
| SlevelMerge (** Join all states separated by slevel. *)
| SlevelDefault (** Use the limit defined by -eva-slevel. *)
| SlevelLocal of int (** Use the given limit instead of -eva-slevel. *)
| SlevelFull (** Remove the limit of number of separated states. *)
(** Loop unroll annotations. *)
| UnrollAmount of Cil_types.term (** Unroll the n first iterations. *)
| UnrollFull (** Unroll amount defined by -eva-default-loop-unroll. *)
type split_term =
| Expression of Cil_types.exp
| Predicate of Cil_types.predicate
(** Split/merge annotations for value partitioning. *)
| FlowSplit of split_term * split_kind
(** Split states according to a term. *)
(** Merge states separated by a previous split. *)
type allocation_kind = By_stack | Fresh | Fresh_weak | Imprecise
val get_slevel_annot : Cil_types.stmt -> slevel_annotation option
val get_unroll_annot : Cil_types.stmt -> unroll_annotation list
val get_flow_annot : Cil_types.stmt -> flow_annotation list
val get_subdivision_annot : Cil_types.stmt -> int list
val get_allocation: Cil_types.stmt -> allocation_kind
val add_slevel_annot : emitter:Emitter.t ->
Cil_types.stmt -> slevel_annotation -> unit
val add_unroll_annot : emitter:Emitter.t ->
Cil_types.stmt -> unroll_annotation -> unit
val add_flow_annot : emitter:Emitter.t ->
Cil_types.stmt -> flow_annotation -> unit
val add_subdivision_annot : emitter:Emitter.t ->
Cil_types.stmt -> int -> unit
end
David Bühler
committed
module Eval: sig
(** Can the results of a function call be cached with memexec? *)
type cacheable =
| Cacheable (** Functions whose result can be safely cached. *)
| NoCache (** Functions whose result should not be cached, but for
which the caller can still be cached. Typically,
functions printing something during the analysis. *)
| NoCacheCallers (** Functions for which neither the call, neither the
callers, can be cached. *)
David Bühler
committed
module Builtins: sig
(** Eva analysis builtins for the cvalue domain, more efficient than their
equivalent in C. *)
David Bühler
committed
open Cil_types
David Bühler
committed
exception Invalid_nb_of_args of int
exception Outside_builtin_possibilities
(* Signature of a builtin: type of the result, and type of the arguments. *)
David Bühler
committed
type builtin_type = unit -> typ * typ list
(** Can the results of a builtin be cached? See {eval.mli} for more details.*)
type cacheable = Eval.cacheable = Cacheable | NoCache | NoCacheCallers
David Bühler
committed
type full_result = {
c_values: (Cvalue.V.t option * Cvalue.Model.t) list;
(** A list of results, consisting of:
- the value returned (ie. what is after the 'return' C keyword)
- the memory state after the function has been executed. *)
David Bühler
committed
c_clobbered: Base.SetLattice.t;
(** An over-approximation of the bases in which addresses of local variables
might have been written *)
David Bühler
committed
c_from: (Function_Froms.froms * Locations.Zone.t) option;
(** If not None, the froms of the function, and its sure outputs;
i.e. the dependencies of the result and of each zone written to. *)
David Bühler
committed
}
(** The result of a builtin can be given in different forms. *)
David Bühler
committed
type call_result =
| States of Cvalue.Model.t list
(** A disjunctive list of post-states at the end of the C function.
Can only be used if the C function does not write the address of local
variables, does not read other locations than the call arguments, and
does not write other locations than the result. *)
David Bühler
committed
| Result of Cvalue.V.t list
(** A disjunctive list of resulting values. The specification is used to
compute the post-state, in which the result is replaced by the values
computed by the builtin. *)
David Bühler
committed
| Full of full_result
(** See [full_result] type. *)
(** Type of a cvalue builtin, whose arguments are:
- the memory state at the beginning of the function call;
- the list of arguments of the function call. *)
David Bühler
committed
type builtin = Cvalue.Model.t -> (exp * Cvalue.V.t) list -> call_result
(** [register_builtin name ?replace ?typ cacheable f] registers the function [f]
as a builtin to be used instead of the C function of name [name].
If [replace] is provided, the builtin is also used instead of the C function
of name [replace], unless option -eva-builtin-auto is disabled.
If [typ] is provided, consistency between the expected [typ] and the type of
the C function is checked before using the builtin.
The results of the builtin are cached according to [cacheable]. *)
David Bühler
committed
val register_builtin:
string -> ?replace:string -> ?typ:builtin_type -> cacheable -> builtin -> unit
(** Has a builtin been registered with the given name? *)
David Bühler
committed
val is_builtin: string -> bool
end
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
module Eval_terms: sig
(** [annot_predicate_deps ~pre ~here p] computes the logic dependencies needed
to evaluate the predicate [p] in a code annotation in cvalue state [here],
in a function whose pre-state is [pre].
Returns None on either an evaluation error or on unsupported construct. *)
val annot_predicate_deps:
pre:Cvalue.Model.t -> here:Cvalue.Model.t ->
Cil_types.predicate -> Locations.Zone.t option
end
module Value_results: sig
type results
val get_results: unit -> results
val set_results: results -> unit
val merge: results -> results -> results
val change_callstacks:
(Value_types.callstack -> Value_types.callstack) -> results -> results
(** Change the callstacks for the results for which this is meaningful.
For technical reasons, the top of the callstack must currently
be preserved. *)
end
module Unit_tests: sig
(** Currently tested by this module:
- semantics of sign values. *)
(** Runs some programmatic tests on Eva. *)
val run: unit -> unit
end