pub trait Context<'a> {
type Value: PartialEq + Eq + Clone;
// Required methods
fn get_graph(&self) -> &Graph<'a>;
fn merge(&self, value1: &Self::Value, value2: &Self::Value) -> Self::Value;
fn update_def(
&self,
value: &Self::Value,
def: &Term<Def>
) -> Option<Self::Value>;
fn update_jump(
&self,
value: &Self::Value,
jump: &Term<Jmp>,
untaken_conditional: Option<&Term<Jmp>>,
target: &Term<Blk>
) -> Option<Self::Value>;
fn update_call(
&self,
value: &Self::Value,
call: &Term<Jmp>,
target: &Node<'_>,
calling_convention: &Option<String>
) -> Option<Self::Value>;
fn update_return(
&self,
value: Option<&Self::Value>,
value_before_call: Option<&Self::Value>,
call_term: &Term<Jmp>,
return_term: &Term<Jmp>,
calling_convention: &Option<String>
) -> Option<Self::Value>;
fn update_call_stub(
&self,
value: &Self::Value,
call: &Term<Jmp>
) -> Option<Self::Value>;
fn specialize_conditional(
&self,
value: &Self::Value,
condition: &Expression,
block_before_condition: &Term<Blk>,
is_true: bool
) -> Option<Self::Value>;
}
Expand description
The context for an interprocedural fixpoint computation.
Basically, a Context
object needs to contain a reference to the actual graph,
a method for merging node values,
and methods for computing the edge transitions for each different edge type.
All trait methods have access to the FixpointProblem structure, so that context informations are accessible through it.
All edge transition functions can return None
to indicate that no information flows through the edge.
For example, this can be used to indicate edges that can never been taken.
Required Associated Types§
Required Methods§
sourcefn get_graph(&self) -> &Graph<'a>
fn get_graph(&self) -> &Graph<'a>
Get a reference to the graph that the fixpoint is computed on.
sourcefn merge(&self, value1: &Self::Value, value2: &Self::Value) -> Self::Value
fn merge(&self, value1: &Self::Value, value2: &Self::Value) -> Self::Value
Merge two node values.
sourcefn update_def(
&self,
value: &Self::Value,
def: &Term<Def>
) -> Option<Self::Value>
fn update_def( &self, value: &Self::Value, def: &Term<Def> ) -> Option<Self::Value>
Transition function for Def
terms.
The transition function for a basic block is computed
by iteratively applying this function to the starting value for each Def
term in the basic block.
The iteration short-circuits and returns None
if update_def
returns None
at any point.
sourcefn update_jump(
&self,
value: &Self::Value,
jump: &Term<Jmp>,
untaken_conditional: Option<&Term<Jmp>>,
target: &Term<Blk>
) -> Option<Self::Value>
fn update_jump( &self, value: &Self::Value, jump: &Term<Jmp>, untaken_conditional: Option<&Term<Jmp>>, target: &Term<Blk> ) -> Option<Self::Value>
Transition function for (conditional and unconditional) Jmp
terms.
sourcefn update_call(
&self,
value: &Self::Value,
call: &Term<Jmp>,
target: &Node<'_>,
calling_convention: &Option<String>
) -> Option<Self::Value>
fn update_call( &self, value: &Self::Value, call: &Term<Jmp>, target: &Node<'_>, calling_convention: &Option<String> ) -> Option<Self::Value>
Transition function for in-program calls.
sourcefn update_return(
&self,
value: Option<&Self::Value>,
value_before_call: Option<&Self::Value>,
call_term: &Term<Jmp>,
return_term: &Term<Jmp>,
calling_convention: &Option<String>
) -> Option<Self::Value>
fn update_return( &self, value: Option<&Self::Value>, value_before_call: Option<&Self::Value>, call_term: &Term<Jmp>, return_term: &Term<Jmp>, calling_convention: &Option<String> ) -> Option<Self::Value>
Transition function for return instructions. Has access to the value at the callsite corresponding to the return edge. This way one can recover caller-specific information on return from a function.
sourcefn update_call_stub(
&self,
value: &Self::Value,
call: &Term<Jmp>
) -> Option<Self::Value>
fn update_call_stub( &self, value: &Self::Value, call: &Term<Jmp> ) -> Option<Self::Value>
Transition function for calls to functions not contained in the binary. The corresponding edge goes from the callsite to the returned-to block.
sourcefn specialize_conditional(
&self,
value: &Self::Value,
condition: &Expression,
block_before_condition: &Term<Blk>,
is_true: bool
) -> Option<Self::Value>
fn specialize_conditional( &self, value: &Self::Value, condition: &Expression, block_before_condition: &Term<Blk>, is_true: bool ) -> Option<Self::Value>
This function is used to refine the value using the information on which branch was taken on a conditional jump.