LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_vm_harness.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 288 326 88.3 %
Date: 2026-11-11 12:40:43 Functions: 4 4 100.0 %

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

Generated by: LCOV version 1.14