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 : }
|