LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_vm_harness.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 351 0.0 %
Date: 2026-05-31 08:07:40 Functions: 0 4 0.0 %

          Line data    Source code
       1             : #include "fd_instr_harness.h"
       2             : #include "../fd_executor.h"
       3             : #include "../fd_runtime.h"
       4             : #include "../fd_system_ids.h"
       5             : #include "../../log_collector/fd_log_collector.h"
       6             : #include "../program/fd_bpf_loader_serialization.h"
       7             : #include "../../../ballet/sbpf/fd_sbpf_loader.h"
       8             : #include "../../vm/fd_vm.h"
       9             : #include "../../vm/test_vm_util.h"
      10             : #include "generated/vm.pb.h"
      11             : #include "generated/vm_serialization.pb.h"
      12             : #include "../fd_bank.h"
      13             : 
      14             : static fd_sbpf_syscalls_t *
      15             : fd_solfuzz_vm_syscall_lookup_func( fd_sbpf_syscalls_t * syscalls,
      16             :                                    const char *         syscall_name,
      17           0 :                                    size_t               len) {
      18           0 :   ulong i;
      19             : 
      20           0 :   if (!syscall_name) return NULL;
      21             : 
      22           0 :   for (i = 0; i < fd_sbpf_syscalls_slot_cnt(); ++i) {
      23           0 :     if (!fd_sbpf_syscalls_key_inval(syscalls[i].key) && syscalls[i].name && strlen(syscalls[i].name) == len) {
      24           0 :       if (!memcmp(syscalls[i].name, syscall_name, len)) {
      25           0 :         return syscalls + i;
      26           0 :       }
      27           0 :     }
      28           0 :   }
      29             : 
      30           0 :   return NULL;
      31           0 : }
      32             : 
      33             : static ulong
      34             : fd_solfuzz_vm_load_from_input_regions( fd_vm_input_region_t const *        input,
      35             :                                        uint                                input_count,
      36             :                                        fd_exec_test_input_data_region_t ** output,
      37             :                                        pb_size_t *                         output_count,
      38             :                                        void *                              output_buf,
      39           0 :                                        ulong                               output_bufsz ) {
      40             :   /* pre-flight checks on output buffer size*/
      41           0 :   ulong input_regions_total_sz = 0;
      42           0 :   for( ulong i=0; i<input_count; i++ ) {
      43           0 :     input_regions_total_sz += input[i].region_sz;
      44           0 :   }
      45             : 
      46           0 :   if( FD_UNLIKELY(   input_regions_total_sz == 0
      47           0 :                   || output_bufsz < input_regions_total_sz ) ) {
      48           0 :     *output = NULL;
      49           0 :     *output_count = 0;
      50           0 :     return 0;
      51           0 :   }
      52             : 
      53           0 :   FD_SCRATCH_ALLOC_INIT( l, output_buf );
      54           0 :   *output = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_input_data_region_t),
      55           0 :                                       input_count * sizeof (fd_exec_test_input_data_region_t) );
      56           0 :   FD_TEST( *output );
      57           0 :   *output_count = input_count;
      58             : 
      59           0 :   for( ulong i=0; i<input_count; i++ ) {
      60           0 :     fd_vm_input_region_t const * vm_region = &input[i];
      61           0 :     fd_exec_test_input_data_region_t * out_region = &(*output)[i];
      62           0 :     out_region->is_writable = vm_region->is_writable;
      63           0 :     out_region->offset = vm_region->vaddr_offset;
      64             : 
      65           0 :     if( vm_region->region_sz > 0 ) {
      66           0 :       out_region->content = FD_SCRATCH_ALLOC_APPEND( l, alignof(pb_bytes_array_t),
      67           0 :                                                  PB_BYTES_ARRAY_T_ALLOCSIZE(vm_region->region_sz) );
      68           0 :       FD_TEST( out_region->content );
      69           0 :       out_region->content->size = vm_region->region_sz;
      70           0 :       fd_memcpy( out_region->content->bytes, (void *)vm_region->haddr, vm_region->region_sz );
      71           0 :     } else {
      72           0 :       out_region->content = NULL;
      73           0 :     }
      74           0 :   }
      75             : 
      76           0 :   ulong end = FD_SCRATCH_ALLOC_FINI( l, 1UL );
      77           0 :   return end - (ulong)output_buf; /* return the number of bytes written */
      78           0 : }
      79             : 
      80             : 
      81             : ulong
      82             : fd_solfuzz_pb_syscall_run( fd_solfuzz_runner_t * runner,
      83             :                            void const *          input_,
      84             :                            void **               output_,
      85             :                            void *                output_buf,
      86           0 :                            ulong                 output_bufsz ) {
      87           0 :   fd_exec_test_syscall_context_t const * input =  fd_type_pun_const( input_ );
      88           0 :   fd_exec_test_syscall_effects_t **      output = fd_type_pun( output_ );
      89             : 
      90             :   /* Create execution context */
      91           0 :   const fd_exec_test_instr_context_t * input_instr_ctx = &input->instr_ctx;
      92           0 :   fd_exec_instr_ctx_t ctx[1];
      93           0 :   fd_solfuzz_pb_instr_ctx_create( runner, ctx, input_instr_ctx );
      94             : 
      95           0 :   ctx->txn_out->err.exec_err = 0;
      96           0 :   ctx->txn_out->err.exec_err_kind = FD_EXECUTOR_ERR_KIND_NONE;
      97           0 :   ctx->bank = runner->bank;
      98             : 
      99             :   /* Capture outputs */
     100           0 :   ulong output_end = (ulong)output_buf + output_bufsz;
     101           0 :   FD_SCRATCH_ALLOC_INIT( l, output_buf );
     102           0 :   fd_exec_test_syscall_effects_t * effects =
     103           0 :     FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_syscall_effects_t),
     104           0 :                                 sizeof (fd_exec_test_syscall_effects_t) );
     105           0 :   if( FD_UNLIKELY( _l > output_end ) ) {
     106           0 :     goto error;
     107           0 :   }
     108             : 
     109           0 :   if( input->vm_ctx.return_data.program_id && input->vm_ctx.return_data.program_id->size == sizeof(fd_pubkey_t) ) {
     110           0 :     fd_memcpy( ctx->txn_out->details.return_data.program_id.uc, input->vm_ctx.return_data.program_id->bytes, sizeof(fd_pubkey_t) );
     111           0 :   }
     112             : 
     113           0 :   if( input->vm_ctx.return_data.data && input->vm_ctx.return_data.data->size>0U ) {
     114           0 :     ctx->txn_out->details.return_data.len = input->vm_ctx.return_data.data->size;
     115           0 :     fd_memcpy( ctx->txn_out->details.return_data.data, input->vm_ctx.return_data.data->bytes, ctx->txn_out->details.return_data.len );
     116           0 :   }
     117             : 
     118           0 :   *effects = (fd_exec_test_syscall_effects_t) FD_EXEC_TEST_SYSCALL_EFFECTS_INIT_ZERO;
     119             : 
     120             :   /* Set up the VM instance */
     121           0 :   fd_spad_t * spad = runner->spad;
     122           0 :   fd_sha256_t _sha[1];
     123           0 :   fd_sha256_t * sha = fd_sha256_join( fd_sha256_new( _sha ) );
     124           0 :   fd_sbpf_syscalls_t * syscalls = fd_sbpf_syscalls_new( fd_spad_alloc_check( spad, fd_sbpf_syscalls_align(), fd_sbpf_syscalls_footprint() ) );
     125           0 :   fd_vm_syscall_register_all( syscalls, 0 );
     126             : 
     127             :   /* Pull out the memory regions */
     128           0 :   if( !input->has_vm_ctx ) {
     129           0 :     goto error;
     130           0 :   }
     131             : 
     132           0 :   ulong rodata_sz = input->vm_ctx.rodata ? input->vm_ctx.rodata->size : 0UL;
     133           0 :   uchar * rodata = fd_spad_alloc_check( spad, 8UL, rodata_sz );
     134           0 :   if ( input->vm_ctx.rodata != NULL ) {
     135           0 :     fd_memcpy( rodata, input->vm_ctx.rodata->bytes, rodata_sz );
     136           0 :   }
     137             : 
     138           0 :   if( input->vm_ctx.heap_max > FD_VM_HEAP_MAX ) {
     139           0 :     goto error;
     140           0 :   }
     141             : 
     142           0 :   fd_vm_t * vm = fd_vm_join( fd_vm_new( fd_spad_alloc_check( spad, fd_vm_align(), fd_vm_footprint() ) ) );
     143           0 :   if ( !vm ) {
     144           0 :     goto error;
     145           0 :   }
     146             : 
     147             :   /* If the program ID account owner is the v1 BPF loader, then alignment is disabled (controlled by
     148             :      the `is_deprecated` flag) */
     149             : 
     150           0 :   ulong                   input_sz                                 = 0UL;
     151           0 :   ulong                   pre_lens[256]                            = {0};
     152           0 :   fd_vm_input_region_t    input_mem_regions[1000]                  = {0}; /* We can have a max of (3 * num accounts + 1) regions */
     153           0 :   fd_vm_acc_region_meta_t acc_region_metas[256]                    = {0}; /* instr acc idx to idx */
     154           0 :   uint                    input_mem_regions_cnt                    = 0U;
     155           0 :   int                     direct_mapping                           = FD_FEATURE_ACTIVE_BANK( ctx->bank, account_data_direct_mapping );
     156           0 :   int                     syscall_parameter_address_restrictions   = FD_FEATURE_ACTIVE_BANK( ctx->bank, syscall_parameter_address_restrictions );
     157           0 :   int                     virtual_address_space_adjustments        = FD_FEATURE_ACTIVE_BANK( ctx->bank, virtual_address_space_adjustments );
     158           0 :   int                     direct_account_pointers_in_program_input = FD_FEATURE_ACTIVE_BANK( ctx->bank, direct_account_pointers_in_program_input );
     159             : 
     160           0 :   uchar               program_id_idx = ctx->instr->program_id;
     161           0 :   fd_account_meta_t * program_acc    = ctx->txn_out->accounts.account[program_id_idx].meta;
     162           0 :   uchar               is_deprecated  = ( program_id_idx < ctx->txn_out->accounts.cnt ) &&
     163           0 :                                       ( !memcmp( program_acc->owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) );
     164             : 
     165             :   /* Push the instruction onto the stack. This may also modify the sysvar instructions account, if its present. */
     166           0 :   int stack_push_err = fd_instr_stack_push( ctx->runtime, ctx->txn_in, ctx->txn_out, (fd_instr_info_t *)ctx->instr );
     167           0 :   if( FD_UNLIKELY( stack_push_err ) ) {
     168           0 :       FD_LOG_WARNING(( "instr stack push err" ));
     169           0 :       goto error;
     170           0 :   }
     171             : 
     172           0 :   ulong instr_data_offset = 0UL;
     173           0 :   int err = fd_bpf_loader_input_serialize_parameters( ctx,
     174           0 :                                                       pre_lens,
     175           0 :                                                       input_mem_regions,
     176           0 :                                                       &input_mem_regions_cnt,
     177           0 :                                                       acc_region_metas,
     178           0 :                                                       virtual_address_space_adjustments,
     179           0 :                                                       direct_mapping,
     180           0 :                                                       direct_account_pointers_in_program_input,
     181           0 :                                                       is_deprecated,
     182           0 :                                                       &instr_data_offset,
     183           0 :                                                       &input_sz );
     184           0 :   if( FD_UNLIKELY( err ) ) {
     185           0 :     FD_LOG_WARNING(( "bpf loader input serialize parameters err" ));
     186           0 :     goto error;
     187           0 :   }
     188             : 
     189           0 :   fd_vm_init( vm,
     190           0 :               ctx,
     191           0 :               input->vm_ctx.heap_max,
     192           0 :               ctx->txn_out->details.compute_budget.compute_meter,
     193           0 :               rodata,
     194           0 :               rodata_sz,
     195           0 :               NULL, // TODO
     196           0 :               0, // TODO
     197           0 :               0, // TODO
     198           0 :               0, // TODO, text_sz
     199           0 :               0, // TODO
     200           0 :               NULL, // TODO
     201           0 :               TEST_VM_DEFAULT_SBPF_VERSION,
     202           0 :               syscalls,
     203           0 :               NULL, // TODO
     204           0 :               sha,
     205           0 :               input_mem_regions,
     206           0 :               input_mem_regions_cnt,
     207           0 :               acc_region_metas,
     208           0 :               is_deprecated,
     209           0 :               direct_mapping,
     210           0 :               syscall_parameter_address_restrictions,
     211           0 :               virtual_address_space_adjustments,
     212           0 :               0 /* dump_syscall_to_pb */,
     213           0 :               0UL /* r2 is set by the fuzzer below */ );
     214             : 
     215             :   // Override some execution state values from the syscall fuzzer input
     216             :   // This is so we can test if the syscall mutates any of these erroneously
     217           0 :   vm->reg[0] = input->vm_ctx.r0;
     218           0 :   vm->reg[1] = input->vm_ctx.r1;
     219           0 :   vm->reg[2] = input->vm_ctx.r2;
     220           0 :   vm->reg[3] = input->vm_ctx.r3;
     221           0 :   vm->reg[4] = input->vm_ctx.r4;
     222           0 :   vm->reg[5] = input->vm_ctx.r5;
     223           0 :   vm->reg[6] = input->vm_ctx.r6;
     224           0 :   vm->reg[7] = input->vm_ctx.r7;
     225           0 :   vm->reg[8] = input->vm_ctx.r8;
     226           0 :   vm->reg[9] = input->vm_ctx.r9;
     227           0 :   vm->reg[10] = input->vm_ctx.r10;
     228           0 :   vm->reg[11] = input->vm_ctx.r11;
     229             : 
     230             :   // Override initial part of the heap, if specified the syscall fuzzer input
     231           0 :   if( input->syscall_invocation.heap_prefix ) {
     232           0 :     fd_memcpy( vm->heap, input->syscall_invocation.heap_prefix->bytes,
     233           0 :                fd_ulong_min(input->syscall_invocation.heap_prefix->size, vm->heap_max) );
     234           0 :   }
     235             : 
     236             :   // Override initial part of the stack, if specified the syscall fuzzer input
     237           0 :   if( input->syscall_invocation.stack_prefix ) {
     238           0 :     fd_memcpy( vm->stack, input->syscall_invocation.stack_prefix->bytes,
     239           0 :                fd_ulong_min(input->syscall_invocation.stack_prefix->size, FD_VM_STACK_MAX) );
     240           0 :   }
     241             : 
     242             :   // Look up the syscall to execute
     243           0 :   char * syscall_name = (char *)input->syscall_invocation.function_name.bytes;
     244           0 :   fd_sbpf_syscalls_t const * syscall = fd_solfuzz_vm_syscall_lookup_func(syscalls, syscall_name, input->syscall_invocation.function_name.size);
     245           0 :   if( !syscall ) {
     246           0 :     goto error;
     247           0 :   }
     248             : 
     249             :   /* There's an instr ctx struct embedded in the txn ctx instr stack. */
     250           0 :   fd_exec_instr_ctx_t * instr_ctx = &ctx->runtime->instr.stack[ ctx->runtime->instr.stack_sz - 1 ];
     251           0 :   *instr_ctx = (fd_exec_instr_ctx_t) {
     252           0 :     .instr   = ctx->instr,
     253           0 :     .txn_out = ctx->txn_out,
     254           0 :     .runtime = ctx->runtime,
     255           0 :   };
     256             : 
     257             :   /* Actually invoke the syscall */
     258           0 :   int syscall_err = syscall->func( vm, vm->reg[1], vm->reg[2], vm->reg[3], vm->reg[4], vm->reg[5], &vm->reg[0] );
     259           0 :   int instr_end_err = fd_execute_instr_end( vm->instr_ctx, ctx->instr, syscall_err );
     260           0 :   if( instr_end_err ) {
     261           0 :     fd_log_collector_program_failure( vm->instr_ctx );
     262           0 :   }
     263             : 
     264             :   /* Capture the effects */
     265           0 :   int exec_err = vm->instr_ctx->txn_out->err.exec_err;
     266           0 :   effects->error = 0;
     267           0 :   if( instr_end_err ) {
     268           0 :     if( exec_err==0 ) {
     269           0 :       FD_LOG_WARNING(( "TODO: syscall returns error, but exec_err not set. this is probably missing a log." ));
     270           0 :       effects->error = -1;
     271           0 :     } else {
     272           0 :       effects->error = (exec_err <= 0) ? -exec_err : -1;
     273             : 
     274             :       /* Map error kind, equivalent to:
     275             :           effects->error_kind = (fd_exec_test_err_kind_t)(vm->instr_ctx->txn_ctx->err.exec_err_kind); */
     276           0 :       switch (vm->instr_ctx->txn_out->err.exec_err_kind) {
     277           0 :         case FD_EXECUTOR_ERR_KIND_EBPF:
     278           0 :           effects->error_kind = FD_EXEC_TEST_ERR_KIND_EBPF;
     279           0 :           break;
     280           0 :         case FD_EXECUTOR_ERR_KIND_SYSCALL:
     281           0 :           effects->error_kind = FD_EXEC_TEST_ERR_KIND_SYSCALL;
     282           0 :           break;
     283           0 :         case FD_EXECUTOR_ERR_KIND_INSTR:
     284           0 :           effects->error_kind = FD_EXEC_TEST_ERR_KIND_INSTRUCTION;
     285           0 :           break;
     286           0 :         default:
     287           0 :           effects->error_kind = FD_EXEC_TEST_ERR_KIND_UNSPECIFIED;
     288           0 :           break;
     289           0 :       }
     290           0 :     }
     291           0 :   }
     292           0 :   effects->r0 = instr_end_err ? 0 : vm->reg[0]; // Save only on success
     293           0 :   effects->cu_avail = (ulong)vm->cu;
     294             : 
     295           0 :   if( vm->heap_max ) {
     296           0 :     effects->heap = FD_SCRATCH_ALLOC_APPEND(
     297           0 :       l, alignof(uint), PB_BYTES_ARRAY_T_ALLOCSIZE( vm->heap_max ) );
     298           0 :     if( FD_UNLIKELY( _l > output_end ) ) {
     299           0 :       goto error;
     300           0 :     }
     301           0 :     effects->heap->size = (uint)vm->heap_max;
     302           0 :     fd_memcpy( effects->heap->bytes, vm->heap, vm->heap_max );
     303           0 :   } else {
     304           0 :     effects->heap = NULL;
     305           0 :   }
     306             : 
     307           0 :   effects->stack = FD_SCRATCH_ALLOC_APPEND(
     308           0 :     l, alignof(pb_bytes_array_t), PB_BYTES_ARRAY_T_ALLOCSIZE( FD_VM_STACK_MAX ) );
     309           0 :     if( FD_UNLIKELY( _l > output_end ) ) {
     310           0 :       goto error;
     311           0 :     }
     312           0 :   effects->stack->size = (uint)FD_VM_STACK_MAX;
     313           0 :   fd_memcpy( effects->stack->bytes, vm->stack, FD_VM_STACK_MAX );
     314             : 
     315           0 :   if( vm->rodata_sz ) {
     316           0 :     effects->rodata = FD_SCRATCH_ALLOC_APPEND(
     317           0 :       l, alignof(pb_bytes_array_t), PB_BYTES_ARRAY_T_ALLOCSIZE( rodata_sz ) );
     318           0 :     if( FD_UNLIKELY( _l > output_end ) ) {
     319           0 :       goto error;
     320           0 :     }
     321           0 :     effects->rodata->size = (uint)rodata_sz;
     322           0 :     fd_memcpy( effects->rodata->bytes, vm->rodata, rodata_sz );
     323           0 :   } else {
     324           0 :     effects->rodata = NULL;
     325           0 :   }
     326             : 
     327           0 :   effects->frame_count = vm->frame_cnt;
     328             : 
     329             :   /* Capture input regions */
     330           0 :   ulong tmp_end = FD_SCRATCH_ALLOC_FINI( l, 1UL );
     331             : 
     332             :   /* Don't compare input data regions if execution failed and
     333             :      virtual_address_space_adjustments is enabled, because
     334             :      Agave leaks data into the input regions under these circumstances. */
     335           0 :   ulong input_regions_size = 0UL;
     336           0 :   if( syscall_err && virtual_address_space_adjustments ) {
     337           0 :     effects->input_data_regions       = NULL;
     338           0 :     effects->input_data_regions_count = 0UL;
     339           0 :   } else {
     340           0 :     input_regions_size = fd_solfuzz_vm_load_from_input_regions(
     341           0 :       vm->input_mem_regions,
     342           0 :       vm->input_mem_regions_cnt,
     343           0 :       &effects->input_data_regions,
     344           0 :       &effects->input_data_regions_count,
     345           0 :       (void *)tmp_end,
     346           0 :       fd_ulong_sat_sub( output_end, tmp_end )
     347           0 :     );
     348             : 
     349           0 :     if( !!vm->input_mem_regions_cnt && !effects->input_data_regions ) {
     350           0 :       goto error;
     351           0 :     }
     352           0 :   }
     353             : 
     354             :   /* Return the effects */
     355           0 :   ulong actual_end = tmp_end + input_regions_size;
     356           0 :   fd_solfuzz_pb_instr_ctx_destroy( runner, ctx );
     357             : 
     358           0 :   *output = effects;
     359           0 :   return actual_end - (ulong)output_buf;
     360             : 
     361           0 : error:
     362           0 :   fd_solfuzz_pb_instr_ctx_destroy( runner, ctx );
     363           0 :   return 0;
     364           0 : }
     365             : 
     366             : ulong
     367             : fd_solfuzz_pb_vm_serialize_run( fd_solfuzz_runner_t * runner,
     368             :                                 void const *          input_,
     369             :                                 void **               output_,
     370             :                                 void *                output_buf,
     371           0 :                                 ulong                 output_bufsz ) {
     372           0 :   fd_exec_test_instr_context_t const * input  = fd_type_pun_const( input_ );
     373           0 :   fd_exec_test_vm_serialization_effects_t ** output = fd_type_pun( output_ );
     374             : 
     375             :   /* Create execution context */
     376           0 :   fd_exec_instr_ctx_t ctx[1];
     377           0 :   fd_solfuzz_pb_instr_ctx_create( runner, ctx, input );
     378             : 
     379           0 :   ctx->txn_out->err.exec_err      = 0;
     380           0 :   ctx->txn_out->err.exec_err_kind = FD_EXECUTOR_ERR_KIND_NONE;
     381           0 :   ctx->bank                       = runner->bank;
     382             : 
     383             :   /* Capture outputs */
     384           0 :   ulong output_end = (ulong)output_buf + output_bufsz;
     385           0 :   FD_SCRATCH_ALLOC_INIT( l, output_buf );
     386           0 :   fd_exec_test_vm_serialization_effects_t * effects =
     387           0 :     FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_vm_serialization_effects_t),
     388           0 :                                 sizeof (fd_exec_test_vm_serialization_effects_t) );
     389           0 :   FD_TEST( _l <= output_end );
     390           0 :   *effects = (fd_exec_test_vm_serialization_effects_t) FD_EXEC_TEST_VM_SERIALIZATION_EFFECTS_INIT_ZERO;
     391             : 
     392             :   /* Determine feature flags and is_deprecated */
     393           0 :   int direct_mapping                           = FD_FEATURE_ACTIVE_BANK( ctx->bank, account_data_direct_mapping );
     394           0 :   int virtual_address_space_adjustments        = FD_FEATURE_ACTIVE_BANK( ctx->bank, virtual_address_space_adjustments );
     395           0 :   int direct_account_pointers_in_program_input = FD_FEATURE_ACTIVE_BANK( ctx->bank, direct_account_pointers_in_program_input );
     396             : 
     397           0 :   uchar               program_id_idx = ctx->instr->program_id;
     398           0 :   fd_account_meta_t * program_acc    = ctx->txn_out->accounts.account[program_id_idx].meta;
     399           0 :   uchar               is_deprecated  = ( program_id_idx < ctx->txn_out->accounts.cnt ) &&
     400           0 :                                        ( !memcmp( program_acc->owner, fd_solana_bpf_loader_deprecated_program_id.key, sizeof(fd_pubkey_t) ) );
     401             : 
     402             :   /* Push the instruction onto the stack */
     403           0 :   FD_TEST( !fd_instr_stack_push( ctx->runtime, ctx->txn_in, ctx->txn_out, (fd_instr_info_t *)ctx->instr ) );
     404             : 
     405             :   /* Call serialize_parameters */
     406           0 :   ulong                   input_sz                = 0UL;
     407           0 :   ulong                   pre_lens[256]           = {0};
     408           0 :   fd_vm_input_region_t    input_mem_regions[1000] = {0};
     409           0 :   fd_vm_acc_region_meta_t acc_region_metas[256]   = {0};
     410           0 :   uint                    input_mem_regions_cnt   = 0U;
     411           0 :   ulong                   instr_data_offset       = 0UL;
     412             : 
     413           0 :   int err = fd_bpf_loader_input_serialize_parameters(
     414           0 :     ctx,
     415           0 :     pre_lens,
     416           0 :     input_mem_regions,
     417           0 :     &input_mem_regions_cnt,
     418           0 :     acc_region_metas,
     419           0 :     virtual_address_space_adjustments,
     420           0 :     direct_mapping,
     421           0 :     direct_account_pointers_in_program_input,
     422           0 :     is_deprecated,
     423           0 :     &instr_data_offset,
     424           0 :     &input_sz
     425           0 :   );
     426             : 
     427           0 :   if( FD_UNLIKELY( err ) ) {
     428           0 :     effects->has_error = true;
     429           0 :     ulong actual_end = FD_SCRATCH_ALLOC_FINI( l, 1UL );
     430           0 :     fd_solfuzz_pb_instr_ctx_destroy( runner, ctx );
     431           0 :     *output = effects;
     432           0 :     return actual_end - (ulong)output_buf;
     433           0 :   }
     434             : 
     435             :   /* Hash the serialized memory buffer. */
     436           0 :   uchar * serialized_buf = ctx->runtime->bpf_loader_serialization.serialization_mem[ ctx->runtime->instr.stack_sz-1UL ];
     437           0 :   effects->serialized_memory_hash = fd_hash( 0UL, serialized_buf, input_sz );
     438             : 
     439             :   /* Populate vm_input_memory_regions */
     440           0 :   effects->vm_input_memory_regions_count = (pb_size_t)input_mem_regions_cnt;
     441           0 :   effects->vm_input_memory_regions =
     442           0 :     FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_vm_input_memory_region_t),
     443           0 :                                 input_mem_regions_cnt * sizeof(fd_exec_test_vm_input_memory_region_t) );
     444           0 :   FD_TEST( _l <= output_end );
     445             : 
     446           0 :   for( uint i=0; i<input_mem_regions_cnt; i++ ) {
     447           0 :     fd_vm_input_region_t const * region = &input_mem_regions[i];
     448           0 :     fd_exec_test_vm_input_memory_region_t * out = &effects->vm_input_memory_regions[i];
     449           0 :     out->vm_address  = FD_VM_MEM_MAP_INPUT_REGION_START + region->vaddr_offset;
     450           0 :     out->region_size = region->region_sz;
     451           0 :     out->is_writable = region->is_writable;
     452           0 :   }
     453             : 
     454             :   /* Populate serialized_account_metadata */
     455           0 :   ulong num_ix_accounts = ctx->instr->acct_cnt;
     456           0 :   effects->serialized_account_metadata_count = (pb_size_t)num_ix_accounts;
     457           0 :   effects->serialized_account_metadata =
     458           0 :     FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_exec_test_vm_serialized_account_metadata_t),
     459           0 :                                 num_ix_accounts * sizeof(fd_exec_test_vm_serialized_account_metadata_t) );
     460           0 :   FD_TEST( _l <= output_end );
     461             : 
     462           0 :   for( ulong i=0; i<num_ix_accounts; i++ ) {
     463           0 :     fd_vm_acc_region_meta_t const * meta = &acc_region_metas[i];
     464           0 :     fd_exec_test_vm_serialized_account_metadata_t * out = &effects->serialized_account_metadata[i];
     465           0 :     out->original_data_len = meta->original_data_len;
     466           0 :     out->vm_data_addr      = meta->vm_data_addr;
     467           0 :     out->vm_key_addr       = meta->vm_key_addr;
     468           0 :     out->vm_lamports_addr  = meta->vm_lamports_addr;
     469           0 :     out->vm_owner_addr     = meta->vm_owner_addr;
     470           0 :   }
     471             : 
     472           0 :   ulong actual_end = FD_SCRATCH_ALLOC_FINI( l, 1UL );
     473           0 :   fd_solfuzz_pb_instr_ctx_destroy( runner, ctx );
     474             : 
     475           0 :   *output = effects;
     476           0 :   return actual_end - (ulong)output_buf;
     477           0 : }

Generated by: LCOV version 1.14