[−][src]Struct solana_rbpf::vm::EbpfVm
A virtual machine to run eBPF program.
Examples
use solana_rbpf::{vm::{EbpfVm, Config}, user_error::UserError}; let prog = &[ 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // exit ]; let mem = &mut [ 0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd ]; // Instantiate a VM. let executable = EbpfVm::<UserError>::create_executable_from_text_bytes(prog, None).unwrap(); let mut vm = EbpfVm::<UserError>::new(executable.as_ref(), Config::default()).unwrap(); // Provide a reference to the packet data. let res = vm.execute_program(mem, &[], &[]).unwrap(); assert_eq!(res, 0);
Implementations
impl<'a, E: UserDefinedError> EbpfVm<'a, E>
[src]
pub fn new(
executable: &'a dyn Executable<E>,
config: Config
) -> Result<EbpfVm<'a, E>, EbpfError<E>>
[src]
executable: &'a dyn Executable<E>,
config: Config
) -> Result<EbpfVm<'a, E>, EbpfError<E>>
Create a new virtual machine instance, and load an eBPF program into that instance. When attempting to load the program, it passes through a simple verifier.
Examples
use solana_rbpf::{vm::{EbpfVm, Config}, user_error::UserError}; let prog = &[ 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // exit ]; // Instantiate a VM. let executable = EbpfVm::<UserError>::create_executable_from_text_bytes(prog, None).unwrap(); let mut vm = EbpfVm::<UserError>::new(executable.as_ref(), Config::default()).unwrap();
pub fn create_executable_from_elf(
elf_bytes: &'a [u8],
verifier: Option<Verifier<E>>
) -> Result<Box<dyn Executable<E>>, EbpfError<E>>
[src]
elf_bytes: &'a [u8],
verifier: Option<Verifier<E>>
) -> Result<Box<dyn Executable<E>>, EbpfError<E>>
Creates a post relocaiton/fixup executable
pub fn create_executable_from_text_bytes(
text_bytes: &'a [u8],
verifier: Option<Verifier<E>>
) -> Result<Box<dyn Executable<E>>, EbpfError<E>>
[src]
text_bytes: &'a [u8],
verifier: Option<Verifier<E>>
) -> Result<Box<dyn Executable<E>>, EbpfError<E>>
Creates a post relocaiton/fixup executable
pub fn get_total_instruction_count(&self) -> u64
[src]
Returns the number of instructions executed by the last program.
pub fn register_syscall(
&mut self,
key: u32,
syscall: SyscallFunction<E>
) -> Result<(), EbpfError<E>>
[src]
&mut self,
key: u32,
syscall: SyscallFunction<E>
) -> Result<(), EbpfError<E>>
Register a built-in or user-defined syscall function in order to use it later from within
the eBPF program. The syscall is registered into a hashmap, so the key
can be any u32
.
If using JIT-compiled eBPF programs, be sure to register all syscalls before compiling the program. You should be able to change registered syscalls after compiling, but not to add new ones (i.e. with new keys).
Examples
use solana_rbpf::{vm::{EbpfVm, Config}, syscalls::bpf_trace_printf, user_error::UserError}; // 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 ]; // Instantiate a VM. let executable = EbpfVm::<UserError>::create_executable_from_text_bytes(prog, None).unwrap(); let mut vm = EbpfVm::<UserError>::new(executable.as_ref(), Config::default()).unwrap(); // Register a syscall. // On running the program this syscall will print the content of registers r3, r4 and r5 to // standard output. vm.register_syscall(6, bpf_trace_printf::<UserError>).unwrap();
pub fn register_syscall_ex(
&mut self,
name: &str,
syscall: SyscallFunction<E>
) -> Result<(), EbpfError<E>>
[src]
&mut self,
name: &str,
syscall: SyscallFunction<E>
) -> Result<(), EbpfError<E>>
Register a user-defined syscall function in order to use it later from within
the eBPF program. Normally syscall functions are referred to by an index. (See syscalls)
but this function takes the name of the function. The name is then hashed into a 32 bit
number and used in the call
instructions imm field. If calling set_elf
then
the elf's relocations must reference this symbol using the same name. This can usually be
achieved by building the elf with unresolved symbols (think extern foo(void)
). If
providing a program directly via set_program
then any call
instructions must already
have the hash of the symbol name in its imm field. To generate the correct hash of the
symbol name use ebpf::syscalls::hash_symbol_name
.
pub fn register_syscall_with_context_ex(
&mut self,
name: &str,
syscall: Box<dyn SyscallObject<E> + 'a>
) -> Result<(), EbpfError<E>>
[src]
&mut self,
name: &str,
syscall: Box<dyn SyscallObject<E> + 'a>
) -> Result<(), EbpfError<E>>
Same as register_syscall_ex except reguster a syscall trait object that carries along context needed by the syscall
pub fn execute_program(
&mut self,
mem: &[u8],
granted_ro_regions: &[MemoryRegion],
granted_rw_regions: &[MemoryRegion]
) -> Result<u64, EbpfError<E>>
[src]
&mut self,
mem: &[u8],
granted_ro_regions: &[MemoryRegion],
granted_rw_regions: &[MemoryRegion]
) -> Result<u64, EbpfError<E>>
Execute the program loaded, with the given packet data.
Warning: The program is executed without limiting the number of instructions that can be executed
Examples
use solana_rbpf::{vm::{EbpfVm, Config}, user_error::UserError}; let prog = &[ 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // exit ]; let mem = &mut [ 0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd ]; // Instantiate a VM. let executable = EbpfVm::<UserError>::create_executable_from_text_bytes(prog, None).unwrap(); let mut vm = EbpfVm::<UserError>::new(executable.as_ref(), Config::default()).unwrap(); // Provide a reference to the packet data. let res = vm.execute_program(mem, &[], &[]).unwrap(); assert_eq!(res, 0);
pub fn execute_program_metered<I: InstructionMeter>(
&mut self,
mem: &[u8],
granted_ro_regions: &[MemoryRegion],
granted_rw_regions: &[MemoryRegion],
instruction_meter: I
) -> Result<u64, EbpfError<E>>
[src]
&mut self,
mem: &[u8],
granted_ro_regions: &[MemoryRegion],
granted_rw_regions: &[MemoryRegion],
instruction_meter: I
) -> Result<u64, EbpfError<E>>
Execute the program loaded, with the given packet data and instruction meter.
pub fn jit_compile(&mut self) -> Result<(), EbpfError<E>>
[src]
JIT-compile the loaded program. No argument required for this.
If using syscall functions, be sure to register them into the VM before calling this function.
Examples
use solana_rbpf::{vm::{EbpfVm, Config}, user_error::UserError}; let prog = &[ 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // exit ]; // Instantiate a VM. let executable = EbpfVm::<UserError>::create_executable_from_text_bytes(prog, None).unwrap(); let mut vm = EbpfVm::<UserError>::new(executable.as_ref(), Config::default()).unwrap(); vm.jit_compile();
pub unsafe fn execute_program_jit(
&self,
mem: &mut [u8]
) -> Result<u64, EbpfError<E>>
[src]
&self,
mem: &mut [u8]
) -> Result<u64, EbpfError<E>>
Execute the previously JIT-compiled program, with the given packet data
in a manner very similar to execute_program(&[], &[])
.
Safety
WARNING: JIT-compiled assembly code is not safe, in particular there is no runtime check for memory access; so if the eBPF program attempts erroneous accesses, this may end very bad (program may segfault). It may be wise to check that the program works with the interpreter before running the JIT-compiled version of it.
For this reason the function should be called from within an unsafe
bloc.
Auto Trait Implementations
impl<'a, E> !RefUnwindSafe for EbpfVm<'a, E>
impl<'a, E> !Send for EbpfVm<'a, E>
impl<'a, E> !Sync for EbpfVm<'a, E>
impl<'a, E> Unpin for EbpfVm<'a, E>
impl<'a, E> !UnwindSafe for EbpfVm<'a, E>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,