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}