LCOV - code coverage report
Current view: top level - flamenco/runtime/tests - fd_solfuzz_exec.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 294 0.0 %
Date: 2026-02-28 05:18:01 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /* fd_solfuzz_exec.c contains internal executors */
       2             : 
       3             : #include "fd_solfuzz_private.h"
       4             : #include "generated/block.pb.h"
       5             : #include "generated/invoke.pb.h"
       6             : #include "generated/txn.pb.h"
       7             : #include "generated/vm.pb.h"
       8             : #if FD_HAS_FLATCC
       9             : #include "flatbuffers/generated/elf_reader.h"
      10             : #endif
      11             : 
      12             : #include "../fd_executor_err.h"
      13             : #include <assert.h>
      14             : 
      15             : /*
      16             :  * fixtures
      17             :  */
      18             : 
      19             : static int
      20             : sol_compat_cmp_binary_strict( void const * effects,
      21             :                               void const * expected,
      22             :                               pb_msgdesc_t const * encode_type,
      23           0 :                               fd_spad_t * spad ) {
      24           0 : #define MAX_SZ 32*1024*1024
      25           0 : FD_SPAD_FRAME_BEGIN( spad ) {
      26           0 :   if( effects==NULL ) {
      27           0 :     FD_LOG_WARNING(( "No output effects" ));
      28           0 :     return 0;
      29           0 :   }
      30             : 
      31             :   /* Note: Most likely this spad allocation won't fail. If it does, you may need to bump
      32             :      the allocated spad memory amount in fd_exec_sol_compat.c. */
      33           0 :   ulong out_sz = MAX_SZ;
      34           0 :   uchar * out = fd_spad_alloc( spad, 1UL, out_sz );
      35           0 :   if( !sol_compat_encode( out, &out_sz, effects, encode_type ) ) {
      36           0 :     FD_LOG_WARNING(( "Error encoding effects" ));
      37           0 :     return 0;
      38           0 :   }
      39             : 
      40           0 :   ulong exp_sz = MAX_SZ;
      41           0 :   uchar * exp = fd_spad_alloc( spad, 1UL, exp_sz );
      42           0 :   if( !sol_compat_encode( exp, &exp_sz, expected, encode_type ) ) {
      43           0 :     FD_LOG_WARNING(( "Error encoding expected" ));
      44           0 :     return 0;
      45           0 :   }
      46             : 
      47           0 :   if( out_sz!=exp_sz ) {
      48           0 :     FD_LOG_WARNING(( "Binary cmp failed: different size. out_sz=%lu exp_sz=%lu", out_sz, exp_sz  ));
      49           0 :     return 0;
      50           0 :   }
      51           0 :   if( !fd_memeq( out, exp, out_sz ) ) {
      52           0 :     FD_LOG_WARNING(( "Binary cmp failed: different values." ));
      53           0 :     return 0;
      54           0 :   }
      55             : 
      56           0 :   return 1;
      57           0 : } FD_SPAD_FRAME_END;
      58           0 : #undef MAX_SIZE
      59           0 : }
      60             : 
      61             : static int
      62             : _diff_txn_acct( fd_exec_test_acct_state_t * expected,
      63           0 :                 fd_exec_test_acct_state_t * actual ) {
      64             :   /* AcctState -> address (This must hold true when calling this function!) */
      65           0 :   assert( fd_memeq( expected->address, actual->address, sizeof(fd_pubkey_t) ) );
      66             : 
      67             :   /* AcctState -> lamports */
      68           0 :   if( expected->lamports != actual->lamports ) {
      69           0 :     FD_LOG_WARNING(( "Lamports mismatch: expected=%lu actual=%lu", expected->lamports, actual->lamports ));
      70           0 :     return 0;
      71           0 :   }
      72             : 
      73             :   /* AcctState -> data */
      74           0 :   if( expected->data != NULL || actual->data != NULL ) {
      75           0 :     if( expected->data == NULL ) {
      76           0 :       FD_LOG_WARNING(( "Expected account data is NULL, actual is non-NULL" ));
      77           0 :       return 0;
      78           0 :     }
      79             : 
      80           0 :     if( actual->data == NULL ) {
      81           0 :       FD_LOG_WARNING(( "Expected account data is NULL, actual is non-NULL" ));
      82           0 :       return 0;
      83           0 :     }
      84             : 
      85           0 :     if( expected->data->size != actual->data->size ) {
      86           0 :       FD_LOG_WARNING(( "Account data size mismatch: expected=%u actual=%u", expected->data->size, actual->data->size ));
      87           0 :       return 0;
      88           0 :     }
      89             : 
      90           0 :     if( !fd_memeq( expected->data->bytes, actual->data->bytes, expected->data->size ) ) {
      91           0 :       FD_LOG_WARNING(( "Account data mismatch" ));
      92           0 :       return 0;
      93           0 :     }
      94           0 :   }
      95             : 
      96             :   /* AcctState -> executable */
      97           0 :   if( expected->executable != actual->executable ) {
      98           0 :     FD_LOG_WARNING(( "Executable mismatch: expected=%d actual=%d", expected->executable, actual->executable ));
      99           0 :     return 0;
     100           0 :   }
     101             : 
     102             :   /* AcctState -> owner */
     103           0 :   if( !fd_memeq( expected->owner, actual->owner, sizeof(fd_pubkey_t) ) ) {
     104           0 :     char a[ FD_BASE58_ENCODED_32_SZ ];
     105           0 :     char b[ FD_BASE58_ENCODED_32_SZ ];
     106           0 :     FD_LOG_WARNING(( "Owner mismatch: expected=%s, actual=%s", fd_acct_addr_cstr( a, expected->owner ), fd_acct_addr_cstr( b, actual->owner ) ));
     107           0 :     return 0;
     108           0 :   }
     109             : 
     110           0 :   return 1;
     111           0 : }
     112             : 
     113             : 
     114             : static int
     115             : _diff_accounts( fd_exec_test_acct_state_t * expected,
     116             :                 pb_size_t                   expected_count,
     117             :                 fd_exec_test_acct_state_t * actual,
     118           0 :                 pb_size_t                   actual_count ) {
     119             :   // Verify that the number of accounts are the same
     120           0 :   if( expected_count != actual_count ) {
     121           0 :     FD_LOG_WARNING(( "Account states count mismatch: expected=%u actual=%u", expected_count, actual_count ));
     122           0 :     return 0;
     123           0 :   }
     124             : 
     125             :   // Verify that the account states are the same
     126           0 :   for( ulong i = 0; i < expected_count; ++i ) {
     127           0 :     uchar found = 0;
     128           0 :     for( ulong j = 0; j < actual_count; ++j ) {
     129           0 :       if( fd_memeq( expected[i].address, actual[j].address, sizeof(fd_pubkey_t) ) ) {
     130           0 :         found = 1;
     131           0 :         if( !_diff_txn_acct( &expected[i], &actual[j] ) ) {
     132           0 :           return 0;
     133           0 :         }
     134           0 :         break;
     135           0 :       }
     136           0 :     }
     137           0 :     if( !found ) {
     138           0 :       char a[ FD_BASE58_ENCODED_32_SZ ];
     139           0 :       FD_LOG_WARNING(( "Account state not found in actual: expected=%s", fd_acct_addr_cstr( a, expected[i].address ) ));
     140           0 :       return 0;
     141           0 :     }
     142           0 :   }
     143             : 
     144           0 :   return 1;
     145           0 : }
     146             : 
     147             : static int
     148             : sol_compat_cmp_txn( fd_exec_test_txn_result_t *  expected,
     149           0 :                     fd_exec_test_txn_result_t *  actual ) {
     150             :   /* TxnResult -> executed */
     151           0 :   if( expected->executed != actual->executed ) {
     152           0 :     FD_LOG_WARNING(( "Executed mismatch: expected=%d actual=%d", expected->executed, actual->executed ));
     153           0 :     return 0;
     154           0 :   }
     155             : 
     156             :   /* TxnResult -> sanitization_error */
     157           0 :   if( expected->sanitization_error != actual->sanitization_error ) {
     158           0 :     FD_LOG_WARNING(( "Sanitization error mismatch: expected=%d actual=%d", expected->sanitization_error, actual->sanitization_error ));
     159           0 :     return 0;
     160           0 :   }
     161             : 
     162             :   /* TxnResult -> modified_accounts */
     163           0 :   if( !_diff_accounts( expected->modified_accounts, expected->modified_accounts_count, actual->modified_accounts, actual->modified_accounts_count ) ) {
     164           0 :     return 0;
     165           0 :   }
     166             : 
     167             :   /* TxnResult -> rollback_accounts */
     168           0 :   if( !_diff_accounts( expected->rollback_accounts, expected->rollback_accounts_count, actual->rollback_accounts, actual->rollback_accounts_count ) ) {
     169           0 :     return 0;
     170           0 :   }
     171             : 
     172             :   /* TxnResult -> is_ok */
     173           0 :   if( expected->is_ok != actual->is_ok ) {
     174           0 :     FD_LOG_WARNING(( "Is ok mismatch: expected=%d actual=%d", expected->is_ok, actual->is_ok ));
     175           0 :     return 0;
     176           0 :   }
     177             : 
     178             :   /* TxnResult -> status */
     179           0 :   if( expected->status != actual->status ) {
     180           0 :     FD_LOG_WARNING(( "Status mismatch: expected=%u actual=%u", expected->status, actual->status ));
     181           0 :     return 0;
     182           0 :   }
     183             : 
     184             :   /* TxnResult -> instruction_error */
     185           0 :   if( expected->instruction_error != actual->instruction_error ) {
     186           0 :     FD_LOG_WARNING(( "Instruction error mismatch: expected=%u actual=%u", expected->instruction_error, actual->instruction_error ));
     187           0 :     return 0;
     188           0 :   }
     189             : 
     190           0 :   if( expected->instruction_error ) {
     191             :     /* TxnResult -> instruction_error_index */
     192           0 :     if( expected->instruction_error_index != actual->instruction_error_index ) {
     193           0 :       FD_LOG_WARNING(( "Instruction error index mismatch: expected=%u actual=%u", expected->instruction_error_index, actual->instruction_error_index ));
     194           0 :       return 0;
     195           0 :     }
     196             : 
     197             :     /* TxnResult -> custom_error */
     198           0 :     if( expected->instruction_error == (ulong) -FD_EXECUTOR_INSTR_ERR_CUSTOM_ERR && expected->custom_error != actual->custom_error ) {
     199           0 :       FD_LOG_WARNING(( "Custom error mismatch: expected=%u actual=%u", expected->custom_error, actual->custom_error ));
     200           0 :       return 0;
     201           0 :     }
     202           0 :   }
     203             : 
     204             :   /* TxnResult -> return_data */
     205           0 :   if( expected->return_data != NULL || actual->return_data != NULL ) {
     206           0 :     if( expected->return_data == NULL ) {
     207           0 :       FD_LOG_WARNING(( "Expected return data is NULL, actual is non-NULL" ));
     208           0 :       return 0;
     209           0 :     }
     210             : 
     211           0 :     if( actual->return_data == NULL ) {
     212           0 :       FD_LOG_WARNING(( "Expected return data is NULL, actual is non-NULL" ));
     213           0 :       return 0;
     214           0 :     }
     215             : 
     216           0 :     if( expected->return_data->size != actual->return_data->size ) {
     217           0 :       FD_LOG_WARNING(( "Return data size mismatch: expected=%u actual=%u", expected->return_data->size, actual->return_data->size ));
     218           0 :       return 0;
     219           0 :     }
     220             : 
     221           0 :     if( !fd_memeq( expected->return_data->bytes, actual->return_data->bytes, expected->return_data->size ) ) {
     222           0 :       FD_LOG_WARNING(( "Return data mismatch" ));
     223           0 :       return 0;
     224           0 :     }
     225           0 :   }
     226             : 
     227             :   /* TxnResult -> executed_units */
     228           0 :   if( expected->executed_units != actual->executed_units ) {
     229           0 :     FD_LOG_WARNING(( "Executed units mismatch: expected=%lu actual=%lu", expected->executed_units, actual->executed_units ));
     230           0 :     return 0;
     231           0 :   }
     232             : 
     233             :   /* TxnResult -> fee_details */
     234           0 :   if( expected->has_fee_details != actual->has_fee_details ) {
     235           0 :     FD_LOG_WARNING(( "Has fee details mismatch: expected=%d actual=%d", expected->has_fee_details, actual->has_fee_details ));
     236           0 :     return 0;
     237           0 :   }
     238             : 
     239           0 :   if( expected->has_fee_details ) {
     240           0 :     if( expected->fee_details.transaction_fee != actual->fee_details.transaction_fee ) {
     241           0 :       FD_LOG_WARNING(( "Transaction fee mismatch: expected=%lu actual=%lu", expected->fee_details.transaction_fee, actual->fee_details.transaction_fee ));
     242           0 :       return 0;
     243           0 :     }
     244             : 
     245           0 :     if( expected->fee_details.prioritization_fee != actual->fee_details.prioritization_fee ) {
     246           0 :       FD_LOG_WARNING(( "Priority fee mismatch: expected=%lu actual=%lu", expected->fee_details.prioritization_fee, actual->fee_details.prioritization_fee ));
     247           0 :       return 0;
     248           0 :     }
     249           0 :   }
     250             : 
     251             :   /* TxnResult -> loaded_accounts_data_size */
     252           0 :   if( expected->loaded_accounts_data_size != actual->loaded_accounts_data_size ) {
     253           0 :     FD_LOG_WARNING(( "Loaded accounts data size mismatch: expected=%lu actual=%lu", expected->loaded_accounts_data_size, actual->loaded_accounts_data_size ));
     254           0 :     return 0;
     255           0 :   }
     256             : 
     257           0 :   return 1;
     258           0 : }
     259             : 
     260             : int
     261             : fd_solfuzz_pb_instr_fixture( fd_solfuzz_runner_t * runner,
     262             :                              uchar const *         in,
     263           0 :                              ulong                 in_sz ) {
     264             :   // Decode fixture
     265           0 :   fd_exec_test_instr_fixture_t fixture[1] = {0};
     266           0 :   void * res = sol_compat_decode_lenient( &fixture, in, in_sz, &fd_exec_test_instr_fixture_t_msg );
     267           0 :   if( !res ) {
     268           0 :     FD_LOG_WARNING(( "Invalid instr fixture." ));
     269           0 :     return 0;
     270           0 :   }
     271             : 
     272           0 :   int ok = 0;
     273             :   // Execute
     274           0 :   void * output = NULL;
     275           0 :   fd_solfuzz_pb_execute_wrapper( runner, &fixture->input, &output, fd_solfuzz_pb_instr_run );
     276             : 
     277             :   // Compare effects
     278           0 :   ok = sol_compat_cmp_binary_strict( output, &fixture->output, &fd_exec_test_instr_effects_t_msg, runner->spad );
     279             : 
     280             :   // Cleanup
     281           0 :   pb_release( &fd_exec_test_instr_fixture_t_msg, fixture );
     282           0 :   return ok;
     283           0 : }
     284             : 
     285             : int
     286             : fd_solfuzz_pb_txn_fixture( fd_solfuzz_runner_t * runner,
     287             :                            uchar const *         in,
     288           0 :                            ulong                 in_sz ) {
     289             :   // Decode fixture
     290           0 :   fd_exec_test_txn_fixture_t fixture[1] = {0};
     291           0 :   void * res = sol_compat_decode_lenient( &fixture, in, in_sz, &fd_exec_test_txn_fixture_t_msg );
     292           0 :   if( !res ) {
     293           0 :     FD_LOG_WARNING(( "Invalid txn fixture." ));
     294           0 :     return 0;
     295           0 :   }
     296             : 
     297           0 :   fd_spad_push( runner->spad );
     298           0 :   int ok = 0;
     299           0 :   void * output = NULL;
     300           0 :   fd_solfuzz_pb_execute_wrapper( runner, &fixture->input, &output, fd_solfuzz_pb_txn_run );
     301           0 :   if( FD_LIKELY( output ) ) {
     302             :     // Compare effects
     303           0 :     fd_exec_test_txn_result_t * effects = output;
     304           0 :     ok = sol_compat_cmp_txn( &fixture->output, effects );
     305           0 :   }
     306           0 :   fd_spad_pop( runner->spad );
     307             : 
     308             :   // Cleanup
     309           0 :   pb_release( &fd_exec_test_txn_fixture_t_msg, fixture );
     310           0 :   return ok;
     311           0 : }
     312             : 
     313             : int
     314             : fd_solfuzz_pb_block_fixture( fd_solfuzz_runner_t * runner,
     315             :                              uchar const *         in,
     316           0 :                              ulong                 in_sz ) {
     317             :   // Decode fixture
     318           0 :   fd_exec_test_block_fixture_t fixture[1] = {0};
     319           0 :   void * res = sol_compat_decode_lenient( &fixture, in, in_sz, &fd_exec_test_block_fixture_t_msg );
     320           0 :   if( !res ) {
     321           0 :     FD_LOG_WARNING(( "Invalid block fixture" ));
     322           0 :     return 0;
     323           0 :   }
     324             : 
     325           0 :   fd_spad_push( runner->spad );
     326           0 :   void * output = NULL;
     327           0 :   fd_solfuzz_pb_execute_wrapper( runner, &fixture->input, &output, fd_solfuzz_pb_block_run );
     328           0 :   int ok = sol_compat_cmp_binary_strict( output, &fixture->output, &fd_exec_test_block_effects_t_msg, runner->spad );
     329           0 :   fd_spad_pop( runner->spad );
     330             : 
     331             :   // Cleanup
     332           0 :   pb_release( &fd_exec_test_block_fixture_t_msg, fixture );
     333           0 :   return ok;
     334           0 : }
     335             : 
     336             : int
     337             : fd_solfuzz_pb_syscall_fixture( fd_solfuzz_runner_t * runner,
     338             :                                uchar const *         in,
     339           0 :                                ulong                 in_sz ) {
     340             :   // Decode fixture
     341           0 :   fd_exec_test_syscall_fixture_t fixture[1] = {0};
     342           0 :   if( !sol_compat_decode_lenient( &fixture, in, in_sz, &fd_exec_test_syscall_fixture_t_msg ) ) {
     343           0 :     FD_LOG_WARNING(( "Invalid syscall fixture." ));
     344           0 :     return 0;
     345           0 :   }
     346             : 
     347           0 :   fd_spad_push( runner->spad );
     348           0 :   void * output = NULL;
     349           0 :   fd_solfuzz_pb_execute_wrapper( runner, &fixture->input, &output, fd_solfuzz_pb_syscall_run );
     350           0 :   int ok = sol_compat_cmp_binary_strict( output, &fixture->output, &fd_exec_test_syscall_effects_t_msg, runner->spad );
     351           0 :   fd_spad_pop( runner->spad );
     352             : 
     353             :   // Cleanup
     354           0 :   pb_release( &fd_exec_test_syscall_fixture_t_msg, fixture );
     355           0 :   return ok;
     356           0 : }
     357             : 
     358             : #if FD_HAS_FLATCC
     359             : 
     360             : /* Flatbuffers */
     361             : static int
     362             : sol_compat_fb_cmp_elf_loader( SOL_COMPAT_NS(ELFLoaderEffects_table_t) expected,
     363           0 :                               SOL_COMPAT_NS(ELFLoaderEffects_table_t) actual ) {
     364             :   /* Compare err_code */
     365           0 :   if( FD_UNLIKELY( SOL_COMPAT_NS(ELFLoaderEffects_err_code( expected ))!=SOL_COMPAT_NS(ELFLoaderEffects_err_code( actual )) ) ) {
     366           0 :     FD_LOG_WARNING(( "Err code mismatch: expected=%u actual=%u", SOL_COMPAT_NS(ELFLoaderEffects_err_code( expected )), SOL_COMPAT_NS(ELFLoaderEffects_err_code( actual )) ));
     367           0 :     return 0;
     368           0 :   }
     369             : 
     370             :   /* Compare rodata_hash */
     371           0 :   SOL_COMPAT_NS(XXHash_struct_t) exp_rodata_hash = SOL_COMPAT_NS(ELFLoaderEffects_rodata_hash( expected ));
     372           0 :   SOL_COMPAT_NS(XXHash_struct_t) act_rodata_hash = SOL_COMPAT_NS(ELFLoaderEffects_rodata_hash( actual ));
     373             : 
     374           0 :   if( (!exp_rodata_hash && !act_rodata_hash) ) {
     375             :     // Both are NULL, considered matching
     376           0 :   } else if( FD_UNLIKELY( (exp_rodata_hash && !act_rodata_hash) || (!exp_rodata_hash && act_rodata_hash) ) ) {
     377           0 :     FD_LOG_WARNING(( "Rodata hash presence mismatch: expected=%p actual=%p", (void*)exp_rodata_hash, (void*)act_rodata_hash ));
     378           0 :     return 0;
     379           0 :   } else if( FD_UNLIKELY( memcmp( &exp_rodata_hash->hash, &act_rodata_hash->hash, sizeof(exp_rodata_hash->hash) ) ) ) {
     380           0 :     FD_LOG_WARNING(( "Rodata hash mismatch: expected=%lu actual=%lu", *((ulong*)exp_rodata_hash->hash), *((ulong*)act_rodata_hash->hash) ));
     381           0 :     return 0;
     382           0 :   }
     383             : 
     384             :   /* Compare text_cnt */
     385           0 :   if( FD_UNLIKELY( SOL_COMPAT_NS(ELFLoaderEffects_text_cnt( expected ))!=SOL_COMPAT_NS(ELFLoaderEffects_text_cnt( actual )) ) ) {
     386           0 :     FD_LOG_WARNING(( "Text cnt mismatch: expected=%lu actual=%lu",
     387           0 :         SOL_COMPAT_NS(ELFLoaderEffects_text_cnt( expected )),
     388           0 :         SOL_COMPAT_NS(ELFLoaderEffects_text_cnt( actual )) ));
     389           0 :     return 0;
     390           0 :   }
     391             : 
     392             :   /* Compare text_off */
     393           0 :   if( FD_UNLIKELY( SOL_COMPAT_NS(ELFLoaderEffects_text_off( expected ))!=SOL_COMPAT_NS(ELFLoaderEffects_text_off( actual )) ) ) {
     394           0 :     FD_LOG_WARNING(( "Text off mismatch: expected=%lu actual=%lu",
     395           0 :         SOL_COMPAT_NS(ELFLoaderEffects_text_off( expected )),
     396           0 :         SOL_COMPAT_NS(ELFLoaderEffects_text_off( actual )) ));
     397           0 :     return 0;
     398           0 :   }
     399             : 
     400             :   /* Compare entry_pc */
     401           0 :   if( FD_UNLIKELY( SOL_COMPAT_NS(ELFLoaderEffects_entry_pc( expected )) != SOL_COMPAT_NS(ELFLoaderEffects_entry_pc( actual )) ) ) {
     402           0 :     FD_LOG_WARNING(( "Entry pc mismatch: expected=%lu actual=%lu",
     403           0 :         SOL_COMPAT_NS(ELFLoaderEffects_entry_pc( expected )),
     404           0 :         SOL_COMPAT_NS(ELFLoaderEffects_entry_pc( actual )) ));
     405           0 :     return 0;
     406           0 :   }
     407             : 
     408             :   /* Compare calldests_hash */
     409           0 :   SOL_COMPAT_NS(XXHash_struct_t) exp_calldests_hash = SOL_COMPAT_NS(ELFLoaderEffects_calldests_hash( expected ));
     410           0 :   SOL_COMPAT_NS(XXHash_struct_t) act_calldests_hash = SOL_COMPAT_NS(ELFLoaderEffects_calldests_hash( actual ));
     411             : 
     412           0 :   if( (!exp_calldests_hash && !act_calldests_hash) ) {
     413             :     // Both are NULL, considered matching
     414           0 :   } else if( FD_UNLIKELY( (exp_calldests_hash && !act_calldests_hash) || (!exp_calldests_hash && act_calldests_hash) ) ) {
     415           0 :     FD_LOG_WARNING(( "Calldests hash presence mismatch: expected=%p actual=%p", (void*)exp_calldests_hash, (void*)act_calldests_hash ));
     416           0 :     return 0;
     417           0 :   } else if( FD_UNLIKELY( memcmp( &exp_calldests_hash->hash, &act_calldests_hash->hash, sizeof(exp_calldests_hash->hash) ) ) ) {
     418           0 :     FD_LOG_WARNING(( "Calldests hash mismatch: expected=%lu actual=%lu", *((ulong*)exp_calldests_hash->hash), *((ulong*)act_calldests_hash->hash) ));
     419           0 :     return 0;
     420           0 :   }
     421             : 
     422           0 :   return 1;
     423           0 : }
     424             : 
     425             : int
     426             : fd_solfuzz_fb_elf_loader_fixture( fd_solfuzz_runner_t * runner,
     427           0 :                                   uchar const *         in ) {
     428             :   /* Decode */
     429           0 :   SOL_COMPAT_NS(ELFLoaderFixture_table_t) fixture = SOL_COMPAT_NS(ELFLoaderFixture_as_root( in ));
     430           0 :   if( FD_UNLIKELY( !fixture ) ) return 0;
     431             : 
     432             :   /* Execute */
     433           0 :   SOL_COMPAT_NS(ELFLoaderCtx_table_t) input = SOL_COMPAT_NS(ELFLoaderFixture_input( fixture ));
     434           0 :   if( FD_UNLIKELY( !input ) ) return 0;
     435             : 
     436           0 :   int err = fd_solfuzz_fb_execute_wrapper( runner, input, fd_solfuzz_fb_elf_loader_run );
     437           0 :   if( FD_UNLIKELY( err==SOL_COMPAT_V2_FAILURE ) ) return err;
     438             : 
     439             :   /* Compare */
     440           0 :   FD_SPAD_FRAME_BEGIN( runner->spad ) {
     441           0 :     ulong   buffer_sz  = flatcc_builder_get_buffer_size( runner->fb_builder );
     442           0 :     uchar * actual_buf = fd_spad_alloc( runner->spad, 1UL, buffer_sz );
     443           0 :     flatcc_builder_copy_buffer( runner->fb_builder, actual_buf, buffer_sz );
     444             : 
     445           0 :     SOL_COMPAT_NS(ELFLoaderEffects_table_t) expected = SOL_COMPAT_NS(ELFLoaderEffects_as_root( actual_buf ));
     446           0 :     SOL_COMPAT_NS(ELFLoaderEffects_table_t) actual   = SOL_COMPAT_NS(ELFLoaderFixture_output( fixture ));
     447           0 :     if( FD_UNLIKELY( !expected || !actual ) ) return 0;
     448             : 
     449           0 :     return sol_compat_fb_cmp_elf_loader( expected, actual );
     450           0 :   } FD_SPAD_FRAME_END;
     451           0 : }
     452             : 
     453             : #endif /* FD_HAS_FLATCC */

Generated by: LCOV version 1.14