Browse Source

Merge pull request #4 from badboy/use-slices

src: make several code style improvements, in part thanks to rust-clippy

* Use slices and references instead of vectors.
* Don't re-borrow slices.
* Remove useless uses of vectors.
* And a few others.
Quentin Monnet 8 years ago
parent
commit
9cd417f232
9 changed files with 57 additions and 64 deletions
  1. 2 2
      README.md
  2. 2 2
      examples/load_elf.rs
  3. 4 4
      examples/to_json.rs
  4. 2 3
      src/disassembler.rs
  5. 4 7
      src/ebpf.rs
  6. 6 6
      src/jit.rs
  7. 28 30
      src/lib.rs
  8. 4 5
      src/verifier.rs
  9. 5 5
      tests/misc.rs

+ 2 - 2
README.md

@@ -380,7 +380,7 @@ fn main() {
         None => panic!("Failed to look up .classifier section"),
         None => panic!("Failed to look up .classifier section"),
     };
     };
 
 
-    let ref prog = &text_scn.data;
+    let prog = &text_scn.data;
 
 
     // This is our data: a real packet, starting with Ethernet header
     // This is our data: a real packet, starting with Ethernet header
     let mut packet = vec![
     let mut packet = vec![
@@ -409,7 +409,7 @@ fn main() {
     // We must provide the offsets at which the pointers to packet data start
     // We must provide the offsets at which the pointers to packet data start
     // and end must be stored: these are the offsets at which the program will
     // and end must be stored: these are the offsets at which the program will
     // load the packet data from the metadata buffer.
     // load the packet data from the metadata buffer.
-    let mut vm = rbpf::EbpfVmFixedMbuff::new(&prog, 0x40, 0x50);
+    let mut vm = rbpf::EbpfVmFixedMbuff::new(prog, 0x40, 0x50);
 
 
     // We register a helper function, that can be called by the program, into
     // We register a helper function, that can be called by the program, into
     // the VM.
     // the VM.

+ 2 - 2
examples/load_elf.rs

@@ -65,7 +65,7 @@ fn main() {
         None => panic!("Failed to look up .classifier section"),
         None => panic!("Failed to look up .classifier section"),
     };
     };
 
 
-    let ref prog = &text_scn.data;
+    let prog = &text_scn.data;
 
 
     let mut packet1 = vec![
     let mut packet1 = vec![
         0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
         0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
@@ -111,7 +111,7 @@ fn main() {
         0x64, 0x66, 0x0au8
         0x64, 0x66, 0x0au8
     ];
     ];
 
 
-    let mut vm = rbpf::EbpfVmFixedMbuff::new(&prog, 0x40, 0x50);
+    let mut vm = rbpf::EbpfVmFixedMbuff::new(prog, 0x40, 0x50);
     vm.register_helper(helpers::BPF_TRACE_PRINTK_IDX, helpers::bpf_trace_printf);
     vm.register_helper(helpers::BPF_TRACE_PRINTK_IDX, helpers::bpf_trace_printf);
 
 
     let res = vm.prog_exec(&mut packet1);
     let res = vm.prog_exec(&mut packet1);

+ 4 - 4
examples/to_json.rs

@@ -24,13 +24,13 @@ use rbpf::disassembler;
 // * Remove the "desc" (description) attributes from the output.
 // * Remove the "desc" (description) attributes from the output.
 // * Print integers as integers, and not as strings containing their hexadecimal representation
 // * Print integers as integers, and not as strings containing their hexadecimal representation
 //   (just replace the relevant `format!()` calls by the commented values.
 //   (just replace the relevant `format!()` calls by the commented values.
-fn to_json(prog: &std::vec::Vec<u8>) -> String {
+fn to_json(prog: &[u8]) -> String {
 
 
     // This call returns a high-level representation of the instructions, with the two parts of
     // This call returns a high-level representation of the instructions, with the two parts of
     // `LD_DW_IMM` instructions merged, and name and descriptions of the instructions.
     // `LD_DW_IMM` instructions merged, and name and descriptions of the instructions.
     // If you prefer to use a lower-level representation, use `ebpf::to_insn_vec()` function
     // If you prefer to use a lower-level representation, use `ebpf::to_insn_vec()` function
     // instead.
     // instead.
-    let insns = disassembler::to_insn_vec(&prog);
+    let insns = disassembler::to_insn_vec(prog);
     let mut json_insns = vec![];
     let mut json_insns = vec![];
     for insn in insns {
     for insn in insns {
         json_insns.push(object!(
         json_insns.push(object!(
@@ -46,7 +46,7 @@ fn to_json(prog: &std::vec::Vec<u8>) -> String {
                 // number is negative. When values takes more than 32 bits with `lddw`, the cast
                 // number is negative. When values takes more than 32 bits with `lddw`, the cast
                 // has no effect and the complete value is printed anyway.
                 // has no effect and the complete value is printed anyway.
                 "imm"  => format!("{:#x}", insn.imm as i32), // => insn.imm,
                 "imm"  => format!("{:#x}", insn.imm as i32), // => insn.imm,
-                "desc" => format!("{}",    insn.desc)
+                "desc" => insn.desc
             )
             )
         );
         );
     }
     }
@@ -73,7 +73,7 @@ fn main() {
         None => panic!("Failed to look up .classifier section"),
         None => panic!("Failed to look up .classifier section"),
     };
     };
 
 
-    let ref prog = &text_scn.data;
+    let prog = &text_scn.data;
 
 
     println!("{}", to_json(&prog));
     println!("{}", to_json(&prog));
 }
 }

+ 2 - 3
src/disassembler.rs

@@ -9,7 +9,6 @@
 //! for example to disassemble the code into a human-readable format.
 //! for example to disassemble the code into a human-readable format.
 
 
 use ebpf;
 use ebpf;
-use std;
 
 
 #[inline]
 #[inline]
 fn alu_imm_str(name: &str, insn: &ebpf::Insn) -> String {
 fn alu_imm_str(name: &str, insn: &ebpf::Insn) -> String {
@@ -146,7 +145,7 @@ pub struct HLInsn {
 ///     },
 ///     },
 /// ]);
 /// ]);
 /// ```
 /// ```
-pub fn to_insn_vec(prog: &std::vec::Vec<u8>) -> std::vec::Vec<HLInsn> {
+pub fn to_insn_vec(prog: &[u8]) -> Vec<HLInsn> {
     if prog.len() % ebpf::INSN_SIZE != 0 {
     if prog.len() % ebpf::INSN_SIZE != 0 {
         panic!("[Disassembler] Error: eBPF program length must be a multiple of {:?} octets",
         panic!("[Disassembler] Error: eBPF program length must be a multiple of {:?} octets",
                ebpf::INSN_SIZE);
                ebpf::INSN_SIZE);
@@ -330,7 +329,7 @@ pub fn to_insn_vec(prog: &std::vec::Vec<u8>) -> std::vec::Vec<HLInsn> {
 /// neg64 r8
 /// neg64 r8
 /// exit
 /// exit
 /// ```
 /// ```
-pub fn disassemble(prog: &std::vec::Vec<u8>) {
+pub fn disassemble(prog: &[u8]) {
     if prog.len() % ebpf::INSN_SIZE != 0 {
     if prog.len() % ebpf::INSN_SIZE != 0 {
         panic!("[Disassembler] Error: eBPF program length must be a multiple of {:?} octets",
         panic!("[Disassembler] Error: eBPF program length must be a multiple of {:?} octets",
                ebpf::INSN_SIZE);
                ebpf::INSN_SIZE);

+ 4 - 7
src/ebpf.rs

@@ -17,8 +17,6 @@
 //! <https://www.kernel.org/doc/Documentation/networking/filter.txt>, or for a shorter version of
 //! <https://www.kernel.org/doc/Documentation/networking/filter.txt>, or for a shorter version of
 //! the list of the operation codes: <https://github.com/iovisor/bpf-docs/blob/master/eBPF.md>
 //! the list of the operation codes: <https://github.com/iovisor/bpf-docs/blob/master/eBPF.md>
 
 
-use std;
-
 /// Maximum number of instructions in an eBPF program.
 /// Maximum number of instructions in an eBPF program.
 pub const PROG_MAX_INSNS: usize = 4096;
 pub const PROG_MAX_INSNS: usize = 4096;
 /// Size of an eBPF instructions, in bytes.
 /// Size of an eBPF instructions, in bytes.
@@ -407,7 +405,7 @@ pub struct Insn {
 ///     ];
 ///     ];
 /// let insn = ebpf::get_insn(&prog, 1);
 /// let insn = ebpf::get_insn(&prog, 1);
 /// ```
 /// ```
-pub fn get_insn(prog: &std::vec::Vec<u8>, idx: usize) -> Insn {
+pub fn get_insn(prog: &[u8], idx: usize) -> Insn {
     // This guard should not be needed in most cases, since the verifier already checks the program
     // This guard should not be needed in most cases, since the verifier already checks the program
     // size, and indexes should be fine in the interpreter/JIT. But this function is publicly
     // size, and indexes should be fine in the interpreter/JIT. But this function is publicly
     // available and user can call it with any `idx`, so we have to check anyway.
     // available and user can call it with any `idx`, so we have to check anyway.
@@ -415,7 +413,7 @@ pub fn get_insn(prog: &std::vec::Vec<u8>, idx: usize) -> Insn {
         panic!("Error: cannot reach instruction at index {:?} in program containing {:?} bytes",
         panic!("Error: cannot reach instruction at index {:?} in program containing {:?} bytes",
                idx, prog.len());
                idx, prog.len());
     }
     }
-    let insn = Insn {
+    Insn {
         opc:  prog[INSN_SIZE * idx],
         opc:  prog[INSN_SIZE * idx],
         dst:  prog[INSN_SIZE * idx + 1] & 0x0f,
         dst:  prog[INSN_SIZE * idx + 1] & 0x0f,
         src: (prog[INSN_SIZE * idx + 1] & 0xf0) >> 4,
         src: (prog[INSN_SIZE * idx + 1] & 0xf0) >> 4,
@@ -425,8 +423,7 @@ pub fn get_insn(prog: &std::vec::Vec<u8>, idx: usize) -> Insn {
         imm: unsafe {
         imm: unsafe {
             let x = prog.as_ptr().offset((INSN_SIZE * idx + 4) as isize) as *const i32; *x
             let x = prog.as_ptr().offset((INSN_SIZE * idx + 4) as isize) as *const i32; *x
         },
         },
-    };
-    insn
+    }
 }
 }
 
 
 /// Return a vector of `struct Insn` built from a program.
 /// Return a vector of `struct Insn` built from a program.
@@ -473,7 +470,7 @@ pub fn get_insn(prog: &std::vec::Vec<u8>, idx: usize) -> Insn {
 ///     },
 ///     },
 /// ]);
 /// ]);
 /// ```
 /// ```
-pub fn to_insn_vec(prog: &std::vec::Vec<u8>) -> std::vec::Vec<Insn> {
+pub fn to_insn_vec(prog: &[u8]) -> Vec<Insn> {
     if prog.len() % INSN_SIZE != 0 {
     if prog.len() % INSN_SIZE != 0 {
         panic!("Error: eBPF program length must be a multiple of {:?} octets",
         panic!("Error: eBPF program length must be a multiple of {:?} octets",
                INSN_SIZE);
                INSN_SIZE);

+ 6 - 6
src/jit.rs

@@ -425,9 +425,9 @@ struct Jump {
 struct JitMemory<'a> {
 struct JitMemory<'a> {
     contents:        &'a mut [u8],
     contents:        &'a mut [u8],
     offset:          usize,
     offset:          usize,
-    pc_locs:         std::vec::Vec<usize>,
+    pc_locs:         Vec<usize>,
     special_targets: HashMap<isize, usize>,
     special_targets: HashMap<isize, usize>,
-    jumps:           std::vec::Vec<Jump>,
+    jumps:           Vec<Jump>,
 }
 }
 
 
 impl<'a> JitMemory<'a> {
 impl<'a> JitMemory<'a> {
@@ -451,7 +451,7 @@ impl<'a> JitMemory<'a> {
         }
         }
     }
     }
 
 
-    fn jit_compile(&mut self, prog: &std::vec::Vec<u8>, use_mbuff: bool, update_data_ptr: bool,
+    fn jit_compile(&mut self, prog: &[u8], use_mbuff: bool, update_data_ptr: bool,
                    helpers: &HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>) {
                    helpers: &HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>) {
         emit_push(self, RBP);
         emit_push(self, RBP);
         emit_push(self, RBX);
         emit_push(self, RBX);
@@ -714,10 +714,10 @@ impl<'a> JitMemory<'a> {
                     // For JIT, helpers in use MUST be registered at compile time. They can be
                     // For JIT, helpers in use MUST be registered at compile time. They can be
                     // updated later, but not created after compiling (we need the address of the
                     // updated later, but not created after compiling (we need the address of the
                     // helper function in the JIT-compiled program).
                     // helper function in the JIT-compiled program).
-                    if let Some(_) = helpers.get(&(insn.imm as u32)) {
+                    if let Some(helper) = helpers.get(&(insn.imm as u32)) {
                         // We reserve RCX for shifts
                         // We reserve RCX for shifts
                         emit_mov(self, R9, RCX);
                         emit_mov(self, R9, RCX);
-                        emit_call(self, helpers[&(insn.imm as u32)] as i64);
+                        emit_call(self, *helper as i64);
                     } else {
                     } else {
                         panic!("[JIT] Error: unknown helper function (id: {:#x})",
                         panic!("[JIT] Error: unknown helper function (id: {:#x})",
                                insn.imm as u32);
                                insn.imm as u32);
@@ -832,7 +832,7 @@ impl<'a> std::fmt::Debug for JitMemory<'a> {
 }
 }
 
 
 // In the end, this is the only thing we export
 // In the end, this is the only thing we export
-pub fn compile(prog: &std::vec::Vec<u8>,
+pub fn compile(prog: &[u8],
                helpers: &HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>,
                helpers: &HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>,
                use_mbuff: bool, update_data_ptr: bool)
                use_mbuff: bool, update_data_ptr: bool)
     -> (unsafe fn(*mut u8, usize, *mut u8, usize, usize, usize) -> u64) {
     -> (unsafe fn(*mut u8, usize, *mut u8, usize, usize, usize) -> u64) {

+ 28 - 30
src/lib.rs

@@ -33,7 +33,7 @@ pub mod disassembler;
 struct MetaBuff {
 struct MetaBuff {
     data_offset:     usize,
     data_offset:     usize,
     data_end_offset: usize,
     data_end_offset: usize,
-    buffer:          std::vec::Vec<u8>,
+    buffer:          Vec<u8>,
 }
 }
 
 
 /// A virtual machine to run eBPF program. This kind of VM is used for programs expecting to work
 /// A virtual machine to run eBPF program. This kind of VM is used for programs expecting to work
@@ -69,7 +69,7 @@ struct MetaBuff {
 /// assert_eq!(res, 0x2211);
 /// assert_eq!(res, 0x2211);
 /// ```
 /// ```
 pub struct EbpfVmMbuff<'a> {
 pub struct EbpfVmMbuff<'a> {
-    prog:    &'a std::vec::Vec<u8>,
+    prog:    &'a [u8],
     jit:     (unsafe fn (*mut u8, usize, *mut u8, usize, usize, usize) -> u64),
     jit:     (unsafe fn (*mut u8, usize, *mut u8, usize, usize, usize) -> u64),
     helpers: HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>,
     helpers: HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>,
 }
 }
@@ -95,12 +95,11 @@ impl<'a> EbpfVmMbuff<'a> {
     /// // Instantiate a VM.
     /// // Instantiate a VM.
     /// let mut vm = rbpf::EbpfVmMbuff::new(&prog);
     /// let mut vm = rbpf::EbpfVmMbuff::new(&prog);
     /// ```
     /// ```
-    pub fn new(prog: &'a std::vec::Vec<u8>) -> EbpfVmMbuff<'a> {
+    pub fn new(prog: &'a [u8]) -> EbpfVmMbuff<'a> {
         verifier::check(prog);
         verifier::check(prog);
 
 
-        #[allow(unused_variables)]
-        fn no_jit(foo: *mut u8, foo_len: usize, bar: *mut u8, bar_len: usize,
-                  nodata_offset: usize, nodata_end_offset: usize) -> u64 {
+        fn no_jit(_mbuff: *mut u8, _len: usize, _mem: *mut u8, _mem_len: usize,
+                  _nodata_offset: usize, _nodata_end_offset: usize) -> u64 {
             panic!("Error: program has not been JIT-compiled");
             panic!("Error: program has not been JIT-compiled");
         }
         }
 
 
@@ -134,7 +133,7 @@ impl<'a> EbpfVmMbuff<'a> {
     /// let mut vm = rbpf::EbpfVmMbuff::new(&prog1);
     /// let mut vm = rbpf::EbpfVmMbuff::new(&prog1);
     /// vm.set_prog(&prog2);
     /// vm.set_prog(&prog2);
     /// ```
     /// ```
-    pub fn set_prog(&mut self, prog: &'a std::vec::Vec<u8>) {
+    pub fn set_prog(&mut self, prog: &'a [u8]) {
         verifier::check(prog);
         verifier::check(prog);
         self.prog = prog;
         self.prog = prog;
     }
     }
@@ -220,7 +219,7 @@ impl<'a> EbpfVmMbuff<'a> {
     /// let res = vm.prog_exec(&mut mem, &mut mbuff);
     /// let res = vm.prog_exec(&mut mem, &mut mbuff);
     /// assert_eq!(res, 0x2211);
     /// assert_eq!(res, 0x2211);
     /// ```
     /// ```
-    pub fn prog_exec(&self, mem: &mut std::vec::Vec<u8>, mbuff: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub fn prog_exec(&self, mem: &[u8], mbuff: &[u8]) -> u64 {
         const U32MAX: u64 = u32::MAX as u64;
         const U32MAX: u64 = u32::MAX as u64;
 
 
         let stack = vec![0u8;ebpf::STACK_SIZE];
         let stack = vec![0u8;ebpf::STACK_SIZE];
@@ -237,10 +236,10 @@ impl<'a> EbpfVmMbuff<'a> {
         }
         }
 
 
         let check_mem_load = | addr: u64, len: usize, insn_ptr: usize | {
         let check_mem_load = | addr: u64, len: usize, insn_ptr: usize | {
-            EbpfVmMbuff::check_mem(addr, len, "load", insn_ptr, &mbuff, &mem, &stack);
+            EbpfVmMbuff::check_mem(addr, len, "load", insn_ptr, mbuff, mem, &stack);
         };
         };
         let check_mem_store = | addr: u64, len: usize, insn_ptr: usize | {
         let check_mem_store = | addr: u64, len: usize, insn_ptr: usize | {
-            EbpfVmMbuff::check_mem(addr, len, "store", insn_ptr, &mbuff, &mem, &stack);
+            EbpfVmMbuff::check_mem(addr, len, "store", insn_ptr, mbuff, mem, &stack);
         };
         };
 
 
         // Loop on instructions
         // Loop on instructions
@@ -464,7 +463,7 @@ impl<'a> EbpfVmMbuff<'a> {
     }
     }
 
 
     fn check_mem(addr: u64, len: usize, access_type: &str, insn_ptr: usize,
     fn check_mem(addr: u64, len: usize, access_type: &str, insn_ptr: usize,
-                 mbuff: &std::vec::Vec<u8>, mem: &std::vec::Vec<u8>, stack: &std::vec::Vec<u8>) {
+                 mbuff: &[u8], mem: &[u8], stack: &[u8]) {
         if mbuff.as_ptr() as u64 <= addr && addr + len as u64 <= mbuff.as_ptr() as u64 + mbuff.len() as u64 {
         if mbuff.as_ptr() as u64 <= addr && addr + len as u64 <= mbuff.as_ptr() as u64 + mbuff.len() as u64 {
             return
             return
         }
         }
@@ -509,7 +508,7 @@ impl<'a> EbpfVmMbuff<'a> {
     /// vm.jit_compile();
     /// vm.jit_compile();
     /// ```
     /// ```
     pub fn jit_compile(&mut self) {
     pub fn jit_compile(&mut self) {
-        self.jit = jit::compile(&self.prog, &self.helpers, true, false);
+        self.jit = jit::compile(self.prog, &self.helpers, true, false);
     }
     }
 
 
     /// Execute the previously JIT-compiled program, with the given packet data and metadata
     /// Execute the previously JIT-compiled program, with the given packet data and metadata
@@ -566,7 +565,7 @@ impl<'a> EbpfVmMbuff<'a> {
     ///     assert_eq!(res, 0x2211);
     ///     assert_eq!(res, 0x2211);
     /// }
     /// }
     /// ```
     /// ```
-    pub unsafe fn prog_exec_jit(&self, mem: &mut std::vec::Vec<u8>, mbuff: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub unsafe fn prog_exec_jit(&self, mem: &mut [u8], mbuff: &'a mut [u8]) -> u64 {
         // If packet data is empty, do not send the address of an empty vector; send a null
         // If packet data is empty, do not send the address of an empty vector; send a null
         // pointer (zero value) as first argument instead, as this is uBPF's behavior (empty
         // pointer (zero value) as first argument instead, as this is uBPF's behavior (empty
         // packet should not happen in the kernel; anyway the verifier would prevent the use of
         // packet should not happen in the kernel; anyway the verifier would prevent the use of
@@ -679,7 +678,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// // Instantiate a VM. Note that we provide the start and end offsets for mem pointers.
     /// // Instantiate a VM. Note that we provide the start and end offsets for mem pointers.
     /// let mut vm = rbpf::EbpfVmFixedMbuff::new(&prog, 0x40, 0x50);
     /// let mut vm = rbpf::EbpfVmFixedMbuff::new(&prog, 0x40, 0x50);
     /// ```
     /// ```
-    pub fn new(prog: &'a std::vec::Vec<u8>, data_offset: usize, data_end_offset: usize) -> EbpfVmFixedMbuff<'a> {
+    pub fn new(prog: &'a [u8], data_offset: usize, data_end_offset: usize) -> EbpfVmFixedMbuff<'a> {
         let parent = EbpfVmMbuff::new(prog);
         let parent = EbpfVmMbuff::new(prog);
         let get_buff_len = | x: usize, y: usize | if x >= y { x + 8 } else { y + 8 };
         let get_buff_len = | x: usize, y: usize | if x >= y { x + 8 } else { y + 8 };
         let buffer = vec![0u8; get_buff_len(data_offset, data_end_offset)];
         let buffer = vec![0u8; get_buff_len(data_offset, data_end_offset)];
@@ -730,7 +729,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// let res = vm.prog_exec(&mut mem);
     /// let res = vm.prog_exec(&mut mem);
     /// assert_eq!(res, 0x27);
     /// assert_eq!(res, 0x27);
     /// ```
     /// ```
-    pub fn set_prog(&mut self, prog: &'a std::vec::Vec<u8>, data_offset: usize, data_end_offset: usize) {
+    pub fn set_prog(&mut self, prog: &'a [u8], data_offset: usize, data_end_offset: usize) {
         let get_buff_len = | x: usize, y: usize | if x >= y { x + 8 } else { y + 8 };
         let get_buff_len = | x: usize, y: usize | if x >= y { x + 8 } else { y + 8 };
         let buffer = vec![0u8; get_buff_len(data_offset, data_end_offset)];
         let buffer = vec![0u8; get_buff_len(data_offset, data_end_offset)];
         self.mbuff.buffer = buffer;
         self.mbuff.buffer = buffer;
@@ -821,7 +820,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// let res = vm.prog_exec(&mut mem);
     /// let res = vm.prog_exec(&mut mem);
     /// assert_eq!(res, 0xdd);
     /// assert_eq!(res, 0xdd);
     /// ```
     /// ```
-    pub fn prog_exec(&mut self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub fn prog_exec(&mut self, mem: &'a mut [u8]) -> u64 {
         let l = self.mbuff.buffer.len();
         let l = self.mbuff.buffer.len();
         // Can this ever happen? Probably not, should be ensured at mbuff creation.
         // Can this ever happen? Probably not, should be ensured at mbuff creation.
         if self.mbuff.data_offset + 8 > l || self.mbuff.data_end_offset + 8 > l {
         if self.mbuff.data_offset + 8 > l || self.mbuff.data_end_offset + 8 > l {
@@ -834,7 +833,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
             *data     = mem.as_ptr() as u64;
             *data     = mem.as_ptr() as u64;
             *data_end = mem.as_ptr() as u64 + mem.len() as u64;
             *data_end = mem.as_ptr() as u64 + mem.len() as u64;
         }
         }
-        self.parent.prog_exec(mem, &mut self.mbuff.buffer)
+        self.parent.prog_exec(mem, &self.mbuff.buffer)
     }
     }
 
 
     /// JIT-compile the loaded program. No argument required for this.
     /// JIT-compile the loaded program. No argument required for this.
@@ -866,7 +865,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// vm.jit_compile();
     /// vm.jit_compile();
     /// ```
     /// ```
     pub fn jit_compile(&mut self) {
     pub fn jit_compile(&mut self) {
-        self.parent.jit = jit::compile(&self.parent.prog, &self.parent.helpers, true, true);
+        self.parent.jit = jit::compile(self.parent.prog, &self.parent.helpers, true, true);
     }
     }
 
 
     /// Execute the previously JIT-compiled program, with the given packet data, in a manner very
     /// Execute the previously JIT-compiled program, with the given packet data, in a manner very
@@ -919,7 +918,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// ```
     /// ```
     // This struct redefines the `prog_exec_jit()` function, in order to pass the offsets
     // This struct redefines the `prog_exec_jit()` function, in order to pass the offsets
     // associated with the fixed mbuff.
     // associated with the fixed mbuff.
-    pub unsafe fn prog_exec_jit(&mut self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub unsafe fn prog_exec_jit(&mut self, mem: &'a mut [u8]) -> u64 {
         // If packet data is empty, do not send the address of an empty vector; send a null
         // If packet data is empty, do not send the address of an empty vector; send a null
         // pointer (zero value) as first argument instead, as this is uBPF's behavior (empty
         // pointer (zero value) as first argument instead, as this is uBPF's behavior (empty
         // packet should not happen in the kernel; anyway the verifier would prevent the use of
         // packet should not happen in the kernel; anyway the verifier would prevent the use of
@@ -982,7 +981,7 @@ impl<'a> EbpfVmRaw<'a> {
     /// // Instantiate a VM.
     /// // Instantiate a VM.
     /// let vm = rbpf::EbpfVmRaw::new(&prog);
     /// let vm = rbpf::EbpfVmRaw::new(&prog);
     /// ```
     /// ```
-    pub fn new(prog: &'a std::vec::Vec<u8>) -> EbpfVmRaw<'a> {
+    pub fn new(prog: &'a [u8]) -> EbpfVmRaw<'a> {
         let parent = EbpfVmMbuff::new(prog);
         let parent = EbpfVmMbuff::new(prog);
         EbpfVmRaw {
         EbpfVmRaw {
             parent: parent,
             parent: parent,
@@ -1019,7 +1018,7 @@ impl<'a> EbpfVmRaw<'a> {
     /// let res = vm.prog_exec(&mut mem);
     /// let res = vm.prog_exec(&mut mem);
     /// assert_eq!(res, 0x22cc);
     /// assert_eq!(res, 0x22cc);
     /// ```
     /// ```
-    pub fn set_prog(&mut self, prog: &'a std::vec::Vec<u8>) {
+    pub fn set_prog(&mut self, prog: &'a [u8]) {
         self.parent.set_prog(prog)
         self.parent.set_prog(prog)
     }
     }
 
 
@@ -1089,9 +1088,8 @@ impl<'a> EbpfVmRaw<'a> {
     /// let res = vm.prog_exec(&mut mem);
     /// let res = vm.prog_exec(&mut mem);
     /// assert_eq!(res, 0x22cc);
     /// assert_eq!(res, 0x22cc);
     /// ```
     /// ```
-    pub fn prog_exec(&self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
-        let mut mbuff = vec![];
-        self.parent.prog_exec(mem, &mut mbuff)
+    pub fn prog_exec(&self, mem: &'a mut [u8]) -> u64 {
+        self.parent.prog_exec(mem, &[])
     }
     }
 
 
     /// JIT-compile the loaded program. No argument required for this.
     /// JIT-compile the loaded program. No argument required for this.
@@ -1119,7 +1117,7 @@ impl<'a> EbpfVmRaw<'a> {
     /// vm.jit_compile();
     /// vm.jit_compile();
     /// ```
     /// ```
     pub fn jit_compile(&mut self) {
     pub fn jit_compile(&mut self) {
-        self.parent.jit = jit::compile(&self.parent.prog, &self.parent.helpers, false, false);
+        self.parent.jit = jit::compile(self.parent.prog, &self.parent.helpers, false, false);
     }
     }
 
 
     /// Execute the previously JIT-compiled program, with the given packet data, in a manner very
     /// Execute the previously JIT-compiled program, with the given packet data, in a manner very
@@ -1161,7 +1159,7 @@ impl<'a> EbpfVmRaw<'a> {
     ///     assert_eq!(res, 0x22cc);
     ///     assert_eq!(res, 0x22cc);
     /// }
     /// }
     /// ```
     /// ```
-    pub unsafe fn prog_exec_jit(&self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub unsafe fn prog_exec_jit(&self, mem: &'a mut [u8]) -> u64 {
         let mut mbuff = vec![];
         let mut mbuff = vec![];
         self.parent.prog_exec_jit(mem, &mut mbuff)
         self.parent.prog_exec_jit(mem, &mut mbuff)
     }
     }
@@ -1231,7 +1229,7 @@ impl<'a> EbpfVmNoData<'a> {
     /// // Instantiate a VM.
     /// // Instantiate a VM.
     /// let vm = rbpf::EbpfVmNoData::new(&prog);
     /// let vm = rbpf::EbpfVmNoData::new(&prog);
     /// ```
     /// ```
-    pub fn new(prog: &'a std::vec::Vec<u8>) -> EbpfVmNoData<'a> {
+    pub fn new(prog: &'a [u8]) -> EbpfVmNoData<'a> {
         let parent = EbpfVmRaw::new(prog);
         let parent = EbpfVmRaw::new(prog);
         EbpfVmNoData {
         EbpfVmNoData {
             parent: parent,
             parent: parent,
@@ -1267,7 +1265,7 @@ impl<'a> EbpfVmNoData<'a> {
     /// let res = vm.prog_exec();
     /// let res = vm.prog_exec();
     /// assert_eq!(res, 0x1122);
     /// assert_eq!(res, 0x1122);
     /// ```
     /// ```
-    pub fn set_prog(&mut self, prog: &'a std::vec::Vec<u8>) {
+    pub fn set_prog(&mut self, prog: &'a [u8]) {
         self.parent.set_prog(prog)
         self.parent.set_prog(prog)
     }
     }
 
 
@@ -1357,7 +1355,7 @@ impl<'a> EbpfVmNoData<'a> {
     /// assert_eq!(res, 0x1122);
     /// assert_eq!(res, 0x1122);
     /// ```
     /// ```
     pub fn prog_exec(&self) -> u64 {
     pub fn prog_exec(&self) -> u64 {
-        self.parent.prog_exec(&mut vec![])
+        self.parent.prog_exec(&mut [])
     }
     }
 
 
     /// Execute the previously JIT-compiled program, without providing pointers to any memory area
     /// Execute the previously JIT-compiled program, without providing pointers to any memory area
@@ -1395,6 +1393,6 @@ impl<'a> EbpfVmNoData<'a> {
     /// }
     /// }
     /// ```
     /// ```
     pub unsafe fn prog_exec_jit(&self) -> u64 {
     pub unsafe fn prog_exec_jit(&self) -> u64 {
-        self.parent.prog_exec_jit(&mut vec![])
+        self.parent.prog_exec_jit(&mut [])
     }
     }
 }
 }

+ 4 - 5
src/verifier.rs

@@ -24,9 +24,8 @@
 
 
 
 
 use ebpf;
 use ebpf;
-use std;
 
 
-fn check_prog_len(prog: &std::vec::Vec<u8>) {
+fn check_prog_len(prog: &[u8]) {
     if prog.len() % ebpf::INSN_SIZE != 0 {
     if prog.len() % ebpf::INSN_SIZE != 0 {
         panic!("[Verifier] Error: eBPF program length must be a multiple of {:?} octets",
         panic!("[Verifier] Error: eBPF program length must be a multiple of {:?} octets",
                ebpf::INSN_SIZE);
                ebpf::INSN_SIZE);
@@ -58,7 +57,7 @@ fn check_imm_endian(insn: &ebpf::Insn, insn_ptr: usize) {
     }
     }
 }
 }
 
 
-fn check_load_dw(prog: &std::vec::Vec<u8>, insn_ptr: usize) {
+fn check_load_dw(prog: &[u8], insn_ptr: usize) {
     // We know we can reach next insn since we enforce an EXIT insn at the end of program, while
     // We know we can reach next insn since we enforce an EXIT insn at the end of program, while
     // this function should be called only for LD_DW insn, that cannot be last in program.
     // this function should be called only for LD_DW insn, that cannot be last in program.
     let next_insn = ebpf::get_insn(prog, insn_ptr + 1);
     let next_insn = ebpf::get_insn(prog, insn_ptr + 1);
@@ -68,7 +67,7 @@ fn check_load_dw(prog: &std::vec::Vec<u8>, insn_ptr: usize) {
 
 
 }
 }
 
 
-fn check_jmp_offset(prog: &std::vec::Vec<u8>, insn_ptr: usize) {
+fn check_jmp_offset(prog: &[u8], insn_ptr: usize) {
     let insn = ebpf::get_insn(prog, insn_ptr);
     let insn = ebpf::get_insn(prog, insn_ptr);
     if insn.off == -1 {
     if insn.off == -1 {
         panic!("[Verifier] Error: infinite loop (insn #{:?})", insn_ptr);
         panic!("[Verifier] Error: infinite loop (insn #{:?})", insn_ptr);
@@ -102,7 +101,7 @@ fn check_registers(insn: &ebpf::Insn, store: bool, insn_ptr: usize) {
     }
     }
 }
 }
 
 
-pub fn check(prog: &std::vec::Vec<u8>) -> bool {
+pub fn check(prog: &[u8]) -> bool {
     check_prog_len(prog);
     check_prog_len(prog);
 
 
     let mut insn_ptr:usize = 0;
     let mut insn_ptr:usize = 0;

+ 5 - 5
tests/misc.rs

@@ -108,7 +108,7 @@ fn test_vm_block_port() {
     //     None => panic!("Failed to look up .classifier section"),
     //     None => panic!("Failed to look up .classifier section"),
     // };
     // };
     //
     //
-    // let ref prog = &text_scn.data;
+    // let prog = &text_scn.data;
     // ---
     // ---
 
 
     let prog = vec![
     let prog = vec![
@@ -189,7 +189,7 @@ fn test_jit_block_port() {
     //     None => panic!("Failed to look up .classifier section"),
     //     None => panic!("Failed to look up .classifier section"),
     // };
     // };
     //
     //
-    // let ref prog = &text_scn.data;
+    // let prog = &text_scn.data;
     // ---
     // ---
 
 
     let prog = vec![
     let prog = vec![
@@ -263,11 +263,11 @@ fn test_vm_mbuff() {
         0x69, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x69, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
     ];
-    let mut mem = vec![
+    let mem = vec![
         0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd
         0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd
     ];
     ];
 
 
-    let mut mbuff = vec![0u8; 32];
+    let mbuff = vec![0u8; 32];
     unsafe {
     unsafe {
         let mut data     = mbuff.as_ptr().offset(8)  as *mut u64;
         let mut data     = mbuff.as_ptr().offset(8)  as *mut u64;
         let mut data_end = mbuff.as_ptr().offset(24) as *mut u64;
         let mut data_end = mbuff.as_ptr().offset(24) as *mut u64;
@@ -276,7 +276,7 @@ fn test_vm_mbuff() {
     }
     }
 
 
     let vm = rbpf::EbpfVmMbuff::new(&prog);
     let vm = rbpf::EbpfVmMbuff::new(&prog);
-    assert_eq!(vm.prog_exec(&mut mem, &mut mbuff), 0x2211);
+    assert_eq!(vm.prog_exec(&mem, &mbuff), 0x2211);
 }
 }
 
 
 // Program and memory come from uBPF test ldxh.
 // Program and memory come from uBPF test ldxh.