123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369(**************************************************************************)(* This file is part of BINSEC. *)(* *)(* Copyright (C) 2016-2026 *)(* 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). *)(* *)(**************************************************************************)exceptionUnknown(** Raised by reasoning functions ({!module-type-S.val-check_sat} and
{!module-type-ENUMERATION.val-next}) when no solution has been found
within the resource budget (e.g. {!constructor-SetSMTSolverTimeout}). *)exceptionUndefinedofDba.Var.t(** Raised by the {!module-type-DATA.val-lookup} function when the variable
is not defined. *)exceptionUndeclaredofstringoption(** Raised by the {!module-type-DATA.val-read}, {!module-type-DATA.val-select},
{!module-type-S.val-write} and {!module-type-S.val-store} functions when
the memory array is not defined. *)exceptionNon_mergeable(** Raised by the {!module-type-S.val-merge} function the two states can not
be merged. *)typetrilean=Basic_types.Ternary.t(** Extends the booleans with {!constructor-Unknown}. *)typesize=Term.size(** A size in bit. *)and'ainterval='aTerm.intervalandunary=Term.unaryandbinary=Term.binaryand'aoperator='aTerm.operator=|Not:unaryoperator|Sext:size->unaryoperator|Uext:size->unaryoperator|Restrict:intinterval->unaryoperator|Plus:binaryoperator|Minus:_operator|Mul:binaryoperator|Udiv:binaryoperator(* Corresponds to *)|Urem:binaryoperator(* the truncated division *)|Sdiv:binaryoperator(* of C99 and most *)|Srem:binaryoperator(* processors *)|Or:binaryoperator|And:binaryoperator|Xor:binaryoperator|Concat:binaryoperator|Lsl:binaryoperator|Lsr:binaryoperator|Asr:binaryoperator|Rol:binaryoperator|Ror:binaryoperator|Eq:binaryoperator|Diff:binaryoperator|Ule:binaryoperator|Ult:binaryoperator|Uge:binaryoperator|Ugt:binaryoperator|Sle:binaryoperator|Slt:binaryoperator|Sge:binaryoperator|Sgt:binaryoperatormoduletypeUID=sigtypet(** A unique identifier for variable naming (SSA form). *)valzero:t(** [zero] returns the first unique identifier. *)valsucc:t->t(** [succ i] returns the unique identifier following [i]. *)valcompare:t->t->int(** [compare i1 i2] same behavior as {!module-Stdlib.val-compare}. *)endmoduletypeVALUE=sigtypet(** A symbolic value. *)typeid(** The unique identifier for variable naming (SSA form). *)(** {3 Creation} *)valconstant:Bitvector.t->t(** [constant v] creates a value that evaluates to the
{!module-Binsec_kernel.module-Bitvector} [v]. *)valzero:t(** [zero] shorthand for {!val-constant} {!module-Binsec_kernel.module-Bitvector.val-zero}. *)valvar:id->string->int->t(** [var i n s] creates a (first-order) constant value of [s] bits,
named [n] and uniquely identified by [i]. *)valunary:unaryoperator->t->t(** [unary o v] returns the application of the unary operator [o] applied
to the value [v]. *)valbinary:binaryoperator->t->t->t(** [binary o v1 v2] returns the application of the binary operator [o]
applied to the values [v1] and [v2]. *)valite:t->t->t->t(** [ite cond if_term else_term] returns the value that evaluates to
[if_term] if [cond] is [true], or [else_term] otherwise. *)(** {3 Inspection} *)valis_symbolic:t->bool(** [is_symbolic v] returns [true] if the [v] does not syntactically evaluate
to constant {!module-Binsec_kernel.module-Bitvector.type-t}. *)valis_zero:t->trilean(** [is_zero v] returns {!constructor-True} if [v] equals zero,
{!constructor-False} if [v] equals one and {!constructor-Unknown} otherwise. *)valsizeof:t->int(** [sizeof v] returns the size in bits of the value [v]. *)endmoduletypeMODEL=sigtypet(** A model is a mapping from symbolic values ({!type-value}) to their concrete
values assignment ({!module-Binsec_kernel.module-Bitvector.type-t}). *)typevalue(** A symbolic value. *)valempty:unit->t(** [empty] returns an empty model. *)valeval:value->t->Bitvector.t(** [eval v m] evaluates the expression [v] in the model [m]. *)valpp:Format.formatter->t->unit(** [pp f m] prints the model [m] in the formatter [f]. *)valpp_with_sections:(Virtual_address.t->stringoption)->Format.formatter->t->unit(** [pp_with_sections s f m] same as {!val-pp}, but may also display the section names from which memory accesses belong. *)endmoduletypeCOOKIE=sigtypet(** A cookie contains the configuration elements to be used to reason on the symbolic formula ({!module-type-S.val-predicate}).
It is passed to the functions {!module-type-S.val-check_sat} and {!module-type-S.val-enumerate}.
It can be configured via the extension implemented by the state (see {!type-feature} and {!module-type-S.val-more}).
For instance, SMT solver based states can use {!constructor-SetSMTSolver} to select a different solver backend. *)valdefault:unit->t(** [default] creates a cookie with default parameters. *)endmoduletypeENUMERATION=sigtypet(** The current state of the value enumeration. *)typevalue(** The value returned by the enumeration. *)valnext:t->valueoption(** [next e] gives the following value possible for the enumeration [e]. If there is no remaining value, it returns [None].
@raise Unknown when no solution is found within the current resource budget (see {!constructor-SetSMTSolverTimeout}).
*)valsuspend:t->unit(** [suspend e] pauses the enumeration [e] and releases the external ressources (e.g. solver session).
It can be used to release ressources as soon as the enumeration is no longer used or will not be used for a long time.
Calling {!val-next} resumes a suspended enumeration where it was paused.
*)endmoduletypeDATA=sigtypet(** A mapping for variables ({!module-Binsec_kernel.module-Dba.module-Var.type-t} [->] {!type-value})
and memory accesses ({!type-value} [->] {!type-value}). *)typevalue(** A symbolic value. *)vallookup:Dba.Var.t->t->value(** [lookup var s] returns the value assigned to [var] in [s].
@raise Undefined if [var] is not in [s].
*)valread:addr:value->int->Machine.endianness->t->value*t(** [read ~addr len d s] returns [len] bytes of the value stored at address [addr] in the main memory array {b \@},
together with the updated state [s]. The byte order is determined by the endianness [d].
@raise Undeclared [None] if there is no main memory in [s] (see {!module-type-S.val-declare}).
*)valselect:string->addr:value->int->Machine.endianness->t->value*t(** [select m ~addr len d s] returns [len] bytes of the value stored at address [addr] in the memory array [m], together with
the updated state [s]. The byte order is determined by the endianness [d].
@raise Undeclared [Some m] if [m] is not in [s] (see {!module-type-S.val-declare}).
*)endtype('value,'state,'cookie,'a)feature=..(** A [feature] is a state functionality that is not part of the common interface.
A value of type ['a] can be queried with the function {!module-type-S.val-more}.
It can be anything, including a function, and may depend on the type parameters
['value], ['state] and ['cookie].
For instance, the function {!module-type-S.val-lookup} can be expressed as a
[!type-feature] as follows.
[type ('value, 'state, 'cookie, 'a) feature +=
| Lookup : ('value, 'state, 'cookie, Dba.Var.t -> 'state -> 'value) feature]
*)moduletypeS=sigtypet(** A symbolic state. *)moduleUid:UIDmoduleValue:VALUEwithtypeid=Uid.tincludeDATAwithtypet:=tandtypevalue:=Value.tvalempty:unit->t(** [empty] creates an empty state. *)valassign:Dba.Var.t->Value.t->t->t(** [assign var v s] returns a copy of [s] with the value [v] assigned to the variable [var]. *)valdeclare:array:stringoption->int->t->t(** [declare ~array idx s] returns a copy of [s] where [array] is a fresh mapping between addresses
of [idx] bits to (first-order) constant.
The [None] represents the main memory {b \@} (e.g. the RAM).
The functions {!val-read} and {!val-write} operate on {b \@}.
The [Some name] represents a named array.
The functions {!val-select} and {!val-store} operate on [name].
*)valwrite:addr:Value.t->Value.t->Machine.endianness->t->t(** [write ~addr v d s] returns a copy of [s] where the value [v] is written at the address [addr]
in the main memory. The byte order is determined by the endianness [d].
@raise Undeclared [None] if there is no main memory {b \@} in [s] (see {!val-declare}).
*)valstore:string->addr:Value.t->Value.t->Machine.endianness->t->t(** [store m ~addr v s] returns a copy of [s] where the value [v] is stored at the address [addr]
in the memory array [m]. The byte order is determined by the endianness [d].
@raise Undeclared [Some m] if [m] is not in [s] (see {!val-declare}).
*)valmemcpy:stringoption->addr:Value.t->int->Loader_types.buffer->t->t(** [memcpy m ~addr len content s] returns a copy of [s] where [len] bytes from the zero extended
buffer [content] are copied to the memory array [m] at the address [addr].
@raise Undeclared [m] is not in [s] (see {!val-declare}).
*)valmerge:t->t->t(** [merge t1 t2] returns a new state with the values of both [t1] and [t2]. *)valassume:Value.t->t->toption(** [assume v s] returns the a copy of the state [s] for which the boolean condition [v] has been
added to the path predicate.
Returns [None] if the state [s] can infer that [v] always evaluates to [false].
*)valpredicate:t->Value.tlist(** [predicate s] returns the state predicate as a list of {!type-value}. *)valis_symbolic:Value.t->t->bool(** [is_symbolic v s] checks if the value [v] may depend on symbolic values. *)valis_zero:Value.t->t->trilean(** [is_zero v s] checks if [v] may depend on symbolic values.
It returns {!constructor-True} when the state implies [v] is [false]
and {!constructor-False} when the state implies [v] is [true].
Otherwise, it returns [!constructor-Unknown], that means that [v] syntactically
depends on a symbolic value. *)moduleModel:MODELwithtypevalue:=Value.tmoduleCookie:COOKIEvalcheck_sat:Cookie.t->t->Model.toption(** [check_sat c s] returns a model that satisfies the predicate of [s], using the
configuration stored in the cookie [c].
@raise Unknown when no solution is found within the current resource budget
(see {!constructor-SetSMTSolverTimeout}).
*)moduleEnumeration:ENUMERATIONwithtypevalue:=Bitvector.t*Model.tvalenumerate:Cookie.t->Value.t->?except:Bitvector.tlist->t->Enumeration.t(** [enumerate c v ~except s] returns a new enumeration for the value [v], using the
configuration stored in the cookie [c].
The enumeration will not contain any {!module-Binsec_kernel.module-Bitvector} present in [except].
*)valprint_smtlib:?slice:(Value.t*string)list->Format.formatter->t->unit(** [print_smtlib ~slice f s] outputs the predicate of [s] in the SMTlib format
in the formatter [f].
If [slice] is given, it outputs the current mapping between values and name.
Otherwise, it outputs the full mapping (variables and arrays) of [s].
*)valpp:Format.formatter->t->unit(** [pp f s] outputs the state [s] in the formatter [f]. *)valmore:(Value.t,t,Cookie.t,'a)feature->'aoption(** [more feature]
returns [Some] a value of type ['a]; or [None] if the current implementation
does not support the queried feature.
*)endtype_value_kind=..(** A witness of the value type used by the state ({!module-type-S.val-more} {!constructor-ValueKind}). *)type('value,'state,'cookie,'a)feature+=|ValueKind:('value,'state,'cookie,'valuevalue_kind)feature|SetSMTSolver:('value,'state,'cookie,'cookie->Smtlib.Solver.backend->unit)feature|SetSMTSolverTimeout:('value,'state,'cookie,'cookie->float->unit)feature|SetSMTDumpDir:('value,'state,'cookie,'cookie->string->unit)feature|SetSMTSolverMultiChecks:('value,'state,'cookie,'cookie->bool->unit)feature|ToFormula:('value,'state,'cookie,'state->Smtlib.Formula.formula)feature