Struct haybale::State[][src]

pub struct State<'p, B: Backend> {
    pub solver: B::SolverRef,
    pub config: Config<'p, B>,
    pub proj: &'p Project,
    pub cur_loc: Location<'p>,
    // some fields omitted
}

A State describes the full program state at a given moment during symbolic execution.

Fields

solver: B::SolverRef

Reference to the solver instance being used

config: Config<'p, B>

The configuration being used

proj: &'p Project

Referece to the Project being used

cur_loc: Location<'p>

Indicates the instruction which is currently being executed

Implementations

impl<'p, B: Backend> State<'p, B> where
    B: 'p, 
[src]

pub fn new(
    project: &'p Project,
    start_loc: Location<'p>,
    config: Config<'p, B>
) -> Self
[src]

start_loc: the Location where the State should begin executing. As of this writing, start_loc should be the entry point of a function, or you will have problems.

pub fn fork(&self) -> Self[src]

Fully duplicate the State. Unlike with clone(), the State this function returns will have a fully separate (fully duplicated) solver instance. (With clone(), the states will still share references to the same solver instance.)

pub fn sat(&self) -> Result<bool>[src]

Returns true if current constraints are satisfiable, false if not.

Returns Error::SolverError if the query failed (e.g., was interrupted or timed out).

pub fn sat_with_extra_constraints<'b>(
    &'b self,
    constraints: impl IntoIterator<Item = &'b B::BV>
) -> Result<bool>
[src]

Returns true if the current constraints plus the given additional constraints are together satisfiable, or false if not.

Returns Error::SolverError if the query failed (e.g., was interrupted or timed out).

Does not permanently add the given constraints to the solver.

pub fn get_bv_by_irname<'s>(
    &'s self,
    funcname: &String,
    name: &Name
) -> &'s B::BV
[src]

Get the BV corresponding to the given IR Name (from the given Function name).

There should already have been a BV created for this Name on this path; this won't attempt to create a BV if there isn't already one for this Name.

pub fn bvs_must_be_equal(&self, a: &B::BV, b: &B::BV) -> Result<bool>[src]

Returns true if under the current constraints, a and b must have the same value. Returns false if a and b may have different values. (If the current constraints are themselves unsatisfiable, that will result in true.)

A common use case for this function is to test whether some BV must be equal to a given concrete value. You can do this with something like state.bvs_must_be_equal(bv, &state.bv_from_u64(...)).

This function and bvs_can_be_equal() are both more efficient than get_a_solution() or get_possible_solutions()-type functions, as they do not require full model generation. You should prefer this function or bvs_can_be_equal() if they are sufficient for your needs.

pub fn bvs_can_be_equal(&self, a: &B::BV, b: &B::BV) -> Result<bool>[src]

Returns true if under the current constraints, a and b can have the same value. Returns false if a and b cannot have the same value. (If the current constraints are themselves unsatisfiable, that will also result in false.)

A common use case for this function is to test whether some BV can be equal to a given concrete value. You can do this with something like state.bvs_can_be_equal(bv, &state.bv_from_u64(...)).

This function and bvs_must_be_equal() are both more efficient than get_a_solution() or get_possible_solutions()-type functions, as they do not require full model generation. You should prefer this function or bvs_must_be_equal() if they are sufficient for your needs.

pub fn get_a_solution_for_bv(&self, bv: &B::BV) -> Result<Option<BVSolution>>[src]

Get one possible concrete value for the BV. Returns Ok(None) if no possible solution, or Error::SolverError if the solver query failed.

pub fn get_a_solution_for_irname(
    &mut self,
    funcname: &String,
    name: &Name
) -> Result<Option<BVSolution>>
[src]

Get one possible concrete value for the given IR Name (from the given Function name). Returns Ok(None) if no possible solution, or Error::SolverError if the solver query failed.

pub fn get_possible_solutions_for_bv(
    &self,
    bv: &B::BV,
    n: usize
) -> Result<PossibleSolutions<BVSolution>>
[src]

Get a description of the possible solutions for the BV.

n: Maximum number of distinct solutions to check for. If there are more than n possible solutions, this returns a PossibleSolutions::AtLeast containing n+1 solutions.

These solutions will be disambiguated - see docs on boolector::BVSolution.

If there are no possible solutions, this returns Ok with an empty PossibleSolutions, rather than returning an Err with Error::Unsat.

pub fn get_possible_solutions_for_irname(
    &mut self,
    funcname: &String,
    name: &Name,
    n: usize
) -> Result<PossibleSolutions<BVSolution>>
[src]

Get a description of the possible solutions for the given IR Name (from the given Function name).

n: Maximum number of distinct solutions to check for. If there are more than n possible solutions, this returns a PossibleSolutions::AtLeast containing n+1 solutions.

These solutions will be disambiguated - see docs on boolector::BVSolution.

If there are no possible solutions, this returns Ok with an empty PossibleSolutions, rather than returning an Err with Error::Unsat.

pub fn max_possible_solution_for_bv_as_u64(
    &self,
    bv: &B::BV
) -> Result<Option<u64>>
[src]

Get the maximum possible solution for the BV: that is, the highest value for which the current set of constraints is still satisfiable. "Maximum" will be interpreted in an unsigned fashion.

Returns Ok(None) if there is no solution for the BV, that is, if the current set of constraints is unsatisfiable. Only returns Err if a solver query itself fails. Panics if the BV is wider than 64 bits.

pub fn max_possible_solution_for_irname_as_u64(
    &mut self,
    funcname: &String,
    name: &Name
) -> Result<Option<u64>>
[src]

Get the maximum possible solution for the given IR Name (from the given Function name): that is, the highest value for which the current set of constraints is still satisfiable. "Maximum" will be interpreted in an unsigned fashion.

Returns Ok(None) if there is no solution for the BV, that is, if the current set of constraints is unsatisfiable. Only returns Err if a solver query itself fails. Panics if the BV is wider than 64 bits.

pub fn min_possible_solution_for_bv_as_u64(
    &self,
    bv: &B::BV
) -> Result<Option<u64>>
[src]

Get the minimum possible solution for the BV: that is, the lowest value for which the current set of constraints is still satisfiable. "Minimum" will be interpreted in an unsigned fashion.

Returns Ok(None) if there is no solution for the BV, that is, if the current set of constraints is unsatisfiable. Only returns Err if a solver query itself fails. Panics if the BV is wider than 64 bits.

pub fn min_possible_solution_for_irname_as_u64(
    &self,
    funcname: &String,
    name: &Name
) -> Result<Option<u64>>
[src]

Get the minimum possible solution for the given IR Name (from the given Function name): that is, the lowest value for which the current set of constraints is still satisfiable. "Minimum" will be interpreted in an unsigned fashion.

Returns Ok(None) if there is no solution for the BV, that is, if the current set of constraints is unsatisfiable. Only returns Err if a solver query itself fails. Panics if the BV is wider than 64 bits.

pub fn bv_from_bool(&self, b: bool) -> B::BV[src]

Create a BV constant representing the given bool (either constant true or constant false). The resulting BV will be either constant 0 or constant 1, and will have bitwidth 1.

pub fn bv_from_i32(&self, i: i32, width: u32) -> B::BV[src]

Create a BV representing the given constant i32 value, with the given bitwidth.

pub fn bv_from_u32(&self, u: u32, width: u32) -> B::BV[src]

Create a BV representing the given constant u32 value, with the given bitwidth.

pub fn bv_from_i64(&self, i: i64, width: u32) -> B::BV[src]

Create a BV representing the given constant i64 value, with the given bitwidth.

pub fn bv_from_u64(&self, u: u64, width: u32) -> B::BV[src]

Create a BV representing the given constant u64 value, with the given bitwidth.

pub fn zero(&self, width: u32) -> B::BV[src]

Create a BV representing the constant 0 of the given bitwidth. This is equivalent to self.bv_from_i32(0, width) but may be more efficient.

pub fn one(&self, width: u32) -> B::BV[src]

Create a BV representing the constant 1 of the given bitwidth. This is equivalent to self.bv_from_i32(1, width) but may be more efficient.

pub fn ones(&self, width: u32) -> B::BV[src]

Create a BV constant of the given width, where all bits are set to one. This is equivalent to self.bv_from_i32(-1, width) but may be more efficient.

pub fn new_bv_with_name(&mut self, name: Name, bits: u32) -> Result<B::BV>[src]

Create a new (unconstrained) BV for the given Name (in the current function).

This function performs uniquing, so if you call it twice with the same Name-Function pair, you will get two different BVs.

Returns the new BV, or Err if it can't be created.

(As of this writing, the only Err that might be returned is Error::LoopBoundExceeded, which is returned if creating the new BV would exceed max_versions_of_name -- see Config.)

Also, we assume that no two Functions share the same name.

pub fn assign_bv_to_name(&mut self, name: Name, bv: B::BV) -> Result<()>[src]

Assign the given BV to the given Name (in the current function).

This function performs uniquing, so it creates a new version of the variable represented by the (String, Name) pair rather than overwriting the current version.

Returns Err if the assignment can't be performed.

(As of this writing, the only Err that might be returned is Error::LoopBoundExceeded, which is returned if creating the new version of the BV would exceed max_versions_of_name -- see Config.)

pub fn record_bv_result(
    &mut self,
    thing: &impl HasResult,
    resultval: B::BV
) -> Result<()>
[src]

Record the result of thing to be resultval. Assumes thing is in the current function. Will fail with Error::LoopBoundExceeded if that would exceed max_versions_of_name (see Config).

pub fn overwrite_latest_version_of_bv(&mut self, name: &Name, bv: B::BV)[src]

Overwrite the latest version of the given Name to instead be bv. Assumes Name is in the current function.

pub fn type_of<T: Typed + ?Sized>(&self, t: &T) -> TypeRef[src]

Convenience function to get the Type of anything that is Typed.

pub fn operand_to_bv(&self, op: &Operand) -> Result<B::BV>[src]

Convert an Operand to the appropriate BV. Assumes the Operand is in the current function. (All Operands should be either a constant or a variable we previously added to the state.)

pub fn const_to_bv(&self, c: &Constant) -> Result<B::BV>[src]

Convert a Constant to the appropriate BV.

pub fn get_pointer_to_function(
    &self,
    funcname: impl Into<String>
) -> Option<&B::BV>
[src]

Get a pointer to the given function name. The name must be the fully-mangled function name, as it appears in the LLVM. The name will be resolved in the current module; this means that it will first look for a module-private (e.g., C static) definition in the current module, then search for a public definition in the same or different module. It will never return a module-private definition from a different module.

Returns None if no function was found with that name.

pub fn get_pointer_to_function_hook(&self, funcname: &str) -> Option<&B::BV>[src]

Get a pointer to the currently active hook for the given function name.

Returns None if no function was found with that name, or if there is no currently active hook for that function.

pub fn get_func_by_name(
    &self,
    funcname: impl Into<String>
) -> Option<(&'p Function, &'p Module)>
[src]

Get a Function by name. The name must be the fully-mangled function name, as it appears in the LLVM. The name will be resolved in the current module; this means that it will first look for a module-private (e.g., C static) definition in the current module, then search for a public definition in the same or different module. It will never return a module-private definition from a different module.

Also returns the Module in which the prevailing definition of the Function was found.

Returns None if no function was found with that name.

pub fn read(&self, addr: &B::BV, bits: u32) -> Result<B::BV>[src]

Read a value bits bits long from memory at addr. Note that bits can be arbitrarily large.

pub fn write(&mut self, addr: &B::BV, val: B::BV) -> Result<()>[src]

Write a value into memory at addr. Note that val can be an arbitrarily large bitvector.

pub fn size(&self, ty: &Type) -> u32[src]

👎 Deprecated:

Prefer size_in_bits()

Get the size of the Type, in bits.

Accounts for the Project's pointer size and named struct definitions.

Note that some types have size 0 bits, and this may return 0.

Panics if ty is a struct which has no definition in the entire Project, or if it is a struct/array/vector where one of the elements is a struct with no definition in the entire Project.

pub fn size_opaque_aware(&self, ty: &Type, _proj: &'p Project) -> Option<u32>[src]

👎 Deprecated:

Renamed to size_in_bits()

Get the size of the Type, in bits.

Accounts for the Project's pointer size and named struct definitions.

Note that some types have size 0 bits, and this may return Some(0).

Returns None for structs which have no definition in the entire Project, or for structs/arrays/vectors where one of the elements is a struct with no definition in the entire Project.

pub fn size_in_bits(&self, ty: &Type) -> Option<u32>[src]

Get the size of the Type, in bits.

Accounts for the Project's pointer size and named struct definitions.

Note that some types have size 0 bits, and this may return Some(0).

Returns None for structs which have no definition in the entire Project, or for structs/arrays/vectors where one of the elements is a struct with no definition in the entire Project.

pub fn fp_size(fpt: FPType) -> u32[src]

👎 Deprecated:

Renamed to fp_size_in_bits

Get the size of the FPType, in bits

pub fn fp_size_in_bits(fpt: FPType) -> u32[src]

pub fn get_offset_constant_index(
    &self,
    base_type: &Type,
    index: usize
) -> Result<(u32, TypeRef)>
[src]

Get the offset (in bytes) of the element at the given index, as well as the Type of the element at that index.

If base_type is a NamedStructType, the struct should be defined in the current module.

pub fn get_offset_bv_index<'t, V: BV>(
    &self,
    base_type: &'t Type,
    index: &V,
    solver: V::SolverRef
) -> Result<(V, &'t Type)>
[src]

Get the offset (in bytes) of the element at the given index, as well as a reference to the Type of the element at that index.

This function differs from get_offset_constant_index in that it takes an arbitrary BV as index instead of a usize, and likewise returns its offset as a BV.

The result BV will have the same width as the input index.

pub fn add_mem_watchpoint(
    &mut self,
    name: impl Into<String>,
    watchpoint: Watchpoint
) -> bool
[src]

Add a memory watchpoint. It will be enabled unless/until disable_watchpoint() is called on it.

If a watchpoint with the same name was previously added, this will replace that watchpoint and return true. Otherwise, this will return false.

When any watched memory is read or written to, an INFO-level log message will be generated.

pub fn rm_mem_watchpoint(&mut self, name: &str) -> bool[src]

Remove the memory watchpoint with the given name.

Returns true if the operation was successful, or false if no watchpoint with that name was found.

pub fn disable_watchpoint(&mut self, name: &str) -> bool[src]

Disable the memory watchpoint with the given name. Disabled watchpoints will not generate any log messages unless/until enable_watchpoint() is called on them.

Returns true if the operation is successful, or false if no watchpoint with that name was found. Disabling an already-disabled watchpoint will have no effect and will return true.

pub fn enable_watchpoint(&mut self, name: &str) -> bool[src]

Enable the memory watchpoint(s) with the given name.

Returns true if the operation is successful, or false if no watchpoint with that name was found. Enabling an already-enabled watchpoint will have no effect and will return true.

pub fn allocate(&mut self, bits: impl Into<u64>) -> B::BV[src]

Allocate a value of size bits; return a pointer to the newly allocated object

pub fn get_allocation_size(&mut self, addr: &B::BV) -> Result<Option<u64>>[src]

Get the size, in bits, of the allocation at the given address, or None if that address is not the result of an alloc().

pub fn record_path_entry(&mut self)[src]

Record the current location as a PathEntry in the current path.

pub fn get_path(&self) -> &Vec<PathEntry<'p>>[src]

Get the PathEntrys that have been recorded, in order

pub fn push_callsite(&mut self, call: &'p Call)[src]

Record entering a normal Call at the current location

pub fn push_invokesite(&mut self, invoke: &'p Invoke)[src]

Record entering the given Invoke at the current location

pub fn pop_callsite(&mut self) -> Option<Callsite<'p>>[src]

Record leaving the current function. Returns the Callsite at which the current function was called, or None if the current function was the top-level function.

Also restores the caller's local variables.

pub fn current_callstack_depth(&self) -> usize[src]

Returns the current callstack depth. 0 indicates we're in the toplevel function, 1 indicates we're in a function directly called by the toplevel function, etc.

pub fn save_backtracking_point(&mut self, bb_to_enter: &Name, constraint: B::BV)[src]

Save the current state, about to enter the BasicBlock with the given Name (which must be in the same Module and Function as state.cur_loc), as a backtracking point. The constraint will be added only if we end up backtracking to this point, and only then.

pub fn revert_to_backtracking_point(&mut self) -> Result<bool>[src]

returns Ok(true) if the operation was successful, Ok(false) if there are no saved backtracking points, or Err for other errors

pub fn count_backtracking_points(&self) -> usize[src]

returns the number of saved backtracking points

pub fn pretty_backtrace(&self) -> String[src]

returns a String containing a formatted view of the current backtrace (in terms of LLVM locations, and possibly also source locations depending on the Config)

pub fn pretty_path_llvm(&self) -> String[src]

returns a String containing a formatted view of the full path which led to this point, in terms of LLVM locations

pub fn pretty_path_llvm_instructions(&self) -> String[src]

returns a String containing a formatted view of the full path which led to this point, in terms of LLVM IR instructions. If the Path includes any hooked functions, the instructions which might be contained within those functions are not included.

pub fn pretty_path_source(&self) -> String[src]

returns a String containing a formatted view of the full path which led to this point, in terms of source locations

pub fn pretty_path_interleaved(&self) -> String[src]

returns a String containing a formatted view of the full path which led to this point, in terms of both LLVM and source locations (interleaved appropriately)

pub fn get_path_length(&self) -> usize[src]

Returns the number of LLVM instructions in the current path. The returned value is only accurate if the path under analysis does not include a panic, exception, exit, or any hooked calls (such as inline assembly).

pub fn demangle(&self, funcname: &str) -> String[src]

Attempt to demangle the given funcname as appropriate based on the Config.

If this fails to demangle funcname, it just returns a copy of funcname unchanged.

pub fn all_vars_in_cur_fn(&self) -> impl Iterator<Item = (&Name, &B::BV)>[src]

Get the most recent BV created for each Name in the current function. Returns pairs of the Name and the BV assigned to that Name.

Returned pairs will be sorted by Name.

pub fn current_assignments_as_pretty_string(&self) -> Result<String>[src]

returns a String describing a set of satisfying assignments for all variables

pub fn full_error_message_with_context(&self, e: Error) -> String[src]

Returns a String describing both the error and the context in which it occurred (backtrace, full path to error, variable values at the point of error, etc). Exactly which information is included is partially dependent on the environment variables HAYBALE_DUMP_PATH and HAYBALE_DUMP_VARS, as explained in the message.

Trait Implementations

impl<'p, B: Clone + Backend> Clone for State<'p, B> where
    B::SolverRef: Clone,
    B::BV: Clone,
    B::Memory: Clone,
    B::BV: Clone
[src]

Auto Trait Implementations

impl<'p, B> !RefUnwindSafe for State<'p, B>[src]

impl<'p, B> !Send for State<'p, B>[src]

impl<'p, B> !Sync for State<'p, B>[src]

impl<'p, B> Unpin for State<'p, B> where
    <B as Backend>::BV: Unpin,
    <B as Backend>::Memory: Unpin,
    <B as Backend>::SolverRef: Unpin
[src]

impl<'p, B> !UnwindSafe for State<'p, B>[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.