Fix copy opcodes when offset is large (#957)

* Fix wcopy

* Fix extcodecopy and use memset

* Comments
This commit is contained in:
wborgeaud 2023-04-05 06:24:26 +02:00 committed by GitHub
parent d59fa59af8
commit 923722b1e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 4 deletions

View File

@ -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.

View File

@ -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)