Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_vm_jit_fd_jit_private_h 2 : #define HEADER_fd_src_flamenco_vm_jit_fd_jit_private_h 3 : 4 : #include "fd_jit.h" 5 : #include <setjmp.h> 6 : 7 : /* DynASM code uses realloc. fd_jit can estimate the number of bytes 8 : needed, so we can do better and allocate once on startup. 9 : 10 : DynASM calls realloc in 4 places: On initialization in dasm_init, 11 : dasm_setupglobal, and dasm_growpc. Then, for every block of code 12 : in dasm_put. 13 : 14 : Checks that enough memory was allocated on initialization are moved 15 : to test_vm_jit. Checks during code generation (dasm_put) are moved 16 : to the fd_dasm_grow_check function call. Calls to 'realloc' and 17 : 'free' are removed. */ 18 : 19 : #include "dasm_proto.h" 20 : 21 : /* FD_DASM_R{...} specify the dynasm register index of x86_64 registers. */ 22 : 23 : #define FD_DASM_RAX (0) 24 : #define FD_DASM_RCX (1) 25 : #define FD_DASM_RDX (2) 26 : #define FD_DASM_RBX (3) 27 : #define FD_DASM_RSP (4) 28 : #define FD_DASM_RBP (5) 29 : #define FD_DASM_RSI (6) 30 : #define FD_DASM_RDI (7) 31 : #define FD_DASM_R8 (8) 32 : #define FD_DASM_R9 (9) 33 : #define FD_DASM_R10 (10) 34 : #define FD_DASM_R11 (11) 35 : #define FD_DASM_R12 (12) 36 : #define FD_DASM_R13 (13) 37 : #define FD_DASM_R14 (14) 38 : #define FD_DASM_R15 (15) 39 : 40 : /* FD_VM_JIT_SEGMENT_MAX is the max number of segments. */ 41 : 42 : #define FD_VM_JIT_SEGMENT_MAX (64) 43 : 44 : /* Thread-local storage ************************************************ 45 : 46 : For now, these are assumed to be absolute-addressed using the fs 47 : segment selector. Practically, this means that fd_jit only supports 48 : targets with FD_HAS_THREADS. (Other targets might use absolute 49 : addressing without a segment selector or rip-relative) */ 50 : 51 : FD_PROTOTYPES_BEGIN 52 : 53 : extern FD_TL fd_vm_t * fd_jit_vm; /* current VM being executed */ 54 : extern FD_TL fd_sbpf_syscalls_t const * fd_jit_syscalls; /* current syscall table */ 55 : 56 : /* Thread-local storage for address translation 57 : 58 : fd_jit_segment_cnt is number of memory regions mapped in by the VM. 59 : For each region i, fd_jit_mem_sz[2*i] is the number of readable bytes 60 : and fd_jit_mem_sz[2*i+1] is the number of writable bytes. 61 : fd_jit_mem_haddr points to the first byte of a region in host address 62 : space. */ 63 : 64 : extern FD_TL uint fd_jit_segment_cnt; 65 : extern FD_TL uint fd_jit_mem_sz [ 2*FD_VM_JIT_SEGMENT_MAX ]; 66 : extern FD_TL ulong fd_jit_mem_haddr[ FD_VM_JIT_SEGMENT_MAX ]; 67 : 68 : /* Thread-local storage for fast return to JIT entrypoint 69 : These are a setjmp()-like anchor for quickly exiting out of a VM 70 : execution, e.g. in case of a VM fault. 71 : Slots: 0=rbx 1=rbp 2=r12 3=r13 4=r14 5=r15 6=rsp 7=rip */ 72 : 73 : extern FD_TL ulong fd_jit_jmp_buf[8]; 74 : 75 : /* Thread-local storage for exception handling */ 76 : 77 : extern FD_TL ulong fd_jit_segfault_vaddr; 78 : extern FD_TL ulong fd_jit_segfault_rip; 79 : 80 : /* Thread-local storage for compile time */ 81 : 82 : /* fd_jit_compile_abort is a setjmp buffer to quickly abort a JIT 83 : compile operation without unwinding. */ 84 : 85 : extern FD_TL jmp_buf fd_jit_compile_abort; 86 : 87 : /* fd_jit_code_section points to the code buffer managed by 88 : dasm_Section. This thread-local is used to detect when this 89 : area is about to run out of space. */ 90 : 91 : extern FD_TL void * fd_jit_code_section_base; 92 : extern FD_TL ulong fd_jit_code_section_sz; 93 : 94 : /* fd_jit_labels is a table of function pointers to 'static' labels in the 95 : JIT code. They are indexed by fd_jit_lbl_{...}. Only used at 96 : compile time. */ 97 : 98 : #define FD_JIT_LABEL_CNT 16 99 : extern FD_TL void * fd_jit_labels[ FD_JIT_LABEL_CNT ]; 100 : 101 : /* FD_JIT_BLOAT_BASE approximates the number of code bytes that the JIT 102 : compiler generates regardless of the BPF instruction count. */ 103 : 104 6 : #define FD_JIT_BLOAT_BASE (10000UL) 105 : 106 : /* FD_JIT_BLOAT_MAX is the max acceptable JIT code bloat factor 107 : (Ratio jit_code_sz / bpf_sz) */ 108 : 109 6 : #define FD_JIT_BLOAT_MAX (3.0f) /* FIXME choose value based on mainnet contracts */ 110 : 111 : FD_PROTOTYPES_END 112 : 113 : /* fd_jit_scratch_layout_t describes the layout of the scratch region. 114 : The scratch region contains preallocated objects used by DynASM. */ 115 : 116 : struct fd_jit_scratch_layout { 117 : ulong dasm_off; 118 : ulong dasm_sz; 119 : 120 : ulong lglabels_off; 121 : ulong lglabels_sz; 122 : 123 : ulong pclabels_off; 124 : ulong pclabels_sz; 125 : 126 : ulong code_off; 127 : ulong code_sz; 128 : 129 : ulong sz; 130 : }; 131 : 132 : typedef struct fd_jit_scratch_layout fd_jit_scratch_layout_t; 133 : 134 : FD_PROTOTYPES_BEGIN 135 : 136 : /* fd_jit_scratch_layout proposes a memory layout for 137 : 138 : The size of the scratch region is assumed to be 139 : fd_jit_est_scratch_sz. */ 140 : 141 : fd_jit_scratch_layout_t * 142 : fd_jit_scratch_layout( fd_jit_scratch_layout_t * scratch, 143 : ulong bpf_sz ); 144 : 145 : /* fd_jit_prepare constructs a dasm_State object in the given scratch 146 : memory region. Calls dasm_init and dasm_setup. */ 147 : 148 : dasm_State * 149 : fd_jit_prepare( void * scratch, 150 : fd_jit_scratch_layout_t const * layout ); 151 : 152 : /* FIXME documentation for fd_jit_compile. */ 153 : 154 : void 155 : fd_jit_compile( struct dasm_State ** Dst, 156 : fd_sbpf_program_t const * prog, 157 : fd_sbpf_syscalls_t const * syscalls ); 158 : 159 : /* fd_jit_vm_compatible checks whether a VM instance is compatible with 160 : fd_jit. Returns FD_VM_SUCCESS or FD_VM_ERR_UNSUP. */ 161 : 162 : FD_FN_PURE int 163 : fd_jit_vm_compatible( fd_vm_t const * vm ); 164 : 165 : fd_jit_entrypoint_t 166 : fd_jit_get_entrypoint( void ); 167 : 168 : FD_PROTOTYPES_END 169 : 170 : #endif /* HEADER_fd_src_flamenco_vm_jit_fd_jit_private_h */