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_jumpsite(
&self,
value_after_jump: &Self::Value,
jump: &Term<Jmp>,
untaken_conditional: Option<&Term<Jmp>>,
jumpsite: &Term<Blk>
) -> Option<Self::Value>;
fn update_callsite(
&self,
target_value: Option<&Self::Value>,
return_value: Option<&Self::Value>,
caller_sub: &Term<Sub>,
call: &Term<Jmp>,
return_: &Term<Jmp>
) -> Option<Self::Value>;
fn split_call_stub(
&self,
combined_value: &Self::Value
) -> Option<Self::Value>;
fn split_return_stub(
&self,
combined_value: &Self::Value,
returned_from_sub: &Term<Sub>
) -> Option<Self::Value>;
fn update_call_stub(
&self,
value_after_call: &Self::Value,
call: &Term<Jmp>
) -> Option<Self::Value>;
fn specialize_conditional(
&self,
value_after_jump: &Self::Value,
condition: &Expression,
is_true: bool
) -> Option<Self::Value>;
}
Expand description
The context for an backward 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. The return value is expected to be the reversed CFG.
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_jumpsite(
&self,
value_after_jump: &Self::Value,
jump: &Term<Jmp>,
untaken_conditional: Option<&Term<Jmp>>,
jumpsite: &Term<Blk>
) -> Option<Self::Value>
fn update_jumpsite( &self, value_after_jump: &Self::Value, jump: &Term<Jmp>, untaken_conditional: Option<&Term<Jmp>>, jumpsite: &Term<Blk> ) -> Option<Self::Value>
Transition function for (conditional and unconditional) Jmp
terms.
sourcefn update_callsite(
&self,
target_value: Option<&Self::Value>,
return_value: Option<&Self::Value>,
caller_sub: &Term<Sub>,
call: &Term<Jmp>,
return_: &Term<Jmp>
) -> Option<Self::Value>
fn update_callsite( &self, target_value: Option<&Self::Value>, return_value: Option<&Self::Value>, caller_sub: &Term<Sub>, call: &Term<Jmp>, return_: &Term<Jmp> ) -> Option<Self::Value>
Transition function for in-program calls. The target value is coming in via the call edge from the BlkStart node of the called subroutine and the return_value is coming in via the call stub edge from the returned-to node of the caller
sourcefn split_call_stub(&self, combined_value: &Self::Value) -> Option<Self::Value>
fn split_call_stub(&self, combined_value: &Self::Value) -> Option<Self::Value>
Transition function for call stub split. Has access to the value at the ReturnCombine node and decides which data is transferred along the Call Stub Edge.
sourcefn split_return_stub(
&self,
combined_value: &Self::Value,
returned_from_sub: &Term<Sub>
) -> Option<Self::Value>
fn split_return_stub( &self, combined_value: &Self::Value, returned_from_sub: &Term<Sub> ) -> Option<Self::Value>
Transition function for return stub split. Has access to the value at the ReturnCombine node and decides which data is transferred along the Return Stub Edge.
sourcefn update_call_stub(
&self,
value_after_call: &Self::Value,
call: &Term<Jmp>
) -> Option<Self::Value>
fn update_call_stub( &self, value_after_call: &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_after_jump: &Self::Value,
condition: &Expression,
is_true: bool
) -> Option<Self::Value>
fn specialize_conditional( &self, value_after_jump: &Self::Value, condition: &Expression, 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.