11#include "fd_bpf_loader_serialization.h"
22#include "../fd_borrowed_account.h"
33#include "../fd_runtime.h"
4+ #include "../../vm/fd_vm_base.h"
45
56/* This file is responsible for serializing and deserializing
67 the input region of the BPF virtual machine. The input region contains
@@ -292,6 +293,10 @@ fd_bpf_loader_input_serialize_aligned( fd_exec_instr_ctx_t * ctx,
292293 FD_STORE ( ulong , serialized_params , 0UL );
293294 FD_STORE ( uchar , serialized_params , (uchar )dup_acc_idx [acc_idx ] );
294295 serialized_params += sizeof (ulong );
296+
297+ /* Clone the account metadata from the original account
298+ https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L552 */
299+ acc_region_metas [i ] = acc_region_metas [dup_acc_idx [acc_idx ]];
295300 } else {
296301 acc_idx_seen [acc_idx ] = 1 ;
297302 dup_acc_idx [acc_idx ] = i ;
@@ -332,22 +337,30 @@ fd_bpf_loader_input_serialize_aligned( fd_exec_instr_ctx_t * ctx,
332337 FD_STORE ( uint , serialized_params , padding_0 );
333338 serialized_params += sizeof (uint );
334339
340+ /* Compute current region vaddr base for VM address calculation */
341+ ulong curr_region_vaddr = * input_mem_regions_cnt == 0U ? 0UL :
342+ input_mem_regions [* input_mem_regions_cnt - 1U ].vaddr_offset +
343+ input_mem_regions [* input_mem_regions_cnt - 1U ].address_space_reserved ;
344+
335345 /* https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L532 */
336346 fd_pubkey_t key = * acc ;
347+ acc_region_metas [i ].vm_key_addr = FD_VM_MEM_MAP_INPUT_REGION_START + curr_region_vaddr +
348+ (ulong )(serialized_params - curr_serialized_params_start );
337349 FD_STORE ( fd_pubkey_t , serialized_params , key );
338- acc_region_metas [i ].expected_pubkey_offset = (uint )(serialized_params - curr_serialized_params_start );
339350 serialized_params += sizeof (fd_pubkey_t );
340351
341352 /* https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L533 */
342353 fd_pubkey_t owner = * (fd_pubkey_t * )& metadata -> owner ;
354+ acc_region_metas [i ].vm_owner_addr = FD_VM_MEM_MAP_INPUT_REGION_START + curr_region_vaddr +
355+ (ulong )(serialized_params - curr_serialized_params_start );
343356 FD_STORE ( fd_pubkey_t , serialized_params , owner );
344- acc_region_metas [i ].expected_owner_offset = (uint )(serialized_params - curr_serialized_params_start );
345357 serialized_params += sizeof (fd_pubkey_t );
346358
347359 /* https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L534 */
348360 ulong lamports = metadata -> lamports ;
361+ acc_region_metas [i ].vm_lamports_addr = FD_VM_MEM_MAP_INPUT_REGION_START + curr_region_vaddr +
362+ (ulong )(serialized_params - curr_serialized_params_start );
349363 FD_STORE ( ulong , serialized_params , lamports );
350- acc_region_metas [i ].expected_lamports_offset = (uint )(serialized_params - curr_serialized_params_start );
351364 serialized_params += sizeof (ulong );
352365
353366 ulong acc_data_len = metadata -> dlen ;
@@ -358,6 +371,10 @@ fd_bpf_loader_input_serialize_aligned( fd_exec_instr_ctx_t * ctx,
358371 FD_STORE ( ulong , serialized_params , data_len );
359372 serialized_params += sizeof (ulong );
360373
374+ /* vm_data_addr: data is written immediately after the data_len field */
375+ acc_region_metas [i ].vm_data_addr = FD_VM_MEM_MAP_INPUT_REGION_START + curr_region_vaddr +
376+ (ulong )(serialized_params - curr_serialized_params_start );
377+
361378 /* https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L536 */
362379 write_account (
363380 & view_acc ,
@@ -389,7 +406,7 @@ fd_bpf_loader_input_serialize_aligned( fd_exec_instr_ctx_t * ctx,
389406 region_vaddr_offset = input_mem_regions [* input_mem_regions_cnt - 1U ].vaddr_offset +
390407 input_mem_regions [* input_mem_regions_cnt - 1U ].address_space_reserved ;
391408 }
392- * instr_data_offset = region_vaddr_offset + (ulong )(serialized_params - curr_serialized_params_start );
409+ * instr_data_offset = FD_VM_MEM_MAP_INPUT_REGION_START + region_vaddr_offset + (ulong )(serialized_params - curr_serialized_params_start );
393410
394411 /* https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L559 */
395412 uchar * instr_data = ctx -> instr -> data ;
@@ -570,6 +587,10 @@ fd_bpf_loader_input_serialize_unaligned( fd_exec_instr_ctx_t * ctx,
570587 // Duplicate
571588 FD_STORE ( uchar , serialized_params , (uchar )dup_acc_idx [acc_idx ] );
572589 serialized_params += sizeof (uchar );
590+
591+ /* Clone the account metadata from the original account
592+ https://github.com/anza-xyz/agave/blob/v3.0.0/program-runtime/src/serialization.rs#L376 */
593+ acc_region_metas [i ] = acc_region_metas [dup_acc_idx [acc_idx ]];
573594 } else {
574595 acc_idx_seen [acc_idx ] = 1 ;
575596 dup_acc_idx [acc_idx ] = i ;
@@ -597,28 +618,45 @@ fd_bpf_loader_input_serialize_unaligned( fd_exec_instr_ctx_t * ctx,
597618 FD_STORE ( uchar , serialized_params , is_writable );
598619 serialized_params += sizeof (uchar );
599620
621+ /* Compute current region vaddr base for VM address calculation */
622+ ulong curr_region_vaddr = * input_mem_regions_cnt == 0U ? 0UL :
623+ input_mem_regions [* input_mem_regions_cnt - 1U ].vaddr_offset +
624+ input_mem_regions [* input_mem_regions_cnt - 1U ].address_space_reserved ;
625+
600626 fd_pubkey_t key = * acc ;
627+ acc_region_metas [i ].vm_key_addr = FD_VM_MEM_MAP_INPUT_REGION_START + curr_region_vaddr +
628+ (ulong )(serialized_params - curr_serialized_params_start );
601629 FD_STORE ( fd_pubkey_t , serialized_params , key );
602- acc_region_metas [i ].expected_pubkey_offset = (uint )(serialized_params - curr_serialized_params_start );
603630 serialized_params += sizeof (fd_pubkey_t );
604631
605632 ulong lamports = metadata -> lamports ;
633+ acc_region_metas [i ].vm_lamports_addr = FD_VM_MEM_MAP_INPUT_REGION_START + curr_region_vaddr +
634+ (ulong )(serialized_params - curr_serialized_params_start );
606635 FD_STORE ( ulong , serialized_params , lamports );
607- acc_region_metas [i ].expected_lamports_offset = (uint )(serialized_params - curr_serialized_params_start );
608636 serialized_params += sizeof (ulong );
609637
610638 ulong acc_data_len = metadata -> dlen ;
611639 FD_STORE ( ulong , serialized_params , acc_data_len );
612640 serialized_params += sizeof (ulong );
613641
614- ulong next_region_offset = write_account ( & view_acc , (uchar )i ,
642+ /* vm_data_addr: data is written immediately after the data_len field */
643+ acc_region_metas [i ].vm_data_addr = FD_VM_MEM_MAP_INPUT_REGION_START + curr_region_vaddr +
644+ (ulong )(serialized_params - curr_serialized_params_start );
645+
646+ write_account ( & view_acc , (uchar )i ,
615647 & serialized_params , & curr_serialized_params_start ,
616648 input_mem_regions , input_mem_regions_cnt , acc_region_metas , 1 ,
617649 stricter_abi_and_runtime_constraints , direct_mapping );
618650
651+ /* After write_account, we may be in a new region, so recompute */
652+ ulong owner_region_vaddr = * input_mem_regions_cnt == 0U ? 0UL :
653+ input_mem_regions [* input_mem_regions_cnt - 1U ].vaddr_offset +
654+ input_mem_regions [* input_mem_regions_cnt - 1U ].address_space_reserved ;
655+
619656 fd_pubkey_t owner = * (fd_pubkey_t * )& metadata -> owner ;
657+ acc_region_metas [i ].vm_owner_addr = FD_VM_MEM_MAP_INPUT_REGION_START + owner_region_vaddr +
658+ (ulong )(serialized_params - curr_serialized_params_start );
620659 FD_STORE ( fd_pubkey_t , serialized_params , owner );
621- acc_region_metas [i ].expected_owner_offset = (uint )next_region_offset ;
622660 serialized_params += sizeof (fd_pubkey_t );
623661
624662 uchar is_executable = (uchar )metadata -> executable ;
@@ -640,7 +678,7 @@ fd_bpf_loader_input_serialize_unaligned( fd_exec_instr_ctx_t * ctx,
640678 region_vaddr_offset = input_mem_regions [* input_mem_regions_cnt - 1U ].vaddr_offset +
641679 input_mem_regions [* input_mem_regions_cnt - 1U ].address_space_reserved ;
642680 }
643- * instr_data_offset = region_vaddr_offset + (ulong )(serialized_params - curr_serialized_params_start );
681+ * instr_data_offset = FD_VM_MEM_MAP_INPUT_REGION_START + region_vaddr_offset + (ulong )(serialized_params - curr_serialized_params_start );
644682
645683 uchar * instr_data = (uchar * )ctx -> instr -> data ;
646684 fd_memcpy ( serialized_params , instr_data , instr_data_len );
0 commit comments