p8n_types/basic_block.rs
1// Panopticon - A libre program analysis library for machine code
2// Copyright (C) 2014-2018 The Panopticon Developers
3//
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8//
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13//
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
18//! A Basic Block is a uninterrupted sequence of machine code.
19
20use std::ops::Range;
21use std::usize;
22
23use petgraph::graph::NodeIndex;
24use ron_uuid::UUID;
25
26use {MnemonicIndex, Area, Function};
27
28/// An uninterrupted sequence of machine code.
29/// Basic blocks cover a continuous address range.
30#[derive(Clone, Debug, PartialEq, Eq)]
31pub struct BasicBlock {
32 /// Fixed UUID of this basic block. Never changes.
33 pub uuid: UUID,
34 /// Range of indices into the functions mnmonic list.
35 pub mnemonics: Range<MnemonicIndex>,
36 /// Node this basic block occupies in the functions control flow graph.
37 pub node: NodeIndex,
38 /// Bytes covered byte the basic block.
39 pub area: Area,
40 /// Range of indices into the functions IL statement list.
41 pub statements: Range<usize>,
42}
43
44impl BasicBlock {
45 /// Address range covered.
46 pub fn area<'a>(&'a self) -> &'a Area { &self.area }
47}
48
49/// Index of the basic block.
50#[derive(Clone,Copy,Debug,PartialOrd,Ord,PartialEq,Eq)]
51pub struct BasicBlockIndex {
52 index: usize
53}
54
55impl BasicBlockIndex {
56 /// Creates an index for basic block number `i`.
57 pub fn new(i: usize) -> BasicBlockIndex { BasicBlockIndex{ index: i } }
58 /// Numeric index.
59 pub fn index(&self) -> usize { self.index }
60}
61
62#[derive(Clone)]
63/// Iterator over basic blocks.
64pub struct BasicBlockIterator<'a> {
65 function: &'a Function,
66 index: usize,
67 max: usize,
68}
69
70impl<'a> BasicBlockIterator<'a> {
71 /// Create a new basic block iterator.
72 pub fn new(function: &'a Function,index: usize, max: usize) -> BasicBlockIterator<'a> {
73 BasicBlockIterator{
74 function: function,
75 index: index,
76 max: max,
77 }
78 }
79}
80
81
82impl<'a> Iterator for BasicBlockIterator<'a> {
83 type Item = (BasicBlockIndex,&'a BasicBlock);
84
85 fn next(&mut self) -> Option<(BasicBlockIndex,&'a BasicBlock)> {
86 if self.index < self.max {
87 let idx = BasicBlockIndex::new(self.index);
88 let bb = self.function.basic_block(idx);
89
90 self.index += 1;
91 Some((idx,bb))
92 } else {
93 None
94 }
95 }
96}
97
98impl<'a> ExactSizeIterator for BasicBlockIterator<'a> {
99 fn len(&self) -> usize {
100 self.max - self.index
101 }
102}
103
104impl<'a> DoubleEndedIterator for BasicBlockIterator<'a> {
105 fn next_back(&mut self) -> Option<(BasicBlockIndex,&'a BasicBlock)> {
106 if self.index < self.max {
107 let idx = BasicBlockIndex::new(self.max - 1);
108 let bb = self.function.basic_block(idx);
109
110 self.max -= 1;
111 Some((idx,bb))
112 } else {
113 None
114 }
115 }
116}