Module Pulselib.PulseOperations
module Import : sig ... endFor
opening in other modules.
include module type of Import
type access_mode=
Imported types for ease of use and so we can write variants without the corresponding module prefix
type 'abductive_domain_t execution_domain_base_t= 'abductive_domain_t PulseDomainInterface.ExecutionDomain.base_t=|ContinueProgram of 'abductive_domain_t|ExitProgram of PulseDomainInterface.AbductiveDomain.summary|AbortProgram of PulseDomainInterface.AbductiveDomain.summary|LatentAbortProgram of{astate : PulseDomainInterface.AbductiveDomain.summary;latent_issue : PulseDomainInterface.LatentIssue.t;}|LatentInvalidAccess of{astate : PulseDomainInterface.AbductiveDomain.summary;address : PulseBasicInterface.AbstractValue.t;must_be_valid : PulseBasicInterface.Trace.t * PulseBasicInterface.Invalidation.must_be_valid_reason option;calling_context : (PulseBasicInterface.CallEvent.t * IBase.Location.t) list;}|ISLLatentMemoryError of PulseDomainInterface.AbductiveDomain.summarytype 'astate base_error= 'astate PulseDomainInterface.AccessResult.error=|PotentialInvalidAccess of{astate : 'astate;address : PulseBasicInterface.AbstractValue.t;must_be_valid : PulseBasicInterface.Trace.t * PulseBasicInterface.Invalidation.must_be_valid_reason option;}|PotentialInvalidAccessSummary of{astate : PulseDomainInterface.AbductiveDomain.summary;address : PulseBasicInterface.AbstractValue.t;must_be_valid : PulseBasicInterface.Trace.t * PulseBasicInterface.Invalidation.must_be_valid_reason option;}|ReportableError of{astate : 'astate;diagnostic : PulseBasicInterface.Diagnostic.t;}|ReportableErrorSummary of{astate : PulseDomainInterface.AbductiveDomain.summary;diagnostic : PulseBasicInterface.Diagnostic.t;}|ISLError of 'astate
Monadic syntax
include module type of IStdlib.IResult.Let_syntax
include module type of IStdlib.IStd.Result.Monad_infix
val let+ : ('ok, 'err) IStdlib.IStd.result -> ('ok -> 'okk) -> ('okk, 'err) IStdlib.IStd.resultval let* : ('ok, 'err) IStdlib.IStd.result -> ('ok -> ('okk, 'err) IStdlib.IStd.result) -> ('okk, 'err) IStdlib.IStd.result
val let<*> : 'a PulseDomainInterface.AccessResult.t -> ('a -> 'b PulseDomainInterface.AccessResult.t list) -> 'b PulseDomainInterface.AccessResult.t listmonadic "bind" but not really that turns an
AccessResult.tinto a list ofAccessResult.ts (not really because the first type is not anAccessResult.t listbut just anAccessResult.t)
val let<+> : 'a PulseDomainInterface.AccessResult.t -> ('a -> 'abductive_domain_t) -> 'abductive_domain_t execution_domain_base_t PulseDomainInterface.AccessResult.t listmonadic "map" but even less really that turns an
AccessResult.tinto an analysis result
val check_addr_access : PulseBasicInterface.PathContext.t -> ?must_be_valid_reason:PulseBasicInterface.Invalidation.must_be_valid_reason -> access_mode -> IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.tCheck that the
addressis not known to be invalid
module Closures : sig ... endval eval : PulseBasicInterface.PathContext.t -> access_mode -> IBase.Location.t -> IR.Exp.t -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) PulseDomainInterface.AccessResult.tUse the stack and heap to evaluate the given expression down to an abstract address representing its value.
Return an error state if it traverses some known invalid address or if the end destination is known to be invalid.
val eval_structure_isl : PulseBasicInterface.PathContext.t -> access_mode -> IBase.Location.t -> IR.Exp.t -> t -> (bool * (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) PulseDomainInterface.AccessResult.t list) PulseDomainInterface.AccessResult.tSimilar to eval but apply to data structures and ISL abduction. Return a list of abduced states (ISLOk and ISLErs); The boolean indicates whether it is data structures or not.
val prune : PulseBasicInterface.PathContext.t -> IBase.Location.t -> condition:IR.Exp.t -> t -> t PulseDomainInterface.AccessResult.tval eval_deref : PulseBasicInterface.PathContext.t -> ?must_be_valid_reason:PulseBasicInterface.Invalidation.must_be_valid_reason -> IBase.Location.t -> IR.Exp.t -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) PulseDomainInterface.AccessResult.tLike
evalbut evaluates*exp.
val eval_deref_isl : PulseBasicInterface.PathContext.t -> IBase.Location.t -> IR.Exp.t -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) PulseDomainInterface.AccessResult.t listval eval_access : PulseBasicInterface.PathContext.t -> ?must_be_valid_reason:PulseBasicInterface.Invalidation.must_be_valid_reason -> access_mode -> IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> Pulselib.PulseDomainInterface.BaseMemory.Access.t -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) PulseDomainInterface.AccessResult.tLike
evalbut starts from an address instead of an expression, checks that it is valid, and if so dereferences it according to the access.
val eval_deref_access : PulseBasicInterface.PathContext.t -> ?must_be_valid_reason:PulseBasicInterface.Invalidation.must_be_valid_reason -> access_mode -> IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> Pulselib.PulseDomainInterface.BaseMemory.Access.t -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) PulseDomainInterface.AccessResult.tLike
eval_accessbut does additional dereference.
val eval_proc_name : PulseBasicInterface.PathContext.t -> IBase.Location.t -> IR.Exp.t -> t -> (t * IR.Procname.t option) PulseDomainInterface.AccessResult.tval havoc_id : IR.Ident.t -> PulseBasicInterface.ValueHistory.t -> t -> tval havoc_deref_field : PulseBasicInterface.PathContext.t -> IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> IR.Fieldname.t -> PulseBasicInterface.ValueHistory.t -> t -> t PulseDomainInterface.AccessResult.tHavoc dereferenced field address.
val realloc_pvar : IR.Tenv.t -> IR.Pvar.t -> IR.Typ.t -> IBase.Location.t -> t -> tval write_id : IR.Ident.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> tval write_field : PulseBasicInterface.PathContext.t -> IBase.Location.t -> ref:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> IR.Fieldname.t -> obj:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.twrite the edge
ref --.field--> obj
val write_deref_field : PulseBasicInterface.PathContext.t -> IBase.Location.t -> ref:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> IR.Fieldname.t -> obj:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.twrite the edge
ref --.field--> _ --*--> obj
val write_arr_index : PulseBasicInterface.PathContext.t -> IBase.Location.t -> ref:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> index:PulseBasicInterface.AbstractValue.t -> obj:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.twrite the edge
ref[index]--> obj
val write_deref : PulseBasicInterface.PathContext.t -> IBase.Location.t -> ref:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> obj:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.twrite the edge
ref --*--> obj
val write_deref_biad_isl : PulseBasicInterface.PathContext.t -> IBase.Location.t -> ref:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> PulseBasicInterface.AbstractValue.t Absint.HilExp.Access.t -> obj:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.t list
type invalidation_access=|MemoryAccess of{pointer : PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t;access : Pulselib.PulseDomainInterface.BaseMemory.Access.t;hist_obj_default : PulseBasicInterface.ValueHistory.t;}the value was read from the heap following the
accessedge at addresspointer|StackAddress of IR.Var.t * PulseBasicInterface.ValueHistory.tthe value was read from the stack
|UntraceableAccesswe don't know where the value came from; avoid using if possible
the way that was used to get to the invalidated address in the state; this is used to record the invalidation point in its history in addition to inside the
Invalidattribute
val invalidate : PulseBasicInterface.PathContext.t -> invalidation_access -> IBase.Location.t -> PulseBasicInterface.Invalidation.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.trecord that the address is invalid
val invalidate_biad_isl : PulseBasicInterface.PathContext.t -> IBase.Location.t -> PulseBasicInterface.Invalidation.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.t listrecord that the address is invalid. If the address has not been allocated, abduce ISL specs for both invalid (null, free, unint) and allocated heap.
val allocate : IR.Procname.t -> IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> tval add_dynamic_type : IR.Typ.t -> PulseBasicInterface.AbstractValue.t -> t -> tval remove_allocation_attr : PulseBasicInterface.AbstractValue.t -> t -> tval invalidate_access : PulseBasicInterface.PathContext.t -> IBase.Location.t -> PulseBasicInterface.Invalidation.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> Pulselib.PulseDomainInterface.BaseMemory.Access.t -> t -> t PulseDomainInterface.AccessResult.trecord that what the address points via the access to is invalid
val invalidate_deref_access : PulseBasicInterface.PathContext.t -> IBase.Location.t -> PulseBasicInterface.Invalidation.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> Pulselib.PulseDomainInterface.BaseMemory.Access.t -> t -> t PulseDomainInterface.AccessResult.tLike
invalidate_accessbut invalidates dereferenced address.
val invalidate_array_elements : PulseBasicInterface.PathContext.t -> IBase.Location.t -> PulseBasicInterface.Invalidation.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t PulseDomainInterface.AccessResult.trecord that all the array elements that address points to is invalid
val shallow_copy : PulseBasicInterface.PathContext.t -> IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) PulseDomainInterface.AccessResult.treturns the address of a new cell with the same edges as the original
val get_dynamic_type_unreachable_values : IR.Var.t list -> t -> (IR.Var.t * IR.Typ.t) listGiven a list of variables, computes the unreachable values if the variables were removed from the stack, then return the dynamic types of those values if they are available
val remove_vars : IR.Var.t list -> IBase.Location.t -> t -> tval check_address_escape : IBase.Location.t -> IR.Procdesc.t -> PulseBasicInterface.AbstractValue.t -> PulseBasicInterface.ValueHistory.t -> t -> t PulseDomainInterface.AccessResult.tval get_captured_actuals : PulseBasicInterface.PathContext.t -> IBase.Location.t -> captured_vars:(IR.Var.t * IR.CapturedVar.capture_mode * IR.Typ.t) list -> actual_closure:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> (t * (IR.Var.t * ((PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) * IR.Typ.t)) list) PulseDomainInterface.AccessResult.t