diff --git a/evm/src/cpu/kernel/asm/account_code.asm b/evm/src/cpu/kernel/asm/account_code.asm index d69adc25..ba19b606 100644 --- a/evm/src/cpu/kernel/asm/account_code.asm +++ b/evm/src/cpu/kernel/asm/account_code.asm @@ -131,6 +131,10 @@ global extcodecopy: %jump(load_code) extcodecopy_contd: + // stack: code_size, size, offset, dest_offset, retdest + DUP1 DUP4 + // stack: offset, code_size, code_size, size, offset, dest_offset, retdest + GT %jumpi(extcodecopy_large_offset) // stack: code_size, size, offset, dest_offset, retdest SWAP1 // stack: size, code_size, offset, dest_offset, retdest @@ -178,6 +182,12 @@ extcodecopy_end: %stack (i, size, code_size, offset, dest_offset, retdest) -> (retdest) JUMP +extcodecopy_large_offset: + // offset is larger than the code size. So we just have to write zeros. + // stack: code_size, size, offset, dest_offset, retdest + GET_CONTEXT + %stack (context, code_size, size, offset, dest_offset, retdest) -> (context, @SEGMENT_MAIN_MEMORY, dest_offset, 0, size, retdest) + %jump(memset) // Loads the code at `address` into memory, at the given context and segment, starting at offset 0. // Checks that the hash of the loaded code corresponds to the `codehash` in the state trie. diff --git a/evm/src/cpu/kernel/asm/memory/syscalls.asm b/evm/src/cpu/kernel/asm/memory/syscalls.asm index 3a233856..206f5735 100644 --- a/evm/src/cpu/kernel/asm/memory/syscalls.asm +++ b/evm/src/cpu/kernel/asm/memory/syscalls.asm @@ -121,7 +121,7 @@ sys_calldataload_after_mload_packing: PANIC // Macro for {CALLDATA,CODE,RETURNDATA}COPY (W_copy in Yellow Paper). -%macro wcopy(segment) +%macro wcopy(segment, context_metadata_size) // stack: kexit_info, dest_offset, offset, size PUSH @GAS_VERYLOW DUP5 @@ -136,25 +136,41 @@ sys_calldataload_after_mload_packing: DUP1 %ensure_reasonable_offset %update_mem_bytes + %mload_context_metadata($context_metadata_size) + // stack: total_size, kexit_info, dest_offset, offset, size + DUP4 + // stack: offset, total_size, kexit_info, dest_offset, offset, size + GT %jumpi(%%wcopy_large_offset) + GET_CONTEXT %stack (context, kexit_info, dest_offset, offset, size) -> (context, @SEGMENT_MAIN_MEMORY, dest_offset, context, $segment, offset, size, %%after, kexit_info) %jump(memcpy) + %%after: // stack: kexit_info EXIT_KERNEL + %%wcopy_empty: // stack: Gverylow, kexit_info, dest_offset, offset, size %charge_gas %stack (kexit_info, dest_offset, offset, size) -> (kexit_info) EXIT_KERNEL + +%%wcopy_large_offset: + // offset is larger than the size of the {CALLDATA,CODE,RETURNDATA}. So we just have to write zeros. + // stack: kexit_info, dest_offset, offset, size + GET_CONTEXT + %stack (context, kexit_info, dest_offset, offset, size) -> + (context, @SEGMENT_MAIN_MEMORY, dest_offset, 0, size, %%after, kexit_info) + %jump(memset) %endmacro global sys_calldatacopy: - %wcopy(@SEGMENT_CALLDATA) + %wcopy(@SEGMENT_CALLDATA, @CTX_METADATA_CALLDATA_SIZE) global sys_codecopy: - %wcopy(@SEGMENT_CODE) + %wcopy(@SEGMENT_CODE, @CTX_METADATA_CODE_SIZE) global sys_returndatacopy: - %wcopy(@SEGMENT_RETURNDATA) + %wcopy(@SEGMENT_RETURNDATA, @CTX_METADATA_RETURNDATA_SIZE)