LCOV - code coverage report
Current view: top level - flamenco/progcache - fd_progcache_rec.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 73 75 97.3 %
Date: 2025-10-27 04:40:00 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "fd_progcache_rec.h"
       2             : #include "../vm/fd_vm.h" /* fd_vm_syscall_register_slot, fd_vm_validate */
       3             : 
       4             : fd_progcache_rec_t *
       5             : fd_progcache_rec_new( void *                          mem,
       6             :                       fd_sbpf_elf_info_t const *      elf_info,
       7             :                       fd_sbpf_loader_config_t const * config,
       8             :                       ulong                           load_slot,
       9             :                       fd_features_t const *           features,
      10             :                       void const *                    progdata,
      11             :                       ulong                           progdata_sz,
      12             :                       void *                          scratch,
      13          39 :                       ulong                           scratch_sz ) {
      14             : 
      15             :   /* Format object */
      16             : 
      17          39 :   int   has_calldests = !fd_sbpf_enable_stricter_elf_headers_enabled( elf_info->sbpf_version );
      18             : 
      19          39 :   FD_SCRATCH_ALLOC_INIT( l, mem );
      20          39 :   fd_progcache_rec_t * rec           = FD_SCRATCH_ALLOC_APPEND( l, fd_progcache_rec_align(),  sizeof(fd_progcache_rec_t) );
      21          39 :   void *               calldests_mem = NULL;
      22          39 :   if( has_calldests ) {
      23          39 :     /*               */calldests_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_sbpf_calldests_align(), fd_sbpf_calldests_footprint( elf_info->text_cnt ) );
      24          39 :   }
      25          39 :   void *               rodata_mem    = FD_SCRATCH_ALLOC_APPEND( l, 8UL,                       elf_info->bin_sz );
      26          39 :   FD_SCRATCH_ALLOC_FINI( l, fd_progcache_rec_align() );
      27          39 :   memset( rec, 0, sizeof(fd_progcache_rec_t) );
      28          39 :   rec->calldests_off = has_calldests ? (uint)( (ulong)calldests_mem - (ulong)mem ) : 0U;
      29          39 :   rec->rodata_off    = (uint)( (ulong)rodata_mem - (ulong)mem );
      30             : 
      31          39 :   rec->text_cnt      = elf_info->text_cnt;
      32          39 :   rec->text_off      = elf_info->text_off;
      33          39 :   rec->text_sz       = (uint)elf_info->text_sz;
      34          39 :   rec->sbpf_version  = (uchar)elf_info->sbpf_version;
      35             : 
      36             :   /* Set up sbpf_loader (redirect writes into progcache_rec object) */
      37             : 
      38          39 :   fd_sbpf_program_t prog[1] = {{
      39          39 :     .info     = *elf_info,
      40          39 :     .rodata   = rodata_mem,
      41          39 :     .text     = (ulong *)((ulong)rodata_mem + elf_info->text_off), /* FIXME: WHAT IF MISALIGNED */
      42          39 :     .entry_pc = ULONG_MAX
      43          39 :   }};
      44          39 :   if( has_calldests && elf_info->text_cnt>0UL ) {
      45          39 :     prog->calldests_shmem = calldests_mem;
      46          39 :     prog->calldests = fd_sbpf_calldests_join( fd_sbpf_calldests_new( calldests_mem, elf_info->text_cnt ) );
      47          39 :   }
      48             : 
      49             :   /* Loader requires syscall table */
      50             : 
      51          39 :   fd_sbpf_syscalls_t _syscalls[ FD_SBPF_SYSCALLS_SLOT_CNT ];
      52          39 :   fd_sbpf_syscalls_t * syscalls = fd_sbpf_syscalls_join( fd_sbpf_syscalls_new( _syscalls ) );
      53          39 :   int syscalls_err = fd_vm_syscall_register_slot( syscalls, load_slot, features, /* is_deploy */ 0 );
      54          39 :   if( FD_UNLIKELY( syscalls_err!=FD_VM_SUCCESS ) ) FD_LOG_CRIT(( "fd_vm_syscall_register_slot failed" ));
      55             : 
      56             :   /* Run ELF loader */
      57             : 
      58          39 :   if( FD_UNLIKELY( 0!=fd_sbpf_program_load( prog, progdata, progdata_sz, syscalls, config, scratch, scratch_sz ) ) ) {
      59           0 :     return NULL;
      60           0 :   }
      61             : 
      62          39 :   rec->entry_pc  = (uint)prog->entry_pc;
      63          39 :   rec->rodata_sz = (uint)prog->rodata_sz;
      64             : 
      65             :   /* Run bytecode validator */
      66             : 
      67          39 :   fd_vm_t _vm[1];
      68          39 :   fd_vm_t * vm = fd_vm_join( fd_vm_new( _vm ) );
      69          39 :   if( FD_UNLIKELY( !vm ) ) FD_LOG_CRIT(( "fd_vm_new failed" ));
      70          39 :   vm = fd_vm_init( vm,
      71          39 :                    NULL, /* OK since unused in `fd_vm_validate()` */
      72          39 :                    0UL,
      73          39 :                    0UL,
      74          39 :                    prog->rodata,
      75          39 :                    prog->rodata_sz,
      76          39 :                    prog->text,
      77          39 :                    prog->info.text_cnt,
      78          39 :                    prog->info.text_off,
      79          39 :                    prog->info.text_sz,
      80          39 :                    prog->entry_pc,
      81          39 :                    prog->calldests,
      82          39 :                    elf_info->sbpf_version,
      83          39 :                    syscalls,
      84          39 :                    NULL,
      85          39 :                    NULL,
      86          39 :                    NULL,
      87          39 :                    0U,
      88          39 :                    NULL,
      89          39 :                    0,
      90          39 :                    FD_FEATURE_ACTIVE( load_slot, features, bpf_account_data_direct_mapping ),
      91          39 :                    FD_FEATURE_ACTIVE( load_slot, features, stricter_abi_and_runtime_constraints ),
      92          39 :                    0 );
      93          39 :   if( FD_UNLIKELY( !vm ) ) FD_LOG_CRIT(( "fd_vm_init failed" ));
      94             : 
      95          39 :   if( FD_UNLIKELY( fd_vm_validate( vm )!=FD_VM_SUCCESS ) ) return NULL;
      96             : 
      97          36 :   rec->slot       = load_slot;
      98          36 :   rec->executable = 1;
      99          36 :   return rec;
     100          39 : }
     101             : 
     102             : fd_progcache_rec_t *
     103             : fd_progcache_rec_new_nx( void * mem,
     104          27 :                          ulong  load_slot ) {
     105          27 :   fd_progcache_rec_t * rec = mem;
     106          27 :   memset( rec, 0, sizeof(fd_progcache_rec_t) );
     107          27 :   rec->slot       = load_slot;
     108          27 :   rec->executable = 0;
     109          27 :   return rec;
     110          27 : }

Generated by: LCOV version 1.14