Commit 4b6ca3be by Enkelmann Committed by Enkelmann

Support basic blocks that are contained in more than one function.

parent c585d9de
......@@ -185,7 +185,10 @@ impl<'a, T: Context<'a>> GeneralFPContext for GeneralizedContext<'a, T> {
NodeValue::Value(_) => panic!("Unexpected interprocedural fixpoint graph state"),
NodeValue::CallReturnCombinator { call, return_ } => {
let return_from_block = match graph.node_weight(start_node) {
Some(Node::CallReturn { call: _, return_ }) => return_,
Some(Node::CallReturn {
call: _,
return_: (return_from_block, _),
}) => return_from_block,
_ => panic!("Malformed Control flow graph"),
};
let return_from_jmp = &return_from_block.term.jmps[0];
......
......@@ -140,7 +140,14 @@ fn context_problem_implementation() {
jmps: Vec::new(),
},
};
let target_node = crate::analysis::graph::Node::BlkStart(&target_block);
let sub = Term {
tid: Tid::new("caller_sub"),
term: Sub {
name: "caller_sub".into(),
blocks: vec![target_block.clone()],
},
};
let target_node = crate::analysis::graph::Node::BlkStart(&target_block, &sub);
let call = call_term("func");
let mut callee_state = context.update_call(&state, &call, &target_node).unwrap();
assert_eq!(callee_state.stack_id, new_id("func", "RSP"));
......
......@@ -77,20 +77,22 @@ impl<'a> PointerInference<'a> {
.collect();
for sub_tid in project.program.term.entry_points.iter() {
if let Some(sub) = subs.get(sub_tid) {
if let Some(entry_block) = sub.term.blocks.iter().next() {
if let Some(entry_block) = sub.term.blocks.get(0) {
entry_sub_to_entry_blocks_map.insert(sub_tid, entry_block.tid.clone());
}
}
}
let tid_to_graph_indices_map = super::graph::get_indices_of_block_nodes(
&context.graph,
entry_sub_to_entry_blocks_map.values(),
);
let mut tid_to_graph_indices_map = HashMap::new();
for node in context.graph.node_indices() {
if let super::graph::Node::BlkStart(block, sub) = context.graph[node] {
tid_to_graph_indices_map.insert((block.tid.clone(), sub.tid.clone()), node);
}
}
let entry_sub_to_entry_node_map: HashMap<Tid, NodeIndex> = entry_sub_to_entry_blocks_map
.into_iter()
.filter_map(|(sub_tid, block_tid)| {
if let Some((start_node_index, _end_node_index)) =
tid_to_graph_indices_map.get(&block_tid)
if let Some(start_node_index) =
tid_to_graph_indices_map.get(&(block_tid, sub_tid.clone()))
{
Some((sub_tid.clone(), *start_node_index))
} else {
......@@ -200,14 +202,14 @@ impl<'a> PointerInference<'a> {
let graph = self.computation.get_graph();
let mut new_entry_points = Vec::new();
for (node_id, node) in graph.node_references() {
if let Node::BlkStart(block) = node {
if !(start_block_to_sub_map.get(&block.tid).is_none()
|| self.computation.get_node_value(node_id).is_some()
|| only_cfg_roots
&& graph
if let Node::BlkStart(block, sub) = node {
if start_block_to_sub_map.get(&block.tid) == Some(sub)
&& self.computation.get_node_value(node_id).is_none()
&& (!only_cfg_roots
|| graph
.neighbors_directed(node_id, Direction::Incoming)
.next()
.is_some())
.is_none())
{
new_entry_points.push(node_id);
}
......@@ -239,7 +241,7 @@ impl<'a> PointerInference<'a> {
let mut stateful_blocks: i64 = 0;
let mut all_blocks: i64 = 0;
for (node_id, node) in graph.node_references() {
if let Node::BlkStart(_block) = node {
if let Node::BlkStart(_block, _sub) = node {
all_blocks += 1;
if self.computation.get_node_value(node_id).is_some() {
stateful_blocks += 1;
......
......@@ -213,7 +213,7 @@ impl AbstractObjectList {
possible_double_free_ids.push((id.clone(), error));
}
}
} else if let Some(id) = ids.iter().next() {
} else if let Some(id) = ids.get(0) {
if let Err(error) = self.objects.get_mut(&id).unwrap().0.mark_as_freed() {
possible_double_free_ids.push((id.clone(), error));
}
......
......@@ -217,6 +217,19 @@ pub struct Program {
pub entry_points: Vec<Tid>,
}
impl Program {
/// Find a block term by its term identifier.
/// WARNING: The function simply iterates through all blocks,
/// i.e. it is very inefficient for large projects!
pub fn find_block(&self, tid: &Tid) -> Option<&Term<Blk>> {
self.subs
.iter()
.map(|sub| sub.term.blocks.iter())
.flatten()
.find(|block| block.tid == *tid)
}
}
/// The `Project` struct is the main data structure representing a binary.
///
/// It contains information about the disassembled binary
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment