From ef31de065e08d3947dbf946e042baff1972c6872 Mon Sep 17 00:00:00 2001 From: Lucas Steuernagel Date: Fri, 18 Oct 2024 20:00:50 -0300 Subject: [PATCH 1/9] Modify interpreter and jit --- src/interpreter.rs | 72 ++++++++++++++++++++++------------------------ src/jit.rs | 62 +++++++++++++++++++-------------------- 2 files changed, 65 insertions(+), 69 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index 75064d81..06323858 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -12,6 +12,7 @@ //! Interpreter for eBPF programs. +use crate::program::BuiltinFunction; use crate::{ ebpf::{self, STACK_PTR_REG}, elf::Executable, @@ -526,32 +527,14 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> { // Do not delegate the check to the verifier, since self.registered functions can be // changed after the program has been verified. - ebpf::CALL_IMM - | ebpf::SYSCALL if insn.opc == ebpf::CALL_IMM || self.executable.get_sbpf_version().static_syscalls() => { - let mut resolved = false; - let (external, internal) = if self.executable.get_sbpf_version().static_syscalls() { - (insn.src == 0, insn.src != 0) - } else { - (true, true) - }; - - if external { - if let Some((_function_name, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { - resolved = true; - - self.vm.due_insn_count = self.vm.previous_instruction_meter - self.vm.due_insn_count; - self.vm.registers[0..6].copy_from_slice(&self.reg[0..6]); - self.vm.invoke_function(function); - self.vm.due_insn_count = 0; - self.reg[0] = match &self.vm.program_result { - ProgramResult::Ok(value) => *value, - ProgramResult::Err(_err) => return false, - }; - } - } - - if internal && !resolved { - if let Some((_function_name, target_pc)) = + ebpf::CALL_IMM => { + if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { + // SBPFv1 syscall + self.reg[0] = match self.dispatch_syscall(function) { + ProgramResult::Ok(value) => *value, + ProgramResult::Err(_err) => return false, + }; + } else if let Some((_, target_pc)) = self.executable .get_function_registry() .lookup_by_key( @@ -559,22 +542,27 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> { .executable .get_sbpf_version() .calculate_call_imm_target_pc(self.reg[11] as usize, insn.imm) - ) - { - resolved = true; - - // make BPF to BPF call - if !self.push_frame(config) { - return false; - } - check_pc!(self, next_pc, target_pc as u64); + ) { + // make BPF to BPF call + if !self.push_frame(config) { + return false; } - } - - if !resolved { + check_pc!(self, next_pc, target_pc as u64); + } else { throw_error!(self, EbpfError::UnsupportedInstruction); } } + ebpf::SYSCALL if self.executable.get_sbpf_version().static_syscalls() => { + if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { + // SBPFv2 syscall + self.reg[0] = match self.dispatch_syscall(function) { + ProgramResult::Ok(value) => *value, + ProgramResult::Err(_err) => return false, + }; + } else { + throw_error!(self, EbpfError::UnsupportedInstruction); + } + }, ebpf::RETURN | ebpf::EXIT => { if (insn.opc == ebpf::EXIT && self.executable.get_sbpf_version().static_syscalls()) @@ -609,4 +597,12 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> { self.reg[11] = next_pc; true } + + fn dispatch_syscall(&mut self, function: BuiltinFunction) -> &ProgramResult { + self.vm.due_insn_count = self.vm.previous_instruction_meter - self.vm.due_insn_count; + self.vm.registers[0..6].copy_from_slice(&self.reg[0..6]); + self.vm.invoke_function(function); + self.vm.due_insn_count = 0; + &self.vm.program_result + } } diff --git a/src/jit.rs b/src/jit.rs index 4b2cddf2..48957e98 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -23,6 +23,7 @@ use rand::{ }; use std::{fmt::Debug, mem, ptr}; +use crate::program::BuiltinFunction; use crate::{ ebpf::{self, FIRST_SCRATCH_REG, FRAME_PTR_REG, INSN_SIZE, SCRATCH_REGS, STACK_PTR_REG}, elf::Executable, @@ -705,29 +706,12 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { ebpf::JSLT_REG => self.emit_conditional_branch_reg(0x8c, false, src, dst, target_pc), ebpf::JSLE_IMM => self.emit_conditional_branch_imm(0x8e, false, insn.imm, dst, target_pc), ebpf::JSLE_REG => self.emit_conditional_branch_reg(0x8e, false, src, dst, target_pc), - ebpf::CALL_IMM | ebpf::SYSCALL - if insn.opc == ebpf::CALL_IMM || self.executable.get_sbpf_version().static_syscalls() => { + ebpf::CALL_IMM => { // For JIT, external functions MUST be registered at compile time. - - let mut resolved = false; - let (external, internal) = if self.executable.get_sbpf_version().static_syscalls() { - (insn.src == 0, insn.src != 0) - } else { - (true, true) - }; - - if external { - if let Some((_function_name, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { - self.emit_validate_and_profile_instruction_count(false, Some(0)); - self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_SCRATCH, function as usize as i64)); - self.emit_ins(X86Instruction::call_immediate(self.relative_to_anchor(ANCHOR_EXTERNAL_FUNCTION_CALL, 5))); - self.emit_undo_profile_instruction_count(0); - resolved = true; - } - } - - if internal { - if let Some((_function_name, target_pc)) = + if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { + // SBPFv1 syscall + self.emit_syscall_dispatch(function); + } else if let Some((_function_name, target_pc)) = self.executable .get_function_registry() .lookup_by_key( @@ -735,16 +719,18 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { .executable .get_sbpf_version() .calculate_call_imm_target_pc(self.pc, insn.imm) - ) - { - self.emit_internal_call(Value::Constant64(target_pc as i64, true)); - resolved = true; - } + ) { + // BPF to BPF call + self.emit_internal_call(Value::Constant64(target_pc as i64, true)); + } else { + self.emit_throw_unsupported_instruction(); } - - if !resolved { - self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_SCRATCH, self.pc as i64)); - self.emit_ins(X86Instruction::jump_immediate(self.relative_to_anchor(ANCHOR_CALL_UNSUPPORTED_INSTRUCTION, 5))); + }, + ebpf::SYSCALL if self.executable.get_sbpf_version().static_syscalls() => { + if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { + self.emit_syscall_dispatch(function); + } else { + self.emit_throw_unsupported_instruction(); } }, ebpf::CALL_REG => { @@ -1144,6 +1130,20 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { } } + #[inline] + fn emit_syscall_dispatch(&mut self, function: BuiltinFunction) { + self.emit_validate_and_profile_instruction_count(false, Some(0)); + self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_SCRATCH, function as usize as i64)); + self.emit_ins(X86Instruction::call_immediate(self.relative_to_anchor(ANCHOR_EXTERNAL_FUNCTION_CALL, 5))); + self.emit_undo_profile_instruction_count(0); + } + + #[inline] + fn emit_throw_unsupported_instruction(&mut self) { + self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_SCRATCH, self.pc as i64)); + self.emit_ins(X86Instruction::jump_immediate(self.relative_to_anchor(ANCHOR_CALL_UNSUPPORTED_INSTRUCTION, 5))); + } + #[inline] fn emit_address_translation(&mut self, dst: Option, vm_addr: Value, len: u64, value: Option) { debug_assert_ne!(dst.is_some(), value.is_some()); From 2c0ab1141dc72cd50cd2c1b794a871de5a477cfb Mon Sep 17 00:00:00 2001 From: Lucas Steuernagel Date: Sun, 20 Oct 2024 11:06:52 -0300 Subject: [PATCH 2/9] Revamp execution tests --- tests/execution.rs | 189 +++++++++++++++++++++------------------------ 1 file changed, 89 insertions(+), 100 deletions(-) diff --git a/tests/execution.rs b/tests/execution.rs index 4dab27af..d5901e77 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -163,6 +163,31 @@ macro_rules! test_interpreter_and_jit_asm { }; } +macro_rules! test_syscall_asm { + (register, $loader:expr, $syscall_number:literal => $syscall_name:expr => $syscall_function:expr) => { + let _ = $loader.register_function($syscall_name, $syscall_number, $syscall_function).unwrap(); + }; + + ($source:tt, $mem:tt, ($($syscall_number:literal => $syscall_name:expr => $syscall_function:expr),*$(,)?), $context_object:expr, $expected_result:expr $(,)?) => { + let mut config = Config { + enable_instruction_tracing: true, + ..Config::default() + }; + for sbpf_version in [SBPFVersion::V1, SBPFVersion::V2] { + config.enabled_sbpf_versions = sbpf_version..=sbpf_version; + let src = if sbpf_version == SBPFVersion::V1 { + format!($source, $($syscall_name, )*) + } else { + format!($source, $($syscall_number, )*) + }; + let mut loader = BuiltinProgram::new_loader_with_dense_registration(config.clone()); + $(test_syscall_asm!(register, loader, $syscall_number => $syscall_name => $syscall_function);)* + let mut executable = assemble(src.as_str(), Arc::new(loader)).unwrap(); + test_interpreter_and_jit!(executable, $mem, $context_object, $expected_result); + } + }; +} + macro_rules! test_interpreter_and_jit_elf { ($verify:literal, $source:tt, $config:tt, $mem:tt, ($($location:expr => $syscall_function:expr),* $(,)?), $context_object:expr, $expected_result:expr $(,)?) => { let mut file = File::open($source).unwrap(); @@ -1999,12 +2024,8 @@ fn test_stack1() { #[test] fn test_stack2() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( - " + test_syscall_asm!( + " stb [r10-4], 0x01 stb [r10-3], 0x02 stb [r10-2], 0x03 @@ -2012,20 +2033,19 @@ fn test_stack2() { mov r1, r10 mov r2, 0x4 sub r1, r2 - syscall bpf_mem_frob + syscall {} mov r1, 0 ldxb r2, [r10-4] ldxb r3, [r10-3] ldxb r4, [r10-2] ldxb r5, [r10-1] - syscall bpf_gather_bytes + syscall {} xor r0, 0x2a2a2a2a exit", - config, [], ( - "bpf_mem_frob" => syscalls::SyscallMemFrob::vm, - "bpf_gather_bytes" => syscalls::SyscallGatherBytes::vm, + 1 => "bpf_mem_frob" => syscalls::SyscallMemFrob::vm, + 2 => "bpf_gather_bytes" => syscalls::SyscallGatherBytes::vm, ), TestContextObject::new(16), ProgramResult::Ok(0x01020304), @@ -2034,11 +2054,7 @@ fn test_stack2() { #[test] fn test_string_stack() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov r1, 0x78636261 stxw [r10-8], r1 @@ -2050,7 +2066,7 @@ fn test_string_stack() { mov r1, r10 add r1, -8 mov r2, r1 - syscall bpf_str_cmp + syscall {} mov r1, r0 mov r0, 0x1 lsh r1, 0x20 @@ -2060,7 +2076,7 @@ fn test_string_stack() { add r1, -8 mov r2, r10 add r2, -16 - syscall bpf_str_cmp + syscall {} mov r1, r0 lsh r1, 0x20 rsh r1, 0x20 @@ -2068,10 +2084,10 @@ fn test_string_stack() { jeq r1, r6, +1 mov r0, 0x0 exit", - config, [], ( - "bpf_str_cmp" => syscalls::SyscallStrCmp::vm, + 3 => "bpf_str_cmp" => syscalls::SyscallStrCmp::vm, + 3 => "bpf_str_cmp" => syscalls::SyscallStrCmp::vm, ), TestContextObject::new(28), ProgramResult::Ok(0x0), @@ -2377,22 +2393,17 @@ fn test_bpf_to_bpf_scratch_registers() { #[test] fn test_syscall_parameter_on_stack() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov64 r1, r10 add64 r1, -0x100 mov64 r2, 0x1 - syscall bpf_syscall_string + syscall {} mov64 r0, 0x0 exit", - config, [], ( - "bpf_syscall_string" => syscalls::SyscallString::vm, + 1 => "bpf_syscall_string" => syscalls::SyscallString::vm, ), TestContextObject::new(6), ProgramResult::Ok(0), @@ -2574,20 +2585,15 @@ fn test_call_save() { #[test] fn test_err_syscall_string() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov64 r1, 0x0 - syscall bpf_syscall_string + syscall {} mov64 r0, 0x0 exit", - config, [72, 101, 108, 108, 111], ( - "bpf_syscall_string" => syscalls::SyscallString::vm, + 2 => "bpf_syscall_string" => syscalls::SyscallString::vm, ), TestContextObject::new(2), ProgramResult::Err(EbpfError::SyscallError(Box::new(EbpfError::AccessViolation(AccessType::Load, 0, 0, "unknown")))), @@ -2596,20 +2602,15 @@ fn test_err_syscall_string() { #[test] fn test_syscall_string() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov64 r2, 0x5 - syscall bpf_syscall_string + syscall {} mov64 r0, 0x0 exit", - config, [72, 101, 108, 108, 111], ( - "bpf_syscall_string" => syscalls::SyscallString::vm, + 1 => "bpf_syscall_string" => syscalls::SyscallString::vm, ), TestContextObject::new(4), ProgramResult::Ok(0), @@ -2618,24 +2619,19 @@ fn test_syscall_string() { #[test] fn test_syscall() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov64 r1, 0xAA mov64 r2, 0xBB mov64 r3, 0xCC mov64 r4, 0xDD mov64 r5, 0xEE - syscall bpf_syscall_u64 + syscall {} mov64 r0, 0x0 exit", - config, [], ( - "bpf_syscall_u64" => syscalls::SyscallU64::vm, + 3 => "bpf_syscall_u64" => syscalls::SyscallU64::vm, ), TestContextObject::new(8), ProgramResult::Ok(0), @@ -2644,23 +2640,18 @@ fn test_syscall() { #[test] fn test_call_gather_bytes() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov r1, 1 mov r2, 2 mov r3, 3 mov r4, 4 mov r5, 5 - syscall bpf_gather_bytes + syscall {} exit", - config, [], ( - "bpf_gather_bytes" => syscalls::SyscallGatherBytes::vm, + 1 => "bpf_gather_bytes" => syscalls::SyscallGatherBytes::vm, ), TestContextObject::new(7), ProgramResult::Ok(0x0102030405), @@ -2669,25 +2660,20 @@ fn test_call_gather_bytes() { #[test] fn test_call_memfrob() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov r6, r1 add r1, 2 mov r2, 4 - syscall bpf_mem_frob + syscall {} ldxdw r0, [r6] be64 r0 exit", - config, [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // ], ( - "bpf_mem_frob" => syscalls::SyscallMemFrob::vm, + 2 => "bpf_mem_frob" => syscalls::SyscallMemFrob::vm, ), TestContextObject::new(7), ProgramResult::Ok(0x102292e2f2c0708), @@ -2701,7 +2687,7 @@ declare_builtin_function!( _context_object: &mut TestContextObject, depth: u64, throw: u64, - _arg3: u64, + version: u64, _arg4: u64, _arg5: u64, _memory_mapping: &mut MemoryMapping, @@ -2719,23 +2705,27 @@ declare_builtin_function!( }; #[allow(unused_mut)] if depth > 0 { - let mut function_registry = - FunctionRegistry::>::default(); - function_registry - .register_function_hashed(*b"nested_vm_syscall", SyscallNestedVm::vm) - .unwrap(); - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() + let mut config = Config::default(); + let syscall_name = if version == 1 { + config.enabled_sbpf_versions = SBPFVersion::V1..=SBPFVersion::V1; + "nested_vm_syscall" + } else { + config.enabled_sbpf_versions = SBPFVersion::V2..=SBPFVersion::V2; + "1" }; - let loader = BuiltinProgram::new_loader(config, function_registry); - let mem = [depth as u8 - 1, throw as u8]; - let mut executable = assemble::( + let mut loader = BuiltinProgram::new_loader_with_dense_registration(config); + loader.register_function("nested_vm_syscall", 1, SyscallNestedVm::vm).unwrap(); + let source_code = format!( " ldxb r2, [r1+1] ldxb r1, [r1] - syscall nested_vm_syscall + syscall {} exit", + syscall_name + ); + let mem = [depth as u8 - 1, throw as u8]; + let mut executable = assemble::( + source_code.as_str(), Arc::new(loader), ) .unwrap(); @@ -2755,9 +2745,17 @@ fn test_nested_vm_syscall() { let config = Config::default(); let mut context_object = TestContextObject::default(); let mut memory_mapping = MemoryMapping::new(vec![], &config, SBPFVersion::V2).unwrap(); - let result = SyscallNestedVm::rust(&mut context_object, 1, 0, 0, 0, 0, &mut memory_mapping); - assert!(result.unwrap() == 42); - let result = SyscallNestedVm::rust(&mut context_object, 1, 1, 0, 0, 0, &mut memory_mapping); + + // SBPFv1 + let result = SyscallNestedVm::rust(&mut context_object, 1, 0, 1, 0, 0, &mut memory_mapping); + assert_eq!(result.unwrap(), 42); + let result = SyscallNestedVm::rust(&mut context_object, 1, 1, 1, 0, 0, &mut memory_mapping); + assert_error!(result, "CallDepthExceeded"); + + // SBPFv2 + let result = SyscallNestedVm::rust(&mut context_object, 1, 0, 2, 0, 0, &mut memory_mapping); + assert_eq!(result.unwrap(), 42); + let result = SyscallNestedVm::rust(&mut context_object, 1, 1, 2, 0, 0, &mut memory_mapping); assert_error!(result, "CallDepthExceeded"); } @@ -2824,20 +2822,15 @@ fn test_tight_infinite_recursion_callx() { #[test] fn test_instruction_count_syscall() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov64 r2, 0x5 - syscall bpf_syscall_string + syscall {} mov64 r0, 0x0 exit", - config, [72, 101, 108, 108, 111], ( - "bpf_syscall_string" => syscalls::SyscallString::vm, + 1 => "bpf_syscall_string" => syscalls::SyscallString::vm, ), TestContextObject::new(4), ProgramResult::Ok(0), @@ -2846,20 +2839,15 @@ fn test_instruction_count_syscall() { #[test] fn test_err_instruction_count_syscall_capped() { - let config = Config { - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( + test_syscall_asm!( " mov64 r2, 0x5 - syscall bpf_syscall_string + syscall {} mov64 r0, 0x0 exit", - config, [72, 101, 108, 108, 111], ( - "bpf_syscall_string" => syscalls::SyscallString::vm, + 1 => "bpf_syscall_string" => syscalls::SyscallString::vm, ), TestContextObject::new(3), ProgramResult::Err(EbpfError::ExceededMaxInstructions), @@ -3002,6 +2990,7 @@ fn test_far_jumps() { #[test] fn test_symbol_relocation() { let config = Config { + // No relocations are necessary in SBFPv2 enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, ..Config::default() }; From 857b45d2b51f1b8d9a7ecfa8b4ec3134a6c4caf4 Mon Sep 17 00:00:00 2001 From: Lucas Steuernagel Date: Sun, 20 Oct 2024 11:28:36 -0300 Subject: [PATCH 3/9] Add invalid syscall test --- tests/execution.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/execution.rs b/tests/execution.rs index d5901e77..8cf7ff87 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -4127,3 +4127,35 @@ fn test_invalid_exit_or_return() { ); } } + +#[test] +fn test_unregistered_syscall() { + let prog = &[ + 0xbf, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov64 r0, 2 + 0x95, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // syscall 2 + 0x9d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // return + ]; + + let config = Config { + enabled_sbpf_versions: SBPFVersion::V2..=SBPFVersion::V2, + enable_instruction_tracing: true, + ..Config::default() + }; + + let loader = Arc::new(BuiltinProgram::new_loader_with_dense_registration(config)); + let mut executable = Executable::::from_text_bytes( + prog, + loader, + SBPFVersion::V2, + FunctionRegistry::default(), + ) + .unwrap(); + + test_interpreter_and_jit!( + false, + executable, + [], + TestContextObject::new(2), + ProgramResult::Err(EbpfError::UnsupportedInstruction), + ); +} From 68efd2c38951bc38e3aa819b788459ed5c80a9aa Mon Sep 17 00:00:00 2001 From: Lucas Steuernagel Date: Sun, 20 Oct 2024 11:36:08 -0300 Subject: [PATCH 4/9] Fix imports --- src/interpreter.rs | 2 +- src/jit.rs | 2 +- tests/execution.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index 06323858..0d6dbd08 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -12,11 +12,11 @@ //! Interpreter for eBPF programs. -use crate::program::BuiltinFunction; use crate::{ ebpf::{self, STACK_PTR_REG}, elf::Executable, error::{EbpfError, ProgramResult}, + program::BuiltinFunction, vm::{Config, ContextObject, EbpfVm}, }; diff --git a/src/jit.rs b/src/jit.rs index 48957e98..147e724d 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -23,7 +23,6 @@ use rand::{ }; use std::{fmt::Debug, mem, ptr}; -use crate::program::BuiltinFunction; use crate::{ ebpf::{self, FIRST_SCRATCH_REG, FRAME_PTR_REG, INSN_SIZE, SCRATCH_REGS, STACK_PTR_REG}, elf::Executable, @@ -32,6 +31,7 @@ use crate::{ allocate_pages, free_pages, get_system_page_size, protect_pages, round_to_page_size, }, memory_region::{AccessType, MemoryMapping}, + program::BuiltinFunction, vm::{get_runtime_environment_key, Config, ContextObject, EbpfVm}, x86::*, }; diff --git a/tests/execution.rs b/tests/execution.rs index 8cf7ff87..e81c891e 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -2990,7 +2990,7 @@ fn test_far_jumps() { #[test] fn test_symbol_relocation() { let config = Config { - // No relocations are necessary in SBFPv2 + // No relocation is necessary in SBFPv2 enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, ..Config::default() }; From db59e7dac09b821c86e8d82aeb2c297d526ba591 Mon Sep 17 00:00:00 2001 From: Lucas Steuernagel Date: Tue, 22 Oct 2024 18:10:46 -0300 Subject: [PATCH 5/9] Use debug_assert --- src/interpreter.rs | 2 +- src/jit.rs | 25 +++++++++++-------------- tests/execution.rs | 2 ++ 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index 0d6dbd08..a5f68df5 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -560,7 +560,7 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> { ProgramResult::Err(_err) => return false, }; } else { - throw_error!(self, EbpfError::UnsupportedInstruction); + debug_assert!(false, "Invalid syscall should have been detected in the verifier."); } }, ebpf::RETURN diff --git a/src/jit.rs b/src/jit.rs index 147e724d..8e54ebe6 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -723,14 +723,15 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { // BPF to BPF call self.emit_internal_call(Value::Constant64(target_pc as i64, true)); } else { - self.emit_throw_unsupported_instruction(); + self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_SCRATCH, self.pc as i64)); + self.emit_ins(X86Instruction::jump_immediate(self.relative_to_anchor(ANCHOR_CALL_UNSUPPORTED_INSTRUCTION, 5))); } }, ebpf::SYSCALL if self.executable.get_sbpf_version().static_syscalls() => { if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { self.emit_syscall_dispatch(function); } else { - self.emit_throw_unsupported_instruction(); + debug_assert!(false, "Invalid syscall should have been detected in the verifier.") } }, ebpf::CALL_REG => { @@ -1138,12 +1139,6 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { self.emit_undo_profile_instruction_count(0); } - #[inline] - fn emit_throw_unsupported_instruction(&mut self) { - self.emit_ins(X86Instruction::load_immediate(OperandSize::S64, REGISTER_SCRATCH, self.pc as i64)); - self.emit_ins(X86Instruction::jump_immediate(self.relative_to_anchor(ANCHOR_CALL_UNSUPPORTED_INSTRUCTION, 5))); - } - #[inline] fn emit_address_translation(&mut self, dst: Option, vm_addr: Value, len: u64, value: Option) { debug_assert_ne!(dst.is_some(), value.is_some()); @@ -1705,7 +1700,7 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { mod tests { use super::*; use crate::{ - program::{BuiltinFunction, BuiltinProgram, FunctionRegistry, SBPFVersion}, + program::{BuiltinProgram, FunctionRegistry, SBPFVersion}, syscalls, vm::TestContextObject, }; @@ -1752,12 +1747,10 @@ mod tests { fn create_mockup_executable(config: Config, program: &[u8]) -> Executable { let sbpf_version = *config.enabled_sbpf_versions.end(); - let mut function_registry = - FunctionRegistry::>::default(); - function_registry - .register_function_hashed(*b"gather_bytes", syscalls::SyscallGatherBytes::vm) + let mut loader = BuiltinProgram::new_loader_with_dense_registration(config); + loader + .register_function("gather_bytes", 1, syscalls::SyscallGatherBytes::vm) .unwrap(); - let loader = BuiltinProgram::new_loader(config, function_registry); let mut function_registry = FunctionRegistry::default(); function_registry .register_function(8, *b"function_foo", 8) @@ -1844,6 +1837,10 @@ mod tests { opcode = 0x85; (0x88, 0x91020CDD) } + 0x95 => { + // Put a valid syscall + (0, 1) + } 0xD4 | 0xDC => (0x88, 16), _ => (0x88, 0xFFFFFFFF), }; diff --git a/tests/execution.rs b/tests/execution.rs index e81c891e..651f8591 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -4090,6 +4090,7 @@ fn test_mod() { } #[test] +#[should_panic(expected = "Invalid syscall should have been detected in the verifier.")] fn test_invalid_exit_or_return() { for sbpf_version in [SBPFVersion::V1, SBPFVersion::V2] { let inst = if sbpf_version == SBPFVersion::V1 { @@ -4129,6 +4130,7 @@ fn test_invalid_exit_or_return() { } #[test] +#[should_panic(expected = "Invalid syscall should have been detected in the verifier.")] fn test_unregistered_syscall() { let prog = &[ 0xbf, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov64 r0, 2 From d0bf95c7df009773b502fa62fbcf31fe86d6ad87 Mon Sep 17 00:00:00 2001 From: Lucas Steuernagel Date: Thu, 24 Oct 2024 10:15:54 -0300 Subject: [PATCH 6/9] Remove unregistered syscall test --- tests/execution.rs | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/tests/execution.rs b/tests/execution.rs index 651f8591..9b7850e5 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -4128,36 +4128,3 @@ fn test_invalid_exit_or_return() { ); } } - -#[test] -#[should_panic(expected = "Invalid syscall should have been detected in the verifier.")] -fn test_unregistered_syscall() { - let prog = &[ - 0xbf, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov64 r0, 2 - 0x95, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // syscall 2 - 0x9d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // return - ]; - - let config = Config { - enabled_sbpf_versions: SBPFVersion::V2..=SBPFVersion::V2, - enable_instruction_tracing: true, - ..Config::default() - }; - - let loader = Arc::new(BuiltinProgram::new_loader_with_dense_registration(config)); - let mut executable = Executable::::from_text_bytes( - prog, - loader, - SBPFVersion::V2, - FunctionRegistry::default(), - ) - .unwrap(); - - test_interpreter_and_jit!( - false, - executable, - [], - TestContextObject::new(2), - ProgramResult::Err(EbpfError::UnsupportedInstruction), - ); -} From ec783874f2bea590c60ff551eadf32849c0314da Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 4 Nov 2024 11:43:28 -0300 Subject: [PATCH 7/9] Gate call imm in sbpf v2 --- src/interpreter.rs | 4 +++- src/jit.rs | 4 +++- tests/execution.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index a5f68df5..440508b3 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -528,7 +528,9 @@ impl<'a, 'b, C: ContextObject> Interpreter<'a, 'b, C> { // Do not delegate the check to the verifier, since self.registered functions can be // changed after the program has been verified. ebpf::CALL_IMM => { - if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { + if let (false, Some((_, function))) = + (self.executable.get_sbpf_version().static_syscalls(), + self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32)) { // SBPFv1 syscall self.reg[0] = match self.dispatch_syscall(function) { ProgramResult::Ok(value) => *value, diff --git a/src/jit.rs b/src/jit.rs index 8e54ebe6..6f2182c6 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -708,7 +708,9 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> { ebpf::JSLE_REG => self.emit_conditional_branch_reg(0x8e, false, src, dst, target_pc), ebpf::CALL_IMM => { // For JIT, external functions MUST be registered at compile time. - if let Some((_, function)) = self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32) { + if let (false, Some((_, function))) = + (self.executable.get_sbpf_version().static_syscalls(), + self.executable.get_loader().get_function_registry(self.executable.get_sbpf_version()).lookup_by_key(insn.imm as u32)) { // SBPFv1 syscall self.emit_syscall_dispatch(function); } else if let Some((_function_name, target_pc)) = diff --git a/tests/execution.rs b/tests/execution.rs index 9b7850e5..949c76ea 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -4089,6 +4089,40 @@ fn test_mod() { ); } +#[test] +fn test_invalid_call_imm() { + // In SBPFv2, `call_imm N` shall not be dispatched to a syscall. + let prog = &[ + 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // call_imm 2 + 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let config = Config { + enabled_sbpf_versions: SBPFVersion::V2..=SBPFVersion::V2, + enable_instruction_tracing: true, + ..Config::default() + }; + let mut loader = BuiltinProgram::new_loader_with_dense_registration(config); + loader + .register_function("syscall_string", 2, syscalls::SyscallString::vm) + .unwrap(); + let mut executable = Executable::::from_text_bytes( + prog, + Arc::new(loader), + SBPFVersion::V2, + FunctionRegistry::default(), + ) + .unwrap(); + + test_interpreter_and_jit!( + false, + executable, + [], + TestContextObject::new(1), + ProgramResult::Err(EbpfError::UnsupportedInstruction), + ); +} + #[test] #[should_panic(expected = "Invalid syscall should have been detected in the verifier.")] fn test_invalid_exit_or_return() { From fe35891bcced3d0f729660a1ecdd7f893a8f7ba6 Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 4 Nov 2024 12:12:32 -0300 Subject: [PATCH 8/9] Reorganize tests --- tests/execution.rs | 185 ++++++++++++++++++++++----------------------- 1 file changed, 90 insertions(+), 95 deletions(-) diff --git a/tests/execution.rs b/tests/execution.rs index 949c76ea..bc5006a3 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -2987,31 +2987,6 @@ fn test_far_jumps() { // Symbols and Relocation -#[test] -fn test_symbol_relocation() { - let config = Config { - // No relocation is necessary in SBFPv2 - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - ..Config::default() - }; - test_interpreter_and_jit_asm!( - " - mov64 r1, r10 - add64 r1, -0x1 - mov64 r2, 0x1 - syscall bpf_syscall_string - mov64 r0, 0x0 - exit", - config, - [72, 101, 108, 108, 111], - ( - "bpf_syscall_string" => syscalls::SyscallString::vm, - ), - TestContextObject::new(6), - ProgramResult::Ok(0), - ); -} - #[test] fn test_err_call_unresolved() { let config = Config { @@ -3497,6 +3472,80 @@ fn test_total_chaos() { } } +#[test] +fn test_invalid_call_imm() { + // In SBPFv2, `call_imm` N shall not be dispatched a syscall. + let prog = &[ + 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // call_imm 2 + 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let config = Config { + enabled_sbpf_versions: SBPFVersion::V2..=SBPFVersion::V2, + enable_instruction_tracing: true, + ..Config::default() + }; + let mut loader = BuiltinProgram::new_loader_with_dense_registration(config); + loader + .register_function("syscall_string", 2, syscalls::SyscallString::vm) + .unwrap(); + let mut executable = Executable::::from_text_bytes( + prog, + Arc::new(loader), + SBPFVersion::V2, + FunctionRegistry::default(), + ) + .unwrap(); + + test_interpreter_and_jit!( + false, + executable, + [], + TestContextObject::new(1), + ProgramResult::Err(EbpfError::UnsupportedInstruction), + ); +} + +#[test] +#[should_panic(expected = "Invalid syscall should have been detected in the verifier.")] +fn test_invalid_exit_or_return() { + for sbpf_version in [SBPFVersion::V1, SBPFVersion::V2] { + let inst = if sbpf_version == SBPFVersion::V1 { + 0x9d + } else { + 0x95 + }; + + let prog = &[ + 0xbf, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov64 r0, 2 + inst, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit/return + ]; + + let config = Config { + enabled_sbpf_versions: sbpf_version..=sbpf_version, + enable_instruction_tracing: true, + ..Config::default() + }; + let function_registry = FunctionRegistry::>::default(); + let loader = Arc::new(BuiltinProgram::new_loader(config, function_registry)); + let mut executable = Executable::::from_text_bytes( + prog, + loader, + sbpf_version, + FunctionRegistry::default(), + ) + .unwrap(); + + test_interpreter_and_jit!( + false, + executable, + [], + TestContextObject::new(2), + ProgramResult::Err(EbpfError::UnsupportedInstruction), + ); + } +} + // SBPFv1 only [DEPRECATED] #[test] @@ -4090,75 +4139,21 @@ fn test_mod() { } #[test] -fn test_invalid_call_imm() { - // In SBPFv2, `call_imm N` shall not be dispatched to a syscall. - let prog = &[ - 0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // call_imm 2 - 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ]; - - let config = Config { - enabled_sbpf_versions: SBPFVersion::V2..=SBPFVersion::V2, - enable_instruction_tracing: true, - ..Config::default() - }; - let mut loader = BuiltinProgram::new_loader_with_dense_registration(config); - loader - .register_function("syscall_string", 2, syscalls::SyscallString::vm) - .unwrap(); - let mut executable = Executable::::from_text_bytes( - prog, - Arc::new(loader), - SBPFVersion::V2, - FunctionRegistry::default(), - ) - .unwrap(); - - test_interpreter_and_jit!( - false, - executable, - [], - TestContextObject::new(1), - ProgramResult::Err(EbpfError::UnsupportedInstruction), +fn test_symbol_relocation() { + // No relocation is necessary in SBFPv2 + test_syscall_asm!( + " + mov64 r1, r10 + add64 r1, -0x1 + mov64 r2, 0x1 + syscall {} + mov64 r0, 0x0 + exit", + [72, 101, 108, 108, 111], + ( + 1 => "bpf_syscall_string" => syscalls::SyscallString::vm, + ), + TestContextObject::new(6), + ProgramResult::Ok(0), ); } - -#[test] -#[should_panic(expected = "Invalid syscall should have been detected in the verifier.")] -fn test_invalid_exit_or_return() { - for sbpf_version in [SBPFVersion::V1, SBPFVersion::V2] { - let inst = if sbpf_version == SBPFVersion::V1 { - 0x9d - } else { - 0x95 - }; - - let prog = &[ - 0xbf, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov64 r0, 2 - inst, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit/return - ]; - - let config = Config { - enabled_sbpf_versions: sbpf_version..=sbpf_version, - enable_instruction_tracing: true, - ..Config::default() - }; - let function_registry = FunctionRegistry::>::default(); - let loader = Arc::new(BuiltinProgram::new_loader(config, function_registry)); - let mut executable = Executable::::from_text_bytes( - prog, - loader, - sbpf_version, - FunctionRegistry::default(), - ) - .unwrap(); - - test_interpreter_and_jit!( - false, - executable, - [], - TestContextObject::new(2), - ProgramResult::Err(EbpfError::UnsupportedInstruction), - ); - } -} From 09d73c121df3283e93f78253142f95596807e316 Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 4 Nov 2024 12:41:18 -0300 Subject: [PATCH 9/9] Remove unused parameters from macro --- tests/execution.rs | 175 +++------------------------------------------ 1 file changed, 11 insertions(+), 164 deletions(-) diff --git a/tests/execution.rs b/tests/execution.rs index bc5006a3..67314ff2 100644 --- a/tests/execution.rs +++ b/tests/execution.rs @@ -143,22 +143,28 @@ macro_rules! test_interpreter_and_jit { } macro_rules! test_interpreter_and_jit_asm { - ($source:tt, $config:expr, $mem:tt, ($($location:expr => $syscall_function:expr),* $(,)?), $context_object:expr, $expected_result:expr $(,)?) => { + ($source:tt, $config:expr, $mem:tt, $context_object:expr, $expected_result:expr $(,)?) => { #[allow(unused_mut)] { let mut config = $config; config.enable_instruction_tracing = true; - let mut function_registry = FunctionRegistry::>::default(); - $(test_interpreter_and_jit!(register, function_registry, $location => $syscall_function);)* + let mut function_registry = + FunctionRegistry::>::default(); let loader = Arc::new(BuiltinProgram::new_loader(config, function_registry)); let mut executable = assemble($source, loader).unwrap(); test_interpreter_and_jit!(executable, $mem, $context_object, $expected_result); } }; - ($source:tt, $mem:tt, ($($location:expr => $syscall_function:expr),* $(,)?), $context_object:expr, $expected_result:expr $(,)?) => { + ($source:tt, $mem:tt, $context_object:expr, $expected_result:expr $(,)?) => { #[allow(unused_mut)] { - test_interpreter_and_jit_asm!($source, Config::default(), $mem, ($($location => $syscall_function),*), $context_object, $expected_result); + test_interpreter_and_jit_asm!( + $source, + Config::default(), + $mem, + $context_object, + $expected_result + ); } }; } @@ -223,7 +229,6 @@ fn test_mov32_imm() { mov32 r0, 1 exit", [], - (), TestContextObject::new(2), ProgramResult::Ok(1), ); @@ -232,7 +237,6 @@ fn test_mov32_imm() { mov32 r0, -1 exit", [], - (), TestContextObject::new(2), ProgramResult::Ok(0xffffffff), ); @@ -246,7 +250,6 @@ fn test_mov32_reg() { mov32 r0, r1 exit", [], - (), TestContextObject::new(3), ProgramResult::Ok(0x1), ); @@ -256,7 +259,6 @@ fn test_mov32_reg() { mov32 r0, r1 exit", [], - (), TestContextObject::new(3), ProgramResult::Ok(0xffffffffffffffff), ); @@ -269,7 +271,6 @@ fn test_mov64_imm() { mov64 r0, 1 exit", [], - (), TestContextObject::new(2), ProgramResult::Ok(1), ); @@ -278,7 +279,6 @@ fn test_mov64_imm() { mov64 r0, -1 exit", [], - (), TestContextObject::new(2), ProgramResult::Ok(0xffffffffffffffff), ); @@ -292,7 +292,6 @@ fn test_mov64_reg() { mov64 r0, r1 exit", [], - (), TestContextObject::new(3), ProgramResult::Ok(0x1), ); @@ -302,7 +301,6 @@ fn test_mov64_reg() { mov64 r0, r1 exit", [], - (), TestContextObject::new(3), ProgramResult::Ok(0xffffffffffffffff), ); @@ -320,7 +318,6 @@ fn test_bounce() { mov r0, r9 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -336,7 +333,6 @@ fn test_add32() { add32 r0, r1 exit", [], - (), TestContextObject::new(5), ProgramResult::Ok(0x3), ); @@ -366,7 +362,6 @@ fn test_alu32_arithmetic() { udiv32 r0, r4 exit", [], - (), TestContextObject::new(19), ProgramResult::Ok(110), ); @@ -396,7 +391,6 @@ fn test_alu64_arithmetic() { udiv r0, r4 exit", [], - (), TestContextObject::new(19), ProgramResult::Ok(110), ); @@ -449,7 +443,6 @@ fn test_lmul128() { stxdw [r1+0x0], r0 exit", [0; 16], - (), TestContextObject::new(42), ProgramResult::Ok(600), ); @@ -481,7 +474,6 @@ fn test_alu32_logic() { xor32 r0, r2 exit", [], - (), TestContextObject::new(21), ProgramResult::Ok(0x11), ); @@ -515,7 +507,6 @@ fn test_alu64_logic() { xor r0, r2 exit", [], - (), TestContextObject::new(23), ProgramResult::Ok(0x11), ); @@ -531,7 +522,6 @@ fn test_arsh32_high_shift() { arsh32 r0, r1 exit", [], - (), TestContextObject::new(5), ProgramResult::Ok(0x4), ); @@ -546,7 +536,6 @@ fn test_arsh32_imm() { arsh32 r0, 16 exit", [], - (), TestContextObject::new(4), ProgramResult::Ok(0xffff8000), ); @@ -562,7 +551,6 @@ fn test_arsh32_reg() { arsh32 r0, r1 exit", [], - (), TestContextObject::new(5), ProgramResult::Ok(0xffff8000), ); @@ -579,7 +567,6 @@ fn test_arsh64() { arsh r0, r1 exit", [], - (), TestContextObject::new(6), ProgramResult::Ok(0xfffffffffffffff8), ); @@ -594,7 +581,6 @@ fn test_lsh64_reg() { lsh r0, r7 exit", [], - (), TestContextObject::new(4), ProgramResult::Ok(0x10), ); @@ -609,7 +595,6 @@ fn test_rhs32_imm() { rsh32 r0, 8 exit", [], - (), TestContextObject::new(4), ProgramResult::Ok(0x00ffffff), ); @@ -624,7 +609,6 @@ fn test_rsh64_reg() { rsh r0, r7 exit", [], - (), TestContextObject::new(4), ProgramResult::Ok(0x1), ); @@ -638,7 +622,6 @@ fn test_be16() { be16 r0 exit", [0x11, 0x22], - (), TestContextObject::new(3), ProgramResult::Ok(0x1122), ); @@ -652,7 +635,6 @@ fn test_be16_high() { be16 r0 exit", [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], - (), TestContextObject::new(3), ProgramResult::Ok(0x1122), ); @@ -666,7 +648,6 @@ fn test_be32() { be32 r0 exit", [0x11, 0x22, 0x33, 0x44], - (), TestContextObject::new(3), ProgramResult::Ok(0x11223344), ); @@ -680,7 +661,6 @@ fn test_be32_high() { be32 r0 exit", [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], - (), TestContextObject::new(3), ProgramResult::Ok(0x11223344), ); @@ -694,7 +674,6 @@ fn test_be64() { be64 r0 exit", [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], - (), TestContextObject::new(3), ProgramResult::Ok(0x1122334455667788), ); @@ -954,7 +933,6 @@ fn test_memory_instructions() { exit", config.clone(), [0xaa, 0xbb, 0x11, 0xcc, 0xdd], - (), TestContextObject::new(2), ProgramResult::Ok(0x11), ); @@ -964,7 +942,6 @@ fn test_memory_instructions() { exit", config.clone(), [0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd], - (), TestContextObject::new(2), ProgramResult::Ok(0x2211), ); @@ -976,7 +953,6 @@ fn test_memory_instructions() { [ 0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0xcc, 0xdd, // ], - (), TestContextObject::new(2), ProgramResult::Ok(0x44332211), ); @@ -989,7 +965,6 @@ fn test_memory_instructions() { 0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, // 0x77, 0x88, 0xcc, 0xdd, // ], - (), TestContextObject::new(2), ProgramResult::Ok(0x8877665544332211), ); @@ -1001,7 +976,6 @@ fn test_memory_instructions() { exit", config.clone(), [0xaa, 0xbb, 0xff, 0xcc, 0xdd], - (), TestContextObject::new(3), ProgramResult::Ok(0x11), ); @@ -1014,7 +988,6 @@ fn test_memory_instructions() { [ 0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd, // ], - (), TestContextObject::new(3), ProgramResult::Ok(0x2211), ); @@ -1027,7 +1000,6 @@ fn test_memory_instructions() { [ 0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd, // ], - (), TestContextObject::new(3), ProgramResult::Ok(0x44332211), ); @@ -1041,7 +1013,6 @@ fn test_memory_instructions() { 0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0xff, 0xff, 0xcc, 0xdd, // ], - (), TestContextObject::new(3), ProgramResult::Ok(0x44332211), ); @@ -1056,7 +1027,6 @@ fn test_memory_instructions() { [ 0xaa, 0xbb, 0xff, 0xcc, 0xdd, // ], - (), TestContextObject::new(4), ProgramResult::Ok(0x11), ); @@ -1070,7 +1040,6 @@ fn test_memory_instructions() { [ 0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd, // ], - (), TestContextObject::new(4), ProgramResult::Ok(0x2211), ); @@ -1084,7 +1053,6 @@ fn test_memory_instructions() { [ 0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd, // ], - (), TestContextObject::new(4), ProgramResult::Ok(0x44332211), ); @@ -1101,7 +1069,6 @@ fn test_memory_instructions() { 0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 0xff, 0xff, 0xcc, 0xdd, // ], - (), TestContextObject::new(6), ProgramResult::Ok(0x8877665544332211), ); @@ -1116,7 +1083,6 @@ fn test_hor64() { hor64 r0, 0x01020304 exit", [], - (), TestContextObject::new(3), ProgramResult::Ok(0x1122334400000000), ); @@ -1131,7 +1097,6 @@ fn test_ldxh_same_reg() { ldxh r0, [r0] exit", [0xff, 0xff], - (), TestContextObject::new(4), ProgramResult::Ok(0x1234), ); @@ -1147,7 +1112,6 @@ fn test_err_ldxdw_oob() { 0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, // 0x77, 0x88, 0xcc, 0xdd, // ], - (), TestContextObject::new(1), ProgramResult::Err(EbpfError::AccessViolation( AccessType::Load, @@ -1165,7 +1129,6 @@ fn test_err_ldxdw_nomem() { ldxdw r0, [r1+6] exit", [], - (), TestContextObject::new(1), ProgramResult::Err(EbpfError::AccessViolation( AccessType::Load, @@ -1215,7 +1178,6 @@ fn test_ldxb_all() { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x08, 0x09, // ], - (), TestContextObject::new(31), ProgramResult::Ok(0x9876543210), ); @@ -1271,7 +1233,6 @@ fn test_ldxh_all() { 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, // 0x00, 0x08, 0x00, 0x09, // ], - (), TestContextObject::new(41), ProgramResult::Ok(0x9876543210), ); @@ -1317,7 +1278,6 @@ fn test_ldxh_all2() { 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80, // 0x01, 0x00, 0x02, 0x00, // ], - (), TestContextObject::new(31), ProgramResult::Ok(0x3ff), ); @@ -1365,7 +1325,6 @@ fn test_ldxw_all() { 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, // 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, // ], - (), TestContextObject::new(31), ProgramResult::Ok(0x030f0f), ); @@ -1397,7 +1356,6 @@ fn test_stxb_all() { [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // ], - (), TestContextObject::new(19), ProgramResult::Ok(0xf0f2f3f4f5f6f7f8), ); @@ -1416,7 +1374,6 @@ fn test_stxb_all2() { be16 r0 exit", [0xff, 0xff], - (), TestContextObject::new(8), ProgramResult::Ok(0xf1f9), ); @@ -1451,7 +1408,6 @@ fn test_stxb_chain() { 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00, 0x00, // ], - (), TestContextObject::new(21), ProgramResult::Ok(0x2a), ); @@ -1472,7 +1428,6 @@ fn test_exit_capped() { exit", config, [], - (), TestContextObject::new(0), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -1492,7 +1447,6 @@ fn test_exit_without_value() { exit", config, [], - (), TestContextObject::new(1), ProgramResult::Ok(0x0), ); @@ -1513,7 +1467,6 @@ fn test_exit() { exit", config, [], - (), TestContextObject::new(2), ProgramResult::Ok(0x0), ); @@ -1536,7 +1489,6 @@ fn test_early_exit() { exit", config, [], - (), TestContextObject::new(2), ProgramResult::Ok(0x3), ); @@ -1552,7 +1504,6 @@ fn test_ja() { mov r0, 2 exit", [], - (), TestContextObject::new(3), ProgramResult::Ok(0x1), ); @@ -1571,7 +1522,6 @@ fn test_jeq_imm() { mov32 r0, 2 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1591,7 +1541,6 @@ fn test_jeq_reg() { mov32 r0, 2 exit", [], - (), TestContextObject::new(8), ProgramResult::Ok(0x1), ); @@ -1610,7 +1559,6 @@ fn test_jge_imm() { mov32 r0, 2 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1630,7 +1578,6 @@ fn test_jge_reg() { mov32 r0, 2 exit", [], - (), TestContextObject::new(8), ProgramResult::Ok(0x1), ); @@ -1650,7 +1597,6 @@ fn test_jle_imm() { mov32 r0, 1 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1672,7 +1618,6 @@ fn test_jle_reg() { mov r0, 1 exit", [], - (), TestContextObject::new(9), ProgramResult::Ok(0x1), ); @@ -1691,7 +1636,6 @@ fn test_jgt_imm() { mov32 r0, 1 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1712,7 +1656,6 @@ fn test_jgt_reg() { mov r0, 1 exit", [], - (), TestContextObject::new(9), ProgramResult::Ok(0x1), ); @@ -1731,7 +1674,6 @@ fn test_jlt_imm() { mov32 r0, 1 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1752,7 +1694,6 @@ fn test_jlt_reg() { mov r0, 1 exit", [], - (), TestContextObject::new(9), ProgramResult::Ok(0x1), ); @@ -1771,7 +1712,6 @@ fn test_jne_imm() { mov32 r0, 2 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1791,7 +1731,6 @@ fn test_jne_reg() { mov32 r0, 2 exit", [], - (), TestContextObject::new(8), ProgramResult::Ok(0x1), ); @@ -1810,7 +1749,6 @@ fn test_jset_imm() { mov32 r0, 2 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1830,7 +1768,6 @@ fn test_jset_reg() { mov32 r0, 2 exit", [], - (), TestContextObject::new(8), ProgramResult::Ok(0x1), ); @@ -1850,7 +1787,6 @@ fn test_jsge_imm() { mov32 r0, 2 exit", [], - (), TestContextObject::new(8), ProgramResult::Ok(0x1), ); @@ -1872,7 +1808,6 @@ fn test_jsge_reg() { mov32 r0, 2 exit", [], - (), TestContextObject::new(10), ProgramResult::Ok(0x1), ); @@ -1892,7 +1827,6 @@ fn test_jsle_imm() { mov32 r0, 2 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1915,7 +1849,6 @@ fn test_jsle_reg() { mov32 r0, 2 exit", [], - (), TestContextObject::new(10), ProgramResult::Ok(0x1), ); @@ -1934,7 +1867,6 @@ fn test_jsgt_imm() { mov32 r0, 2 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1954,7 +1886,6 @@ fn test_jsgt_reg() { mov32 r0, 2 exit", [], - (), TestContextObject::new(8), ProgramResult::Ok(0x1), ); @@ -1973,7 +1904,6 @@ fn test_jslt_imm() { mov32 r0, 1 exit", [], - (), TestContextObject::new(7), ProgramResult::Ok(0x1), ); @@ -1994,7 +1924,6 @@ fn test_jslt_reg() { mov32 r0, 1 exit", [], - (), TestContextObject::new(9), ProgramResult::Ok(0x1), ); @@ -2016,7 +1945,6 @@ fn test_stack1() { ldxdw r0, [r2-16] exit", [], - (), TestContextObject::new(9), ProgramResult::Ok(0xcd), ); @@ -2111,7 +2039,6 @@ fn test_err_dynamic_stack_out_of_bound() { exit", config.clone(), [], - (), TestContextObject::new(1), ProgramResult::Err(EbpfError::AccessViolation( AccessType::Store, @@ -2128,7 +2055,6 @@ fn test_err_dynamic_stack_out_of_bound() { exit", config.clone(), [], - (), TestContextObject::new(1), ProgramResult::Err(EbpfError::AccessViolation( AccessType::Store, @@ -2158,7 +2084,6 @@ fn test_err_dynamic_stack_ptr_overflow() { stb [r10], 0 exit", [], - (), TestContextObject::new(7), ProgramResult::Err(EbpfError::AccessViolation( AccessType::Store, @@ -2183,7 +2108,6 @@ fn test_dynamic_stack_frames_empty() { exit", config.clone(), [], - (), TestContextObject::new(4), ProgramResult::Ok(ebpf::MM_STACK_START + config.stack_size() as u64), ); @@ -2205,7 +2129,6 @@ fn test_dynamic_frame_ptr() { exit", config.clone(), [], - (), TestContextObject::new(5), ProgramResult::Ok(ebpf::MM_STACK_START + config.stack_size() as u64 - 8), ); @@ -2223,7 +2146,6 @@ fn test_dynamic_frame_ptr() { ", config.clone(), [], - (), TestContextObject::new(5), ProgramResult::Ok(ebpf::MM_STACK_START + config.stack_size() as u64), ); @@ -2256,7 +2178,6 @@ fn test_entrypoint_exit() { exit", config, [], - (), TestContextObject::new(5), ProgramResult::Ok(42), ); @@ -2286,7 +2207,6 @@ fn test_stack_call_depth_tracking() { ", config.clone(), [], - (), TestContextObject::new(5), ProgramResult::Ok(0), ); @@ -2305,7 +2225,6 @@ fn test_stack_call_depth_tracking() { ", config, [], - (), TestContextObject::new(2), ProgramResult::Err(EbpfError::CallDepthExceeded), ); @@ -2385,7 +2304,6 @@ fn test_bpf_to_bpf_scratch_registers() { mov64 r9, 0x00 exit", [], - (), TestContextObject::new(15), ProgramResult::Ok(0xFF), ); @@ -2422,7 +2340,6 @@ fn test_callx() { mov64 r0, 0x2A exit", [], - (), TestContextObject::new(6), ProgramResult::Ok(42), ); @@ -2439,7 +2356,6 @@ fn test_err_callx_unregistered() { mov64 r0, 0x2A exit", [], - (), TestContextObject::new(4), ProgramResult::Err(EbpfError::UnsupportedInstruction), ); @@ -2458,7 +2374,6 @@ fn test_err_callx_oob_low() { exit", config, [], - (), TestContextObject::new(2), ProgramResult::Err(EbpfError::CallOutsideTextSegment), ); @@ -2474,7 +2389,6 @@ fn test_err_callx_oob_high() { callx r0 exit", [], - (), TestContextObject::new(4), ProgramResult::Err(EbpfError::CallOutsideTextSegment), ); @@ -2511,7 +2425,6 @@ fn test_bpf_to_bpf_depth() { exit", config.clone(), [max_call_depth as u8], - (), TestContextObject::new(max_call_depth as u64 * 4 - 2), ProgramResult::Ok(0), ); @@ -2529,7 +2442,6 @@ fn test_bpf_to_bpf_depth() { exit", config, [max_call_depth as u8 + 1], - (), TestContextObject::new(max_call_depth as u64 * 3), ProgramResult::Err(EbpfError::CallDepthExceeded), ); @@ -2549,7 +2461,6 @@ fn test_err_reg_stack_depth() { exit", config, [], - (), TestContextObject::new(max_call_depth as u64), ProgramResult::Err(EbpfError::CallDepthExceeded), ); @@ -2768,7 +2679,6 @@ fn test_tight_infinite_loop_conditional() { jsge r0, r0, -1 exit", [], - (), TestContextObject::new(4), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2781,7 +2691,6 @@ fn test_tight_infinite_loop_unconditional() { ja -1 exit", [], - (), TestContextObject::new(4), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2796,7 +2705,6 @@ fn test_tight_infinite_recursion() { call entrypoint exit", [], - (), TestContextObject::new(4), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2814,7 +2722,6 @@ fn test_tight_infinite_recursion_callx() { callx r8 exit", [], - (), TestContextObject::new(6), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2868,7 +2775,6 @@ fn test_err_non_terminate_capped() { ja -0x8 exit", [], - (), TestContextObject::new(7), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2884,7 +2790,6 @@ fn test_err_non_terminate_capped() { ja -0x8 exit", [], - (), TestContextObject::new(1000), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2900,7 +2805,6 @@ fn test_err_capped_before_exception() { mov64 r0, 0x0 exit", [], - (), TestContextObject::new(2), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2913,7 +2817,6 @@ fn test_err_capped_before_exception() { mov64 r0, 0x0 exit", [], - (), TestContextObject::new(2), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2930,7 +2833,6 @@ fn test_err_exit_capped() { exit ", [], - (), TestContextObject::new(3), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2944,7 +2846,6 @@ fn test_err_exit_capped() { exit ", [], - (), TestContextObject::new(4), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2957,7 +2858,6 @@ fn test_err_exit_capped() { exit ", [], - (), TestContextObject::new(3), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -2979,7 +2879,6 @@ fn test_far_jumps() { callx r1 exit", [], - (), TestContextObject::new(6), ProgramResult::Ok(0), ); @@ -3005,7 +2904,6 @@ fn test_err_call_unresolved() { exit", config.clone(), [], - (), TestContextObject::new(6), ProgramResult::Err(EbpfError::UnsupportedInstruction), ); @@ -3168,7 +3066,6 @@ fn test_lmul_loop() { jne r1, 0x0, -3 exit", [], - (), TestContextObject::new(37), ProgramResult::Ok(0x75db9c97), ); @@ -3195,7 +3092,6 @@ fn test_prime() { jne r4, 0x0, -10 exit", [], - (), TestContextObject::new(655), ProgramResult::Ok(0x1), ); @@ -3231,7 +3127,6 @@ fn test_subnet() { 0x27, 0x24, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, // 0x03, 0x00, // ], - (), TestContextObject::new(11), ProgramResult::Ok(0x1), ); @@ -3256,7 +3151,6 @@ fn test_tcp_port80_match() { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // 0x44, 0x44, 0x44, 0x44, // ], - (), TestContextObject::new(17), ProgramResult::Ok(0x1), ); @@ -3281,7 +3175,6 @@ fn test_tcp_port80_nomatch() { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // 0x44, 0x44, 0x44, 0x44, // ], - (), TestContextObject::new(18), ProgramResult::Ok(0x0), ); @@ -3306,7 +3199,6 @@ fn test_tcp_port80_nomatch_ethertype() { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // 0x44, 0x44, 0x44, 0x44, // ], - (), TestContextObject::new(7), ProgramResult::Ok(0x0), ); @@ -3331,7 +3223,6 @@ fn test_tcp_port80_nomatch_proto() { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // 0x44, 0x44, 0x44, 0x44, // ], - (), TestContextObject::new(9), ProgramResult::Ok(0x0), ); @@ -3342,7 +3233,6 @@ fn test_tcp_sack_match() { test_interpreter_and_jit_asm!( TCP_SACK_ASM, TCP_SACK_MATCH, - (), TestContextObject::new(79), ProgramResult::Ok(0x1), ); @@ -3353,7 +3243,6 @@ fn test_tcp_sack_nomatch() { test_interpreter_and_jit_asm!( TCP_SACK_ASM, TCP_SACK_NOMATCH, - (), TestContextObject::new(55), ProgramResult::Ok(0x0), ); @@ -3561,7 +3450,6 @@ fn test_err_fixed_stack_out_of_bound() { exit", config, [], - (), TestContextObject::new(1), ProgramResult::Err(EbpfError::AccessViolation( AccessType::Store, @@ -3583,7 +3471,6 @@ fn test_execution_overrun() { add r1, 0", config.clone(), [], - (), TestContextObject::new(2), ProgramResult::Err(EbpfError::ExecutionOverrun), ); @@ -3592,7 +3479,6 @@ fn test_execution_overrun() { add r1, 0", config.clone(), [], - (), TestContextObject::new(1), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -3601,7 +3487,6 @@ fn test_execution_overrun() { add r1, 0", config.clone(), [], - (), TestContextObject::new(0), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -3620,7 +3505,6 @@ fn test_mov32_reg_truncating() { exit", config, [], - (), TestContextObject::new(3), ProgramResult::Ok(0xffffffff), ); @@ -3637,7 +3521,6 @@ fn test_lddw() { lddw r0, 0x1122334455667788", config.clone(), [], - (), TestContextObject::new(2), ProgramResult::Err(EbpfError::ExecutionOverrun), ); @@ -3647,7 +3530,6 @@ fn test_lddw() { exit", config.clone(), [], - (), TestContextObject::new(2), ProgramResult::Ok(0x1122334455667788), ); @@ -3657,7 +3539,6 @@ fn test_lddw() { exit", config.clone(), [], - (), TestContextObject::new(2), ProgramResult::Ok(0x80000000), ); @@ -3676,7 +3557,6 @@ fn test_lddw() { ", config.clone(), [], - (), TestContextObject::new(9), ProgramResult::Ok(0x2), ); @@ -3690,7 +3570,6 @@ fn test_lddw() { exit", config.clone(), [], - (), TestContextObject::new(4), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -3704,7 +3583,6 @@ fn test_lddw() { exit", config.clone(), [], - (), TestContextObject::new(5), ProgramResult::Err(EbpfError::UnsupportedInstruction), ); @@ -3721,7 +3599,6 @@ fn test_lddw() { ", config.clone(), [], - (), TestContextObject::new(5), ProgramResult::Err(EbpfError::UnsupportedInstruction), ); @@ -3737,7 +3614,6 @@ fn test_lddw() { ", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Err(EbpfError::UnsupportedInstruction), ); @@ -3750,7 +3626,6 @@ fn test_lddw() { ", config, [], - (), TestContextObject::new(2), ProgramResult::Err(EbpfError::ExceededMaxInstructions), ); @@ -3769,7 +3644,6 @@ fn test_le() { exit", config.clone(), [0x22, 0x11], - (), TestContextObject::new(3), ProgramResult::Ok(0x1122), ); @@ -3780,7 +3654,6 @@ fn test_le() { exit", config.clone(), [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], - (), TestContextObject::new(3), ProgramResult::Ok(0x2211), ); @@ -3791,7 +3664,6 @@ fn test_le() { exit", config.clone(), [0x44, 0x33, 0x22, 0x11], - (), TestContextObject::new(3), ProgramResult::Ok(0x11223344), ); @@ -3802,7 +3674,6 @@ fn test_le() { exit", config.clone(), [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88], - (), TestContextObject::new(3), ProgramResult::Ok(0x44332211), ); @@ -3813,7 +3684,6 @@ fn test_le() { exit", config, [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11], - (), TestContextObject::new(3), ProgramResult::Ok(0x1122334455667788), ); @@ -3832,7 +3702,6 @@ fn test_neg() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Ok(0xfffffffe), ); @@ -3843,7 +3712,6 @@ fn test_neg() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Ok(0xfffffffffffffffe), ); @@ -3854,7 +3722,6 @@ fn test_neg() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Ok(2), ); @@ -3865,7 +3732,6 @@ fn test_neg() { exit", config, [], - (), TestContextObject::new(3), ProgramResult::Ok(2), ); @@ -3890,7 +3756,6 @@ fn test_callx_imm() { exit", config, [], - (), TestContextObject::new(8), ProgramResult::Ok(42), ); @@ -3909,7 +3774,6 @@ fn test_mul() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Ok(0xc), ); @@ -3921,7 +3785,6 @@ fn test_mul() { exit", config.clone(), [], - (), TestContextObject::new(4), ProgramResult::Ok(0xc), ); @@ -3933,7 +3796,6 @@ fn test_mul() { exit", config.clone(), [], - (), TestContextObject::new(4), ProgramResult::Ok(0x4), ); @@ -3944,7 +3806,6 @@ fn test_mul() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Ok(0x100000004), ); @@ -3956,7 +3817,6 @@ fn test_mul() { exit", config.clone(), [], - (), TestContextObject::new(4), ProgramResult::Ok(0x100000004), ); @@ -3967,7 +3827,6 @@ fn test_mul() { exit", config, [], - (), TestContextObject::new(3), ProgramResult::Ok(0xFFFFFFFFFFFFFFFC), ); @@ -3987,7 +3846,6 @@ fn test_div() { exit", config.clone(), [], - (), TestContextObject::new(4), ProgramResult::Ok(0x3), ); @@ -3998,7 +3856,6 @@ fn test_div() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Ok(0x3), ); @@ -4010,7 +3867,6 @@ fn test_div() { exit", config.clone(), [], - (), TestContextObject::new(4), ProgramResult::Ok(0x3), ); @@ -4022,7 +3878,6 @@ fn test_div() { exit", config.clone(), [], - (), TestContextObject::new(4), ProgramResult::Ok(0x300000000), ); @@ -4035,7 +3890,6 @@ fn test_div() { exit", config.clone(), [], - (), TestContextObject::new(5), ProgramResult::Ok(0x300000000), ); @@ -4047,7 +3901,6 @@ fn test_div() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Err(EbpfError::DivideByZero), ); @@ -4059,7 +3912,6 @@ fn test_div() { exit", config, [], - (), TestContextObject::new(3), ProgramResult::Err(EbpfError::DivideByZero), ); @@ -4080,7 +3932,6 @@ fn test_mod() { exit", config.clone(), [], - (), TestContextObject::new(5), ProgramResult::Ok(0x5), ); @@ -4091,7 +3942,6 @@ fn test_mod() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Ok(0x0), ); @@ -4108,7 +3958,6 @@ fn test_mod() { exit", config.clone(), [], - (), TestContextObject::new(9), ProgramResult::Ok(0x30ba5a04), ); @@ -4120,7 +3969,6 @@ fn test_mod() { exit", config.clone(), [], - (), TestContextObject::new(3), ProgramResult::Err(EbpfError::DivideByZero), ); @@ -4132,7 +3980,6 @@ fn test_mod() { exit", config, [], - (), TestContextObject::new(3), ProgramResult::Err(EbpfError::DivideByZero), );