Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_vm_syscall_fd_vm_cpi_h 2 : #define HEADER_fd_src_flamenco_vm_syscall_fd_vm_cpi_h 3 : 4 : #ifndef HEADER_fd_src_flamenco_vm_syscall_fd_vm_syscall_h 5 : #error "Do not include this directly; use fd_vm_syscall.h" 6 : #endif 7 : 8 : /* fd_vm_cpi contains type definitions for the cross-program-invocation 9 : (CPI) API. These types are passed from the virtual machine to the 10 : CPI syscall handlers and are thus untrusted. Addresses are in VM 11 : address space. Struct parameter offsets and sizes match exactly. 12 : Structs also have alignment requirements in VM address space. These 13 : alignments are provided as const macros. Since we cannot guarantee 14 : that a type is aligned in host address space even when aligned in VM 15 : address space (FIXME: HMMM ... THAT DOESN'T SOUND RIGHT), all structs 16 : support unaligned access (i.e. alignof(type)==1UL). 17 : 18 : Unfortunately, the Solana protocol provides this API twice: 19 : In a C-style ABI and in Rust ABI. */ 20 : 21 : 22 : /* Structs fd_vm_c_{...}_t are part of the C ABI for the cross-program 23 : invocation syscall API. */ 24 : 25 : #define FD_VM_C_INSTRUCTION_ALIGN (8UL) 26 : #define FD_VM_C_INSTRUCTION_SIZE (40UL) 27 : 28 : struct __attribute__((packed)) fd_vm_c_instruction { 29 : ulong program_id_addr; 30 : ulong accounts_addr; 31 : ulong accounts_len; 32 : ulong data_addr; 33 : ulong data_len; 34 : }; 35 : 36 : typedef struct fd_vm_c_instruction fd_vm_c_instruction_t; 37 : 38 : #define FD_VM_C_ACCOUNT_META_ALIGN (8UL) 39 : #define FD_VM_C_ACCOUNT_META_SIZE (16UL) 40 : struct fd_vm_c_account_meta { 41 : ulong pubkey_addr; 42 : uchar is_writable; 43 : uchar is_signer; 44 : }; 45 : 46 : typedef struct fd_vm_c_account_meta fd_vm_c_account_meta_t; 47 : 48 : #define FD_VM_C_ACCOUNT_INFO_ALIGN (8UL) 49 0 : #define FD_VM_C_ACCOUNT_INFO_SIZE (56UL) 50 : 51 : struct fd_vm_c_account_info { 52 : ulong pubkey_addr; 53 : ulong lamports_addr; 54 : ulong data_sz; 55 : ulong data_addr; 56 : ulong owner_addr; 57 : ulong rent_epoch; 58 : uchar is_signer; 59 : uchar is_writable; 60 : uchar executable; 61 : }; 62 : 63 : typedef struct fd_vm_c_account_info fd_vm_c_account_info_t; 64 : 65 : /* Structs fd_vm_rust_{...}_t are part of the Rust ABI for the 66 : cross-program-invocation syscall API. */ 67 : 68 : /* fd_vm_rust_vec_t is Rust type Vec<_> using the default allocator. */ 69 : 70 : #define FD_VM_RUST_VEC_ALIGN (8UL) 71 : #define FD_VM_RUST_VEC_SIZE (24UL) 72 : 73 : struct __attribute__((packed)) fd_vm_rust_vec { 74 : ulong addr; 75 : ulong cap; 76 : ulong len; 77 : }; 78 : 79 : typedef struct fd_vm_rust_vec fd_vm_rust_vec_t; 80 : 81 : #define FD_VM_RUST_RC_ALIGN (8UL) 82 : 83 : #define FD_VM_RUST_INSTRUCTION_ALIGN (8UL) 84 : #define FD_VM_RUST_INSTRUCTION_SIZE (80UL) 85 : 86 : struct __attribute__((packed)) fd_vm_rust_instruction { 87 : fd_vm_rust_vec_t accounts; /* points to fd_vm_rust_account_meta_t */ 88 : fd_vm_rust_vec_t data; /* points to bytes */ 89 : uchar pubkey[32]; 90 : }; 91 : 92 : typedef struct fd_vm_rust_instruction fd_vm_rust_instruction_t; 93 : 94 0 : #define FD_VM_RUST_ACCOUNT_META_SIZE (34UL) 95 0 : #define FD_VM_RUST_ACCOUNT_META_ALIGN (1UL) 96 : 97 : struct __attribute__((packed)) fd_vm_rust_account_meta { 98 : uchar pubkey[32]; 99 : uchar is_signer; 100 : uchar is_writable; 101 : }; 102 : 103 : typedef struct fd_vm_rust_account_meta fd_vm_rust_account_meta_t; 104 : 105 : #define FD_VM_RUST_ACCOUNT_INFO_ALIGN (8UL) 106 0 : #define FD_VM_RUST_ACCOUNT_INFO_SIZE (48UL) 107 : 108 : struct __attribute__((packed)) fd_vm_rust_account_info { 109 : ulong pubkey_addr; /* points to uchar[32] */ 110 : ulong lamports_box_addr; /* points to Rc with embedded RefCell which points to u64 */ 111 : ulong data_box_addr; /* points to Rc with embedded RefCell which contains slice which points to bytes */ 112 : ulong owner_addr; /* points to uchar[32] */ 113 : ulong rent_epoch; 114 : uchar is_signer; 115 : uchar is_writable; 116 : uchar executable; 117 : uchar _padding_0[5]; 118 : }; 119 : 120 : typedef struct fd_vm_rust_account_info fd_vm_rust_account_info_t; 121 : 122 : /* These define the in-memory layout of Rc<Refcell<T>> types to 123 : facilitate checks on Rust AccountInfo fields. 124 : */ 125 : 126 : #define FD_VM_RC_REFCELL_ALIGN (8UL) 127 : 128 : struct __attribute__((packed)) fd_vm_rc_refcell { 129 : ulong strong; /* Rc */ 130 : ulong weak; /* Rc */ 131 : ulong borrow; /* RefCell */ 132 : ulong payload[]; /* Underlying data */ 133 : }; 134 : typedef struct fd_vm_rc_refcell fd_vm_rc_refcell_t; 135 : 136 : struct __attribute__((packed)) fd_vm_rc_refcell_vec { 137 : ulong strong; /* Rc */ 138 : ulong weak; /* Rc */ 139 : ulong borrow; /* RefCell */ 140 : ulong addr; /* Slice */ 141 : ulong len; /* Slice */ 142 : }; 143 : typedef struct fd_vm_rc_refcell_vec fd_vm_rc_refcell_vec_t; 144 : 145 : FD_STATIC_ASSERT( sizeof(fd_vm_rc_refcell_t)+sizeof(fd_vm_vec_t)==sizeof(fd_vm_rc_refcell_vec_t), sizeof_fd_vm_rc_refcell_vec_t ); 146 : 147 : struct __attribute__((packed)) fd_vm_rc_refcell_ref { 148 : ulong strong; /* Rc */ 149 : ulong weak; /* Rc */ 150 : ulong borrow; /* RefCell */ 151 : ulong addr; /* Ref */ 152 : }; 153 : typedef struct fd_vm_rc_refcell_ref fd_vm_rc_refcell_ref_t; 154 : 155 : /* https://github.com/anza-xyz/agave/blob/v2.1.6/programs/bpf_loader/src/syscalls/cpi.rs#L81 156 : 157 : This struct abstracts over the Rust/C ABI differences for the 158 : cross-program-invocation (CPI) syscall. 159 : It serves the same purpose as the corresponding struct in Agave. 160 : Essentially, it caches the results of translations that have been 161 : performed leading up to the CPI. 162 : Or, in the case of direct mapping, it sometimes stores the vm 163 : virtual addresses for translation later on. 164 : In direct mapping, translation is sometimes delayed because 165 : "permissions on the realloc region can change during CPI". 166 : */ 167 : struct fd_vm_cpi_caller_account { 168 : ulong * lamports; 169 : fd_pubkey_t * owner; 170 : ulong orig_data_len; 171 : uchar * serialized_data; /* NULL if direct mapping */ 172 : ulong serialized_data_len; 173 : ulong vm_data_vaddr; 174 : union { 175 : ulong * translated; /* Set if direct mapping false */ 176 : ulong vaddr; /* Set if direct mapping */ 177 : } ref_to_len_in_vm; 178 : }; 179 : typedef struct fd_vm_cpi_caller_account fd_vm_cpi_caller_account_t; 180 : 181 : #endif /* HEADER_fd_src_flamenco_vm_syscall_fd_vm_cpi_h */