p8n_types/
bitcode.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
18use std::io::{Write,Cursor,Read};
19use std::ops::{Range};
20use leb128;
21use ron_uuid::UUID;
22use {
23    Statement,
24    Endianess,
25    Operation,
26    MemoryOperation,
27    FlowOperation,
28    Constant,
29    Variable,
30    Value,
31    StrRef,
32    Result,
33    RewriteControl,
34    NameRef,
35    Names,
36    Strings,
37    Segment,
38    SegmentRef,
39    Segments,
40    Constraint
41};
42
43/// Memory conserving representation of IL code.
44#[derive(Clone,Debug)]
45pub struct Bitcode {
46    data: Vec<u8>,
47}
48// const: <len, pow2><leb128 value>
49// var: <name, leb128 str idx>, <subscript, leb128 + 1>, <len, value>
50
51//  1\2  c   v   u
52//   c|000 001 010
53//   v|011 100 101
54//   u|110 111 xxx
55//
56// add  00000--- <a> <b> <res>
57// sub  00001--- <a> <b> <res>
58// mul  00010--- <a> <b> <res>
59// divu 00011--- <a> <b> <res>
60// divs 00100--- <a> <b> <res>
61// shl  00101--- <a> <b> <res>
62// shru 00110--- <a> <b> <res>
63// shrs 00111--- <a> <b> <res>
64// mod  01000--- <a> <b> <res>
65// and  01001--- <a> <b> <res>
66// or   01010--- <a> <b> <res>
67// xor  01011--- <a> <b> <res>
68// eq   01100--- <a> <b> <res>
69// leu  01101--- <a> <b> <res>
70// les  01110--- <a> <b> <res>
71// ltu  01111--- <a> <b> <res>
72// lts  10000--- <a> <b> <res>
73//
74//  \  e   u   s   f
75// v | 000 001 010 011
76// u | 100 101 110 111
77//
78// c: 0, v: 1
79// little: 0, big: 1
80// zext   1000100- <size, leb128> <a>
81// sext   1000101- <size, leb128> <a>
82// mov    1000110- <a>
83// movu   10001110
84// init   10001111 <name, leb128> <size, leb128>
85// sel    100100-- <offset, leb128> <sz, leb128> <a>
86// load   100101e- <region, leb128> <size, leb128> <a>
87// phi2   10011000 <a, var> <b, var> 3 0x0
88// phi3   10011001 <a, var> <b, var> <c, var>
89// call   10011010 <stub, leb128>
90// call   10011011 <uuid, leb128>
91// icall  1001110- <a>
92// ucall  10011110
93// phi0   10011111 3*3 0x0
94// store  1010e--- <region, leb128> <size, leb128> <addr> <val>
95// ret    10110000
96//        10110001
97// loadu  1011001e <region, leb128> <size, leb128>
98// phi1   10110100 <a> 2*3 0x0
99// mphi0  10110101 3*3 0x0
100// mphi1  10110110 <a, seg> 2*3 0x0
101// mphi2  10110111 <a, seg> <b, seg> 3 0x0
102// mphi3  10111000 <a, seg> <b, seg> <c, seg>
103// alloc  10111001 <name, leb128>
104// assume 11000--- <constr> <a>
105
106macro_rules! encoding_rule {
107    ( $val:tt [ c , c ] => $a:expr, $b:expr, $res:expr, $data:expr ) => {{
108        let val = $val;
109        let a = $a;
110        let b = $b;
111        let res = $res;
112        let data = $data;
113
114        data.write(&[val])?;
115        Self::encode_constant(a,data)?;
116        Self::encode_constant(b,data)?;
117        Self::encode_variable(res,data)?;
118    }};
119    ( $val:tt [ c , v ] => $a:expr, $b:expr, $res:expr, $data:expr ) => {{
120        let val = $val;
121        let a = $a;
122        let b = $b;
123        let res = $res;
124        let data = $data;
125
126        data.write(&[val])?;
127        Self::encode_constant(a,data)?;
128        Self::encode_variable(b,data)?;
129        Self::encode_variable(res,data)?;
130    }};
131    ( $val:tt [ c , u ] => $a:expr, $res:expr, $data:expr ) => {{
132        let val = $val;
133        let a = $a;
134        let res = $res;
135        let data = $data;
136
137        data.write(&[val])?;
138        Self::encode_constant(a,data)?;
139        Self::encode_variable(res,data)?;
140    }};
141    ( $val:tt [ v , c ] => $a:expr, $b:expr, $res:expr, $data:expr ) => {{
142        let val = $val;
143        let a = $a;
144        let b = $b;
145        let res = $res;
146        let data = $data;
147
148        data.write(&[val])?;
149        Self::encode_variable(a,data)?;
150        Self::encode_constant(b,data)?;
151        Self::encode_variable(res,data)?;
152    }};
153    ( $val:tt [ v , v ] => $a:expr, $b:expr, $res:expr, $data:expr ) => {{
154        let val = $val;
155        let a = $a;
156        let b = $b;
157        let res = $res;
158        let data = $data;
159
160        data.write(&[val])?;
161        Self::encode_variable(a,data)?;
162        Self::encode_variable(b,data)?;
163        Self::encode_variable(res,data)?;
164    }};
165    ( $val:tt [ v , u ] => $a:expr, $res:expr, $data:expr ) => {{
166        let val = $val;
167        let a = $a;
168        let res = $res;
169        let data = $data;
170
171        data.write(&[val])?;
172        Self::encode_variable(a,data)?;
173        Self::encode_variable(res,data)?;
174    }};
175    ( $val:tt [ u , c ] => $b:expr, $res:expr, $data:expr ) => {{
176        let val = $val;
177        let b = $b;
178        let res = $res;
179        let data = $data;
180
181        data.write(&[val])?;
182        Self::encode_constant(b,data)?;
183        Self::encode_variable(res,data)?;
184    }};
185    ( $val:tt [ u , v ] => $b:expr, $res:expr, $data:expr ) => {{
186        let val = $val;
187        let b = $b;
188        let res = $res;
189        let data = $data;
190
191        data.write(&[val])?;
192        Self::encode_variable(b,data)?;
193        Self::encode_variable(res,data)?;
194    }};
195}
196
197impl Default for Bitcode {
198    fn default() -> Bitcode {
199        Bitcode{
200            data: Vec::new(),
201        }
202    }
203}
204
205impl Bitcode {
206    /// Appends statements  in `i` to the bitcode vector, returing the new byte range.
207    pub fn append<I: IntoIterator<Item=Statement> + Sized>(&mut self, i: I) -> Result<Range<usize>> {
208        let mut buf = Cursor::new(Vec::new());
209        let start = self.data.len();
210
211        for stmt in i {
212            Self::encode_statement(stmt,&mut buf)?;
213        }
214
215        self.data.extend(buf.into_inner().into_iter());
216        Ok(start..self.data.len())
217    }
218
219    /// Creates a new Bitcode instance from `v`.
220    pub fn new(v: Vec<Statement>) -> Result<Bitcode> {
221        let mut buf = Cursor::new(Vec::new());
222
223        for stmt in v {
224            Self::encode_statement(stmt,&mut buf)?;
225        }
226
227        Ok(Bitcode{ data: buf.into_inner() })
228    }
229
230    /// Creates an empty Bitcode vector with initial capacity `cap`.
231    pub fn with_capacity(cap: usize) -> Bitcode {
232        Bitcode{
233            data: Vec::with_capacity(cap),
234        }
235    }
236
237    /// Maps function `func` over all statements in `range`, and writing them back into the vector.
238    pub fn rewrite<F: FnMut(&mut Statement,&mut Names,&mut Strings,&mut Segments) -> Result<RewriteControl> + Sized>(&mut self, range: Range<usize>, names: &mut Names, strings: &mut Strings, segments: &mut Segments, mut func: F) -> Result<Range<usize>> {
239        if range.start == range.end { return Ok(range); }
240
241        debug!("rewrite bitcode in {:?}",range);
242        let mut read_pos = range.start;
243        let mut bytes_left = range.end - range.start;
244        let mut write_pos = range.start;
245        let mut tmp = Vec::with_capacity(10);
246
247        while bytes_left > 0 {
248            let mut stmt = {
249                debug!("read from {:?}",read_pos);
250                let mut read = Cursor::new(&self.data[read_pos..]);
251                let stmt = self.decode_statement(&mut read)?;
252
253                read_pos += read.position() as usize;
254                debug!("left: {:?}",bytes_left);
255                debug!("read {:?}",read.position());
256                debug!("read to {:?}",read_pos);
257                bytes_left -= read.position() as usize;
258                stmt
259            };
260
261            debug!("map {:?}",stmt);
262            match func(&mut stmt,names,strings,segments)? {
263                RewriteControl::Continue => { /* fall-thru */ }
264                RewriteControl::Break => { return Ok(range.start..(read_pos + bytes_left)); }
265            }
266            debug!("  to {:?}",stmt);
267
268            {
269                let mut write = Cursor::new(tmp);
270
271                Self::encode_statement(stmt, &mut write)?;
272                tmp = write.into_inner();
273
274                if read_pos - write_pos < tmp.len() {
275                    let diff = tmp.len() - (read_pos - write_pos);
276                    debug!("make space for {} more bytes",diff);
277
278                    self.data.reserve(diff);
279                    // XXX
280                    for _ in 0..diff { self.data.insert(write_pos,42); }
281                    read_pos += diff;
282                }
283            }
284
285            //debug!("data: {:?}",self.data);
286            debug!("write {:?} at {}",tmp,write_pos);
287
288            {
289                let mut write = Cursor::new(&mut self.data[write_pos..]);
290                write_pos += write.write(&tmp)?;
291                tmp.clear();
292            }
293
294            if read_pos > write_pos {
295                debug!("remove {:?}",write_pos..read_pos);
296                self.data.drain(write_pos..read_pos);
297                read_pos = write_pos;
298            }
299
300            assert_eq!(read_pos, write_pos);
301            //debug!("data: {:?}",self.data);
302        }
303
304        Ok(range.start..write_pos)
305    }
306
307    /// Removes the serialized statements inside `range`.
308    pub fn remove(&mut self, range: Range<usize>) {
309        self.data.drain(range);
310    }
311
312    /// Serializes the statements in `stmts` and writes the bytes into position `pos`. Returns the
313    /// inserted byte range.
314    pub fn insert(&mut self, pos: usize, stmts: Vec<Statement>) -> Result<Range<usize>> {
315        let data = Vec::with_capacity(stmts.len() * 10);
316        let mut cur = Cursor::new(data);
317
318        for stmt in stmts {
319            Self::encode_statement(stmt, &mut cur)?;
320        }
321
322        let buf = cur.into_inner();
323        let len = buf.len();
324
325        for b in buf.into_iter().rev() {
326            self.data.insert(pos,b);
327        }
328            //        self.data.splice(pos..pos,buf.into_iter());
329        Ok(pos..(pos + len))
330    }
331
332    fn encode_statement<W: Write>(stmt: Statement, data: &mut W) -> Result<()> {
333        use il::Operation::*;
334        use value::Value::*;
335
336        match stmt {
337            // Add: 0b00000---
338            Statement::Expression{ op: Add(Constant(a),Constant(b)), result } => encoding_rule!( 0b00000_000 [c,c] => a, b, result, data ),
339            Statement::Expression{ op: Add(Constant(a),Variable(b)), result } => encoding_rule!( 0b00000_001 [c,v] => a, b, result, data ),
340            Statement::Expression{ op: Add(Constant(a),Undefined), result } => encoding_rule!( 0b00000_010 [c,u] => a, result, data ),
341            Statement::Expression{ op: Add(Variable(a),Constant(b)), result } => encoding_rule!( 0b00000_011 [v,c] => a, b, result, data ),
342            Statement::Expression{ op: Add(Variable(a),Variable(b)), result } => encoding_rule!( 0b00000_100 [v,v] => a, b, result, data ),
343            Statement::Expression{ op: Add(Variable(a),Undefined), result } => encoding_rule!( 0b00000_101 [v,u] => a, result, data ),
344            Statement::Expression{ op: Add(Undefined,Constant(b)), result } => encoding_rule!( 0b00000_110 [u,c] => b, result, data ),
345            Statement::Expression{ op: Add(Undefined,Variable(b)), result } => encoding_rule!( 0b00000_111 [u,v] => b, result, data ),
346            Statement::Expression{ op: Add(Undefined,Undefined), result } => {
347                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
348            }
349
350            // Subtract: 0b00001---
351            Statement::Expression{ op: Subtract(Constant(a),Constant(b)), result } => encoding_rule!( 0b00001_000 [c,c] => a, b, result, data ),
352            Statement::Expression{ op: Subtract(Constant(a),Variable(b)), result } => encoding_rule!( 0b00001_001 [c,v] => a, b, result, data ),
353            Statement::Expression{ op: Subtract(Constant(a),Undefined), result } => encoding_rule!( 0b00001_010 [c,u] => a, result, data ),
354            Statement::Expression{ op: Subtract(Variable(a),Constant(b)), result } => encoding_rule!( 0b00001_011 [v,c] => a, b, result, data ),
355            Statement::Expression{ op: Subtract(Variable(a),Variable(b)), result } => encoding_rule!( 0b00001_100 [v,v] => a, b, result, data ),
356            Statement::Expression{ op: Subtract(Variable(a),Undefined), result } => encoding_rule!( 0b00001_101 [v,u] => a, result, data ),
357            Statement::Expression{ op: Subtract(Undefined,Constant(b)), result } => encoding_rule!( 0b00001_110 [u,c] => b, result, data ),
358            Statement::Expression{ op: Subtract(Undefined,Variable(b)), result } => encoding_rule!( 0b00001_111 [u,v] => b, result, data ),
359            Statement::Expression{ op: Subtract(Undefined,Undefined), result } => {
360                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
361            }
362
363            // Multiply: 0b00010---
364            Statement::Expression{ op: Multiply(Constant(a),Constant(b)), result } => encoding_rule!( 0b00010_000 [c,c] => a, b, result, data ),
365            Statement::Expression{ op: Multiply(Constant(a),Variable(b)), result } => encoding_rule!( 0b00010_001 [c,v] => a, b, result, data ),
366            Statement::Expression{ op: Multiply(Constant(a),Undefined), result } => encoding_rule!( 0b00010_010 [c,u] => a, result, data ),
367            Statement::Expression{ op: Multiply(Variable(a),Constant(b)), result } => encoding_rule!( 0b00010_011 [v,c] => a, b, result, data ),
368            Statement::Expression{ op: Multiply(Variable(a),Variable(b)), result } => encoding_rule!( 0b00010_100 [v,v] => a, b, result, data ),
369            Statement::Expression{ op: Multiply(Variable(a),Undefined), result } => encoding_rule!( 0b00010_101 [v,u] => a, result, data ),
370            Statement::Expression{ op: Multiply(Undefined,Constant(b)), result } => encoding_rule!( 0b00010_110 [u,c] => b, result, data ),
371            Statement::Expression{ op: Multiply(Undefined,Variable(b)), result } => encoding_rule!( 0b00010_111 [u,v] => b, result, data ),
372            Statement::Expression{ op: Multiply(Undefined,Undefined), result } => {
373                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
374            }
375
376            // DivideUnsigned: 0b00011---
377            Statement::Expression{ op: DivideUnsigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b00011_000 [c,c] => a, b, result, data ),
378            Statement::Expression{ op: DivideUnsigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b00011_001 [c,v] => a, b, result, data ),
379            Statement::Expression{ op: DivideUnsigned(Constant(a),Undefined), result } => encoding_rule!( 0b00011_010 [c,u] => a, result, data ),
380            Statement::Expression{ op: DivideUnsigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b00011_011 [v,c] => a, b, result, data ),
381            Statement::Expression{ op: DivideUnsigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b00011_100 [v,v] => a, b, result, data ),
382            Statement::Expression{ op: DivideUnsigned(Variable(a),Undefined), result } => encoding_rule!( 0b00011_101 [v,u] => a, result, data ),
383            Statement::Expression{ op: DivideUnsigned(Undefined,Constant(b)), result } => encoding_rule!( 0b00011_110 [u,c] => b, result, data ),
384            Statement::Expression{ op: DivideUnsigned(Undefined,Variable(b)), result } => encoding_rule!( 0b00011_111 [u,v] => b, result, data ),
385            Statement::Expression{ op: DivideUnsigned(Undefined,Undefined), result } => {
386                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
387            }
388
389            // DivideSigned: 0b00100---
390            Statement::Expression{ op: DivideSigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b00100_000 [c,c] => a, b, result, data ),
391            Statement::Expression{ op: DivideSigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b00100_001 [c,v] => a, b, result, data ),
392            Statement::Expression{ op: DivideSigned(Constant(a),Undefined), result } => encoding_rule!( 0b00100_010 [c,u] => a, result, data ),
393            Statement::Expression{ op: DivideSigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b00100_011 [v,c] => a, b, result, data ),
394            Statement::Expression{ op: DivideSigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b00100_100 [v,v] => a, b, result, data ),
395            Statement::Expression{ op: DivideSigned(Variable(a),Undefined), result } => encoding_rule!( 0b00100_101 [v,u] => a, result, data ),
396            Statement::Expression{ op: DivideSigned(Undefined,Constant(b)), result } => encoding_rule!( 0b00100_110 [u,c] => b, result, data ),
397            Statement::Expression{ op: DivideSigned(Undefined,Variable(b)), result } => encoding_rule!( 0b00100_111 [u,v] => b, result, data ),
398            Statement::Expression{ op: DivideSigned(Undefined,Undefined), result } => {
399                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
400            }
401
402            // ShiftLeft: 0b00101---
403            Statement::Expression{ op: ShiftLeft(Constant(a),Constant(b)), result } => encoding_rule!( 0b00101_000 [c,c] => a, b, result, data ),
404            Statement::Expression{ op: ShiftLeft(Constant(a),Variable(b)), result } => encoding_rule!( 0b00101_001 [c,v] => a, b, result, data ),
405            Statement::Expression{ op: ShiftLeft(Constant(a),Undefined), result } => encoding_rule!( 0b00101_010 [c,u] => a, result, data ),
406            Statement::Expression{ op: ShiftLeft(Variable(a),Constant(b)), result } => encoding_rule!( 0b00101_011 [v,c] => a, b, result, data ),
407            Statement::Expression{ op: ShiftLeft(Variable(a),Variable(b)), result } => encoding_rule!( 0b00101_100 [v,v] => a, b, result, data ),
408            Statement::Expression{ op: ShiftLeft(Variable(a),Undefined), result } => encoding_rule!( 0b00101_101 [v,u] => a, result, data ),
409            Statement::Expression{ op: ShiftLeft(Undefined,Constant(b)), result } => encoding_rule!( 0b00101_110 [u,c] => b, result, data ),
410            Statement::Expression{ op: ShiftLeft(Undefined,Variable(b)), result } => encoding_rule!( 0b00101_111 [u,v] => b, result, data ),
411            Statement::Expression{ op: ShiftLeft(Undefined,Undefined), result } => {
412                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
413            }
414
415            // ShiftRightUnsigned: 0b00110---
416            Statement::Expression{ op: ShiftRightUnsigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b00110_000 [c,c] => a, b, result, data ),
417            Statement::Expression{ op: ShiftRightUnsigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b00110_001 [c,v] => a, b, result, data ),
418            Statement::Expression{ op: ShiftRightUnsigned(Constant(a),Undefined), result } => encoding_rule!( 0b00110_010 [c,u] => a, result, data ),
419            Statement::Expression{ op: ShiftRightUnsigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b00110_011 [v,c] => a, b, result, data ),
420            Statement::Expression{ op: ShiftRightUnsigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b00110_100 [v,v] => a, b, result, data ),
421            Statement::Expression{ op: ShiftRightUnsigned(Variable(a),Undefined), result } => encoding_rule!( 0b00110_101 [v,u] => a, result, data ),
422            Statement::Expression{ op: ShiftRightUnsigned(Undefined,Constant(b)), result } => encoding_rule!( 0b00110_110 [u,c] => b, result, data ),
423            Statement::Expression{ op: ShiftRightUnsigned(Undefined,Variable(b)), result } => encoding_rule!( 0b00110_111 [u,v] => b, result, data ),
424            Statement::Expression{ op: ShiftRightUnsigned(Undefined,Undefined), result } => {
425                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
426            }
427
428            // ShiftRightSigned: 0b00111---
429            Statement::Expression{ op: ShiftRightSigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b00111_000 [c,c] => a, b, result, data ),
430            Statement::Expression{ op: ShiftRightSigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b00111_001 [c,v] => a, b, result, data ),
431            Statement::Expression{ op: ShiftRightSigned(Constant(a),Undefined), result } => encoding_rule!( 0b00111_010 [c,u] => a, result, data ),
432            Statement::Expression{ op: ShiftRightSigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b00111_011 [v,c] => a, b, result, data ),
433            Statement::Expression{ op: ShiftRightSigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b00111_100 [v,v] => a, b, result, data ),
434            Statement::Expression{ op: ShiftRightSigned(Variable(a),Undefined), result } => encoding_rule!( 0b00111_101 [v,u] => a, result, data ),
435            Statement::Expression{ op: ShiftRightSigned(Undefined,Constant(b)), result } => encoding_rule!( 0b00111_110 [u,c] => b, result, data ),
436            Statement::Expression{ op: ShiftRightSigned(Undefined,Variable(b)), result } => encoding_rule!( 0b00111_111 [u,v] => b, result, data ),
437            Statement::Expression{ op: ShiftRightSigned(Undefined,Undefined), result } => {
438                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
439            }
440
441            // Modulo: 0b01000---
442            Statement::Expression{ op: Modulo(Constant(a),Constant(b)), result } => encoding_rule!( 0b01000_000 [c,c] => a, b, result, data ),
443            Statement::Expression{ op: Modulo(Constant(a),Variable(b)), result } => encoding_rule!( 0b01000_001 [c,v] => a, b, result, data ),
444            Statement::Expression{ op: Modulo(Constant(a),Undefined), result } => encoding_rule!( 0b01000_010 [c,u] => a, result, data ),
445            Statement::Expression{ op: Modulo(Variable(a),Constant(b)), result } => encoding_rule!( 0b01000_011 [v,c] => a, b, result, data ),
446            Statement::Expression{ op: Modulo(Variable(a),Variable(b)), result } => encoding_rule!( 0b01000_100 [v,v] => a, b, result, data ),
447            Statement::Expression{ op: Modulo(Variable(a),Undefined), result } => encoding_rule!( 0b01000_101 [v,u] => a, result, data ),
448            Statement::Expression{ op: Modulo(Undefined,Constant(b)), result } => encoding_rule!( 0b01000_110 [u,c] => b, result, data ),
449            Statement::Expression{ op: Modulo(Undefined,Variable(b)), result } => encoding_rule!( 0b01000_111 [u,v] => b, result, data ),
450            Statement::Expression{ op: Modulo(Undefined,Undefined), result } => {
451                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
452            }
453
454            // And: 0b01001---
455            Statement::Expression{ op: And(Constant(a),Constant(b)), result } => encoding_rule!( 0b01001_000 [c,c] => a, b, result, data ),
456            Statement::Expression{ op: And(Constant(a),Variable(b)), result } => encoding_rule!( 0b01001_001 [c,v] => a, b, result, data ),
457            Statement::Expression{ op: And(Constant(a),Undefined), result } => encoding_rule!( 0b01001_010 [c,u] => a, result, data ),
458            Statement::Expression{ op: And(Variable(a),Constant(b)), result } => encoding_rule!( 0b01001_011 [v,c] => a, b, result, data ),
459            Statement::Expression{ op: And(Variable(a),Variable(b)), result } => encoding_rule!( 0b01001_100 [v,v] => a, b, result, data ),
460            Statement::Expression{ op: And(Variable(a),Undefined), result } => encoding_rule!( 0b01001_101 [v,u] => a, result, data ),
461            Statement::Expression{ op: And(Undefined,Constant(b)), result } => encoding_rule!( 0b01001_110 [u,c] => b, result, data ),
462            Statement::Expression{ op: And(Undefined,Variable(b)), result } => encoding_rule!( 0b01001_111 [u,v] => b, result, data ),
463            Statement::Expression{ op: And(Undefined,Undefined), result } => {
464                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
465            }
466
467            // InclusiveOr: 0b01010---
468            Statement::Expression{ op: InclusiveOr(Constant(a),Constant(b)), result } => encoding_rule!( 0b01010_000 [c,c] => a, b, result, data ),
469            Statement::Expression{ op: InclusiveOr(Constant(a),Variable(b)), result } => encoding_rule!( 0b01010_001 [c,v] => a, b, result, data ),
470            Statement::Expression{ op: InclusiveOr(Constant(a),Undefined), result } => encoding_rule!( 0b01010_010 [c,u] => a, result, data ),
471            Statement::Expression{ op: InclusiveOr(Variable(a),Constant(b)), result } => encoding_rule!( 0b01010_011 [v,c] => a, b, result, data ),
472            Statement::Expression{ op: InclusiveOr(Variable(a),Variable(b)), result } => encoding_rule!( 0b01010_100 [v,v] => a, b, result, data ),
473            Statement::Expression{ op: InclusiveOr(Variable(a),Undefined), result } => encoding_rule!( 0b01010_101 [v,u] => a, result, data ),
474            Statement::Expression{ op: InclusiveOr(Undefined,Constant(b)), result } => encoding_rule!( 0b01010_110 [u,c] => b, result, data ),
475            Statement::Expression{ op: InclusiveOr(Undefined,Variable(b)), result } => encoding_rule!( 0b01010_111 [u,v] => b, result, data ),
476            Statement::Expression{ op: InclusiveOr(Undefined,Undefined), result } => {
477                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
478            }
479
480            // ExclusiveOr: 0b01011---
481            Statement::Expression{ op: ExclusiveOr(Constant(a),Constant(b)), result } => encoding_rule!( 0b01011_000 [c,c] => a, b, result, data ),
482            Statement::Expression{ op: ExclusiveOr(Constant(a),Variable(b)), result } => encoding_rule!( 0b01011_001 [c,v] => a, b, result, data ),
483            Statement::Expression{ op: ExclusiveOr(Constant(a),Undefined), result } => encoding_rule!( 0b01011_010 [c,u] => a, result, data ),
484            Statement::Expression{ op: ExclusiveOr(Variable(a),Constant(b)), result } => encoding_rule!( 0b01011_011 [v,c] => a, b, result, data ),
485            Statement::Expression{ op: ExclusiveOr(Variable(a),Variable(b)), result } => encoding_rule!( 0b01011_100 [v,v] => a, b, result, data ),
486            Statement::Expression{ op: ExclusiveOr(Variable(a),Undefined), result } => encoding_rule!( 0b01011_101 [v,u] => a, result, data ),
487            Statement::Expression{ op: ExclusiveOr(Undefined,Constant(b)), result } => encoding_rule!( 0b01011_110 [u,c] => b, result, data ),
488            Statement::Expression{ op: ExclusiveOr(Undefined,Variable(b)), result } => encoding_rule!( 0b01011_111 [u,v] => b, result, data ),
489            Statement::Expression{ op: ExclusiveOr(Undefined,Undefined), result } => {
490                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
491            }
492
493            // Equal: 0b01100---
494            Statement::Expression{ op: Equal(Constant(a),Constant(b)), result } => encoding_rule!( 0b01100_000 [c,c] => a, b, result, data ),
495            Statement::Expression{ op: Equal(Constant(a),Variable(b)), result } => encoding_rule!( 0b01100_001 [c,v] => a, b, result, data ),
496            Statement::Expression{ op: Equal(Constant(a),Undefined), result } => encoding_rule!( 0b01100_010 [c,u] => a, result, data ),
497            Statement::Expression{ op: Equal(Variable(a),Constant(b)), result } => encoding_rule!( 0b01100_011 [v,c] => a, b, result, data ),
498            Statement::Expression{ op: Equal(Variable(a),Variable(b)), result } => encoding_rule!( 0b01100_100 [v,v] => a, b, result, data ),
499            Statement::Expression{ op: Equal(Variable(a),Undefined), result } => encoding_rule!( 0b01100_101 [v,u] => a, result, data ),
500            Statement::Expression{ op: Equal(Undefined,Constant(b)), result } => encoding_rule!( 0b01100_110 [u,c] => b, result, data ),
501            Statement::Expression{ op: Equal(Undefined,Variable(b)), result } => encoding_rule!( 0b01100_111 [u,v] => b, result, data ),
502            Statement::Expression{ op: Equal(Undefined,Undefined), result } => {
503                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
504            }
505
506            // LessOrEqualUnsigned: 0b01101---
507            Statement::Expression{ op: LessOrEqualUnsigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b01101_000 [c,c] => a, b, result, data ),
508            Statement::Expression{ op: LessOrEqualUnsigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b01101_001 [c,v] => a, b, result, data ),
509            Statement::Expression{ op: LessOrEqualUnsigned(Constant(a),Undefined), result } => encoding_rule!( 0b01101_010 [c,u] => a, result, data ),
510            Statement::Expression{ op: LessOrEqualUnsigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b01101_011 [v,c] => a, b, result, data ),
511            Statement::Expression{ op: LessOrEqualUnsigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b01101_100 [v,v] => a, b, result, data ),
512            Statement::Expression{ op: LessOrEqualUnsigned(Variable(a),Undefined), result } => encoding_rule!( 0b01101_101 [v,u] => a, result, data ),
513            Statement::Expression{ op: LessOrEqualUnsigned(Undefined,Constant(b)), result } => encoding_rule!( 0b01101_110 [u,c] => b, result, data ),
514            Statement::Expression{ op: LessOrEqualUnsigned(Undefined,Variable(b)), result } => encoding_rule!( 0b01101_111 [u,v] => b, result, data ),
515            Statement::Expression{ op: LessOrEqualUnsigned(Undefined,Undefined), result } => {
516                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
517            }
518
519            // LessOrEqualSigned: 0b01110---
520            Statement::Expression{ op: LessOrEqualSigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b01110_000 [c,c] => a, b, result, data ),
521            Statement::Expression{ op: LessOrEqualSigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b01110_001 [c,v] => a, b, result, data ),
522            Statement::Expression{ op: LessOrEqualSigned(Constant(a),Undefined), result } => encoding_rule!( 0b01110_010 [c,u] => a, result, data ),
523            Statement::Expression{ op: LessOrEqualSigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b01110_011 [v,c] => a, b, result, data ),
524            Statement::Expression{ op: LessOrEqualSigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b01110_100 [v,v] => a, b, result, data ),
525            Statement::Expression{ op: LessOrEqualSigned(Variable(a),Undefined), result } => encoding_rule!( 0b01110_101 [v,u] => a, result, data ),
526            Statement::Expression{ op: LessOrEqualSigned(Undefined,Constant(b)), result } => encoding_rule!( 0b01110_110 [u,c] => b, result, data ),
527            Statement::Expression{ op: LessOrEqualSigned(Undefined,Variable(b)), result } => encoding_rule!( 0b01110_111 [u,v] => b, result, data ),
528            Statement::Expression{ op: LessOrEqualSigned(Undefined,Undefined), result } => {
529                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
530            }
531
532            // LessUnsigned: 0b01111---
533            Statement::Expression{ op: LessUnsigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b01111_000 [c,c] => a, b, result, data ),
534            Statement::Expression{ op: LessUnsigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b01111_001 [c,v] => a, b, result, data ),
535            Statement::Expression{ op: LessUnsigned(Constant(a),Undefined), result } => encoding_rule!( 0b01111_010 [c,u] => a, result, data ),
536            Statement::Expression{ op: LessUnsigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b01111_011 [v,c] => a, b, result, data ),
537            Statement::Expression{ op: LessUnsigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b01111_100 [v,v] => a, b, result, data ),
538            Statement::Expression{ op: LessUnsigned(Variable(a),Undefined), result } => encoding_rule!( 0b01111_101 [v,u] => a, result, data ),
539            Statement::Expression{ op: LessUnsigned(Undefined,Constant(b)), result } => encoding_rule!( 0b01111_110 [u,c] => b, result, data ),
540            Statement::Expression{ op: LessUnsigned(Undefined,Variable(b)), result } => encoding_rule!( 0b01111_111 [u,v] => b, result, data ),
541            Statement::Expression{ op: LessUnsigned(Undefined,Undefined), result } => {
542                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
543            }
544
545            // LessSigned: 0b10000---
546            Statement::Expression{ op: LessSigned(Constant(a),Constant(b)), result } => encoding_rule!( 0b10000_000 [c,c] => a, b, result, data ),
547            Statement::Expression{ op: LessSigned(Constant(a),Variable(b)), result } => encoding_rule!( 0b10000_001 [c,v] => a, b, result, data ),
548            Statement::Expression{ op: LessSigned(Constant(a),Undefined), result } => encoding_rule!( 0b10000_010 [c,u] => a, result, data ),
549            Statement::Expression{ op: LessSigned(Variable(a),Constant(b)), result } => encoding_rule!( 0b10000_011 [v,c] => a, b, result, data ),
550            Statement::Expression{ op: LessSigned(Variable(a),Variable(b)), result } => encoding_rule!( 0b10000_100 [v,v] => a, b, result, data ),
551            Statement::Expression{ op: LessSigned(Variable(a),Undefined), result } => encoding_rule!( 0b10000_101 [v,u] => a, result, data ),
552            Statement::Expression{ op: LessSigned(Undefined,Constant(b)), result } => encoding_rule!( 0b10000_110 [u,c] => b, result, data ),
553            Statement::Expression{ op: LessSigned(Undefined,Variable(b)), result } => encoding_rule!( 0b10000_111 [u,v] => b, result, data ),
554            Statement::Expression{ op: LessSigned(Undefined,Undefined), result } => {
555                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
556            }
557
558            // ZeroExtend: 0b1000100- <size, leb128> <a>
559            Statement::Expression{ op: ZeroExtend(sz,Constant(a)), result } => {
560                data.write(&[0b10001000])?;
561                leb128::write::unsigned(data,sz as u64)?;
562                Self::encode_constant(a,data)?;
563                Self::encode_variable(result,data)?;
564            }
565            Statement::Expression{ op: ZeroExtend(sz,Variable(a)), result } => {
566                data.write(&[0b10001001])?;
567                leb128::write::unsigned(data,sz as u64)?;
568                Self::encode_variable(a,data)?;
569                Self::encode_variable(result,data)?;
570            }
571            Statement::Expression{ op: ZeroExtend(_,Undefined), result } => {
572                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
573            }
574
575            // SignExtend: 0b1000101- <size, leb128> <a>
576            Statement::Expression{ op: SignExtend(sz,Constant(a)), result } => {
577                data.write(&[0b10001010])?;
578                leb128::write::unsigned(data,sz as u64)?;
579                Self::encode_constant(a,data)?;
580                Self::encode_variable(result,data)?;
581            }
582            Statement::Expression{ op: SignExtend(sz,Variable(a)), result } => {
583                data.write(&[0b10001011])?;
584                leb128::write::unsigned(data,sz as u64)?;
585                Self::encode_variable(a,data)?;
586                Self::encode_variable(result,data)?;
587            }
588            Statement::Expression{ op: SignExtend(_,Undefined), result } => {
589                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
590            }
591
592            // Move: 0b1000110- <a>
593            Statement::Expression{ op: Move(Constant(a)), result } => {
594                data.write(&[0b10001100])?;
595                Self::encode_constant(a,data)?;
596                Self::encode_variable(result,data)?;
597            }
598            Statement::Expression{ op: Move(Variable(a)), result } => {
599                data.write(&[0b10001101])?;
600                Self::encode_variable(a,data)?;
601                Self::encode_variable(result,data)?;
602            }
603
604            // Move Undefined: 0b10001110
605            Statement::Expression{ op: Move(Undefined), result } => {
606                data.write(&[0b10001110])?;
607                Self::encode_variable(result,data)?;
608            }
609
610            // Initialize: 0b10001111 <name, leb128> <size, leb128>
611            Statement::Expression{ op: Initialize(name,sz), result } => {
612                data.write(&[0b10001111])?;
613                leb128::write::unsigned(data,name.index() as u64)?;
614                leb128::write::unsigned(data,sz as u64)?;
615                Self::encode_variable(result,data)?;
616            }
617
618            // Select: 0b100100-- <off, leb128> <sz, leb128> <a>
619            Statement::Expression{ op: Select(off,sz,Constant(src)), result } => {
620                data.write(&[0b10010000])?;
621                leb128::write::unsigned(data,off as u64)?;
622                leb128::write::unsigned(data,sz as u64)?;
623                Self::encode_constant(src,data)?;
624                Self::encode_variable(result,data)?;
625            }
626            Statement::Expression{ op: Select(off,sz,Variable(src)), result } => {
627                data.write(&[0b10010001])?;
628                leb128::write::unsigned(data,off as u64)?;
629                leb128::write::unsigned(data,sz as u64)?;
630                Self::encode_variable(src,data)?;
631                Self::encode_variable(result,data)?;
632            }
633            Statement::Expression{ op: Select(_,_,Undefined), result } => {
634                Self::encode_statement(Statement::Expression{ op: Move(Undefined), result: result },data)?;
635            }
636
637            // Load: 0b100101e- <region, leb128> <size, leb128> <a>
638            Statement::Expression{ op: Load(segment,Endianess::Little,bytes,Constant(addr)), result } => {
639                data.write(&[0b10010100])?;
640                Self::encode_segment(segment,data)?;
641                leb128::write::unsigned(data,bytes as u64)?;
642                Self::encode_constant(addr,data)?;
643                Self::encode_variable(result,data)?;
644            }
645            Statement::Expression{ op: Load(segment,Endianess::Big,bytes,Constant(addr)), result } => {
646                data.write(&[0b10010110])?;
647                Self::encode_segment(segment,data)?;
648                leb128::write::unsigned(data,bytes as u64)?;
649                Self::encode_constant(addr,data)?;
650                Self::encode_variable(result,data)?;
651            }
652            Statement::Expression{ op: Load(segment,Endianess::Little,bytes,Variable(addr)), result } => {
653                data.write(&[0b10010101])?;
654                Self::encode_segment(segment,data)?;
655                leb128::write::unsigned(data,bytes as u64)?;
656                Self::encode_variable(addr,data)?;
657                Self::encode_variable(result,data)?;
658            }
659            Statement::Expression{ op: Load(segment,Endianess::Big,bytes,Variable(addr)), result } => {
660                data.write(&[0b10010111])?;
661                Self::encode_segment(segment,data)?;
662                leb128::write::unsigned(data,bytes as u64)?;
663                Self::encode_variable(addr,data)?;
664                Self::encode_variable(result,data)?;
665            }
666
667            // Phi2: 0b10011000 <a> <b>
668            Statement::Expression{ op: Phi(Variable(a),Variable(b),Undefined), result } |
669            Statement::Expression{ op: Phi(Variable(a),Undefined,Variable(b)), result } |
670            Statement::Expression{ op: Phi(Undefined,Variable(a),Variable(b)), result } => {
671                data.write(&[0b10011000])?;
672                Self::encode_variable(a,data)?;
673                Self::encode_variable(b,data)?;
674                Self::encode_variable(result,data)?;
675            }
676
677            // Phi3: 0b10011001 <a> <b> <c>
678            Statement::Expression{ op: Phi(Variable(a),Variable(b),Variable(c)), result } => {
679                data.write(&[0b10011001])?;
680                Self::encode_variable(a,data)?;
681                Self::encode_variable(b,data)?;
682                Self::encode_variable(c,data)?;
683                Self::encode_variable(result,data)?;
684            }
685
686            // Call: 0b10011010 <stub, leb128>
687            Statement::Flow{ op: FlowOperation::ExternalCall{ external: name } } => {
688                data.write(&[0b10011010])?;
689                leb128::write::unsigned(data,name.index() as u64)?;
690            }
691
692            // Call: 0b10011011 <uuid, leb128>
693            Statement::Flow{ op: FlowOperation::Call{ function: uuid } } => {
694                data.write(&[0b10011011])?;
695                Self::encode_uuid(uuid,data)?;
696            }
697
698            // IndirectCall: 0b1001110- <a>
699            Statement::Flow{ op: FlowOperation::IndirectCall{ target: tgt } } => {
700                data.write(&[0b10011101])?;
701                Self::encode_variable(tgt,data)?;
702            }
703
704            // Phi0: 0b10011111
705            Statement::Expression{ op: Phi(Undefined,Undefined,Undefined), result } => {
706                data.write(&[0b10011111])?;
707                Self::encode_variable(result,data)?;
708            }
709
710            // Store: 0b1010e--- <region, leb128> <size, leb128> <addr> <val>
711            Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Constant(addr), value: Constant(value) }, result } => {
712                data.write(&[0b10100000 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
713                Self::encode_segment(segment,data)?;
714                leb128::write::unsigned(data,bytes as u64)?;
715                Self::encode_constant(addr,data)?;
716                Self::encode_constant(value,data)?;
717                Self::encode_segment(result,data)?;
718            }
719            Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Constant(addr), value: Variable(value) }, result } => {
720                data.write(&[0b10100001 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
721                Self::encode_segment(segment,data)?;
722                leb128::write::unsigned(data,bytes as u64)?;
723                Self::encode_constant(addr,data)?;
724                Self::encode_variable(value,data)?;
725                Self::encode_segment(result,data)?;
726            }
727            Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Constant(addr), value: Undefined }, result } => {
728                data.write(&[0b10100010 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
729                Self::encode_segment(segment,data)?;
730                leb128::write::unsigned(data,bytes as u64)?;
731                Self::encode_constant(addr,data)?;
732                Self::encode_segment(result,data)?;
733            }
734            Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Variable(addr), value: Constant(value) }, result } => {
735                data.write(&[0b10100011 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
736                Self::encode_segment(segment,data)?;
737                leb128::write::unsigned(data,bytes as u64)?;
738                Self::encode_variable(addr,data)?;
739                Self::encode_constant(value,data)?;
740                Self::encode_segment(result,data)?;
741            }
742            Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Variable(addr), value: Variable(value) }, result } => {
743                data.write(&[0b10100100 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
744                Self::encode_segment(segment,data)?;
745                leb128::write::unsigned(data,bytes as u64)?;
746                Self::encode_variable(addr,data)?;
747                Self::encode_variable(value,data)?;
748                Self::encode_segment(result,data)?;
749            }
750            Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Variable(addr), value: Undefined }, result } => {
751                data.write(&[0b10100101 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
752                Self::encode_segment(segment,data)?;
753                leb128::write::unsigned(data,bytes as u64)?;
754                Self::encode_variable(addr,data)?;
755                Self::encode_segment(result,data)?;
756            }
757            Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Undefined, value: Constant(value) }, result } => {
758                data.write(&[0b10100110 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
759                Self::encode_segment(segment,data)?;
760                leb128::write::unsigned(data,bytes as u64)?;
761                Self::encode_constant(value,data)?;
762                Self::encode_segment(result,data)?;
763            }
764            Statement::Memory{ op: MemoryOperation::Store{ segment, bytes, endianess, address: Undefined, value: Variable(value) }, result } => {
765                data.write(&[0b10100111 | if endianess == Endianess::Little { 0 } else { 0b1000 }])?;
766                Self::encode_segment(segment,data)?;
767                leb128::write::unsigned(data,bytes as u64)?;
768                Self::encode_variable(value,data)?;
769                Self::encode_segment(result,data)?;
770            }
771            Statement::Memory{ op: MemoryOperation::Store{ address: Undefined, value: Undefined,.. },.. } => { /* NOP */ }
772
773            // Return: 0b10110000
774            Statement::Flow{ op: FlowOperation::Return } => {
775                data.write(&[0b10110000])?;
776            }
777
778            // Load Undefined: 0b1011 001e <region, leb128> <size, leb128>
779            Statement::Expression{ op: Load(segment,endianess,bytes,Undefined), result } => {
780                data.write(&[0b1011_0010 | if endianess == Endianess::Little { 0 } else { 0b1 }])?;
781                Self::encode_segment(segment,data)?;
782                leb128::write::unsigned(data,bytes as u64)?;
783                Self::encode_variable(result,data)?;
784            }
785
786            // Phi1: 0b10110100 <a>
787            Statement::Expression{ op: Phi(Variable(a),Undefined,Undefined), result } => {
788                data.write(&[0b10110100])?;
789                Self::encode_variable(a,data)?;
790                Self::encode_variable(result,data)?;
791            }
792
793            Statement::Expression{ op: Phi(_,_,_),.. } => {
794                return Err(format!("Internal error: invalid Phi expression {:?}",stmt).into());
795            }
796
797            // MemoryPhi0: 0b10110101
798            Statement::Memory{ op: MemoryOperation::MemoryPhi(None,None,None), result } => {
799                data.write(&[0b10110101])?;
800                Self::encode_segment(result,data)?;
801                data.write(&[0,0,0])?;
802            }
803
804            // MemoryPhi1: 0b10110110 <a>
805            Statement::Memory{ op: MemoryOperation::MemoryPhi(Some(a),None,None), result } |
806            Statement::Memory{ op: MemoryOperation::MemoryPhi(None,Some(a),None), result } |
807            Statement::Memory{ op: MemoryOperation::MemoryPhi(None,None,Some(a)), result } => {
808                data.write(&[0b10110110])?;
809                Self::encode_segment(a,data)?;
810                Self::encode_segment(result,data)?;
811                data.write(&[0,0])?;
812            }
813
814            // MemoryPhi2: 0b10110111 <a> <b>
815            Statement::Memory{ op: MemoryOperation::MemoryPhi(Some(a),Some(b),None), result } |
816            Statement::Memory{ op: MemoryOperation::MemoryPhi(Some(a),None,Some(b)), result } |
817            Statement::Memory{ op: MemoryOperation::MemoryPhi(None,Some(a),Some(b)), result } => {
818                data.write(&[0b10110111])?;
819                Self::encode_segment(a,data)?;
820                Self::encode_segment(b,data)?;
821                Self::encode_segment(result,data)?;
822                data.write(&[0])?;
823            }
824
825            // MemoryPhi3: 0b10111000 <a> <b> <c>
826            Statement::Memory{ op: MemoryOperation::MemoryPhi(Some(a),Some(b),Some(c)), result } => {
827                data.write(&[0b10111000])?;
828                Self::encode_segment(a,data)?;
829                Self::encode_segment(b,data)?;
830                Self::encode_segment(c,data)?;
831                Self::encode_segment(result,data)?;
832            }
833
834            // Allocate: 0b10111001 <name, leb128>
835            Statement::Memory{ op: MemoryOperation::Allocate{ base }, result } => {
836                data.write(&[0b10111001])?;
837                leb128::write::unsigned(data,base.index() as u64)?;
838                Self::encode_segment(result,data)?;
839            }
840
841            // Assume 11000--- <constr> <a>
842            Statement::Expression{ op: Assume(constr,a), result } => {
843                let code = match (&constr,&a) {
844                    (&Constraint::Empty{ .. },&Value::Variable(..)) => 0b000,
845                    (&Constraint::Unsigned{ .. },&Value::Variable(..)) => 0b001,
846                    (&Constraint::Signed{ .. },&Value::Variable(..)) => 0b010,
847                    (&Constraint::Full{ .. },&Value::Variable(..)) => 0b011,
848                    (&Constraint::Empty{ .. },_) => 0b100,
849                    (&Constraint::Unsigned{ .. },_) => 0b101,
850                    (&Constraint::Signed{ .. },_) => 0b110,
851                    (&Constraint::Full{ .. },_) => 0b111,
852                };
853
854                data.write(&[0b1100_0000 | code])?;
855                Self::encode_constraint(constr,data)?;
856                if let Value::Variable(var) = a {
857                    Self::encode_variable(var,data)?;
858                }
859                Self::encode_variable(result,data)?;
860            }
861        }
862
863        Ok(())
864    }
865
866    // const: <len, pow2><leb128 value>
867    fn encode_constant<W: Write>(c: Constant, data: &mut W) -> Result<()> {
868        let Constant{ value, bits } = c;
869        leb128::write::unsigned(data,bits as u64)?;
870        leb128::write::unsigned(data,value)?;
871        Ok(())
872    }
873
874    // var: <name, leb128 str idx>, <subscript, leb128 + 1>, <len, pow2>
875    fn encode_variable<W: Write>(c: Variable, data: &mut W) -> Result<()> {
876        let Variable{ name, bits } = c;
877        leb128::write::unsigned(data,name.index() as u64)?;
878        leb128::write::unsigned(data,bits as u64)?;
879        Ok(())
880    }
881
882    // seg: <name, leb128 str idx>
883    fn encode_segment<W: Write>(c: Segment, data: &mut W) -> Result<()> {
884        let Segment{ name } = c;
885        leb128::write::unsigned(data,name.index() as u64)?;
886        Ok(())
887    }
888
889    fn encode_constraint<W: Write>(c: Constraint, data: &mut W) -> Result<()> {
890        match c {
891            Constraint::Empty{ bits } => {
892                leb128::write::unsigned(data,bits as u64)?;
893            }
894            Constraint::Unsigned{ from, to, bits } => {
895                leb128::write::unsigned(data,bits as u64)?;
896                leb128::write::unsigned(data,from)?;
897                leb128::write::unsigned(data,to)?;
898            }
899            Constraint::Signed{ from, to, bits } => {
900                leb128::write::unsigned(data,bits as u64)?;
901                leb128::write::signed(data,from)?;
902                leb128::write::signed(data,to)?;
903            }
904            Constraint::Full{ bits } => {
905                leb128::write::unsigned(data,bits as u64)?;
906            }
907        }
908
909        Ok(())
910    }
911
912    fn encode_uuid<W: Write>(uu: UUID, data: &mut W) -> Result<()> {
913        let (sch, hi, lo) = match uu {
914            UUID::Name{ name, scope } => (0, name, scope),
915            UUID::Number{ value1, value2 } => (1, value1, value2),
916            UUID::Derived{ timestamp, origin } => (2, timestamp, origin),
917            UUID::Event{ timestamp, origin } => (3, timestamp, origin),
918        };
919
920        data.write(&[sch])?;
921        leb128::write::unsigned(data,hi)?;
922        leb128::write::unsigned(data,lo)?;
923
924        Ok(())
925    }
926
927    fn decode_statement<R: Read>(&self, data: &mut R) -> Result<Statement> {
928        let mut opcode = [0u8; 1];
929        data.read_exact(&mut opcode)?;
930
931        match opcode[0] {
932            0b00000_000...0b00001_000 => {
933                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
934                let res = self.decode_variable(data)?;
935                let stmt = Statement::Expression{ op: Operation::Add(a,b), result: res };
936
937                Ok(stmt)
938            }
939            0b00001_000...0b00010_000 => {
940                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
941                let res = self.decode_variable(data)?;
942                let stmt = Statement::Expression{ op: Operation::Subtract(a,b), result: res };
943
944                Ok(stmt)
945            }
946            0b00010_000...0b00011_000 => {
947                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
948                let res = self.decode_variable(data)?;
949                let stmt = Statement::Expression{ op: Operation::Multiply(a,b), result: res };
950
951                Ok(stmt)
952            }
953            0b00011_000...0b00100_000 => {
954                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
955                let res = self.decode_variable(data)?;
956                let stmt = Statement::Expression{ op: Operation::DivideUnsigned(a,b), result: res };
957
958                Ok(stmt)
959            }
960            0b00100_000...0b00101_000 => {
961                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
962                let res = self.decode_variable(data)?;
963                let stmt = Statement::Expression{ op: Operation::DivideSigned(a,b), result: res };
964
965                Ok(stmt)
966            }
967            0b00101_000...0b00110_000 => {
968                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
969                let res = self.decode_variable(data)?;
970                let stmt = Statement::Expression{ op: Operation::ShiftLeft(a,b), result: res };
971
972                Ok(stmt)
973            }
974            0b00110_000...0b00111_000 => {
975                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
976                let res = self.decode_variable(data)?;
977                let stmt = Statement::Expression{ op: Operation::ShiftRightUnsigned(a,b), result: res };
978
979                Ok(stmt)
980            }
981            0b00111_000...0b01000_000 => {
982                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
983                let res = self.decode_variable(data)?;
984                let stmt = Statement::Expression{ op: Operation::ShiftRightSigned(a,b), result: res };
985
986                Ok(stmt)
987            }
988            0b01000_000...0b01001_000 => {
989                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
990                let res = self.decode_variable(data)?;
991                let stmt = Statement::Expression{ op: Operation::Modulo(a,b), result: res };
992
993                Ok(stmt)
994            }
995            0b01001_000...0b01010_000 => {
996                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
997                let res = self.decode_variable(data)?;
998                let stmt = Statement::Expression{ op: Operation::And(a,b), result: res };
999
1000                Ok(stmt)
1001            }
1002            0b01010_000...0b01011_000 => {
1003                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1004                let res = self.decode_variable(data)?;
1005                let stmt = Statement::Expression{ op: Operation::InclusiveOr(a,b), result: res };
1006
1007                Ok(stmt)
1008            }
1009            0b01011_000...0b01100_000 => {
1010                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1011                let res = self.decode_variable(data)?;
1012                let stmt = Statement::Expression{ op: Operation::ExclusiveOr(a,b), result: res };
1013
1014                Ok(stmt)
1015            }
1016            0b01100_000...0b01101_000 => {
1017                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1018                let res = self.decode_variable(data)?;
1019                let stmt = Statement::Expression{ op: Operation::Equal(a,b), result: res };
1020
1021                Ok(stmt)
1022            }
1023            0b01101_000...0b01110_000 => {
1024                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1025                let res = self.decode_variable(data)?;
1026                let stmt = Statement::Expression{ op: Operation::LessOrEqualUnsigned(a,b), result: res };
1027
1028                Ok(stmt)
1029            }
1030            0b01110_000...0b01111_000 => {
1031                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1032                let res = self.decode_variable(data)?;
1033                let stmt = Statement::Expression{ op: Operation::LessOrEqualSigned(a,b), result: res };
1034
1035                Ok(stmt)
1036            }
1037            0b01111_000...0b10000_000 => {
1038                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1039                let res = self.decode_variable(data)?;
1040                let stmt = Statement::Expression{ op: Operation::LessUnsigned(a,b), result: res };
1041
1042                Ok(stmt)
1043            }
1044            0b10000_000...0b10000_111 => {
1045                let (a,b) = self.decode_arguments(opcode[0] & 0b111,data)?;
1046                let res = self.decode_variable(data)?;
1047                let stmt = Statement::Expression{ op: Operation::LessSigned(a,b), result: res };
1048
1049                Ok(stmt)
1050            }
1051
1052            // zext  1000 100- <size, leb128> <a>
1053            0b1000_1000 | 0b1000_1001 => {
1054                let sz = leb128::read::unsigned(data)? as usize;
1055                let a = if opcode[0] & 1 == 0 {
1056                    Value::Constant(self.decode_constant(data)?)
1057                } else {
1058                    Value::Variable(self.decode_variable(data)?)
1059                };
1060                let res = self.decode_variable(data)?;
1061                let stmt = Statement::Expression{ op: Operation::ZeroExtend(sz,a), result: res };
1062
1063                Ok(stmt)
1064            }
1065
1066            // sext  1000 101- <size, leb128> <a>
1067            0b1000_1010 | 0b1000_1011 => {
1068                let sz = leb128::read::unsigned(data)? as usize;
1069                let a = if opcode[0] & 1 == 0 {
1070                    Value::Constant(self.decode_constant(data)?)
1071                } else {
1072                    Value::Variable(self.decode_variable(data)?)
1073                };
1074                let res = self.decode_variable(data)?;
1075                let stmt = Statement::Expression{ op: Operation::SignExtend(sz,a), result: res };
1076
1077                Ok(stmt)
1078            }
1079
1080            // mov   1000 110- <a>
1081            0b1000_1100 | 0b1000_1101 => {
1082                let a = if opcode[0] & 1 == 0 {
1083                    Value::Constant(self.decode_constant(data)?)
1084                } else {
1085                    Value::Variable(self.decode_variable(data)?)
1086                };
1087                let res = self.decode_variable(data)?;
1088                let stmt = Statement::Expression{ op: Operation::Move(a), result: res };
1089
1090                Ok(stmt)
1091            }
1092
1093            // movu  1000 1110
1094            0b1000_1110 => {
1095                let res = self.decode_variable(data)?;
1096                let stmt = Statement::Expression{ op: Operation::Move(Value::Undefined), result: res };
1097
1098                Ok(stmt)
1099            }
1100
1101            // init  1000 1111 <name, leb128> <size, leb128>
1102            0b1000_1111 => {
1103                let name = leb128::read::unsigned(data)? as usize;
1104                let sz = leb128::read::unsigned(data)? as usize;
1105                let res = self.decode_variable(data)?;
1106                let stmt = Statement::Expression{
1107                    op: Operation::Initialize(StrRef::new(name),sz),
1108                    result: res
1109                };
1110
1111                Ok(stmt)
1112            }
1113
1114            // sel   1001 00-- <off, leb128> <sz, leb128> <a>
1115            0b1001_0000...0b1001_0011 => {
1116                let off = leb128::read::unsigned(data)? as usize;
1117                let sz = leb128::read::unsigned(data)? as usize;
1118                let val = if opcode[0] & 0b1 == 0 {
1119                    Value::Constant(self.decode_constant(data)?)
1120                } else {
1121                    Value::Variable(self.decode_variable(data)?)
1122                };
1123                let res = self.decode_variable(data)?;
1124                let stmt = Statement::Expression{
1125                    op: Operation::Select(off,sz,val),
1126                    result: res
1127                };
1128
1129                Ok(stmt)
1130            }
1131
1132            // load  1001 01e- <region, leb128> <size, leb128> <a>
1133            0b1001_0100...0b1001_0111 => {
1134                let seg = self.decode_segment(data)?;
1135                let sz = leb128::read::unsigned(data)? as usize;
1136                let val = if opcode[0] & 0b1 == 0 {
1137                    Value::Constant(self.decode_constant(data)?)
1138                } else {
1139                    Value::Variable(self.decode_variable(data)?)
1140                };
1141                let endianess = if opcode[0] & 0b10 == 0 {
1142                    Endianess::Little
1143                } else {
1144                    Endianess::Big
1145                };
1146                let res = self.decode_variable(data)?;
1147                let stmt = Statement::Expression{
1148                    op: Operation::Load(seg,endianess,sz,val),
1149                    result: res
1150                };
1151
1152                Ok(stmt)
1153            }
1154
1155            // phi2  1001 1000 <a, var> <b, var> 0x000000
1156            0b1001_1000 => {
1157                let a = Value::Variable(self.decode_variable(data)?);
1158                let b = Value::Variable(self.decode_variable(data)?);
1159                let res = self.decode_variable(data)?;
1160                let stmt = Statement::Expression{
1161                    op: Operation::Phi(a,b,Value::Undefined),
1162                    result: res
1163                };
1164
1165                Ok(stmt)
1166            }
1167
1168            // phi3  1001 1001 <a, var> <b, var> <c, var>
1169            0b1001_1001 => {
1170                let a = Value::Variable(self.decode_variable(data)?);
1171                let b = Value::Variable(self.decode_variable(data)?);
1172                let c = Value::Variable(self.decode_variable(data)?);
1173                let res = self.decode_variable(data)?;
1174                let stmt = Statement::Expression{
1175                    op: Operation::Phi(a,b,c),
1176                    result: res
1177                };
1178
1179                Ok(stmt)
1180            }
1181
1182            // excall  1001 1010 <stub, leb128>
1183            0b1001_1010 => {
1184                let s = leb128::read::unsigned(data)? as usize;
1185                let stmt = Statement::Flow{
1186                    op: FlowOperation::ExternalCall{
1187                        external: StrRef::new(s)
1188                    }
1189                };
1190
1191                Ok(stmt)
1192            }
1193
1194            // call  1001 1011 <uuid, leb128>
1195            0b1001_1011 => {
1196                let stmt = Statement::Flow{
1197                    op: FlowOperation::Call{
1198                        function: self.decode_uuid(data)?
1199                    }
1200                };
1201
1202                Ok(stmt)
1203            }
1204
1205            // icall 1001 1101 <a>
1206            0b1001_1101 => {
1207                let stmt = Statement::Flow{ op:
1208                    FlowOperation::IndirectCall{
1209                        target: self.decode_variable(data)?
1210                    },
1211                };
1212
1213                Ok(stmt)
1214            }
1215
1216            // phi0  1001 1111
1217            0b1001_1111 => {
1218                let res = self.decode_variable(data)?;
1219                let stmt = Statement::Expression{
1220                    op: Operation::Phi(
1221                        Value::undef(),
1222                        Value::undef(),
1223                        Value::undef()),
1224                    result: res
1225                };
1226
1227                Ok(stmt)
1228            }
1229
1230            // store 1010 e--- <region, leb128> <size, leb128> <addr> <val>
1231            0b1010_0000...0b1010_1111 => {
1232                let seg = self.decode_segment(data)?;
1233                let sz = leb128::read::unsigned(data)? as usize;
1234                let (addr,val) = self.decode_arguments(opcode[0] & 0b111,data)?;
1235                let res = self.decode_segment(data)?;
1236                let endianess = if opcode[0] & 0b1000 == 0 {
1237                    Endianess::Little
1238                } else {
1239                    Endianess::Big
1240                };
1241                let stmt = Statement::Memory{
1242                    op: MemoryOperation::Store{
1243                        segment: seg,
1244                        bytes: sz,
1245                        endianess: endianess,
1246                        address: addr,
1247                        value: val,
1248                    },
1249                    result: res,
1250                };
1251
1252                Ok(stmt)
1253            }
1254
1255            // ret   1011 0000
1256            0b1011_0000 => {
1257                let stmt = Statement::Flow{ op: FlowOperation::Return };
1258
1259                Ok(stmt)
1260            }
1261
1262            // loadu: 0b1011001e <region, leb128> <size, leb128>
1263            0b1011_0010 | 0b1011_0011 => {
1264                let seg = self.decode_segment(data)?;
1265                let sz = leb128::read::unsigned(data)? as usize;
1266                let endianess = if opcode[0] & 1 == 0 {
1267                    Endianess::Little
1268                } else {
1269                    Endianess::Big
1270                };
1271                let res = self.decode_variable(data)?;
1272                let stmt = Statement::Expression{
1273                    op: Operation::Load(seg,endianess,sz,Value::Undefined),
1274                    result: res
1275                };
1276
1277                Ok(stmt)
1278            }
1279
1280            // phi1: 0b10110100 <a>
1281            0b10110100 => {
1282                let a = Value::Variable(self.decode_variable(data)?);
1283                let res = self.decode_variable(data)?;
1284                let stmt = Statement::Expression{
1285                    op: Operation::Phi(a,Value::undef(),Value::undef()),
1286                    result: res
1287                };
1288
1289                Ok(stmt)
1290            }
1291
1292            // mphi0  10110101 3 0x0
1293            0b10110101 => {
1294                let res = self.decode_segment(data)?;
1295                let stmt = Statement::Memory{
1296                    op: MemoryOperation::MemoryPhi(None,None,None),
1297                    result: res
1298                };
1299
1300                data.read(&mut [0;3])?;
1301                Ok(stmt)
1302            }
1303
1304            // mphi1  10110110 <a, seg> 2 0x0
1305            0b10110110 => {
1306                let a = self.decode_segment(data)?;
1307                let res = self.decode_segment(data)?;
1308                let stmt = Statement::Memory{
1309                    op: MemoryOperation::MemoryPhi(Some(a),None,None),
1310                    result: res
1311                };
1312
1313                data.read(&mut [0;2])?;
1314                Ok(stmt)
1315            }
1316
1317            // mphi2  10110111 <a, seg> <b, seg> 0x0
1318            0b10110111 => {
1319                let a = self.decode_segment(data)?;
1320                let b = self.decode_segment(data)?;
1321                let res = self.decode_segment(data)?;
1322                let stmt = Statement::Memory{
1323                    op: MemoryOperation::MemoryPhi(Some(a),Some(b),None),
1324                    result: res
1325                };
1326
1327                data.read(&mut [0;1])?;
1328                Ok(stmt)
1329            }
1330
1331            // mphi3  10111000 <a, seg> <b, seg> <c, seg>
1332            0b10111000 => {
1333                let a = self.decode_segment(data)?;
1334                let b = self.decode_segment(data)?;
1335                let c = self.decode_segment(data)?;
1336                let res = self.decode_segment(data)?;
1337                let stmt = Statement::Memory{
1338                    op: MemoryOperation::MemoryPhi(Some(a),Some(b),Some(c)),
1339                    result: res
1340                };
1341
1342                Ok(stmt)
1343            }
1344
1345            // alloc  10111001 <name, leb128>
1346            0b1011_1001 => {
1347                let name = leb128::read::unsigned(data)? as usize;
1348                let res = self.decode_segment(data)?;
1349                let stmt = Statement::Memory{
1350                    op: MemoryOperation::Allocate{ base: StrRef::new(name) },
1351                    result: res
1352                };
1353
1354                Ok(stmt)
1355            }
1356
1357            // assume 11000--- <constr> <a>
1358            0b1100_0000...0b1100_0111 => {
1359                let constr = self.decode_constraint(opcode[0] & 0b11,data)?;
1360                let a = if opcode[0] & 0b100 == 0 {
1361                    Value::Variable(self.decode_variable(data)?)
1362                } else {
1363                    Value::Undefined
1364                };
1365                let res = self.decode_variable(data)?;
1366                let stmt = Statement::Expression{ op: Operation::Assume(constr,a), result: res };
1367
1368                Ok(stmt)
1369            }
1370
1371            _ => Err(format!("Internal error: invalid bitcode {:b}",opcode[0]).into()),
1372        }
1373    }
1374
1375    //  1\2  c   v   u
1376    //   c|000 001 010
1377    //   v|011 100 101
1378    //   u|110 111 xxx
1379    fn decode_arguments<R: Read>(&self, code: u8, data: &mut R) -> Result<(Value,Value)> {
1380        match code {
1381            0b000 => {
1382                let a = self.decode_constant(data)?;
1383                let b = self.decode_constant(data)?;
1384                Ok((Value::Constant(a),Value::Constant(b)))
1385            }
1386            0b001 => {
1387                let a = self.decode_constant(data)?;
1388                let b = self.decode_variable(data)?;
1389                Ok((Value::Constant(a),Value::Variable(b)))
1390            }
1391            0b010 => {
1392                let a = self.decode_constant(data)?;
1393                Ok((Value::Constant(a),Value::Undefined))
1394            }
1395            0b011 => {
1396                let a = self.decode_variable(data)?;
1397                let b = self.decode_constant(data)?;
1398                Ok((Value::Variable(a),Value::Constant(b)))
1399            }
1400            0b100 => {
1401                let a = self.decode_variable(data)?;
1402                let b = self.decode_variable(data)?;
1403                Ok((Value::Variable(a),Value::Variable(b)))
1404            }
1405            0b101 => {
1406                let a = self.decode_variable(data)?;
1407                Ok((Value::Variable(a),Value::Undefined))
1408            }
1409            0b110 => {
1410                let a = self.decode_constant(data)?;
1411                Ok((Value::Undefined,Value::Constant(a)))
1412            }
1413            0b111 => {
1414                let a = self.decode_variable(data)?;
1415                Ok((Value::Undefined,Value::Variable(a)))
1416            }
1417            _ => Err(format!("internal error: impossible argument code {:b}",code).into())
1418        }
1419    }
1420
1421    fn decode_uuid<R: Read>(&self, data: &mut R) -> Result<UUID> {
1422        let mut buf = [0u8; 1];
1423
1424        data.read_exact(&mut buf)?;
1425        let hi = leb128::read::unsigned(data)?;
1426        let lo = leb128::read::unsigned(data)?;
1427
1428        match buf[0] {
1429            0 => Ok(UUID::Name{ name: hi, scope: lo }),
1430            1 => Ok(UUID::Number{ value1: hi, value2: lo }),
1431            2 => Ok(UUID::Derived{ timestamp: hi, origin: lo }),
1432            3 => Ok(UUID::Event{ timestamp: hi, origin: lo }),
1433            _ => Err("unknown UUID scheme".into()),
1434        }
1435    }
1436
1437    // const: <len, pow2><leb128 value>
1438    fn decode_constant<R: Read>(&self, data: &mut R) -> Result<Constant> {
1439        let bits = leb128::read::unsigned(data)?;
1440        let value = leb128::read::unsigned(data)?;
1441
1442        Ok(Constant{ bits: bits as usize, value: value })
1443    }
1444
1445    // var: <name, leb128 str idx>
1446    fn decode_segment<R: Read>(&self, data: &mut R) -> Result<Segment> {
1447        let name = leb128::read::unsigned(data)?;
1448        let seg = Segment{
1449            name: SegmentRef::new(name as usize),
1450        };
1451
1452        Ok(seg)
1453    }
1454
1455    // seg: <name, leb128 str idx>, <subscript, leb128 + 1>, <len, pow2>
1456    fn decode_variable<R: Read>(&self, data: &mut R) -> Result<Variable> {
1457        let name = leb128::read::unsigned(data)?;
1458        let bits = leb128::read::unsigned(data)?;
1459        let var = Variable{
1460            name: NameRef::new(name as usize),
1461            bits: bits as usize,
1462        };
1463
1464
1465        Ok(var)
1466    }
1467
1468    // |  e  u  s  f
1469    // | 00 01 10 11
1470    fn decode_constraint<R: Read>(&self, code: u8, data: &mut R) -> Result<Constraint> {
1471        let bits = leb128::read::unsigned(data)? as usize;
1472
1473        match code {
1474            0b00 => {
1475                Ok(Constraint::Empty{ bits: bits })
1476            }
1477            0b01 => {
1478                let from = leb128::read::unsigned(data)?;
1479                let to = leb128::read::unsigned(data)?;
1480                let ret = Constraint::Unsigned{
1481                    bits: bits,
1482                    from: from,
1483                    to: to,
1484                };
1485                Ok(ret)
1486            }
1487            0b10 => {
1488                let from = leb128::read::signed(data)?;
1489                let to = leb128::read::signed(data)?;
1490                let ret = Constraint::Signed{
1491                    bits: bits,
1492                    from: from,
1493                    to: to,
1494                };
1495                Ok(ret)
1496            }
1497            0b11 => {
1498                Ok(Constraint::Full{ bits: bits })
1499            }
1500            _ => Err(format!("internal error: impossible constraint code {:b}",code).into())
1501        }
1502    }
1503
1504    /// Iterator over all statements.
1505    pub fn iter<'a>(&'a self) -> BitcodeIter<'a> {
1506        BitcodeIter{
1507            cursor: Cursor::new(&self.data),
1508            bitcode: self,
1509        }
1510    }
1511
1512    /// Iterator over all statements inside byte range `rgn`.
1513    pub fn iter_range<'a>(&'a self, rgn: Range<usize>) -> BitcodeIter<'a> {
1514        BitcodeIter{
1515            cursor: Cursor::new(&self.data[rgn]),
1516            bitcode: self,
1517        }
1518    }
1519
1520    /// Number of bytes of serialized statements.
1521    pub fn num_bytes(&self) -> usize {
1522        self.data.len()
1523    }
1524}
1525
1526/// Iterator over serialized statements.
1527pub struct BitcodeIter<'a> {
1528    cursor: Cursor<&'a [u8]>,
1529    bitcode: &'a Bitcode,
1530}
1531
1532impl<'a> Iterator for BitcodeIter<'a> {
1533    type Item = Statement;
1534
1535    fn next(&mut self) -> Option<Self::Item> {
1536        self.bitcode.decode_statement(&mut self.cursor).ok()
1537    }
1538}
1539
1540#[cfg(test)]
1541mod tests {
1542    use super::*;
1543    use simple_logger;
1544
1545    quickcheck! {
1546        fn round_trip(v: Vec<Statement>) -> bool {
1547            let _ = simple_logger::init();
1548
1549            debug!("in: {:?}",v);
1550            match Bitcode::new(v.clone()) {
1551                Ok(bt) => {
1552                    debug!("{:?}",bt);
1553                    let w = bt.iter().collect::<Vec<_>>();
1554                    debug!("decoded: {:?}",w);
1555                    v == w
1556                }
1557                Err(s) => {
1558                    debug!("err: {}",s);
1559                    false
1560                }
1561            }
1562        }
1563    }
1564
1565    #[test]
1566    fn rewrite_equal_size() {
1567        use Operation::Add;
1568        let s1 = Statement::Expression{
1569            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1570            result: Variable::new(NameRef::new(0),32).unwrap()
1571        };
1572        let s2 = Statement::Expression{
1573            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1574            result: Variable::new(NameRef::new(0),32).unwrap()
1575        };
1576        let s3 = Statement::Expression{
1577            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1578            result: Variable::new(NameRef::new(0),32).unwrap()
1579        };
1580        let mut bitcode = Bitcode::default();
1581
1582        let _ = bitcode.append(vec![s1]).unwrap();
1583        let rgn = bitcode.append(vec![s2]).unwrap();
1584        let _ = bitcode.append(vec![s3]).unwrap();
1585        let mut names = Names::default();
1586        let mut strings = Strings::default();
1587        let mut segments = Segments::default();
1588
1589        let new_rgn = bitcode.rewrite(rgn.clone(),&mut names,&mut strings,&mut segments, |stmt,_,_,_| {
1590            match stmt {
1591                &mut Statement::Expression{ op: Add(Value::Constant(ref mut a),Value::Variable(ref mut b)), ref mut result } => {
1592                    *a = Constant::new(43,32).unwrap();
1593                    *b = Variable::new(NameRef::new(1),32).unwrap();
1594                    *result = Variable::new(NameRef::new(2),32).unwrap();
1595                }
1596                _ => { unreachable!() }
1597            }
1598
1599            Ok(RewriteControl::Continue)
1600        }).unwrap();
1601
1602        assert_eq!(rgn, new_rgn);
1603        for (idx,stmt) in bitcode.iter().enumerate() {
1604            match stmt {
1605                Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1606                    if idx == 0 || idx == 2 {
1607                        assert_eq!(a, Constant::new(42,32).unwrap());
1608                        assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1609                        assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1610                    } else if idx == 1 {
1611                        assert_eq!(a, Constant::new(43,32).unwrap());
1612                        assert_eq!(b, Variable::new(NameRef::new(1),32).unwrap());
1613                        assert_eq!(result, Variable::new(NameRef::new(2),32).unwrap());
1614                    } else {
1615                        unreachable!()
1616                    }
1617                }
1618                _ => { unreachable!() }
1619            }
1620        }
1621    }
1622
1623    #[test]
1624    fn rewrite_smaller_size() {
1625        use Operation::Add;
1626        let s1 = Statement::Expression{
1627            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1628            result: Variable::new(NameRef::new(0),32).unwrap()
1629        };
1630        let s2 = Statement::Expression{
1631            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1632            result: Variable::new(NameRef::new(0),32).unwrap()
1633        };
1634        let s3 = Statement::Expression{
1635            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1636            result: Variable::new(NameRef::new(0),32).unwrap()
1637        };
1638        let mut bitcode = Bitcode::default();
1639
1640        let _ = bitcode.append(vec![s1]).unwrap();
1641        let rgn = bitcode.append(vec![s2]).unwrap();
1642        let _ = bitcode.append(vec![s3]).unwrap();
1643        let mut names = Names::default();
1644        let mut strings = Strings::default();
1645        let mut segments = Segments::default();
1646
1647        let new_rgn = bitcode.rewrite(rgn.clone(),&mut names, &mut strings,&mut segments, |stmt,_,_,_| {
1648            *stmt = Statement::Flow{ op: FlowOperation::Return };
1649
1650            Ok(RewriteControl::Continue)
1651        }).unwrap();
1652
1653        assert_eq!(rgn.start, new_rgn.start);
1654        for (idx,stmt) in bitcode.iter().enumerate() {
1655            match stmt {
1656                Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1657                    assert_eq!(a, Constant::new(42,32).unwrap());
1658                    assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1659                    assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1660                    assert!(idx == 0 || idx == 2);
1661                }
1662                Statement::Flow{ op: FlowOperation::Return } => {
1663                    assert_eq!(idx, 1);
1664                }
1665                _ => { unreachable!() }
1666            }
1667        }
1668    }
1669
1670    #[test]
1671    fn rewrite_larger_size() {
1672        use Operation::Add;
1673        let s1 = Statement::Expression{
1674            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1675            result: Variable::new(NameRef::new(0),32).unwrap()
1676        };
1677        let s2 = Statement::Flow{ op: FlowOperation::Return };
1678        let s3 = Statement::Expression{
1679            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1680            result: Variable::new(NameRef::new(0),32).unwrap()
1681        };
1682        let mut bitcode = Bitcode::default();
1683
1684        let _ = bitcode.append(vec![s1]).unwrap();
1685        let rgn = bitcode.append(vec![s2]).unwrap();
1686        let _ = bitcode.append(vec![s3]).unwrap();
1687        let mut names = Names::default();
1688        let mut strings = Strings::default();
1689        let mut segments = Segments::default();
1690
1691        let new_rgn = bitcode.rewrite(rgn.clone(),&mut names,&mut strings,&mut segments, |stmt,_,_,_| {
1692            *stmt = Statement::Expression{
1693                op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1694                result: Variable::new(NameRef::new(0),32).unwrap()
1695            };
1696
1697            Ok(RewriteControl::Continue)
1698        }).unwrap();
1699
1700        assert_eq!(rgn.start, new_rgn.start);
1701        assert!(rgn.end < new_rgn.end);
1702        for stmt in bitcode.iter() {
1703            match stmt {
1704                Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1705                    assert_eq!(a, Constant::new(42,32).unwrap());
1706                    assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1707                    assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1708                }
1709                _ => { unreachable!() }
1710            }
1711        }
1712    }
1713
1714    #[test]
1715    fn insert_mid() {
1716        use Operation::Add;
1717        let s1 = Statement::Expression{
1718            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1719            result: Variable::new(NameRef::new(0),32).unwrap()
1720        };
1721        let s2 = Statement::Expression{
1722            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1723            result: Variable::new(NameRef::new(0),32).unwrap()
1724        };
1725        let mut bitcode = Bitcode::default();
1726
1727        let _ = bitcode.append(vec![s1]).unwrap();
1728        let rgn = bitcode.append(vec![s2]).unwrap();
1729
1730        let new_rgn = bitcode.insert(rgn.start,vec![Statement::Flow{ op: FlowOperation::Return }]).unwrap();
1731
1732        assert_eq!(rgn.start, new_rgn.start);
1733        for (idx,stmt) in bitcode.iter().enumerate() {
1734            match stmt {
1735                Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1736                    assert_eq!(a, Constant::new(42,32).unwrap());
1737                    assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1738                    assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1739                    assert!(idx == 0 || idx == 2);
1740                }
1741                Statement::Flow{ op: FlowOperation::Return } => {
1742                    assert_eq!(idx, 1);
1743                }
1744                _ => { unreachable!() }
1745            }
1746        }
1747    }
1748
1749    #[test]
1750    fn insert_start() {
1751        use Operation::Add;
1752        let s1 = Statement::Expression{
1753            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1754            result: Variable::new(NameRef::new(0),32).unwrap()
1755        };
1756        let mut bitcode = Bitcode::default();
1757        let rgn = bitcode.append(vec![s1]).unwrap();
1758        let new_rgn = bitcode.insert(rgn.start,vec![Statement::Flow{ op: FlowOperation::Return }]).unwrap();
1759
1760        assert_eq!(rgn.start, new_rgn.start);
1761        for (idx,stmt) in bitcode.iter().enumerate() {
1762            match stmt {
1763                Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1764                    assert_eq!(a, Constant::new(42,32).unwrap());
1765                    assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1766                    assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1767                    assert_eq!(idx, 1);
1768                }
1769                Statement::Flow{ op: FlowOperation::Return }=> {
1770                    assert_eq!(idx, 0);
1771                }
1772                _ => { unreachable!() }
1773            }
1774        }
1775    }
1776
1777    #[test]
1778    fn insert_end() {
1779        use Operation::Add;
1780        let s1 = Statement::Expression{
1781            op: Add(Value::val(42,32).unwrap(),Value::var(NameRef::new(0),32).unwrap()),
1782            result: Variable::new(NameRef::new(0),32).unwrap()
1783        };
1784        let mut bitcode = Bitcode::default();
1785        let rgn = bitcode.append(vec![s1]).unwrap();
1786        let new_rgn = bitcode.insert(rgn.end,vec![Statement::Flow{ op: FlowOperation::Return }]).unwrap();
1787
1788        assert_eq!(rgn.end, new_rgn.start);
1789        for (idx,stmt) in bitcode.iter().enumerate() {
1790            match stmt {
1791                Statement::Expression{ op: Add(Value::Constant(a),Value::Variable(b)), result } => {
1792                    assert_eq!(a, Constant::new(42,32).unwrap());
1793                    assert_eq!(b, Variable::new(NameRef::new(0),32).unwrap());
1794                    assert_eq!(result, Variable::new(NameRef::new(0),32).unwrap());
1795                    assert_eq!(idx, 0);
1796                }
1797                Statement::Flow{ op: FlowOperation::Return } => {
1798                    assert_eq!(idx, 1);
1799                }
1800                _ => { unreachable!() }
1801            }
1802        }
1803    }
1804}