Skip to content

Commit

Permalink
Replaces bind_syscall_context_object() by a parameter in the construc…
Browse files Browse the repository at this point in the history
…tor. (#388)
  • Loading branch information
Lichtso authored Oct 3, 2022
1 parent 2e9ec24 commit 34660e9
Show file tree
Hide file tree
Showing 11 changed files with 37 additions and 68 deletions.
2 changes: 1 addition & 1 deletion benches/jit_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn bench_init_vm(bencher: &mut Bencher) {
let verified_executable =
VerifiedExecutable::<TautologyVerifier, TestInstructionMeter>::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))]
Expand Down
6 changes: 3 additions & 3 deletions benches/vm_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn bench_init_interpreter_execution(bencher: &mut Bencher) {
let verified_executable =
VerifiedExecutable::<TautologyVerifier, TestInstructionMeter>::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()
Expand All @@ -56,7 +56,7 @@ fn bench_init_jit_execution(bencher: &mut Bencher) {
VerifiedExecutable::<TautologyVerifier, TestInstructionMeter>::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()
Expand All @@ -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(|| {
Expand Down
3 changes: 1 addition & 2 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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::<u16>().unwrap();
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/dumb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fuzz_target!(|data: DumbFuzzData| {
VerifiedExecutable::<TautologyVerifier, TestInstructionMeter>::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 },
Expand Down
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/smart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fuzz_target!(|data: FuzzData| {
VerifiedExecutable::<TautologyVerifier, TestInstructionMeter>::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 },
Expand Down
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/smart_jit_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/smarter_jit_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
57 changes: 8 additions & 49 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -441,7 +441,7 @@ impl Tracer {
/// let mut executable = Executable::<TestInstructionMeter>::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::<RequisiteVerifier, TestInstructionMeter>::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();
Expand Down Expand Up @@ -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::<TestInstructionMeter>::from_text_bytes(prog, config, syscall_registry, bpf_functions).unwrap();
/// let verified_executable = VerifiedExecutable::<RequisiteVerifier, TestInstructionMeter>::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<O>(
verified_executable: &'a VerifiedExecutable<V, I>,
syscall_context_object: &mut O,
heap_region: &mut [u8],
additional_regions: Vec<MemoryRegion>,
) -> Result<EbpfVm<'a, V, I>, EbpfError> {
Expand All @@ -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,
Expand All @@ -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::<TestInstructionMeter>::from_text_bytes(prog, config, syscall_registry, bpf_functions).unwrap();
/// let verified_executable = VerifiedExecutable::<RequisiteVerifier, TestInstructionMeter>::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<O>(&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
Expand All @@ -593,7 +552,7 @@ impl<'a, V: Verifier, I: InstructionMeter> EbpfVm<'a, V, I> {
/// let mut executable = Executable::<TestInstructionMeter>::from_text_bytes(prog, config, syscall_registry, bpf_functions).unwrap();
/// let verified_executable = VerifiedExecutable::<RequisiteVerifier, TestInstructionMeter>::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();
Expand Down Expand Up @@ -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!(
Expand Down
2 changes: 1 addition & 1 deletion tests/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,11 @@ fn test_fuzz_execute() {
{
let mut vm = EbpfVm::<RequisiteVerifier, TestInstructionMeter>::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,
});
Expand Down
22 changes: 16 additions & 6 deletions tests/ubpf_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
});
Expand All @@ -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,
});
Expand Down Expand Up @@ -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,
});
Expand All @@ -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,
});
Expand Down
1 change: 1 addition & 0 deletions tests/ubpf_verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fn test_verifier_success() {
.unwrap();
let _vm = EbpfVm::<TautologyVerifier, TestInstructionMeter>::new(
&verified_executable,
&mut (),
&mut [],
Vec::new(),
)
Expand Down

0 comments on commit 34660e9

Please sign in to comment.