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