diff --git a/scripts/run_test_vectors.sh b/scripts/run_test_vectors.sh index fbc69c4..62308fe 100755 --- a/scripts/run_test_vectors.sh +++ b/scripts/run_test_vectors.sh @@ -23,7 +23,10 @@ else fi find dump/test-vectors/instr/fixtures -type f -name '*.fix' -exec ./target/release/test_exec_instr {} + > $LOG_PATH/test_exec_instr.log 2>&1 -find dump/test-vectors/txn/fixtures/precompile -type f -name '*.fix' -exec ./target/release/test_exec_txn {} + > $LOG_PATH/test_exec_precompile.log 2>&1 +# secp256r1 currently not working, agave has bugs +# find dump/test-vectors/txn/fixtures/precompile -type f -name '*.fix' -exec ./target/release/test_exec_txn {} + > $LOG_PATH/test_exec_precompile.log 2>&1 +find dump/test-vectors/txn/fixtures/precompile/ed25519 -type f -name '*.fix' -exec ./target/release/test_exec_txn {} + > $LOG_PATH/test_exec_precompile.log 2>&1 +find dump/test-vectors/txn/fixtures/precompile/secp256k1 -type f -name '*.fix' -exec ./target/release/test_exec_txn {} + > $LOG_PATH/test_exec_precompile.log 2>&1 find dump/test-vectors/txn/fixtures/programs -type f -name '*.fix' -exec ./target/release/test_exec_txn {} + > $LOG_PATH/test_exec_txn.log 2>&1 find dump/test-vectors/cpi/fixtures -type f -name '*.fix' -exec ./target/release/test_exec_cpi {} + > $LOG_PATH/test_exec_cpi.log 2>&1 find dump/test-vectors/syscall/fixtures -type f -name '*.fix' -exec ./target/release/test_exec_vm_syscall {} + > $LOG_PATH/test_exec_vm_syscall.log 2>&1 diff --git a/src/utils/vm/err_map.rs b/src/utils/vm/err_map.rs index 6b14f7b..81b67ab 100644 --- a/src/utils/vm/err_map.rs +++ b/src/utils/vm/err_map.rs @@ -16,12 +16,16 @@ pub fn get_fd_vm_err_code(ebpf_err: &EbpfError) -> i32 { EbpfError::CallDepthExceeded => 11, /* FD_VM_ERR_SIGSTACK */ EbpfError::InvalidInstruction => 12, /* FD_VM_ERR_SIGILL */ EbpfError::AccessViolation(_, _, _, _) => 13, /* FD_VM_ERR_SIGSEGV */ + EbpfError::StackAccessViolation(_, _, _, _) => 13, /* FD_VM_ERR_SIGSEGV */ /* FD_VM_ERR_SIGBUS (14) and FD_VM_ERR_SIGRDONLY (15) not used */ EbpfError::ExceededMaxInstructions => 16, /* FD_VM_ERR_SIGCOST*/ - EbpfError::DivideByZero => 17, /* FD_VM_ERR_SIGFPE */ + EbpfError::DivideByZero => 18, /* FD_VM_ERR_SIGFPE */ /* EbpfError::DivideOverflow isn't possible in SBPFv1 bytecode, so we don't have a mapping. */ - _ => -1, + err => { + eprintln!("unknown error: {:?}", err); + -1 + } } } diff --git a/src/vm_interp.rs b/src/vm_interp.rs index bd43c80..33ac094 100644 --- a/src/vm_interp.rs +++ b/src/vm_interp.rs @@ -111,10 +111,19 @@ pub fn execute_vm_interp(syscall_context: SyscallContext) -> Option Option::from(&vec![0; vm_ctx.heap_max as usize]); - /* TODO: should we just use loader.get_config()? */ - let config = &Config { - aligned_memory_mapping: true, - enabled_sbpf_versions: SBPFVersion::V1..=SBPFVersion::V1, - enable_stack_frame_gaps: !feature_set.is_active(&bpf_account_data_direct_mapping::id()), - ..Config::default() - }; - let mut regions = vec![ MemoryRegion::new_readonly(rodata.as_slice(), ebpf::MM_PROGRAM_START), MemoryRegion::new_writable_gapped( @@ -200,14 +201,14 @@ pub fn execute_vm_interp(syscall_context: SyscallContext) -> Option().is_err() { return Some(SyscallEffects { - error: -1, + error: -2, ..Default::default() }); } if executable.jit_compile().is_err() { return Some(SyscallEffects { - error: -1, + error: -3, ..Default::default() }); } @@ -226,6 +227,14 @@ pub fn execute_vm_interp(syscall_context: SyscallContext) -> Option StableResult::Ok(n), }; + // When a program fails, the register in trace_log are not properly + // captured (they represent the state at the end of the previous ix). + // For simplicity, we ignore them. + let out_registers = match result { + StableResult::Err(_) => &[0; 12], + StableResult::Ok(_) => vm.context_object_pointer.trace_log.last()?, + }; + if let StableResult::Err(err) = result.borrow() { if let EbpfError::ExceededMaxInstructions = err { /* CU error is difficult to properly compare as there may have been @@ -246,10 +255,17 @@ pub fn execute_vm_interp(syscall_context: SyscallContext) -> Option 0, StableResult::Err(ref ebpf_err) => err_map::get_fd_vm_err_code(ebpf_err).into(), }, - r0: match result { - StableResult::Ok(n) => n, - StableResult::Err(_) => 0, - }, + r0: out_registers[0], + r1: out_registers[1], + r2: out_registers[2], + r3: out_registers[3], + r4: out_registers[4], + r5: out_registers[5], + r6: out_registers[6], + r7: out_registers[7], + r8: out_registers[8], + r9: out_registers[9], + r10: out_registers[10], cu_avail: vm.context_object_pointer.get_remaining(), frame_count: vm.call_depth, heap: heap.as_slice().into(), @@ -264,7 +280,7 @@ pub fn execute_vm_interp(syscall_context: SyscallContext) -> Option vm.registers[11], }, - ..Default::default() // FIXME: implement rodata + ..Default::default() }) } diff --git a/src/vm_syscalls.rs b/src/vm_syscalls.rs index d929dd3..3ebbcfd 100644 --- a/src/vm_syscalls.rs +++ b/src/vm_syscalls.rs @@ -317,6 +317,17 @@ pub fn execute_vm_syscall(input: SyscallContext) -> Option { // Register 0 doesn't seem to contain the result, maybe we're missing some code from agave. // Regardless, the result is available in vm.program_result, so we can return it from there. r0, + // Registers are only for vm_interp + r1: 0, + r2: 0, + r3: 0, + r4: 0, + r5: 0, + r6: 0, + r7: 0, + r8: 0, + r9: 0, + r10: 0, cu_avail: vm.context_object_pointer.get_remaining(), heap: heap.as_slice().into(), stack: stack.as_slice().into(),