diff --git a/benches/jit_compile.rs b/benches/jit_compile.rs index af5295b0..6b785e24 100644 --- a/benches/jit_compile.rs +++ b/benches/jit_compile.rs @@ -31,7 +31,7 @@ fn bench_init_vm(bencher: &mut Bencher) { let verified_executable = VerifiedExecutable::::from_executable(executable) .unwrap(); - bencher.iter(|| EbpfVm::new(&verified_executable, &mut [], Vec::new()).unwrap()); + bencher.iter(|| EbpfVm::new(&verified_executable, &mut (), &mut [], Vec::new()).unwrap()); } #[cfg(not(windows))] diff --git a/benches/vm_execution.rs b/benches/vm_execution.rs index 36770421..c47052c6 100644 --- a/benches/vm_execution.rs +++ b/benches/vm_execution.rs @@ -33,7 +33,7 @@ fn bench_init_interpreter_execution(bencher: &mut Bencher) { let verified_executable = VerifiedExecutable::::from_executable(executable) .unwrap(); - let mut vm = EbpfVm::new(&verified_executable, &mut [], Vec::new()).unwrap(); + let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], Vec::new()).unwrap(); bencher.iter(|| { vm.execute_program_interpreted(&mut TestInstructionMeter { remaining: 29 }) .unwrap() @@ -56,7 +56,7 @@ fn bench_init_jit_execution(bencher: &mut Bencher) { VerifiedExecutable::::from_executable(executable) .unwrap(); verified_executable.jit_compile().unwrap(); - let mut vm = EbpfVm::new(&verified_executable, &mut [], Vec::new()).unwrap(); + let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], Vec::new()).unwrap(); bencher.iter(|| { vm.execute_program_jit(&mut TestInstructionMeter { remaining: 29 }) .unwrap() @@ -82,7 +82,7 @@ fn bench_jit_vs_interpreter( .unwrap(); verified_executable.jit_compile().unwrap(); let mem_region = MemoryRegion::new_writable(mem, ebpf::MM_INPUT_START); - let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); + let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![mem_region]).unwrap(); let interpreter_summary = bencher .bench(|bencher| { bencher.iter(|| { diff --git a/cli/src/main.rs b/cli/src/main.rs index 450a5cc4..20f761b4 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -153,7 +153,7 @@ fn main() { verified_executable.jit_compile().unwrap(); } let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START); - let mut vm = EbpfVm::new(&verified_executable, &mut heap, vec![mem_region]).unwrap(); + let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut heap, vec![mem_region]).unwrap(); let analysis = if matches.value_of("use") == Some("cfg") || matches.value_of("use") == Some("disassembler") @@ -186,7 +186,6 @@ fn main() { _ => {} } - vm.bind_syscall_context_object(&mut ()); let result = if matches.value_of("use").unwrap() == "debugger" { let mut interpreter = Interpreter::new(&mut vm, &mut instruction_meter).unwrap(); let port = matches.value_of("port").unwrap().parse::().unwrap(); diff --git a/fuzz/fuzz_targets/dumb.rs b/fuzz/fuzz_targets/dumb.rs index 96ce56ad..6d34a5ce 100644 --- a/fuzz/fuzz_targets/dumb.rs +++ b/fuzz/fuzz_targets/dumb.rs @@ -47,7 +47,7 @@ fuzz_target!(|data: DumbFuzzData| { VerifiedExecutable::::from_executable(executable) .unwrap(); let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START); - let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); + let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![mem_region]).unwrap(); drop(black_box(vm.execute_program_interpreted( &mut TestInstructionMeter { remaining: 1024 }, diff --git a/fuzz/fuzz_targets/smart.rs b/fuzz/fuzz_targets/smart.rs index aa489c4f..f6829a48 100644 --- a/fuzz/fuzz_targets/smart.rs +++ b/fuzz/fuzz_targets/smart.rs @@ -51,7 +51,7 @@ fuzz_target!(|data: FuzzData| { VerifiedExecutable::::from_executable(executable) .unwrap(); let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START); - let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); + let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![mem_region]).unwrap(); drop(black_box(vm.execute_program_interpreted( &mut TestInstructionMeter { remaining: 1 << 16 }, diff --git a/fuzz/fuzz_targets/smart_jit_diff.rs b/fuzz/fuzz_targets/smart_jit_diff.rs index c5223cf8..431b0048 100644 --- a/fuzz/fuzz_targets/smart_jit_diff.rs +++ b/fuzz/fuzz_targets/smart_jit_diff.rs @@ -62,9 +62,9 @@ fuzz_target!(|data: FuzzData| { if verified_executable.jit_compile().is_ok() { let interp_mem_region = MemoryRegion::new_writable(&mut interp_mem, ebpf::MM_INPUT_START); let mut interp_vm = - EbpfVm::new(&verified_executable, &mut [], vec![interp_mem_region]).unwrap(); + EbpfVm::new(&verified_executable, &mut (), &mut [], vec![interp_mem_region]).unwrap(); let jit_mem_region = MemoryRegion::new_writable(&mut jit_mem, ebpf::MM_INPUT_START); - let mut jit_vm = EbpfVm::new(&verified_executable, &mut [], vec![jit_mem_region]).unwrap(); + let mut jit_vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![jit_mem_region]).unwrap(); let mut interp_meter = TestInstructionMeter { remaining: 1 << 16 }; let interp_res = interp_vm.execute_program_interpreted(&mut interp_meter); diff --git a/fuzz/fuzz_targets/smarter_jit_diff.rs b/fuzz/fuzz_targets/smarter_jit_diff.rs index 40f96775..e97d38cf 100644 --- a/fuzz/fuzz_targets/smarter_jit_diff.rs +++ b/fuzz/fuzz_targets/smarter_jit_diff.rs @@ -63,9 +63,9 @@ fuzz_target!(|data: FuzzData| { if verified_executable.jit_compile().is_ok() { let interp_mem_region = MemoryRegion::new_writable(&mut interp_mem, ebpf::MM_INPUT_START); let mut interp_vm = - EbpfVm::new(&verified_executable, &mut [], vec![interp_mem_region]).unwrap(); + EbpfVm::new(&verified_executable, &mut (), &mut [], vec![interp_mem_region]).unwrap(); let jit_mem_region = MemoryRegion::new_writable(&mut jit_mem, ebpf::MM_INPUT_START); - let mut jit_vm = EbpfVm::new(&verified_executable, &mut [], vec![jit_mem_region]).unwrap(); + let mut jit_vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![jit_mem_region]).unwrap(); let mut interp_meter = TestInstructionMeter { remaining: 1 << 16 }; let interp_res = interp_vm.execute_program_interpreted(&mut interp_meter); diff --git a/src/vm.rs b/src/vm.rs index 180a4814..93dac595 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -27,7 +27,7 @@ use std::{ collections::{BTreeMap, HashMap}, fmt::Debug, marker::PhantomData, - mem, ptr, + mem, }; /// Same as `Result` but provides a stable memory layout @@ -441,7 +441,7 @@ impl Tracer { /// let mut executable = Executable::::from_text_bytes(prog, config, syscall_registry, bpf_functions).unwrap(); /// let mem_region = MemoryRegion::new_writable(mem, ebpf::MM_INPUT_START); /// let verified_executable = VerifiedExecutable::::from_executable(executable).unwrap(); -/// let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); +/// let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![mem_region]).unwrap(); /// /// // Provide a reference to the packet data. /// let res = vm.execute_program_interpreted(&mut TestInstructionMeter { remaining: 1 }).unwrap(); @@ -476,10 +476,11 @@ impl<'a, V: Verifier, I: InstructionMeter> EbpfVm<'a, V, I> { /// register_bpf_function(&config, &mut bpf_functions, &syscall_registry, 0, "entrypoint").unwrap(); /// let mut executable = Executable::::from_text_bytes(prog, config, syscall_registry, bpf_functions).unwrap(); /// let verified_executable = VerifiedExecutable::::from_executable(executable).unwrap(); - /// let mut vm = EbpfVm::new(&verified_executable, &mut [], Vec::new()).unwrap(); + /// let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], Vec::new()).unwrap(); /// ``` - pub fn new( + pub fn new( verified_executable: &'a VerifiedExecutable, + syscall_context_object: &mut O, heap_region: &mut [u8], additional_regions: Vec, ) -> Result, EbpfError> { @@ -501,7 +502,7 @@ impl<'a, V: Verifier, I: InstructionMeter> EbpfVm<'a, V, I> { program_vm_addr, program_environment: ProgramEnvironment { memory_mapping: MemoryMapping::new(regions, config)?, - syscall_context_object: ptr::null_mut(), + syscall_context_object: syscall_context_object as *mut O as *mut (), tracer: Tracer::default(), }, stack, @@ -526,48 +527,6 @@ impl<'a, V: Verifier, I: InstructionMeter> EbpfVm<'a, V, I> { &self.program_environment } - /// Initializes and binds the context object instances for all previously registered syscalls - /// - /// # Examples - /// - /// ``` - /// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, vm::{Config, EbpfVm, SyscallRegistry, TestInstructionMeter, VerifiedExecutable}, syscalls::BpfTracePrintf, verifier::RequisiteVerifier}; - /// - /// // This program was compiled with clang, from a C program containing the following single - /// // instruction: `return bpf_trace_printk("foo %c %c %c\n", 10, 1, 2, 3);` - /// let prog = &[ - /// 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // load 0 as u64 into r1 (That would be - /// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // replaced by tc by the address of - /// // the format string, in the .map - /// // section of the ELF file). - /// 0xb7, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, // mov r2, 10 - /// 0xb7, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // mov r3, 1 - /// 0xb7, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // mov r4, 2 - /// 0xb7, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // mov r5, 3 - /// 0x85, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, // call syscall with key 6 - /// 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // exit - /// ]; - /// - /// // Register a syscall. - /// // On running the program this syscall will print the content of registers r3, r4 and r5 to - /// // standard output. - /// let mut syscall_registry = SyscallRegistry::default(); - /// syscall_registry.register_syscall_by_hash(6, BpfTracePrintf::call).unwrap(); - /// // Instantiate an Executable and VM - /// let config = Config::default(); - /// let mut bpf_functions = std::collections::BTreeMap::new(); - /// register_bpf_function(&config, &mut bpf_functions, &syscall_registry, 0, "entrypoint").unwrap(); - /// let mut executable = Executable::::from_text_bytes(prog, config, syscall_registry, bpf_functions).unwrap(); - /// let verified_executable = VerifiedExecutable::::from_executable(executable).unwrap(); - /// let mut vm = EbpfVm::new(&verified_executable, &mut [], Vec::new()).unwrap(); - /// // Bind a context object instance to the previously registered syscall - /// vm.bind_syscall_context_object(&mut ()); - /// ``` - pub fn bind_syscall_context_object(&mut self, syscall_context_object: &mut O) { - self.program_environment.syscall_context_object = - syscall_context_object as *mut O as *mut (); - } - /// Execute the program loaded, with the given packet data. /// /// Warning: The program is executed without limiting the number of @@ -593,7 +552,7 @@ impl<'a, V: Verifier, I: InstructionMeter> EbpfVm<'a, V, I> { /// let mut executable = Executable::::from_text_bytes(prog, config, syscall_registry, bpf_functions).unwrap(); /// let verified_executable = VerifiedExecutable::::from_executable(executable).unwrap(); /// let mem_region = MemoryRegion::new_writable(mem, ebpf::MM_INPUT_START); - /// let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); + /// let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![mem_region]).unwrap(); /// /// // Provide a reference to the packet data. /// let res = vm.execute_program_interpreted(&mut TestInstructionMeter { remaining: 1 }).unwrap(); @@ -715,7 +674,7 @@ mod tests { let config = Config::default(); let env = ProgramEnvironment { memory_mapping: MemoryMapping::new(vec![], &config).unwrap(), - syscall_context_object: ptr::null_mut(), + syscall_context_object: std::ptr::null_mut(), tracer: Tracer::default(), }; assert_eq!( diff --git a/tests/misc.rs b/tests/misc.rs index b707a63b..b8d2f5f6 100644 --- a/tests/misc.rs +++ b/tests/misc.rs @@ -131,11 +131,11 @@ fn test_fuzz_execute() { { let mut vm = EbpfVm::::new( &verified_executable, + &mut (), &mut [], Vec::new(), ) .unwrap(); - vm.bind_syscall_context_object(&mut ()); let _ = vm.execute_program_interpreted(&mut TestInstructionMeter { remaining: 1_000_000, }); diff --git a/tests/ubpf_execution.rs b/tests/ubpf_execution.rs index 9d11ce5a..b7f3cfdc 100644 --- a/tests/ubpf_execution.rs +++ b/tests/ubpf_execution.rs @@ -49,8 +49,13 @@ macro_rules! test_interpreter_and_jit { let mut mem = $mem; let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START); - let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); - vm.bind_syscall_context_object($syscall_context); + let mut vm = EbpfVm::new( + &verified_executable, + $syscall_context, + &mut [], + vec![mem_region], + ) + .unwrap(); let result = vm.execute_program_interpreted(&mut TestInstructionMeter { remaining: $expected_instruction_count, }); @@ -67,11 +72,16 @@ macro_rules! test_interpreter_and_jit { let compilation_result = verified_executable.jit_compile(); let mut mem = $mem; let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START); - let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); + let mut vm = EbpfVm::new( + &verified_executable, + $syscall_context, + &mut [], + vec![mem_region], + ) + .unwrap(); match compilation_result { Err(err) => assert!(check_closure(&vm, ProgramResult::Err(err))), Ok(()) => { - vm.bind_syscall_context_object($syscall_context); let result = vm.execute_program_jit(&mut TestInstructionMeter { remaining: $expected_instruction_count, }); @@ -4215,7 +4225,7 @@ fn execute_generated_program(prog: &[u8]) -> bool { let (instruction_count_interpreter, tracer_interpreter, result_interpreter) = { let mut mem = vec![0u8; mem_size]; let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START); - let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); + let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![mem_region]).unwrap(); let result_interpreter = vm.execute_program_interpreted(&mut TestInstructionMeter { remaining: max_instruction_count, }); @@ -4228,7 +4238,7 @@ fn execute_generated_program(prog: &[u8]) -> bool { }; let mut mem = vec![0u8; mem_size]; let mem_region = MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START); - let mut vm = EbpfVm::new(&verified_executable, &mut [], vec![mem_region]).unwrap(); + let mut vm = EbpfVm::new(&verified_executable, &mut (), &mut [], vec![mem_region]).unwrap(); let result_jit = vm.execute_program_jit(&mut TestInstructionMeter { remaining: max_instruction_count, }); diff --git a/tests/ubpf_verifier.rs b/tests/ubpf_verifier.rs index f58efacd..9ccd9137 100644 --- a/tests/ubpf_verifier.rs +++ b/tests/ubpf_verifier.rs @@ -62,6 +62,7 @@ fn test_verifier_success() { .unwrap(); let _vm = EbpfVm::::new( &verified_executable, + &mut (), &mut [], Vec::new(), )