Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_progcache_fd_progcache_rec_h 2 : #define HEADER_fd_src_flamenco_progcache_fd_progcache_rec_h 3 : 4 : #include "fd_progcache_base.h" 5 : #include "../../ballet/sbpf/fd_sbpf_loader.h" 6 : #include "../fd_flamenco_base.h" 7 : #include "../fd_rwlock.h" 8 : 9 : #include <stdatomic.h> 10 : 11 : struct fd_progcache_rec_key { 12 : fd_progcache_fork_id_t xid; 13 : fd_pubkey_t prog; 14 : }; 15 : 16 : typedef struct fd_progcache_rec_key fd_progcache_rec_key_t; 17 : 18 : static inline int 19 : fd_progcache_rec_key_eq( fd_progcache_rec_key_t const * k0, 20 354 : fd_progcache_rec_key_t const * k1 ) { 21 354 : return ( (k0->xid == k1->xid) & fd_pubkey_eq( &k0->prog, &k1->prog ) ); 22 354 : } 23 : 24 : /* fd_progcache_rec_t is the fixed size header of a program cache entry 25 : object. Entries are either non-executable (e.g. programs that failed 26 : verification) or executable. Non-executable entry objects consist 27 : only of this header struct. Executable entry objects are variable- 28 : sized and contain additional structures past this header (rodata/ROM 29 : segment, control flow metadata, ...). */ 30 : 31 : struct __attribute__((aligned(64))) fd_progcache_rec { 32 : fd_progcache_rec_key_t pair; /* Transaction id and record key pair */ 33 : 34 : ulong feature_slot; 35 : ulong deploy_slot; 36 : 37 : uint map_next; /* Internal use by map */ 38 : atomic_uint txn_idx; 39 : uint next_idx; /* Record map index of next record in its transaction */ 40 : uint prev_idx; /* Record map index of previous record in its transaction */ 41 : 42 : ulong data_gaddr; /* wksp-base relative pointer to data */ 43 : uint data_max; /* size of allocation */ 44 : 45 : uint entry_pc; 46 : uint text_cnt; 47 : uint text_off; 48 : uint text_sz; 49 : 50 : uint rodata_sz; 51 : 52 : uint calldests_off; /* offset to sbpf_calldests map */ 53 : uint rodata_off; /* offset to rodata segment */ 54 : 55 : uint reclaim_next; 56 : 57 : ushort sbpf_version : 8; /* SBPF version, SIMD-0161 */ 58 : ushort exists : 1; /* if ==0, record is dead, no longer in map, and awaiting cleanup */ 59 : fd_rwlock_t lock; 60 : }; 61 : 62 : FD_STATIC_ASSERT( sizeof(fd_progcache_rec_t)==128, layout ); 63 : 64 : FD_PROTOTYPES_BEGIN 65 : 66 : /* Accessors */ 67 : 68 : static inline uchar const * 69 : fd_progcache_rec_rodata( fd_progcache_rec_t const * rec, 70 2454 : fd_wksp_t * wksp ) { 71 2454 : return fd_wksp_laddr_fast( wksp, rec->data_gaddr + rec->rodata_off ); 72 2454 : } 73 : 74 : static inline fd_sbpf_calldests_t const * 75 : fd_progcache_rec_calldests( fd_progcache_rec_t const * rec, 76 2454 : fd_wksp_t * wksp ) { 77 2454 : if( rec->calldests_off==UINT_MAX ) return NULL; 78 2454 : return fd_sbpf_calldests_join( fd_wksp_laddr_fast( wksp, rec->data_gaddr + rec->calldests_off ) ); 79 2454 : } 80 : 81 : /* Heap allocator for variable-size cache entry data */ 82 : 83 : /* fd_progcache_use_malloc allows link-time (build-time) selection of 84 : libc malloc instead of fd_alloc for testing. Cannot be configured at 85 : runtime because that would create an attack vector. */ 86 : 87 : extern int const fd_progcache_use_malloc; 88 : 89 : /* fd_progcache_val_{align,footprint} give the params of variable-size 90 : backing memory for an executable cache entry with the given ELF info. 91 : elf_info must describe a successfully peeked ELF. Non-executable 92 : cache entries do not allocate value storage; fd_progcache_rec_nx marks 93 : their fixed record with data_gaddr==0. */ 94 : 95 : FD_FN_CONST static inline ulong 96 25296 : fd_progcache_val_align( void ) { 97 25296 : return fd_sbpf_calldests_align(); 98 25296 : } 99 : 100 : FD_FN_PURE ulong 101 : fd_progcache_val_footprint( fd_sbpf_elf_info_t const * elf_info ); 102 : 103 : void * 104 : fd_progcache_val_alloc( fd_progcache_rec_t * rec, 105 : fd_progcache_join_t * join, 106 : ulong val_align, 107 : ulong val_footprint ); 108 : 109 : void 110 : fd_progcache_val_free1( fd_progcache_rec_t * rec, 111 : void * val, 112 : fd_alloc_t * alloc ); 113 : 114 : void 115 : fd_progcache_val_free( fd_progcache_rec_t * rec, 116 : fd_progcache_join_t * join ); 117 : 118 : fd_progcache_rec_t * 119 : fd_progcache_rec_load( fd_progcache_rec_t * rec, 120 : fd_wksp_t * wksp, 121 : fd_sbpf_elf_info_t const * elf_info, 122 : fd_sbpf_loader_config_t const * config, 123 : ulong load_slot, 124 : fd_features_t const * features, 125 : void const * progdata, 126 : ulong progdata_sz, 127 : void * scratch, 128 : ulong scratch_sz ); 129 : 130 : fd_progcache_rec_t * 131 : fd_progcache_rec_nx( fd_progcache_rec_t * rec ); 132 : 133 : FD_PROTOTYPES_END 134 : 135 : #endif /* HEADER_fd_src_flamenco_progcache_fd_progcache_rec_h */