瀏覽代碼

Use slices everywhere instead of references to vectors

Jan-Erik Rediger 8 年之前
父節點
當前提交
b8eec6a49f
共有 6 個文件被更改,包括 30 次插入34 次删除
  1. 1 1
      examples/to_json.rs
  2. 2 3
      src/disassembler.rs
  3. 2 4
      src/ebpf.rs
  4. 4 4
      src/jit.rs
  5. 17 17
      src/lib.rs
  6. 4 5
      src/verifier.rs

+ 1 - 1
examples/to_json.rs

@@ -24,7 +24,7 @@ use rbpf::disassembler;
 // * Remove the "desc" (description) attributes from the output.
 // * Print integers as integers, and not as strings containing their hexadecimal representation
 //   (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
     // `LD_DW_IMM` instructions merged, and name and descriptions of the instructions.

+ 2 - 3
src/disassembler.rs

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

+ 2 - 4
src/ebpf.rs

@@ -17,8 +17,6 @@
 //! <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>
 
-use std;
-
 /// Maximum number of instructions in an eBPF program.
 pub const PROG_MAX_INSNS: usize = 4096;
 /// Size of an eBPF instructions, in bytes.
@@ -407,7 +405,7 @@ pub struct Insn {
 ///     ];
 /// 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
     // 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.
@@ -473,7 +471,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 {
         panic!("Error: eBPF program length must be a multiple of {:?} octets",
                INSN_SIZE);

+ 4 - 4
src/jit.rs

@@ -425,9 +425,9 @@ struct Jump {
 struct JitMemory<'a> {
     contents:        &'a mut [u8],
     offset:          usize,
-    pc_locs:         std::vec::Vec<usize>,
+    pc_locs:         Vec<usize>,
     special_targets: HashMap<isize, usize>,
-    jumps:           std::vec::Vec<Jump>,
+    jumps:           Vec<Jump>,
 }
 
 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>) {
         emit_push(self, RBP);
         emit_push(self, RBX);
@@ -832,7 +832,7 @@ impl<'a> std::fmt::Debug for JitMemory<'a> {
 }
 
 // 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>,
                use_mbuff: bool, update_data_ptr: bool)
     -> (unsafe fn(*mut u8, usize, *mut u8, usize, usize, usize) -> u64) {

+ 17 - 17
src/lib.rs

@@ -33,7 +33,7 @@ pub mod disassembler;
 struct MetaBuff {
     data_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
@@ -69,7 +69,7 @@ struct MetaBuff {
 /// assert_eq!(res, 0x2211);
 /// ```
 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),
     helpers: HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>,
 }
@@ -95,7 +95,7 @@ impl<'a> EbpfVmMbuff<'a> {
     /// // Instantiate a VM.
     /// 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);
 
         #[allow(unused_variables)]
@@ -134,7 +134,7 @@ impl<'a> EbpfVmMbuff<'a> {
     /// let mut vm = rbpf::EbpfVmMbuff::new(&prog1);
     /// 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);
         self.prog = prog;
     }
@@ -220,7 +220,7 @@ impl<'a> EbpfVmMbuff<'a> {
     /// let res = vm.prog_exec(&mut mem, &mut mbuff);
     /// 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;
 
         let stack = vec![0u8;ebpf::STACK_SIZE];
@@ -464,7 +464,7 @@ impl<'a> EbpfVmMbuff<'a> {
     }
 
     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 {
             return
         }
@@ -566,7 +566,7 @@ impl<'a> EbpfVmMbuff<'a> {
     ///     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
         // 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
@@ -679,7 +679,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// // Instantiate a VM. Note that we provide the start and end offsets for mem pointers.
     /// 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 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)];
@@ -730,7 +730,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// let res = vm.prog_exec(&mut mem);
     /// 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 buffer = vec![0u8; get_buff_len(data_offset, data_end_offset)];
         self.mbuff.buffer = buffer;
@@ -821,7 +821,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// let res = vm.prog_exec(&mut mem);
     /// 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();
         // 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 {
@@ -919,7 +919,7 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// ```
     // This struct redefines the `prog_exec_jit()` function, in order to pass the offsets
     // 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
         // 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
@@ -982,7 +982,7 @@ impl<'a> EbpfVmRaw<'a> {
     /// // Instantiate a VM.
     /// 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);
         EbpfVmRaw {
             parent: parent,
@@ -1019,7 +1019,7 @@ impl<'a> EbpfVmRaw<'a> {
     /// let res = vm.prog_exec(&mut mem);
     /// 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)
     }
 
@@ -1089,7 +1089,7 @@ impl<'a> EbpfVmRaw<'a> {
     /// let res = vm.prog_exec(&mut mem);
     /// assert_eq!(res, 0x22cc);
     /// ```
-    pub fn prog_exec(&self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub fn prog_exec(&self, mem: &'a mut [u8]) -> u64 {
         let mut mbuff = vec![];
         self.parent.prog_exec(mem, &mut mbuff)
     }
@@ -1161,7 +1161,7 @@ impl<'a> EbpfVmRaw<'a> {
     ///     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![];
         self.parent.prog_exec_jit(mem, &mut mbuff)
     }
@@ -1231,7 +1231,7 @@ impl<'a> EbpfVmNoData<'a> {
     /// // Instantiate a VM.
     /// 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);
         EbpfVmNoData {
             parent: parent,
@@ -1267,7 +1267,7 @@ impl<'a> EbpfVmNoData<'a> {
     /// let res = vm.prog_exec();
     /// 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)
     }
 

+ 4 - 5
src/verifier.rs

@@ -24,9 +24,8 @@
 
 
 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 {
         panic!("[Verifier] Error: eBPF program length must be a multiple of {:?} octets",
                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
     // 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);
@@ -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);
     if insn.off == -1 {
         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);
 
     let mut insn_ptr:usize = 0;