solana_program_test

Struct EbpfVm

source
#[repr(C)]
pub struct EbpfVm<'a, C>
where 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: StableResult<u64, EbpfError>, 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: StableResult<u64, EbpfError>

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> EbpfVm<'a, C>
where C: ContextObject,

source

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

Creates a new virtual machine instance.

source

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

Execute the program

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

source

pub fn invoke_function( &mut self, function: fn(_: *mut EbpfVm<'_, C>, _: u64, _: u64, _: u64, _: u64, _: u64), )

Invokes a built-in function

Auto Trait Implementations§

§

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

§

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> AbiExample for T

source§

default fn example() -> T

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<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

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> FutureExt for T

source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<T> Pointable for T

source§

const ALIGN: usize = _

The alignment of pointer.
source§

type Init = T

The type for initializers.
source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> Same for T

source§

type Output = T

Should always be Self
source§

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

source§

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>,

source§

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.
source§

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

source§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more