Bläddra i källkod

rbpf: Improve formatting, prepare/protect for rustfmt

Slightly improve code formatting in a few places, and protect all blocks
that we don't want rustfmt to change by adding #[rustfmt::skip]
attributes where relevant. This is in preparation for running rustfmt on
the whole repository.

Signed-off-by: Quentin Monnet <qmo@qmon.net>
Quentin Monnet 2 månader sedan
förälder
incheckning
e41119db59

+ 1 - 0
examples/disassemble.rs

@@ -6,6 +6,7 @@ use rbpf::disassembler;
 
 // Simply disassemble a program into human-readable instructions.
 fn main() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x79, 0x12, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,

+ 2 - 0
examples/load_elf.rs

@@ -62,6 +62,7 @@ fn main() {
 
     let prog = &text_scn.data;
 
+    #[rustfmt::skip]
     let packet1 = &mut [
         0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
         0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
@@ -84,6 +85,7 @@ fn main() {
         0x64, 0x66, 0x0au8
     ];
 
+    #[rustfmt::skip]
     let packet2 = &mut [
         0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
         0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,

+ 1 - 1
examples/rbpf_plugin.rs

@@ -15,7 +15,7 @@ fn _unwind(a: u64, _b: u64, _c: u64, _d: u64, _e: u64) -> u64
 // It reads the program from stdin.
 fn main() {
     let mut args: Vec<String> = std::env::args().collect();
-    #[cfg_attr(not(feature = "std"), allow(unused_mut))] // In no_std the jit variable isn't mutated.
+    #[cfg_attr(not(feature = "std"), allow(unused_mut))] // in no_std, jit variable isn't mutated
     let mut jit : bool = false;
     let mut cranelift : bool = false;
     let mut program_text = String::new();

+ 7 - 0
examples/uptime.rs

@@ -11,6 +11,7 @@ use rbpf::helpers;
 //
 // The two eBPF programs are independent and are not related to one another.
 fn main() {
+    #[rustfmt::skip]
     let prog1 = &[
         0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov32 r0, 0
         0xb4, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov32 r1, 2
@@ -24,6 +25,7 @@ fn main() {
     // constant, so that we can remain compatible with programs for the kernel. Here we also cast
     // it to a u8 so as to use it directly in program instructions.
     let hkey = helpers::BPF_KTIME_GETNS_IDX as u8;
+    #[rustfmt::skip]
     let prog2 = &[
         0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
         0xb7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r1, 0
@@ -64,6 +66,11 @@ fn main() {
         time = vm.execute_program().unwrap();
     }
 
+    print_time(time);
+}
+
+#[rustfmt::skip]
+fn print_time(time: u64) {
     let days    =  time / 10u64.pow(9)  / 60   / 60  / 24;
     let hours   = (time / 10u64.pow(9)  / 60   / 60) % 24;
     let minutes = (time / 10u64.pow(9)  / 60 ) % 60;

+ 52 - 47
src/asm_parser.rs

@@ -322,55 +322,60 @@ mod tests {
         // Sample program from ubpf.
         // We could technically indent the instructions since the parser support white spaces at
         // the beginning, but there is another test for that.
-        let src = "\
-ldxb r2, [r1+12]
-ldxb r3, [r1+13]
-lsh r3, 0x8
-or r3, r2
-mov r0, 0x0
-jne r3, 0x8, +37
-ldxb r2, [r1+23]
-jne r2, 0x6, +35
-ldxb r2, [r1+14]
-add r1, 0xe
-and r2, 0xf
-lsh r2, 0x2
-add r1, r2
-mov r0, 0x0
-ldxh r4, [r1+12]
-add r1, 0x14
-rsh r4, 0x2
-and r4, 0x3c
-mov r2, r4
-add r2, 0xffffffec
-mov r5, 0x15
-mov r3, 0x0
-jgt r5, r4, +20
-mov r5, r3
-lsh r5, 0x20
-arsh r5, 0x20
-mov r4, r1
-add r4, r5
-ldxb r5, [r4]
-jeq r5, 0x1, +4
-jeq r5, 0x0, +12
-mov r6, r3
-jeq r5, 0x5, +9
-ja +2
-add r3, 0x1
-mov r6, r3
-ldxb r3, [r4+1]
-add r3, r6
-lsh r3, 0x20
-arsh r3, 0x20
-jsgt r2, r3, -18
-ja +1
-mov r0, 0x1
-exit
-";
+        let src = "
+            ldxb r2, [r1+12]
+            ldxb r3, [r1+13]
+            lsh r3, 0x8
+            or r3, r2
+            mov r0, 0x0
+            jne r3, 0x8, +37
+            ldxb r2, [r1+23]
+            jne r2, 0x6, +35
+            ldxb r2, [r1+14]
+            add r1, 0xe
+            and r2, 0xf
+            lsh r2, 0x2
+            add r1, r2
+            mov r0, 0x0
+            ldxh r4, [r1+12]
+            add r1, 0x14
+            rsh r4, 0x2
+            and r4, 0x3c
+            mov r2, r4
+            add r2, 0xffffffec
+            mov r5, 0x15
+            mov r3, 0x0
+            jgt r5, r4, +20
+            mov r5, r3
+            lsh r5, 0x20
+            arsh r5, 0x20
+            mov r4, r1
+            add r4, r5
+            ldxb r5, [r4]
+            jeq r5, 0x1, +4
+            jeq r5, 0x0, +12
+            mov r6, r3
+            jeq r5, 0x5, +9
+            ja +2
+            add r3, 0x1
+            mov r6, r3
+            ldxb r3, [r4+1]
+            add r3, r6
+            lsh r3, 0x20
+            arsh r3, 0x20
+            jsgt r2, r3, -18
+            ja +1
+            mov r0, 0x1
+            exit
+        "
+        .trim()
+        .lines()
+        .map(|l| l.trim())
+        .collect::<Vec<_>>()
+        .join("\n");
 
         assert_eq!(
-            parse(src),
+            parse(&src),
             Ok(vec![
                 Instruction {
                     name: "ldxb".to_string(),

+ 2 - 0
src/disassembler.rs

@@ -188,6 +188,8 @@ pub fn to_insn_vec(prog: &[u8]) -> Vec<HLInsn> {
         let name;
         let desc;
         let mut imm = insn.imm as i64;
+        #[rustfmt::skip]
+        #[allow(clippy::let_unit_value)] // assign, to avoid #[rustfmt::skip] on an expression
         match insn.opc {
 
             // BPF_LD class

+ 19 - 12
src/ebpf.rs

@@ -14,8 +14,10 @@
 //! <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 byteorder::{ByteOrder, LittleEndian};
+#![cfg_attr(rustfmt, rustfmt_skip)]
+
 use crate::lib::*;
+use byteorder::{ByteOrder, LittleEndian};
 
 /// Maximum number of instructions in an eBPF program.
 pub const PROG_MAX_INSNS: usize = 1000000;
@@ -471,7 +473,7 @@ impl Insn {
     /// };
     /// assert_eq!(insn.to_array(), prog);
     /// ```
-    pub fn to_array(&self) -> [u8;INSN_SIZE] {
+    pub fn to_array(&self) -> [u8; INSN_SIZE] {
         [
             self.opc,
             self.src.wrapping_shl(4) | self.dst,
@@ -554,15 +556,18 @@ pub fn get_insn(prog: &[u8], idx: usize) -> Insn {
     // 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.
     if (idx + 1) * INSN_SIZE > prog.len() {
-        panic!("Error: cannot reach instruction at index {:?} in program containing {:?} bytes",
-               idx, prog.len());
+        panic!(
+            "Error: cannot reach instruction at index {:?} in program containing {:?} bytes",
+            idx,
+            prog.len()
+        );
     }
     Insn {
-        opc:  prog[INSN_SIZE * idx],
-        dst:  prog[INSN_SIZE * idx + 1] & 0x0f,
+        opc: prog[INSN_SIZE * idx],
+        dst: prog[INSN_SIZE * idx + 1] & 0x0f,
         src: (prog[INSN_SIZE * idx + 1] & 0xf0) >> 4,
-        off: LittleEndian::read_i16(&prog[(INSN_SIZE * idx + 2) .. ]),
-        imm: LittleEndian::read_i32(&prog[(INSN_SIZE * idx + 4) .. ]),
+        off: LittleEndian::read_i16(&prog[(INSN_SIZE * idx + 2)..]),
+        imm: LittleEndian::read_i32(&prog[(INSN_SIZE * idx + 4)..]),
     }
 }
 
@@ -612,17 +617,19 @@ pub fn get_insn(prog: &[u8], idx: usize) -> 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);
+        panic!(
+            "Error: eBPF program length must be a multiple of {:?} octets",
+            INSN_SIZE
+        );
     }
 
     let mut res = vec![];
-    let mut insn_ptr:usize = 0;
+    let mut insn_ptr: usize = 0;
 
     while insn_ptr * INSN_SIZE < prog.len() {
         let insn = get_insn(prog, insn_ptr);
         res.push(insn);
         insn_ptr += 1;
-    };
+    }
     res
 }

+ 10 - 8
src/insn_builder.rs

@@ -80,15 +80,16 @@ impl<I: Instruction> IntoBytes for &I {
     /// [ 1 byte ,      1 byte      , 2 bytes,  4 bytes  ]
     /// [ OP_CODE, SRC_REG | DST_REG, OFFSET , IMMEDIATE ]
     fn into_bytes(self) -> Self::Bytes {
+        #[rustfmt::skip]
         let buffer = vec![
-            self.opt_code_byte(),
-            self.get_src() << 4 | self.get_dst(),
-            self.get_off()          as u8,
-            (self.get_off() >> 8)   as u8,
-            self.get_imm()          as u8,
-            (self.get_imm() >> 8)   as u8,
-            (self.get_imm() >> 16)  as u8,
-            (self.get_imm() >> 24)  as u8,
+             self.opt_code_byte(),
+             self.get_src() << 4 | self.get_dst(),
+             self.get_off()        as u8,
+            (self.get_off() >> 8)  as u8,
+             self.get_imm()        as u8,
+            (self.get_imm() >> 8)  as u8,
+            (self.get_imm() >> 16) as u8,
+            (self.get_imm() >> 24) as u8,
         ];
         buffer
     }
@@ -1545,6 +1546,7 @@ mod tests {
                    .exit().push();
 
             let bytecode = program.into_bytes();
+            #[rustfmt::skip]
             let ref_prog = &[
                 0x07, 0x01, 0x00, 0x00, 0x05, 0x06, 0x00, 0x00,
                 0xb7, 0x02, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,

+ 25 - 6
src/interpreter.rs

@@ -106,7 +106,9 @@ pub fn execute_program(
             };
         }
 
-        match insn.opc {
+        #[rustfmt::skip]
+        #[allow(clippy::let_unit_value)] // assign, to avoid #[rustfmt::skip] on an expression
+        let _ = match insn.opc {
 
             // BPF_LD class
             // LD_ABS_* and LD_IND_* are supposed to load pointer to data from metadata buffer.
@@ -373,13 +375,24 @@ pub fn execute_program(
                         if let Some(function) = helpers.get(&(insn.imm as u32)) {
                             reg[0] = function(reg[1], reg[2], reg[3], reg[4], reg[5]);
                         } else {
-                            Err(Error::new(ErrorKind::Other, format!("Error: unknown helper function (id: {:#x})", insn.imm as u32)))?;
+                            Err(Error::new(
+                                ErrorKind::Other,
+                                format!(
+                                    "Error: unknown helper function (id: {:#x})",
+                                    insn.imm as u32
+                                )
+                            ))?;
                         }
                     }
-                    // eBPF to eBPF call
+                    // eBPF-to-eBPF call
                     1 => {
                         if stack_frame_idx >= MAX_CALL_DEPTH {
-                            Err(Error::new(ErrorKind::Other, format!("Error: too many nested calls (max: {MAX_CALL_DEPTH})")))?;
+                            Err(Error::new(
+                                ErrorKind::Other,
+                                format!(
+                                    "Error: too many nested calls (max: {MAX_CALL_DEPTH})"
+                                )
+                            ))?;
                         }
                         stacks[stack_frame_idx].save_registers(&reg[6..=9]);
                         stacks[stack_frame_idx].save_return_address(insn_ptr);
@@ -391,7 +404,13 @@ pub fn execute_program(
                         insn_ptr += insn.imm as usize;
                     }
                     _ => {
-                        Err(Error::new(ErrorKind::Other, format!("Error: unsupported call type #{} (insn #{})", _src, insn_ptr-1)))?;
+                        Err(Error::new(
+                            ErrorKind::Other,
+                            format!("Error: unsupported call type #{} (insn #{})",
+                                _src,
+                                insn_ptr-1
+                            )
+                        ))?;
                     }
                 }
             }
@@ -408,7 +427,7 @@ pub fn execute_program(
             }
 
             _                => unreachable!()
-        }
+        };
     }
 
     unreachable!()

+ 95 - 72
src/jit.rs

@@ -289,6 +289,7 @@ impl JitCompiler {
     }
 
     // Store register src to [dst + offset]
+    #[rustfmt::skip]
     fn emit_store(&self, mem: &mut JitMemory, size: OperandSize, src: u8, dst: u8, offset: i32) {
         match size {
             OperandSize::S16 => self.emit1(mem, 0x66), // 16-bit override
@@ -309,13 +310,14 @@ impl JitCompiler {
             self.emit_rex(mem, rexw, is_masked(src, 8), 0, is_masked(dst, 8));
         }
         match size {
-            OperandSize::S8 => self.emit1(mem, 0x88),
-            _               => self.emit1(mem, 0x89),
+            OperandSize::S8  => self.emit1(mem, 0x88),
+            _                => self.emit1(mem, 0x89),
         };
         self.emit_modrm_and_displacement(mem, src, dst, offset);
     }
 
     // Store immediate to [dst + offset]
+    #[rustfmt::skip]
     fn emit_store_imm32(&self, mem: &mut JitMemory, size: OperandSize, dst: u8, offset: i32, imm: i32) {
         match size {
             OperandSize::S16 => self.emit1(mem, 0x66), // 16-bit override
@@ -326,8 +328,8 @@ impl JitCompiler {
             _                => self.emit_basic_rex(mem, 0, 0, dst),
         };
         match size {
-            OperandSize::S8 => self.emit1(mem, 0xc6),
-            _               => self.emit1(mem, 0xc7),
+            OperandSize::S8  => self.emit1(mem, 0xc6),
+            _                => self.emit1(mem, 0xc7),
         };
         self.emit_modrm_and_displacement(mem, 0, dst, offset);
         match size {
@@ -508,9 +510,11 @@ impl JitCompiler {
             },
             (true, true) => {
                 // We have a fixed (simulated) mbuff: update mem and mem_end offset values in it.
+
                 // Store mem at mbuff + mem_offset. Trash R8.
                 self.emit_alu64(mem, 0x01, RDI, R8);                // add mbuff to mem_offset in R8
                 self.emit_store(mem, OperandSize::S64, RDX, R8, 0); // set mem at mbuff + mem_offset
+
                 // Store mem_end at mbuff + mem_end_offset. Trash R9.
                 self.emit_load(mem, OperandSize::S64, RDX, R8, 0);  // load mem into R8
                 self.emit_alu64(mem, 0x01, RCX, R8);                // add mem_len to mem (= mem_end)
@@ -552,7 +556,9 @@ impl JitCompiler {
             let src = map_register(insn.src);
             let target_pc = insn_ptr as isize + insn.off as isize + 1;
 
-            match insn.opc {
+            #[rustfmt::skip]
+            #[allow(clippy::let_unit_value)] // assign, to avoid #[rustfmt::skip] on an expression
+            let _ = match insn.opc {
 
                 // BPF_LD class
                 // R10 is a constant pointer to mem.
@@ -568,29 +574,29 @@ impl JitCompiler {
                     self.emit_mov(mem, R10, R11);                              // load mem into R11
                     self.emit_alu64(mem, 0x01, src, R11);                      // add src to R11
                     self.emit_load(mem, OperandSize::S8,  R11, RAX, insn.imm); // ld R0, mem[src+imm]
-                },
+                }
                 ebpf::LD_IND_H   => {
                     self.emit_mov(mem, R10, R11);                              // load mem into R11
                     self.emit_alu64(mem, 0x01, src, R11);                      // add src to R11
                     self.emit_load(mem, OperandSize::S16, R11, RAX, insn.imm); // ld R0, mem[src+imm]
-                },
+                }
                 ebpf::LD_IND_W   => {
                     self.emit_mov(mem, R10, R11);                              // load mem into R11
                     self.emit_alu64(mem, 0x01, src, R11);                      // add src to R11
                     self.emit_load(mem, OperandSize::S32, R11, RAX, insn.imm); // ld R0, mem[src+imm]
-                },
+                }
                 ebpf::LD_IND_DW  => {
                     self.emit_mov(mem, R10, R11);                              // load mem into R11
                     self.emit_alu64(mem, 0x01, src, R11);                      // add src to R11
                     self.emit_load(mem, OperandSize::S64, R11, RAX, insn.imm); // ld R0, mem[src+imm]
-                },
+                }
 
                 ebpf::LD_DW_IMM  => {
                     insn_ptr += 1;
                     let second_part = ebpf::get_insn(prog, insn_ptr).imm as u64;
                     let imm = (insn.imm as u32) as u64 | second_part.wrapping_shl(32);
                     self.emit_load_imm(mem, dst, imm as i64);
-                },
+                }
 
                 // BPF_LDX class
                 ebpf::LD_B_REG   =>
@@ -629,9 +635,12 @@ impl JitCompiler {
                 ebpf::ADD32_REG  => self.emit_alu32(mem, 0x01, src, dst),
                 ebpf::SUB32_IMM  => self.emit_alu32_imm32(mem, 0x81, 5, dst, insn.imm),
                 ebpf::SUB32_REG  => self.emit_alu32(mem, 0x29, src, dst),
-                ebpf::MUL32_IMM | ebpf::MUL32_REG |
-                    ebpf::DIV32_IMM | ebpf::DIV32_REG |
-                    ebpf::MOD32_IMM | ebpf::MOD32_REG =>
+                ebpf::MUL32_IMM
+                | ebpf::MUL32_REG
+                | ebpf::DIV32_IMM
+                | ebpf::DIV32_REG
+                | ebpf::MOD32_IMM
+                | ebpf::MOD32_REG =>
                     self.emit_muldivmod(mem, insn_ptr as u16, insn.opc, src, dst, insn.imm),
                 ebpf::OR32_IMM   => self.emit_alu32_imm32(mem, 0x81, 1, dst, insn.imm),
                 ebpf::OR32_REG   => self.emit_alu32(mem, 0x09, src, dst),
@@ -641,12 +650,12 @@ impl JitCompiler {
                 ebpf::LSH32_REG  => {
                     self.emit_mov(mem, src, RCX);
                     self.emit_alu32(mem, 0xd3, 4, dst);
-                },
+                }
                 ebpf::RSH32_IMM  => self.emit_alu32_imm8(mem, 0xc1, 5, dst, insn.imm as i8),
                 ebpf::RSH32_REG  => {
                     self.emit_mov(mem, src, RCX);
                     self.emit_alu32(mem, 0xd3, 5, dst);
-                },
+                }
                 ebpf::NEG32      => self.emit_alu32(mem, 0xf7, 3, dst),
                 ebpf::XOR32_IMM  => self.emit_alu32_imm32(mem, 0x81, 6, dst, insn.imm),
                 ebpf::XOR32_REG  => self.emit_alu32(mem, 0x31, src, dst),
@@ -656,7 +665,7 @@ impl JitCompiler {
                 ebpf::ARSH32_REG => {
                     self.emit_mov(mem, src, RCX);
                     self.emit_alu32(mem, 0xd3, 7, dst);
-                },
+                }
                 ebpf::LE         => {}, // No-op
                 ebpf::BE         => {
                     match insn.imm {
@@ -717,181 +726,181 @@ impl JitCompiler {
                 ebpf::JEQ_IMM    => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x84, target_pc);
-                },
+                }
                 ebpf::JEQ_REG    => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x84, target_pc);
-                },
+                }
                 ebpf::JGT_IMM    => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x87, target_pc);
-                },
+                }
                 ebpf::JGT_REG    => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x87, target_pc);
-                },
+                }
                 ebpf::JGE_IMM    => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x83, target_pc);
-                },
+                }
                 ebpf::JGE_REG    => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x83, target_pc);
-                },
+                }
                 ebpf::JLT_IMM    => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x82, target_pc);
-                },
+                }
                 ebpf::JLT_REG    => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x82, target_pc);
-                },
+                }
                 ebpf::JLE_IMM    => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x86, target_pc);
-                },
+                }
                 ebpf::JLE_REG    => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x86, target_pc);
-                },
+                }
                 ebpf::JSET_IMM   => {
                     self.emit_alu64_imm32(mem, 0xf7, 0, dst, insn.imm);
                     self.emit_jcc(mem, 0x85, target_pc);
-                },
+                }
                 ebpf::JSET_REG   => {
                     self.emit_alu64(mem, 0x85, src, dst);
                     self.emit_jcc(mem, 0x85, target_pc);
-                },
+                }
                 ebpf::JNE_IMM    => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x85, target_pc);
-                },
+                }
                 ebpf::JNE_REG    => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x85, target_pc);
-                },
+                }
                 ebpf::JSGT_IMM   => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x8f, target_pc);
-                },
+                }
                 ebpf::JSGT_REG   => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x8f, target_pc);
-                },
+                }
                 ebpf::JSGE_IMM   => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x8d, target_pc);
-                },
+                }
                 ebpf::JSGE_REG   => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x8d, target_pc);
-                },
+                }
                 ebpf::JSLT_IMM   => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x8c, target_pc);
-                },
+                }
                 ebpf::JSLT_REG   => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x8c, target_pc);
-                },
+                }
                 ebpf::JSLE_IMM   => {
                     self.emit_cmp_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x8e, target_pc);
-                },
+                }
                 ebpf::JSLE_REG   => {
                     self.emit_cmp(mem, src, dst);
                     self.emit_jcc(mem, 0x8e, target_pc);
-                },
+                }
 
                 // BPF_JMP32 class
                 ebpf::JEQ_IMM32  => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x84, target_pc);
-                },
+                }
                 ebpf::JEQ_REG32  => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x84, target_pc);
-                },
+                }
                 ebpf::JGT_IMM32  => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x87, target_pc);
-                },
+                }
                 ebpf::JGT_REG32  => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x87, target_pc);
-                },
+                }
                 ebpf::JGE_IMM32  => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x83, target_pc);
-                },
+                }
                 ebpf::JGE_REG32  => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x83, target_pc);
-                },
+                }
                 ebpf::JLT_IMM32  => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x82, target_pc);
-                },
+                }
                 ebpf::JLT_REG32  => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x82, target_pc);
-                },
+                }
                 ebpf::JLE_IMM32  => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x86, target_pc);
-                },
+                }
                 ebpf::JLE_REG32  => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x86, target_pc);
-                },
+                }
                 ebpf::JSET_IMM32 => {
                     self.emit_alu32_imm32(mem, 0xf7, 0, dst, insn.imm);
                     self.emit_jcc(mem, 0x85, target_pc);
-                },
+                }
                 ebpf::JSET_REG32 => {
                     self.emit_alu32(mem, 0x85, src, dst);
                     self.emit_jcc(mem, 0x85, target_pc);
-                },
+                }
                 ebpf::JNE_IMM32  => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x85, target_pc);
-                },
+                }
                 ebpf::JNE_REG32  => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x85, target_pc);
-                },
+                }
                 ebpf::JSGT_IMM32 => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x8f, target_pc);
-                },
+                }
                 ebpf::JSGT_REG32 => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x8f, target_pc);
-                },
+                }
                 ebpf::JSGE_IMM32 => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x8d, target_pc);
-                },
+                }
                 ebpf::JSGE_REG32 => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x8d, target_pc);
-                },
+                }
                 ebpf::JSLT_IMM32 => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x8c, target_pc);
-                },
+                }
                 ebpf::JSLT_REG32 => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x8c, target_pc);
-                },
+                }
                 ebpf::JSLE_IMM32 => {
                     self.emit_cmp32_imm32(mem, dst, insn.imm);
                     self.emit_jcc(mem, 0x8e, target_pc);
-                },
+                }
                 ebpf::JSLE_REG32 => {
                     self.emit_cmp32(mem, src, dst);
                     self.emit_jcc(mem, 0x8e, target_pc);
-                },
+                }
 
                 ebpf::CALL       => {
                     match insn.src {
@@ -904,31 +913,45 @@ impl JitCompiler {
                                 self.emit_mov(mem, R9, RCX);
                                 self.emit_call(mem, *helper as usize);
                             } else {
-                                Err(Error::new(ErrorKind::Other,
-                                            format!("[JIT] Error: unknown helper function (id: {:#x})",
-                                                    insn.imm as u32)))?;
+                                Err(Error::new(
+                                    ErrorKind::Other,
+                                    format!(
+                                        "[JIT] Error: unknown helper function (id: {:#x})",
+                                        insn.imm as u32
+                                    )
+                                ))?;
                             };
                         }
                         0x1 => {
                             let target_pc = insn_ptr as isize + insn.imm as isize + 1;
                             self.emit_local_call(mem, target_pc);
-                        }   
+                        }
                         _ => {
-                            Err(Error::new(ErrorKind::Other, format!("[JIT] Error: unexpected call type #{:?} (insn #{insn_ptr:?})", insn.src)))?;
+                            Err(Error::new(
+                                ErrorKind::Other,
+                                format!(
+                                    "[JIT] Error: unexpected call type #{:?} (insn #{insn_ptr:?})",
+                                    insn.src
+                                )
+                            ))?;
                         }
                     }
-                },
+                }
                 ebpf::TAIL_CALL  => { unimplemented!() },
                 ebpf::EXIT       => {
                     self.emit1(mem, 0xc3); // ret
-                },
+                }
 
                 _                => {
-                    Err(Error::new(ErrorKind::Other,
-                                   format!("[JIT] Error: unknown eBPF opcode {:#2x} (insn #{insn_ptr:?})",
-                                           insn.opc)))?;
-                },
-            }
+                    Err(Error::new(
+                        ErrorKind::Other,
+                        format!(
+                            "[JIT] Error: unknown eBPF opcode {:#2x} (insn #{insn_ptr:?})",
+                            insn.opc
+                        ),
+                    ))?;
+                }
+            };
 
             insn_ptr += 1;
         }

+ 0 - 1
src/lib.rs

@@ -1928,7 +1928,6 @@ impl<'a> EbpfVmNoData<'a> {
     ///
     /// let mut vm = rbpf::EbpfVmNoData::new(Some(prog)).unwrap();
     ///
-    ///
     /// vm.jit_compile();
     /// ```
     #[cfg(all(not(windows), feature = "std"))]

+ 4 - 2
src/verifier.rs

@@ -105,7 +105,9 @@ pub fn check(prog: &[u8]) -> Result<(), Error> {
         let insn = ebpf::get_insn(prog, insn_ptr);
         let mut store = false;
 
-        match insn.opc {
+        #[rustfmt::skip]
+        #[allow(clippy::let_unit_value)] // assign, to avoid #[rustfmt::skip] on an expression
+        let _ = match insn.opc {
 
             // BPF_LD class
             ebpf::LD_ABS_B   => {},
@@ -267,7 +269,7 @@ pub fn check(prog: &[u8]) -> Result<(), Error> {
             _                => {
                 reject(format!("unknown eBPF opcode {:#2x} (insn #{insn_ptr:?})", insn.opc))?;
             },
-        }
+        };
 
         check_registers(&insn, store, insn_ptr)?;
 

+ 179 - 145
tests/assembler.rs

@@ -144,18 +144,20 @@ fn test_stxh() {
 // Test all supported AluBinary mnemonics.
 #[test]
 fn test_alu_binary() {
-    assert_eq!(asm("add r1, r2
-                    sub r1, r2
-                    mul r1, r2
-                    div r1, r2
-                    or r1, r2
-                    and r1, r2
-                    lsh r1, r2
-                    rsh r1, r2
-                    mod r1, r2
-                    xor r1, r2
-                    mov r1, r2
-                    arsh r1, r2"),
+    assert_eq!(asm("
+            add r1, r2
+            sub r1, r2
+            mul r1, r2
+            div r1, r2
+            or r1, r2
+            and r1, r2
+            lsh r1, r2
+            rsh r1, r2
+            mod r1, r2
+            xor r1, r2
+            mov r1, r2
+            arsh r1, r2
+        "),
                Ok(vec![insn(ebpf::ADD64_REG, 1, 2, 0, 0),
                        insn(ebpf::SUB64_REG, 1, 2, 0, 0),
                        insn(ebpf::MUL64_REG, 1, 2, 0, 0),
@@ -169,18 +171,20 @@ fn test_alu_binary() {
                        insn(ebpf::MOV64_REG, 1, 2, 0, 0),
                        insn(ebpf::ARSH64_REG, 1, 2, 0, 0)]));
 
-    assert_eq!(asm("add r1, 2
-                    sub r1, 2
-                    mul r1, 2
-                    div r1, 2
-                    or r1, 2
-                    and r1, 2
-                    lsh r1, 2
-                    rsh r1, 2
-                    mod r1, 2
-                    xor r1, 2
-                    mov r1, 2
-                    arsh r1, 2"),
+    assert_eq!(asm("
+            add r1, 2
+            sub r1, 2
+            mul r1, 2
+            div r1, 2
+            or r1, 2
+            and r1, 2
+            lsh r1, 2
+            rsh r1, 2
+            mod r1, 2
+            xor r1, 2
+            mov r1, 2
+            arsh r1, 2
+        "),
                Ok(vec![insn(ebpf::ADD64_IMM, 1, 0, 0, 2),
                        insn(ebpf::SUB64_IMM, 1, 0, 0, 2),
                        insn(ebpf::MUL64_IMM, 1, 0, 0, 2),
@@ -194,18 +198,20 @@ fn test_alu_binary() {
                        insn(ebpf::MOV64_IMM, 1, 0, 0, 2),
                        insn(ebpf::ARSH64_IMM, 1, 0, 0, 2)]));
 
-    assert_eq!(asm("add64 r1, r2
-                    sub64 r1, r2
-                    mul64 r1, r2
-                    div64 r1, r2
-                    or64 r1, r2
-                    and64 r1, r2
-                    lsh64 r1, r2
-                    rsh64 r1, r2
-                    mod64 r1, r2
-                    xor64 r1, r2
-                    mov64 r1, r2
-                    arsh64 r1, r2"),
+    assert_eq!(asm("
+            add64 r1, r2
+            sub64 r1, r2
+            mul64 r1, r2
+            div64 r1, r2
+            or64 r1, r2
+            and64 r1, r2
+            lsh64 r1, r2
+            rsh64 r1, r2
+            mod64 r1, r2
+            xor64 r1, r2
+            mov64 r1, r2
+            arsh64 r1, r2
+        "),
                Ok(vec![insn(ebpf::ADD64_REG, 1, 2, 0, 0),
                        insn(ebpf::SUB64_REG, 1, 2, 0, 0),
                        insn(ebpf::MUL64_REG, 1, 2, 0, 0),
@@ -219,18 +225,20 @@ fn test_alu_binary() {
                        insn(ebpf::MOV64_REG, 1, 2, 0, 0),
                        insn(ebpf::ARSH64_REG, 1, 2, 0, 0)]));
 
-    assert_eq!(asm("add64 r1, 2
-                    sub64 r1, 2
-                    mul64 r1, 2
-                    div64 r1, 2
-                    or64 r1, 2
-                    and64 r1, 2
-                    lsh64 r1, 2
-                    rsh64 r1, 2
-                    mod64 r1, 2
-                    xor64 r1, 2
-                    mov64 r1, 2
-                    arsh64 r1, 2"),
+    assert_eq!(asm("
+            add64 r1, 2
+            sub64 r1, 2
+            mul64 r1, 2
+            div64 r1, 2
+            or64 r1, 2
+            and64 r1, 2
+            lsh64 r1, 2
+            rsh64 r1, 2
+            mod64 r1, 2
+            xor64 r1, 2
+            mov64 r1, 2
+            arsh64 r1, 2
+        "),
                Ok(vec![insn(ebpf::ADD64_IMM, 1, 0, 0, 2),
                        insn(ebpf::SUB64_IMM, 1, 0, 0, 2),
                        insn(ebpf::MUL64_IMM, 1, 0, 0, 2),
@@ -244,18 +252,20 @@ fn test_alu_binary() {
                        insn(ebpf::MOV64_IMM, 1, 0, 0, 2),
                        insn(ebpf::ARSH64_IMM, 1, 0, 0, 2)]));
 
-    assert_eq!(asm("add32 r1, r2
-                    sub32 r1, r2
-                    mul32 r1, r2
-                    div32 r1, r2
-                    or32 r1, r2
-                    and32 r1, r2
-                    lsh32 r1, r2
-                    rsh32 r1, r2
-                    mod32 r1, r2
-                    xor32 r1, r2
-                    mov32 r1, r2
-                    arsh32 r1, r2"),
+    assert_eq!(asm("
+            add32 r1, r2
+            sub32 r1, r2
+            mul32 r1, r2
+            div32 r1, r2
+            or32 r1, r2
+            and32 r1, r2
+            lsh32 r1, r2
+            rsh32 r1, r2
+            mod32 r1, r2
+            xor32 r1, r2
+            mov32 r1, r2
+            arsh32 r1, r2
+        "),
                Ok(vec![insn(ebpf::ADD32_REG, 1, 2, 0, 0),
                        insn(ebpf::SUB32_REG, 1, 2, 0, 0),
                        insn(ebpf::MUL32_REG, 1, 2, 0, 0),
@@ -269,18 +279,20 @@ fn test_alu_binary() {
                        insn(ebpf::MOV32_REG, 1, 2, 0, 0),
                        insn(ebpf::ARSH32_REG, 1, 2, 0, 0)]));
 
-    assert_eq!(asm("add32 r1, 2
-                    sub32 r1, 2
-                    mul32 r1, 2
-                    div32 r1, 2
-                    or32 r1, 2
-                    and32 r1, 2
-                    lsh32 r1, 2
-                    rsh32 r1, 2
-                    mod32 r1, 2
-                    xor32 r1, 2
-                    mov32 r1, 2
-                    arsh32 r1, 2"),
+    assert_eq!(asm("
+            add32 r1, 2
+            sub32 r1, 2
+            mul32 r1, 2
+            div32 r1, 2
+            or32 r1, 2
+            and32 r1, 2
+            lsh32 r1, 2
+            rsh32 r1, 2
+            mod32 r1, 2
+            xor32 r1, 2
+            mov32 r1, 2
+            arsh32 r1, 2
+        "),
                Ok(vec![insn(ebpf::ADD32_IMM, 1, 0, 0, 2),
                        insn(ebpf::SUB32_IMM, 1, 0, 0, 2),
                        insn(ebpf::MUL32_IMM, 1, 0, 0, 2),
@@ -298,9 +310,11 @@ fn test_alu_binary() {
 // Test all supported AluUnary mnemonics.
 #[test]
 fn test_alu_unary() {
-    assert_eq!(asm("neg r1
-                    neg64 r1
-                    neg32 r1"),
+    assert_eq!(asm("
+            neg r1
+            neg64 r1
+            neg32 r1
+        "),
                Ok(vec![insn(ebpf::NEG64, 1, 0, 0, 0),
                        insn(ebpf::NEG64, 1, 0, 0, 0),
                        insn(ebpf::NEG32, 1, 0, 0, 0)]));
@@ -309,10 +323,12 @@ fn test_alu_unary() {
 // Test all supported LoadAbs mnemonics.
 #[test]
 fn test_load_abs() {
-    assert_eq!(asm("ldabsw 1
-                    ldabsh 1
-                    ldabsb 1
-                    ldabsdw 1"),
+    assert_eq!(asm("
+            ldabsw 1
+            ldabsh 1
+            ldabsb 1
+            ldabsdw 1
+        "),
                Ok(vec![insn(ebpf::LD_ABS_W, 0, 0, 0, 1),
                        insn(ebpf::LD_ABS_H, 0, 0, 0, 1),
                        insn(ebpf::LD_ABS_B, 0, 0, 0, 1),
@@ -322,10 +338,12 @@ fn test_load_abs() {
 // Test all supported LoadInd mnemonics.
 #[test]
 fn test_load_ind() {
-    assert_eq!(asm("ldindw r1, 2
-                    ldindh r1, 2
-                    ldindb r1, 2
-                    ldinddw r1, 2"),
+    assert_eq!(asm("
+            ldindw r1, 2
+            ldindh r1, 2
+            ldindb r1, 2
+            ldinddw r1, 2
+        "),
                Ok(vec![insn(ebpf::LD_IND_W, 0, 1, 0, 2),
                        insn(ebpf::LD_IND_H, 0, 1, 0, 2),
                        insn(ebpf::LD_IND_B, 0, 1, 0, 2),
@@ -335,10 +353,12 @@ fn test_load_ind() {
 // Test all supported LoadReg mnemonics.
 #[test]
 fn test_load_reg() {
-    assert_eq!(asm("ldxw r1, [r2+3]
-                    ldxh r1, [r2+3]
-                    ldxb r1, [r2+3]
-                    ldxdw r1, [r2+3]"),
+    assert_eq!(asm("
+            ldxw r1, [r2+3]
+            ldxh r1, [r2+3]
+            ldxb r1, [r2+3]
+            ldxdw r1, [r2+3]
+        "),
                Ok(vec![insn(ebpf::LD_W_REG, 1, 2, 3, 0),
                        insn(ebpf::LD_H_REG, 1, 2, 3, 0),
                        insn(ebpf::LD_B_REG, 1, 2, 3, 0),
@@ -348,10 +368,12 @@ fn test_load_reg() {
 // Test all supported StoreImm mnemonics.
 #[test]
 fn test_store_imm() {
-    assert_eq!(asm("stw [r1+2], 3
-                    sth [r1+2], 3
-                    stb [r1+2], 3
-                    stdw [r1+2], 3"),
+    assert_eq!(asm("
+            stw [r1+2], 3
+            sth [r1+2], 3
+            stb [r1+2], 3
+            stdw [r1+2], 3
+        "),
                Ok(vec![insn(ebpf::ST_W_IMM, 1, 0, 2, 3),
                        insn(ebpf::ST_H_IMM, 1, 0, 2, 3),
                        insn(ebpf::ST_B_IMM, 1, 0, 2, 3),
@@ -361,10 +383,12 @@ fn test_store_imm() {
 // Test all supported StoreReg mnemonics.
 #[test]
 fn test_store_reg() {
-    assert_eq!(asm("stxw [r1+2], r3
-                    stxh [r1+2], r3
-                    stxb [r1+2], r3
-                    stxdw [r1+2], r3"),
+    assert_eq!(asm("
+            stxw [r1+2], r3
+            stxh [r1+2], r3
+            stxb [r1+2], r3
+            stxdw [r1+2], r3
+        "),
                Ok(vec![insn(ebpf::ST_W_REG, 1, 3, 2, 0),
                        insn(ebpf::ST_H_REG, 1, 3, 2, 0),
                        insn(ebpf::ST_B_REG, 1, 3, 2, 0),
@@ -374,17 +398,19 @@ fn test_store_reg() {
 // Test all supported JumpConditional mnemonics.
 #[test]
 fn test_jump_conditional() {
-    assert_eq!(asm("jeq r1, r2, +3
-                    jgt r1, r2, +3
-                    jge r1, r2, +3
-                    jlt r1, r2, +3
-                    jle r1, r2, +3
-                    jset r1, r2, +3
-                    jne r1, r2, +3
-                    jsgt r1, r2, +3
-                    jsge r1, r2, +3
-                    jslt r1, r2, +3
-                    jsle r1, r2, +3"),
+    assert_eq!(asm("
+            jeq r1, r2, +3
+            jgt r1, r2, +3
+            jge r1, r2, +3
+            jlt r1, r2, +3
+            jle r1, r2, +3
+            jset r1, r2, +3
+            jne r1, r2, +3
+            jsgt r1, r2, +3
+            jsge r1, r2, +3
+            jslt r1, r2, +3
+            jsle r1, r2, +3
+        "),
                Ok(vec![insn(ebpf::JEQ_REG, 1, 2, 3, 0),
                        insn(ebpf::JGT_REG, 1, 2, 3, 0),
                        insn(ebpf::JGE_REG, 1, 2, 3, 0),
@@ -397,17 +423,19 @@ fn test_jump_conditional() {
                        insn(ebpf::JSLT_REG, 1, 2, 3, 0),
                        insn(ebpf::JSLE_REG, 1, 2, 3, 0)]));
 
-    assert_eq!(asm("jeq r1, 2, +3
-                    jgt r1, 2, +3
-                    jge r1, 2, +3
-                    jlt r1, 2, +3
-                    jle r1, 2, +3
-                    jset r1, 2, +3
-                    jne r1, 2, +3
-                    jsgt r1, 2, +3
-                    jsge r1, 2, +3
-                    jslt r1, 2, +3
-                    jsle r1, 2, +3"),
+    assert_eq!(asm("
+            jeq r1, 2, +3
+            jgt r1, 2, +3
+            jge r1, 2, +3
+            jlt r1, 2, +3
+            jle r1, 2, +3
+            jset r1, 2, +3
+            jne r1, 2, +3
+            jsgt r1, 2, +3
+            jsge r1, 2, +3
+            jslt r1, 2, +3
+            jsle r1, 2, +3
+        "),
                Ok(vec![insn(ebpf::JEQ_IMM, 1, 0, 3, 2),
                        insn(ebpf::JGT_IMM, 1, 0, 3, 2),
                        insn(ebpf::JGE_IMM, 1, 0, 3, 2),
@@ -420,17 +448,19 @@ fn test_jump_conditional() {
                        insn(ebpf::JSLT_IMM, 1, 0, 3, 2),
                        insn(ebpf::JSLE_IMM, 1, 0, 3, 2)]));
 
-    assert_eq!(asm("jeq32 r1, r2, +3
-                    jgt32 r1, r2, +3
-                    jge32 r1, r2, +3
-                    jlt32 r1, r2, +3
-                    jle32 r1, r2, +3
-                    jset32 r1, r2, +3
-                    jne32 r1, r2, +3
-                    jsgt32 r1, r2, +3
-                    jsge32 r1, r2, +3
-                    jslt32 r1, r2, +3
-                    jsle32 r1, r2, +3"),
+    assert_eq!(asm("
+            jeq32 r1, r2, +3
+            jgt32 r1, r2, +3
+            jge32 r1, r2, +3
+            jlt32 r1, r2, +3
+            jle32 r1, r2, +3
+            jset32 r1, r2, +3
+            jne32 r1, r2, +3
+            jsgt32 r1, r2, +3
+            jsge32 r1, r2, +3
+            jslt32 r1, r2, +3
+            jsle32 r1, r2, +3
+        "),
                Ok(vec![insn(ebpf::JEQ_REG32, 1, 2, 3, 0),
                        insn(ebpf::JGT_REG32, 1, 2, 3, 0),
                        insn(ebpf::JGE_REG32, 1, 2, 3, 0),
@@ -443,17 +473,19 @@ fn test_jump_conditional() {
                        insn(ebpf::JSLT_REG32, 1, 2, 3, 0),
                        insn(ebpf::JSLE_REG32, 1, 2, 3, 0)]));
 
-    assert_eq!(asm("jeq32 r1, 2, +3
-                    jgt32 r1, 2, +3
-                    jge32 r1, 2, +3
-                    jlt32 r1, 2, +3
-                    jle32 r1, 2, +3
-                    jset32 r1, 2, +3
-                    jne32 r1, 2, +3
-                    jsgt32 r1, 2, +3
-                    jsge32 r1, 2, +3
-                    jslt32 r1, 2, +3
-                    jsle32 r1, 2, +3"),
+    assert_eq!(asm("
+            jeq32 r1, 2, +3
+            jgt32 r1, 2, +3
+            jge32 r1, 2, +3
+            jlt32 r1, 2, +3
+            jle32 r1, 2, +3
+            jset32 r1, 2, +3
+            jne32 r1, 2, +3
+            jsgt32 r1, 2, +3
+            jsge32 r1, 2, +3
+            jslt32 r1, 2, +3
+            jsle32 r1, 2, +3
+        "),
                Ok(vec![insn(ebpf::JEQ_IMM32, 1, 0, 3, 2),
                        insn(ebpf::JGT_IMM32, 1, 0, 3, 2),
                        insn(ebpf::JGE_IMM32, 1, 0, 3, 2),
@@ -470,12 +502,14 @@ fn test_jump_conditional() {
 // Test all supported Endian mnemonics.
 #[test]
 fn test_endian() {
-    assert_eq!(asm("be16 r1
-                    be32 r1
-                    be64 r1
-                    le16 r1
-                    le32 r1
-                    le64 r1"),
+    assert_eq!(asm("
+            be16 r1
+            be32 r1
+            be64 r1
+            le16 r1
+            le32 r1
+            le64 r1
+        "),
                Ok(vec![insn(ebpf::BE, 1, 0, 0, 16),
                        insn(ebpf::BE, 1, 0, 0, 32),
                        insn(ebpf::BE, 1, 0, 0, 64),

+ 3 - 0
tests/common.rs

@@ -53,6 +53,7 @@ pub const TCP_SACK_ASM: &str = "
     exit";
 
 #[allow(dead_code)]
+#[rustfmt::skip]
 pub const TCP_SACK_BIN: [u8;352] = [
     0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -101,6 +102,7 @@ pub const TCP_SACK_BIN: [u8;352] = [
 ];
 
 #[allow(dead_code)]
+#[rustfmt::skip]
 pub const TCP_SACK_MATCH: [u8;78] = [
     0x00, 0x26, 0x62, 0x2f, 0x47, 0x87, 0x00, 0x1d,
     0x60, 0xb3, 0x01, 0x84, 0x08, 0x00, 0x45, 0x00,
@@ -115,6 +117,7 @@ pub const TCP_SACK_MATCH: [u8;78] = [
 ];
 
 #[allow(dead_code)]
+#[rustfmt::skip]
 pub const TCP_SACK_NOMATCH: [u8;66] = [
     0x00, 0x26, 0x62, 0x2f, 0x47, 0x87, 0x00, 0x1d,
     0x60, 0xb3, 0x01, 0x84, 0x08, 0x00, 0x45, 0x00,

+ 38 - 11
tests/cranelift.rs

@@ -466,9 +466,10 @@ test_cranelift!(
 // #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
 #[ignore = "We have stack OOB checks, but we don't yet catch the trap code and convert it into a panic"]
 fn test_cranelift_err_stack_out_of_bound() {
+    #[rustfmt::skip]
     let prog = [
-        0x72, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-        0x00,
+        0x72, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     ];
     let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
     vm.cranelift_compile().unwrap();
@@ -2010,16 +2011,26 @@ test_cranelift!(
     0x1
 );
 
+#[rustfmt::skip]
 const PROG_TCP_PORT_80: [u8; 152] = [
-    0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00,
-    0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x02, 0x0a, 0x00, 0x06, 0x00, 0x00, 0x00,
-    0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
-    0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
-    0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x15, 0x02, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x69, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x55, 0x01, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x55, 0x03, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x55, 0x02, 0x0a, 0x00, 0x06, 0x00, 0x00, 0x00,
+    0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+    0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
+    0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x69, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x15, 0x02, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00,
+    0x69, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x55, 0x01, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00,
+    0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
     0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 ];
 
@@ -2112,10 +2123,12 @@ fn test_cranelift_tcp_sack_nomatch() {
 
 #[test]
 fn test_cranelift_ldabsb() {
+    #[rustfmt::skip]
     let prog = &[
         0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -2128,10 +2141,12 @@ fn test_cranelift_ldabsb() {
 
 #[test]
 fn test_cranelift_ldabsh() {
+    #[rustfmt::skip]
     let prog = &[
         0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -2144,10 +2159,12 @@ fn test_cranelift_ldabsh() {
 
 #[test]
 fn test_cranelift_ldabsw() {
+    #[rustfmt::skip]
     let prog = &[
         0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -2160,10 +2177,12 @@ fn test_cranelift_ldabsw() {
 
 #[test]
 fn test_cranelift_ldabsdw() {
+    #[rustfmt::skip]
     let prog = &[
         0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -2176,11 +2195,13 @@ fn test_cranelift_ldabsdw() {
 
 #[test]
 fn test_cranelift_ldindb() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
         0x50, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -2193,11 +2214,13 @@ fn test_cranelift_ldindb() {
 
 #[test]
 fn test_cranelift_ldindh() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
         0x48, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -2210,11 +2233,13 @@ fn test_cranelift_ldindh() {
 
 #[test]
 fn test_cranelift_ldindw() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
         0x40, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -2227,11 +2252,13 @@ fn test_cranelift_ldindw() {
 
 #[test]
 fn test_cranelift_ldinddw() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
         0x58, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,

+ 173 - 140
tests/disassembler.rs

@@ -13,8 +13,8 @@ use rbpf::disassembler::to_insn_vec;
 macro_rules! disasm {
     ($src:expr) => {
         {
-            let src = $src;
-            let asm = assemble(src).expect("Can't assemble from string");
+            let src = $src.trim().lines().map(|l| l.trim()).collect::<Vec<_>>().join("\n");
+            let asm = assemble(&src).expect("Can't assemble from string");
             let insn = to_insn_vec(&asm);
             let reasm = insn.into_iter().map(|ins| ins.desc).collect::<Vec<_>>().join("\n");
 
@@ -130,172 +130,202 @@ fn test_stxh() {
 // Test all supported AluBinary mnemonics.
 #[test]
 fn test_alu_binary() {
-    disasm!("add64 r1, r2
-sub64 r1, r2
-mul64 r1, r2
-div64 r1, r2
-or64 r1, r2
-and64 r1, r2
-lsh64 r1, r2
-rsh64 r1, r2
-mod64 r1, r2
-xor64 r1, r2
-mov64 r1, r2
-arsh64 r1, r2");
-
-    disasm!("add64 r1, 0x2
-sub64 r1, 0x2
-mul64 r1, 0x2
-div64 r1, 0x2
-or64 r1, 0x2
-and64 r1, 0x2
-lsh64 r1, 0x2
-rsh64 r1, 0x2
-mod64 r1, 0x2
-xor64 r1, 0x2
-mov64 r1, 0x2
-arsh64 r1, 0x2");
-
-    disasm!("add32 r1, r2
-sub32 r1, r2
-mul32 r1, r2
-div32 r1, r2
-or32 r1, r2
-and32 r1, r2
-lsh32 r1, r2
-rsh32 r1, r2
-mod32 r1, r2
-xor32 r1, r2
-mov32 r1, r2
-arsh32 r1, r2");
-
-    disasm!("add32 r1, 0x2
-sub32 r1, 0x2
-mul32 r1, 0x2
-div32 r1, 0x2
-or32 r1, 0x2
-and32 r1, 0x2
-lsh32 r1, 0x2
-rsh32 r1, 0x2
-mod32 r1, 0x2
-xor32 r1, 0x2
-mov32 r1, 0x2
-arsh32 r1, 0x2");
+    disasm!("
+        add64 r1, r2
+        sub64 r1, r2
+        mul64 r1, r2
+        div64 r1, r2
+        or64 r1, r2
+        and64 r1, r2
+        lsh64 r1, r2
+        rsh64 r1, r2
+        mod64 r1, r2
+        xor64 r1, r2
+        mov64 r1, r2
+        arsh64 r1, r2
+        ");
+
+    disasm!("
+        add64 r1, 0x2
+        sub64 r1, 0x2
+        mul64 r1, 0x2
+        div64 r1, 0x2
+        or64 r1, 0x2
+        and64 r1, 0x2
+        lsh64 r1, 0x2
+        rsh64 r1, 0x2
+        mod64 r1, 0x2
+        xor64 r1, 0x2
+        mov64 r1, 0x2
+        arsh64 r1, 0x2
+        ");
+
+    disasm!("
+        add32 r1, r2
+        sub32 r1, r2
+        mul32 r1, r2
+        div32 r1, r2
+        or32 r1, r2
+        and32 r1, r2
+        lsh32 r1, r2
+        rsh32 r1, r2
+        mod32 r1, r2
+        xor32 r1, r2
+        mov32 r1, r2
+        arsh32 r1, r2
+        ");
+
+    disasm!("
+        add32 r1, 0x2
+        sub32 r1, 0x2
+        mul32 r1, 0x2
+        div32 r1, 0x2
+        or32 r1, 0x2
+        and32 r1, 0x2
+        lsh32 r1, 0x2
+        rsh32 r1, 0x2
+        mod32 r1, 0x2
+        xor32 r1, 0x2
+        mov32 r1, 0x2
+        arsh32 r1, 0x2
+        ");
 }
 
 // Test all supported AluUnary mnemonics.
 #[test]
 fn test_alu_unary() {
-    disasm!("neg64 r1
-neg32 r1");
+    disasm!("
+        neg64 r1
+        neg32 r1
+        ");
 }
 
 // Test all supported LoadAbs mnemonics.
 #[test]
 fn test_load_abs() {
-    disasm!("ldabsw 0x1
-ldabsh 0x1
-ldabsb 0x1
-ldabsdw 0x1");
+    disasm!("
+        ldabsw 0x1
+        ldabsh 0x1
+        ldabsb 0x1
+        ldabsdw 0x1
+        ");
 }
 
 // Test all supported LoadInd mnemonics.
 #[test]
 fn test_load_ind() {
-    disasm!("ldindw r1, 0x2
-ldindh r1, 0x2
-ldindb r1, 0x2
-ldinddw r1, 0x2");
+    disasm!("
+        ldindw r1, 0x2
+        ldindh r1, 0x2
+        ldindb r1, 0x2
+        ldinddw r1, 0x2
+        ");
 }
 
 // Test all supported LoadReg mnemonics.
 #[test]
 fn test_load_reg() {
-    disasm!(r"ldxw r1, [r2+0x3]
-ldxh r1, [r2+0x3]
-ldxb r1, [r2+0x3]
-ldxdw r1, [r2+0x3]");
+    disasm!(r"
+        ldxw r1, [r2+0x3]
+        ldxh r1, [r2+0x3]
+        ldxb r1, [r2+0x3]
+        ldxdw r1, [r2+0x3]
+        ");
 }
 
 // Test all supported StoreImm mnemonics.
 #[test]
 fn test_store_imm() {
-    disasm!("stw [r1+0x2], 0x3
-sth [r1+0x2], 0x3
-stb [r1+0x2], 0x3
-stdw [r1+0x2], 0x3");
+    disasm!("
+        stw [r1+0x2], 0x3
+        sth [r1+0x2], 0x3
+        stb [r1+0x2], 0x3
+        stdw [r1+0x2], 0x3
+        ");
 }
 
 // Test all supported StoreReg mnemonics.
 #[test]
 fn test_store_reg() {
-    disasm!("stxw [r1+0x2], r3
-stxh [r1+0x2], r3
-stxb [r1+0x2], r3
-stxdw [r1+0x2], r3");
+    disasm!("
+        stxw [r1+0x2], r3
+        stxh [r1+0x2], r3
+        stxb [r1+0x2], r3
+        stxdw [r1+0x2], r3
+        ");
 }
 
 // Test all supported JumpConditional mnemonics.
 #[test]
 fn test_jump_conditional() {
-    disasm!("jeq r1, r2, +0x3
-jgt r1, r2, +0x3
-jge r1, r2, +0x3
-jlt r1, r2, +0x3
-jle r1, r2, +0x3
-jset r1, r2, +0x3
-jne r1, r2, +0x3
-jsgt r1, r2, +0x3
-jsge r1, r2, -0x3
-jslt r1, r2, +0x3
-jsle r1, r2, -0x3");
-
-    disasm!("jeq r1, 0x2, +0x3
-jgt r1, 0x2, +0x3
-jge r1, 0x2, +0x3
-jlt r1, 0x2, +0x3
-jle r1, 0x2, +0x3
-jset r1, 0x2, +0x3
-jne r1, 0x2, +0x3
-jsgt r1, 0x2, +0x3
-jsge r1, 0x2, -0x3
-jslt r1, 0x2, +0x3
-jsle r1, 0x2, -0x3");
-
-    disasm!("jeq32 r1, r2, +0x3
-jgt32 r1, r2, +0x3
-jge32 r1, r2, +0x3
-jlt32 r1, r2, +0x3
-jle32 r1, r2, +0x3
-jset32 r1, r2, +0x3
-jne32 r1, r2, +0x3
-jsgt32 r1, r2, +0x3
-jsge32 r1, r2, -0x3
-jslt32 r1, r2, +0x3
-jsle32 r1, r2, -0x3");
-
-    disasm!("jeq32 r1, 0x2, +0x3
-jgt32 r1, 0x2, +0x3
-jge32 r1, 0x2, +0x3
-jlt32 r1, 0x2, +0x3
-jle32 r1, 0x2, +0x3
-jset32 r1, 0x2, +0x3
-jne32 r1, 0x2, +0x3
-jsgt32 r1, 0x2, +0x3
-jsge32 r1, 0x2, -0x3
-jslt32 r1, 0x2, +0x3
-jsle32 r1, 0x2, -0x3");
+    disasm!("
+        jeq r1, r2, +0x3
+        jgt r1, r2, +0x3
+        jge r1, r2, +0x3
+        jlt r1, r2, +0x3
+        jle r1, r2, +0x3
+        jset r1, r2, +0x3
+        jne r1, r2, +0x3
+        jsgt r1, r2, +0x3
+        jsge r1, r2, -0x3
+        jslt r1, r2, +0x3
+        jsle r1, r2, -0x3
+        ");
+
+    disasm!("
+        jeq r1, 0x2, +0x3
+        jgt r1, 0x2, +0x3
+        jge r1, 0x2, +0x3
+        jlt r1, 0x2, +0x3
+        jle r1, 0x2, +0x3
+        jset r1, 0x2, +0x3
+        jne r1, 0x2, +0x3
+        jsgt r1, 0x2, +0x3
+        jsge r1, 0x2, -0x3
+        jslt r1, 0x2, +0x3
+        jsle r1, 0x2, -0x3
+        ");
+
+    disasm!("
+        jeq32 r1, r2, +0x3
+        jgt32 r1, r2, +0x3
+        jge32 r1, r2, +0x3
+        jlt32 r1, r2, +0x3
+        jle32 r1, r2, +0x3
+        jset32 r1, r2, +0x3
+        jne32 r1, r2, +0x3
+        jsgt32 r1, r2, +0x3
+        jsge32 r1, r2, -0x3
+        jslt32 r1, r2, +0x3
+        jsle32 r1, r2, -0x3
+        ");
+
+    disasm!("
+        jeq32 r1, 0x2, +0x3
+        jgt32 r1, 0x2, +0x3
+        jge32 r1, 0x2, +0x3
+        jlt32 r1, 0x2, +0x3
+        jle32 r1, 0x2, +0x3
+        jset32 r1, 0x2, +0x3
+        jne32 r1, 0x2, +0x3
+        jsgt32 r1, 0x2, +0x3
+        jsge32 r1, 0x2, -0x3
+        jslt32 r1, 0x2, +0x3
+        jsle32 r1, 0x2, -0x3
+        ");
 }
 
 // Test all supported Endian mnemonics.
 #[test]
 fn test_endian() {
-    disasm!("be16 r1
-be32 r1
-be64 r1
-le16 r1
-le32 r1
-le64 r1");
+    disasm!("
+        be16 r1
+        be32 r1
+        be64 r1
+        le16 r1
+        le32 r1
+        le64 r1
+        ");
 }
 
 #[test]
@@ -307,6 +337,7 @@ fn test_large_immediate() {
 // Non-regression tests for overflow when trying to negate offset 0x8000i16.
 #[test]
 fn test_offset_overflow() {
+    #[rustfmt::skip]
     let insns = [
         0x62, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, // stw
         0x6a, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, // sth
@@ -322,18 +353,20 @@ fn test_offset_overflow() {
         0x1e, 0x21, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, // jeq32 (reg)
     ];
 
-    let expected_output = "stw [r1-0x8000], 0x1
-sth [r1-0x8000], 0x1
-stb [r1-0x8000], 0x1
-stdw [r1-0x8000], 0x1
-ldxw r1, [r0-0x8000]
-ldxh r1, [r0-0x8000]
-ldxb r1, [r0-0x8000]
-ldxdw r1, [r0-0x8000]
-jeq r1, 0x2, -0x8000
-jeq r1, r2, -0x8000
-jeq32 r1, 0x2, -0x8000
-jeq32 r1, r2, -0x8000";
+    let expected_output = "
+        stw [r1-0x8000], 0x1
+        sth [r1-0x8000], 0x1
+        stb [r1-0x8000], 0x1
+        stdw [r1-0x8000], 0x1
+        ldxw r1, [r0-0x8000]
+        ldxh r1, [r0-0x8000]
+        ldxb r1, [r0-0x8000]
+        ldxdw r1, [r0-0x8000]
+        jeq r1, 0x2, -0x8000
+        jeq r1, r2, -0x8000
+        jeq32 r1, 0x2, -0x8000
+        jeq32 r1, r2, -0x8000
+    ".trim().lines().map(|l| l.trim()).collect::<Vec<_>>().join("\n");
 
     let prog = to_insn_vec(&insns);
     let asm = prog.into_iter().map(|ins| ins.desc).collect::<Vec<_>>().join("\n");

+ 35 - 2
tests/misc.rs

@@ -110,6 +110,7 @@ fn test_vm_block_port() {
     // let prog = &text_scn.data;
     // ---
 
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x79, 0x12, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x79 instead of 0x61
@@ -138,6 +139,7 @@ fn test_vm_block_port() {
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
 
+    #[rustfmt::skip]
     let packet = &mut [
         0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
         0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
@@ -192,6 +194,7 @@ fn test_jit_block_port() {
     // let prog = &text_scn.data;
     // ---
 
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x79, 0x12, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x79 instead of 0x61
@@ -220,6 +223,7 @@ fn test_jit_block_port() {
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
 
+    #[rustfmt::skip]
     let packet = &mut [
         0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
         0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
@@ -256,6 +260,7 @@ fn test_jit_block_port() {
 // Program and memory come from uBPF test ldxh.
 #[test]
 fn test_vm_mbuff() {
+    #[rustfmt::skip]
     let prog = &[
         // Load mem from mbuff into R1
         0x79, 0x11, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -310,6 +315,7 @@ fn test_vm_mbuff_with_rust_api() {
 #[test]
 #[cfg(all(not(windows), feature = "std"))]
 fn test_jit_mbuff() {
+    #[rustfmt::skip]
     let prog = &[
         // Load mem from mbuff into R1
         0x79, 0x11, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -339,10 +345,12 @@ fn test_jit_mbuff() {
 #[cfg(all(not(windows), feature = "std"))]
 #[test]
 fn test_vm_jit_ldabsb() {
+    #[rustfmt::skip]
     let prog = &[
         0x30, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -359,10 +367,12 @@ fn test_vm_jit_ldabsb() {
 #[cfg(all(not(windows), feature = "std"))]
 #[test]
 fn test_vm_jit_ldabsh() {
+    #[rustfmt::skip]
     let prog = &[
         0x28, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -379,10 +389,12 @@ fn test_vm_jit_ldabsh() {
 #[cfg(all(not(windows), feature = "std"))]
 #[test]
 fn test_vm_jit_ldabsw() {
+    #[rustfmt::skip]
     let prog = &[
         0x20, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -399,10 +411,12 @@ fn test_vm_jit_ldabsw() {
 #[cfg(all(not(windows), feature = "std"))]
 #[test]
 fn test_vm_jit_ldabsdw() {
+    #[rustfmt::skip]
     let prog = &[
         0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -419,10 +433,12 @@ fn test_vm_jit_ldabsdw() {
 #[test]
 #[should_panic(expected = "Error: out of bounds memory load (insn #1),")]
 fn test_vm_err_ldabsb_oob() {
+    #[rustfmt::skip]
     let prog = &[
         0x38, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -436,6 +452,7 @@ fn test_vm_err_ldabsb_oob() {
 #[test]
 #[should_panic(expected = "Error: out of bounds memory load (insn #1),")]
 fn test_vm_err_ldabsb_nomem() {
+    #[rustfmt::skip]
     let prog = &[
         0x38, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -449,11 +466,13 @@ fn test_vm_err_ldabsb_nomem() {
 #[cfg(all(not(windows), feature = "std"))]
 #[test]
 fn test_vm_jit_ldindb() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
         0x50, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -470,11 +489,13 @@ fn test_vm_jit_ldindb() {
 #[cfg(all(not(windows), feature = "std"))]
 #[test]
 fn test_vm_jit_ldindh() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
         0x48, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -491,11 +512,13 @@ fn test_vm_jit_ldindh() {
 #[cfg(all(not(windows), feature = "std"))]
 #[test]
 fn test_vm_jit_ldindw() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
         0x40, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -512,11 +535,13 @@ fn test_vm_jit_ldindw() {
 #[cfg(all(not(windows), feature = "std"))]
 #[test]
 fn test_vm_jit_ldinddw() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
         0x58, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -533,11 +558,13 @@ fn test_vm_jit_ldinddw() {
 #[test]
 #[should_panic(expected = "Error: out of bounds memory load (insn #2),")]
 fn test_vm_err_ldindb_oob() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
         0x38, 0x10, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     ];
+    #[rustfmt::skip]
     let mem = &mut [
         0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
@@ -551,6 +578,7 @@ fn test_vm_err_ldindb_oob() {
 #[test]
 #[should_panic(expected = "Error: out of bounds memory load (insn #2),")]
 fn test_vm_err_ldindb_nomem() {
+    #[rustfmt::skip]
     let prog = &[
         0xb7, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0x38, 0x10, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
@@ -643,7 +671,8 @@ fn test_vm_jit_bpf_to_bpf_call(){
         exit
         mov64 r0, r2
         add64 r0, r1
-        exit").unwrap();
+        exit
+        ").unwrap();
     let mut vm = rbpf::EbpfVmNoData::new(Some(&test_code)).unwrap();
     vm.jit_compile().unwrap();
     let vm_res= unsafe { vm.execute_program_jit().unwrap() };
@@ -653,6 +682,7 @@ fn test_vm_jit_bpf_to_bpf_call(){
 #[test]
 #[should_panic(expected = "[Verifier] Error: unsupported call type #2 (insn #0)")]
 fn test_verifier_err_other_type_call(){
+    #[rustfmt::skip]
     let prog = &[
         0x85, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -664,6 +694,7 @@ fn test_verifier_err_other_type_call(){
 #[test]
 #[should_panic(expected = "Error: unsupported call type #2 (insn #0)")]
 fn test_vm_other_type_call(){
+    #[rustfmt::skip]
     let prog = &[
         0x85, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -680,6 +711,7 @@ fn test_vm_other_type_call(){
 #[test]
 #[should_panic(expected = "[JIT] Error: unexpected call type #2 (insn #0)")]
 fn test_vm_jit_other_type_call(){
+    #[rustfmt::skip]
     let prog = &[
         0x85, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -712,7 +744,8 @@ fn test_stack_overflow(){
         exit
         mov64 r0, r2
         add64 r0, r1
-        exit").unwrap();
+        exit
+        ").unwrap();
     let mut vm = rbpf::EbpfVmNoData::new(Some(&test_code)).unwrap();
     vm.set_stack_usage_calculator(|_,_,_| 512, Box::new(())).unwrap();
     vm.execute_program().unwrap();

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 214 - 112
tests/ubpf_jit_x86_64.rs


+ 18 - 7
tests/ubpf_verifier.rs

@@ -24,6 +24,7 @@ use rbpf::ebpf;
 #[test]
 #[should_panic(expected = "[Verifier] Error: unsupported argument for LE/BE (insn #0)")]
 fn test_verifier_err_endian_size() {
+    #[rustfmt::skip]
     let prog = &[
         0xdc, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
         0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -33,9 +34,11 @@ fn test_verifier_err_endian_size() {
     vm.execute_program().unwrap();
 }
 
+// Note: uBPF has test-err-incomplete-lddw2, which is the same
 #[test]
 #[should_panic(expected = "[Verifier] Error: incomplete LD_DW instruction (insn #0)")]
-fn test_verifier_err_incomplete_lddw() { // Note: ubpf has test-err-incomplete-lddw2, which is the same
+fn test_verifier_err_incomplete_lddw() {
+    #[rustfmt::skip]
     let prog = &[
         0x18, 0x00, 0x00, 0x00, 0x88, 0x77, 0x66, 0x55,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -49,7 +52,8 @@ fn test_verifier_err_incomplete_lddw() { // Note: ubpf has test-err-incomplete-l
 fn test_verifier_err_infinite_loop() {
     let prog = assemble("
         ja -1
-        exit").unwrap();
+        exit
+        ").unwrap();
     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
     vm.execute_program().unwrap();
 }
@@ -59,7 +63,8 @@ fn test_verifier_err_infinite_loop() {
 fn test_verifier_err_invalid_reg_dst() {
     let prog = assemble("
         mov r11, 1
-        exit").unwrap();
+        exit
+        ").unwrap();
     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
     vm.execute_program().unwrap();
 }
@@ -69,7 +74,8 @@ fn test_verifier_err_invalid_reg_dst() {
 fn test_verifier_err_invalid_reg_src() {
     let prog = assemble("
         mov r0, r11
-        exit").unwrap();
+        exit
+        ").unwrap();
     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
     vm.execute_program().unwrap();
 }
@@ -80,7 +86,8 @@ fn test_verifier_err_jmp_lddw() {
     let prog = assemble("
         ja +1
         lddw r0, 0x1122334455667788
-        exit").unwrap();
+        exit
+        ").unwrap();
     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
     vm.execute_program().unwrap();
 }
@@ -90,7 +97,8 @@ fn test_verifier_err_jmp_lddw() {
 fn test_verifier_err_jmp_out() {
     let prog = assemble("
         ja +2
-        exit").unwrap();
+        exit
+        ").unwrap();
     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
     vm.execute_program().unwrap();
 }
@@ -133,6 +141,7 @@ fn test_verifier_err_too_many_instructions() {
 #[test]
 #[should_panic(expected = "[Verifier] Error: unknown eBPF opcode 0x6 (insn #0)")]
 fn test_verifier_err_unknown_opcode() {
+    #[rustfmt::skip]
     let prog = &[
         0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
@@ -146,7 +155,8 @@ fn test_verifier_err_unknown_opcode() {
 fn test_verifier_err_write_r10() {
     let prog = assemble("
         mov r10, 1
-        exit").unwrap();
+        exit
+        ").unwrap();
     let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
     vm.execute_program().unwrap();
 }
@@ -154,6 +164,7 @@ fn test_verifier_err_write_r10() {
 #[test]
 #[should_panic(expected = "[Verifier] Error: call out of code to #2 (insn #0)")]
 fn test_verifier_err_funcall_over_the_end() {
+    #[rustfmt::skip]
     let prog = &[
         0x85, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
         0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 216 - 115
tests/ubpf_vm.rs


Vissa filer visades inte eftersom för många filer har ändrats