@@ -378,10 +378,10 @@ impl<'a, 'b, S: Syscall> Executor<'a, 'b, S> {
378378 fn ecall_software ( & mut self ) -> Result < bool > {
379379 tracing:: debug!( "[{}] ecall_software" , self . insn_cycles) ;
380380 let into_guest_ptr = ByteAddr ( self . load_register ( REG_A0 ) ?) ;
381- if !is_guest_memory ( into_guest_ptr. 0 ) && !into_guest_ptr. is_null ( ) {
381+ let into_guest_len = self . load_register ( REG_A1 ) ? as usize ;
382+ if into_guest_len > 0 && !is_guest_memory ( into_guest_ptr. 0 ) {
382383 bail ! ( "{into_guest_ptr:?} is an invalid guest address" ) ;
383384 }
384- let into_guest_len = self . load_register ( REG_A1 ) ? as usize ;
385385 let name_ptr = self . load_guest_addr_from_register ( REG_A2 ) ?;
386386 let syscall_name = self . peek_string ( name_ptr) ?;
387387 let name_end = name_ptr + syscall_name. len ( ) ;
@@ -410,7 +410,7 @@ impl<'a, 'b, S: Syscall> Executor<'a, 'b, S> {
410410
411411 // The guest uses a null pointer to indicate that a transfer from host
412412 // to guest is not needed.
413- if !into_guest_ptr. is_null ( ) {
413+ if into_guest_len > 0 && !into_guest_ptr. is_null ( ) {
414414 Self :: check_guest_addr ( into_guest_ptr + into_guest_len) ?;
415415 self . store_region ( into_guest_ptr, bytemuck:: cast_slice ( & syscall. to_guest ) ) ?
416416 }
@@ -431,8 +431,6 @@ impl<'a, 'b, S: Syscall> Executor<'a, 'b, S> {
431431 tracing:: debug!( "[{}] ecall_sha" , self . insn_cycles) ;
432432 let state_out_ptr = self . load_guest_addr_from_register ( REG_A0 ) ?;
433433 let state_in_ptr = self . load_guest_addr_from_register ( REG_A1 ) ?;
434- let mut block1_ptr = self . load_guest_addr_from_register ( REG_A2 ) ?;
435- let mut block2_ptr = self . load_guest_addr_from_register ( REG_A3 ) ?;
436434 let count = self . load_register ( REG_A4 ) ?;
437435
438436 let state_in: [ u8 ; DIGEST_BYTES ] = self . load_array_from_guest ( state_in_ptr) ?;
@@ -441,25 +439,30 @@ impl<'a, 'b, S: Syscall> Executor<'a, 'b, S> {
441439 * word = word. to_be ( ) ;
442440 }
443441
444- // tracing::debug!("ecall_sha: start state: {state:08x?}");
445- let mut block = [ 0u32 ; BLOCK_WORDS ] ;
442+ if count > 0 {
443+ let mut block1_ptr = self . load_guest_addr_from_register ( REG_A2 ) ?;
444+ let mut block2_ptr = self . load_guest_addr_from_register ( REG_A3 ) ?;
446445
447- for _ in 0 ..count {
448- let ( digest1, digest2) = block. split_at_mut ( DIGEST_WORDS ) ;
449- for ( i, word) in digest1. iter_mut ( ) . enumerate ( ) {
450- * word = self . load_u32_from_guest ( block1_ptr + ( i * WORD_SIZE ) ) ?;
451- }
452- for ( i, word) in digest2. iter_mut ( ) . enumerate ( ) {
453- * word = self . load_u32_from_guest ( block2_ptr + ( i * WORD_SIZE ) ) ?;
446+ // tracing::debug!("ecall_sha: start state: {state:08x?}");
447+ let mut block = [ 0u32 ; BLOCK_WORDS ] ;
448+
449+ for _ in 0 ..count {
450+ let ( digest1, digest2) = block. split_at_mut ( DIGEST_WORDS ) ;
451+ for ( i, word) in digest1. iter_mut ( ) . enumerate ( ) {
452+ * word = self . load_u32_from_guest ( block1_ptr + ( i * WORD_SIZE ) ) ?;
453+ }
454+ for ( i, word) in digest2. iter_mut ( ) . enumerate ( ) {
455+ * word = self . load_u32_from_guest ( block2_ptr + ( i * WORD_SIZE ) ) ?;
456+ }
457+ // tracing::debug!("Compressing block {block:02x?}");
458+ sha2:: compress256 (
459+ & mut state,
460+ & [ * GenericArray :: from_slice ( bytemuck:: cast_slice ( & block) ) ] ,
461+ ) ;
462+
463+ block1_ptr += BLOCK_BYTES ;
464+ block2_ptr += BLOCK_BYTES ;
454465 }
455- // tracing::debug!("Compressing block {block:02x?}");
456- sha2:: compress256 (
457- & mut state,
458- & [ * GenericArray :: from_slice ( bytemuck:: cast_slice ( & block) ) ] ,
459- ) ;
460-
461- block1_ptr += BLOCK_BYTES ;
462- block2_ptr += BLOCK_BYTES ;
463466 }
464467
465468 // tracing::debug!("ecall_sha: final state: {state:08x?}");
0 commit comments