From 31c8b6f83e4eb3480442f2541fe4ae10ae253078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Sat, 30 Sep 2023 16:13:13 +0200 Subject: [PATCH] Adds a reference to the loader in the VM. (#533) --- cli/src/main.rs | 2 +- src/jit.rs | 2 +- src/vm.rs | 16 ++++++++++------ test_utils/src/lib.rs | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/cli/src/main.rs b/cli/src/main.rs index 905028a1..30c8e2ca 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -171,7 +171,7 @@ fn main() { let memory_mapping = MemoryMapping::new(regions, config, sbpf_version).unwrap(); let mut vm = EbpfVm::new( - executable.get_config(), + executable.get_loader().clone(), executable.get_sbpf_version(), &mut context_object, memory_mapping, diff --git a/src/jit.rs b/src/jit.rs index 8f9a4653..ae555132 100644 --- a/src/jit.rs +++ b/src/jit.rs @@ -1628,7 +1628,7 @@ mod tests { let executable = create_mockup_executable(&[]); let mut context_object = TestContextObject::new(0); let env = EbpfVm::new( - executable.get_config(), + executable.get_loader().clone(), executable.get_sbpf_version(), &mut context_object, MemoryMapping::new_identity(), diff --git a/src/vm.rs b/src/vm.rs index 7b677d12..365239a2 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -319,13 +319,12 @@ pub struct CallFrame { /// /// let loader = std::sync::Arc::new(BuiltinProgram::new_mock()); /// let function_registry = FunctionRegistry::default(); -/// let mut executable = Executable::::from_text_bytes(prog, loader, SBPFVersion::V2, function_registry).unwrap(); +/// let mut executable = Executable::::from_text_bytes(prog, loader.clone(), SBPFVersion::V2, function_registry).unwrap(); /// executable.verify::().unwrap(); /// let mut context_object = TestContextObject::new(1); -/// let config = executable.get_config(); /// let sbpf_version = executable.get_sbpf_version(); /// -/// let mut stack = AlignedMemory::<{ebpf::HOST_ALIGN}>::zero_filled(config.stack_size()); +/// let mut stack = AlignedMemory::<{ebpf::HOST_ALIGN}>::zero_filled(executable.get_config().stack_size()); /// let stack_len = stack.len(); /// let mut heap = AlignedMemory::<{ebpf::HOST_ALIGN}>::with_capacity(0); /// @@ -339,9 +338,9 @@ pub struct CallFrame { /// MemoryRegion::new_writable(mem, ebpf::MM_INPUT_START), /// ]; /// -/// let memory_mapping = MemoryMapping::new(regions, config, sbpf_version).unwrap(); +/// let memory_mapping = MemoryMapping::new(regions, executable.get_config(), sbpf_version).unwrap(); /// -/// let mut vm = EbpfVm::new(config, sbpf_version, &mut context_object, memory_mapping, stack_len); +/// let mut vm = EbpfVm::new(loader, sbpf_version, &mut context_object, memory_mapping, stack_len); /// /// let (instruction_count, result) = vm.execute_program(&executable, true); /// assert_eq!(instruction_count, 1); @@ -379,6 +378,8 @@ pub struct EbpfVm<'a, C: ContextObject> { pub memory_mapping: MemoryMapping<'a>, /// Stack of CallFrames used by the Interpreter pub call_frames: Vec, + /// Loader built-in program + pub loader: Arc>, /// TCP port for the debugger interface #[cfg(feature = "debugger")] pub debug_port: Option, @@ -387,12 +388,13 @@ pub struct EbpfVm<'a, C: ContextObject> { impl<'a, C: ContextObject> EbpfVm<'a, C> { /// Creates a new virtual machine instance. pub fn new( - config: &Config, + loader: Arc>, sbpf_version: &SBPFVersion, context_object: &'a mut C, mut memory_mapping: MemoryMapping<'a>, stack_len: usize, ) -> Self { + let config = loader.get_config(); let stack_pointer = ebpf::MM_STACK_START.saturating_add(if sbpf_version.dynamic_stack_frames() { // the stack is fully descending, frames start as empty and change size anytime r11 is modified @@ -416,6 +418,7 @@ impl<'a, C: ContextObject> EbpfVm<'a, C> { program_result: ProgramResult::Ok(0), memory_mapping, call_frames: vec![CallFrame::default(); config.max_call_depth], + loader, #[cfg(feature = "debugger")] debug_port: None, } @@ -429,6 +432,7 @@ impl<'a, C: ContextObject> EbpfVm<'a, C> { executable: &Executable, interpreted: bool, ) -> (u64, ProgramResult) { + debug_assert!(Arc::ptr_eq(&self.loader, executable.get_loader())); // R1 points to beginning of input memory, R10 to the stack of the first frame, R11 is the pc (hidden) self.registers[1] = ebpf::MM_INPUT_START; self.registers[ebpf::FRAME_PTR_REG] = self.stack_pointer; diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs index d173dd94..7c56eb57 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs @@ -208,7 +208,7 @@ macro_rules! create_vm { ) .unwrap(); let mut $vm_name = solana_rbpf::vm::EbpfVm::new( - $verified_executable.get_config(), + $verified_executable.get_loader().clone(), $verified_executable.get_sbpf_version(), $context_object, memory_mapping,