Struct solana_rbpf::vm::EbpfVm

source ·
#[repr(C)]
pub struct EbpfVm<'a, C: ContextObject> {
Show 13 fields pub host_stack_pointer: *mut u64, pub call_depth: u64, pub stack_pointer: u64, pub context_object_pointer: &'a mut C, pub previous_instruction_meter: u64, pub due_insn_count: u64, pub stopwatch_numerator: u64, pub stopwatch_denominator: u64, pub registers: [u64; 12], pub program_result: ProgramResult, pub memory_mapping: MemoryMapping<'a>, pub call_frames: Vec<CallFrame>, pub loader: Arc<BuiltinProgram<C>>,
}
Expand description

A virtual machine to run eBPF programs.

Examples

use solana_rbpf::{
    aligned_memory::AlignedMemory,
    ebpf,
    elf::Executable,
    memory_region::{MemoryMapping, MemoryRegion},
    program::{BuiltinProgram, FunctionRegistry, SBPFVersion},
    verifier::RequisiteVerifier,
    vm::{Config, EbpfVm, TestContextObject},
};

let prog = &[
    0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // exit
];
let mem = &mut [
    0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd
];

let loader = std::sync::Arc::new(BuiltinProgram::new_mock());
let function_registry = FunctionRegistry::default();
let mut executable = Executable::<TestContextObject>::from_text_bytes(prog, loader.clone(), SBPFVersion::V2, function_registry).unwrap();
executable.verify::<RequisiteVerifier>().unwrap();
let mut context_object = TestContextObject::new(1);
let sbpf_version = executable.get_sbpf_version();

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);

let regions: Vec<MemoryRegion> = vec![
    executable.get_ro_region(),
    MemoryRegion::new_writable(
        stack.as_slice_mut(),
        ebpf::MM_STACK_START,
    ),
    MemoryRegion::new_writable(heap.as_slice_mut(), ebpf::MM_HEAP_START),
    MemoryRegion::new_writable(mem, ebpf::MM_INPUT_START),
];

let memory_mapping = MemoryMapping::new(regions, executable.get_config(), sbpf_version).unwrap();

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);
assert_eq!(result.unwrap(), 0);

Fields§

§host_stack_pointer: *mut u64

Needed to exit from the guest back into the host

§call_depth: u64

The current call depth.

Incremented on calls and decremented on exits. It’s used to enforce config.max_call_depth and to know when to terminate execution.

§stack_pointer: u64

Guest stack pointer (r11).

The stack pointer isn’t exposed as an actual register. Only sub and add instructions (typically generated by the LLVM backend) are allowed to access it when sbpf_version.dynamic_stack_frames()=true. Its value is only stored here and therefore the register is not tracked in REGISTER_MAP.

§context_object_pointer: &'a mut C

Pointer to ContextObject

§previous_instruction_meter: u64

Last return value of instruction_meter.get_remaining()

§due_insn_count: u64

Outstanding value to instruction_meter.consume()

§stopwatch_numerator: u64

CPU cycles accumulated by the stop watch

§stopwatch_denominator: u64

Number of times the stop watch was used

§registers: [u64; 12]

Registers inlined

§program_result: ProgramResult

ProgramResult inlined

§memory_mapping: MemoryMapping<'a>

MemoryMapping inlined

§call_frames: Vec<CallFrame>

Stack of CallFrames used by the Interpreter

§loader: Arc<BuiltinProgram<C>>

Loader built-in program

Implementations§

source§

impl<'a, C: ContextObject> EbpfVm<'a, C>

source

pub fn new( loader: Arc<BuiltinProgram<C>>, sbpf_version: &SBPFVersion, context_object: &'a mut C, memory_mapping: MemoryMapping<'a>, stack_len: usize ) -> Self

Creates a new virtual machine instance.

source

pub fn execute_program( &mut self, executable: &Executable<C>, interpreted: bool ) -> (u64, ProgramResult)

Execute the program

If interpreted = false then the JIT compiled executable is used.

source

pub fn invoke_function(&mut self, function: BuiltinFunction<C>)

Invokes a built-in function

Auto Trait Implementations§

§

impl<'a, C> !RefUnwindSafe for EbpfVm<'a, C>

§

impl<'a, C> !Send for EbpfVm<'a, C>

§

impl<'a, C> !Sync for EbpfVm<'a, C>

§

impl<'a, C> Unpin for EbpfVm<'a, C>

§

impl<'a, C> !UnwindSafe for EbpfVm<'a, C>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V