LCOV - code coverage report
Current view: top level - flamenco/vm/syscall - fd_vm_syscall.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 41 43 95.3 %
Date: 2026-10-22 18:10:43 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_flamenco_vm_syscall_fd_vm_syscall_h
       2             : #define HEADER_fd_src_flamenco_vm_syscall_fd_vm_syscall_h
       3             : 
       4             : #include "../fd_vm_private.h"
       5             : #include "fd_vm_syscall_macros.h"
       6             : #include "fd_vm_cpi.h"                /* FIXME: REFINE THIS MORE */
       7             : #include "../../runtime/fd_runtime.h" /* FIXME: REFINE THIS MORE */
       8             : #include "../../runtime/context/fd_exec_instr_ctx.h"
       9             : #include "../../log_collector/fd_log_collector.h"
      10             : 
      11             : #define FD_VM_RETURN_DATA_MAX  (1024UL) /* FIXME: DOCUMENT AND DOES THIS BELONG HERE? */
      12             : 
      13             : /* The maximum number of seeds a PDA can have
      14             :    https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L21 */
      15             : #define FD_VM_PDA_SEEDS_MAX    (16UL)
      16             : /* The maximum length of a PDA seed
      17             :    https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L19 */
      18             : #define FD_VM_PDA_SEED_MEM_MAX (32UL)
      19             : 
      20             : /* PYTHON3 CODE FOR COMPUTING THE SYSCALL MURMUR3 HASH (e.g. sol_get_epoch_stake):
      21             :   ```
      22             :   import mmh3
      23             :   import ctypes
      24             : 
      25             :   def compute_murmur3_hash(input_string):
      26             :       # Compute the Murmur3 hash of the input string
      27             :       hash_value = mmh3.hash(input_string)
      28             :       # Convert the hash value to a 32-bit unsigned integer
      29             :       u32_hash_value = ctypes.c_uint32(hash_value).value
      30             :       return u32_hash_value
      31             : 
      32             :   input_string = b"sol_get_epoch_stake"
      33             :   hash_value = compute_murmur3_hash(input_string)
      34             :   print(f"The Murmur3 hash of '{input_string}' as u32 is: {hex(hash_value)}")
      35             : 
      36             :   Output:
      37             :   The Murmur3 hash of 'b'sol_get_epoch_stake'' as u32 is: 0x5be92f4a
      38             :   ```
      39             : */
      40             : 
      41             : /* https://github.com/solana-labs/solana/blob/2afde1b028ed4593da5b6c735729d8994c4bfac6/sdk/program/src/pubkey.rs#L22 */
      42             : 
      43             : /* FIXME: CONSIDER NOT PREFIXING SYSCALLS WITH SOL_? (OR MAYBE THIS
      44             :    IS NECESSARY TO DISAMBIGUATE SOLANA SYSCALLS FROM NON-SOLANA?
      45             :    SYSCALLS? */
      46             : 
      47             : /* FD_VM_SYSCALL_DECL declares a prototype of a syscall.  When a
      48             :    syscall implementation is called, the syscall will see a precise
      49             :    reporting VM's state at time of the syscall.  Notably:
      50             : 
      51             :    - vm->pc will be at the syscall instruction
      52             :    - vm->ic will include the syscall instruction
      53             :    - vm->cu will include the 1 cu cost of the syscall instruction.
      54             :      Further, it will be positive.
      55             : 
      56             :    r1,r2,r3,r4,r5 are the values in r1,r2,r3,r4,r5 at time of the
      57             :    syscall.
      58             : 
      59             :    When a syscall implementation returns FD_VM_SUCCESS, vm->reg[0] holds
      60             :    the application return value.
      61             : 
      62             :    When an syscall implementation returns FD_VM_SYSCALL_ERR*, the
      63             :    syscall is considered to have faulted the VM.  It ideally should not
      64             :    have set vm->reg[0] (or changed any vm state, except vm->cu, though
      65             :    that often isn't practical, and not critical to consensus).
      66             : 
      67             :    It is the syscall's responsibility to deduct from vm->cu its specific
      68             :    cost model (not including the syscall instruction itself).  As such,
      69             :    when a syscall returns COMPUTE_BUDGET_EXCEEDED, it should have set
      70             :    vm->cu to zero. When it returns anything else, it should have set cu
      71             :    to something in [0,cu_at_function_entry] (upper bound inclusive,
      72             :    despite most syscalls deducing base CUs first thing, some don't,
      73             :    e.g., sol_sha256).
      74             : 
      75             :    To mitigate risks of from syscall implementations that do not
      76             :    strictly enforce this and other similar risks that can affect
      77             :    bookkeeping, on return from a syscall, the VM will:
      78             : 
      79             :    - Ignore updates to pc, ic and frame_cnt.
      80             :    - Ignore updates to cu that increase it.
      81             :    - Treat updates to cu that zero it as SIGCOST.
      82             :    - Treat SIGCOST returns that didn't update cu to zero as zeroing it.
      83             : 
      84             :    FIXME: ADD NO SETTING OF R0 ON VM_ERR IN VM_INTERP. */
      85             : 
      86             : #define FD_VM_SYSCALL_DECL(name)   \
      87             : int                                \
      88             : fd_vm_syscall_##name( void *  _vm, \
      89             :                       ulong   r1,  \
      90             :                       ulong   r2,  \
      91             :                       ulong   r3,  \
      92             :                       ulong   r4,  \
      93             :                       ulong   r5 )
      94             : 
      95             : FD_PROTOTYPES_BEGIN
      96             : 
      97             : /* fd_vm_syscall_util *************************************************/
      98             : 
      99             : /* syscall(b6fc1a11) "abort"
     100             :    Abort program execution and fail transaction.
     101             : 
     102             :    Inputs:
     103             : 
     104             :      r1 - ignored
     105             :      r2 - ignored
     106             :      r3 - ignored
     107             :      r4 - ignored
     108             :      r5 - ignored
     109             : 
     110             :    Return:
     111             : 
     112             :      FD_VM_SYSCALL_ERR_ABORT: vm->reg[0] unchanged.  vm->cu unchanged.
     113             : 
     114             :    FIXME: SHOULD THIS BE NAMED "SOL_ABORT"? */
     115             : 
     116             : FD_VM_SYSCALL_DECL( abort );
     117             : 
     118             : /* syscall(686093bb) "sol_panic_"
     119             :    Log panic message, abort program execution, and fail transaction.
     120             : 
     121             :    Inputs:
     122             : 
     123             :      r1 - msg, byte VM pointer, indexed [0,msg_sz), msg doesn't have to
     124             :      be \0 terminated and can contain \0 within,
     125             :      r2 - msg_sz, may be 0,
     126             :      r3 - ignored
     127             :      r4 - ignored
     128             :      r5 - ignored
     129             : 
     130             :    Return:
     131             : 
     132             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     133             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     134             : 
     135             :      FD_VM_SYSCALL_ERR_INVALID_STRING: Bad filepath string, msg is not
     136             :      a valid sequence of utf8 bytes.  vm->reg[0] unchanged and vm->cu>=0.
     137             : 
     138             :      FD_VM_SYSCALL_ERR_PANIC: vm->reg[0] unchanged.  vm->cu
     139             :      decremented and vm->cu>=0. */
     140             : 
     141             : FD_VM_SYSCALL_DECL( sol_panic );
     142             : 
     143             : /* syscall(207559bd) "sol_log_"
     144             :    Write message encoded as (msg, msg_sz) to log, prefixed with
     145             :    "Program log: ".
     146             : 
     147             :    Inputs:
     148             : 
     149             :      r1 - msg, byte VM pointer, indexed [0,msg_sz),
     150             :      r2 - msg_sz, may be 0,
     151             :      r3 - ignored
     152             :      r4 - ignored
     153             :      r5 - ignored
     154             : 
     155             :    Return:
     156             : 
     157             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     158             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     159             : 
     160             :      FD_VM_SYSCALL_ERR_INVALID_STRING: bad message string.  vm->reg[0]
     161             :      unchanged. vm->cu decremented and vm->cu>=0.
     162             : 
     163             :      FD_VM_SUCCESS: success.  vm->reg[0]==0.  vm->cu decremented and
     164             :      vm->cu>=0.
     165             : 
     166             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     167             :      if there was not enough room for the message in the syscall log
     168             :      when called. */
     169             : 
     170             : FD_VM_SYSCALL_DECL( sol_log );
     171             : 
     172             : /* syscall(5c2a3178) "sol_log_64_"
     173             :    Write r1:5 to the log as a hexadecimal
     174             : 
     175             :    Inputs:
     176             : 
     177             :      r1 - ulong
     178             :      r2 - ulong
     179             :      r3 - ulong
     180             :      r4 - ulong
     181             :      r5 - ulong
     182             : 
     183             :    Return:
     184             : 
     185             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     186             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     187             : 
     188             :      FD_VM_SUCCESS: success.  vm->reg[0]=0.  vm->cu decremented and
     189             :      vm->cu>=0.
     190             : 
     191             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     192             :      if there was not enough room for the message in the syscall log
     193             :      when called. */
     194             : 
     195             : FD_VM_SYSCALL_DECL( sol_log_64 );
     196             : 
     197             : /* syscall(7ef088ca) "sol_log_pubkey"
     198             :    Write the base58 encoding of 32 byte array to the log.
     199             : 
     200             :    Inputs:
     201             : 
     202             :      r1 - pubkey, byte VM pointer, indexed [0,32)
     203             :      r2 - ignored
     204             :      r3 - ignored
     205             :      r4 - ignored
     206             :      r5 - ignored
     207             : 
     208             :    Return:
     209             : 
     210             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     211             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     212             : 
     213             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0] unchanged.
     214             :      vm->cu decremented and vm->cu>=0.
     215             : 
     216             :      FD_VM_SUCCESS: success.  vm->reg[0]==0.  vm->cu decremented and
     217             :      vm->cu>=0.
     218             : 
     219             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     220             :      if there was not enough room for the message in the syscall log
     221             :      when called. */
     222             : 
     223             : FD_VM_SYSCALL_DECL( sol_log_pubkey );
     224             : 
     225             : /* syscall(52ba5096) "sol_log_compute_units_"
     226             :    Write remaining compute unit count to log.
     227             : 
     228             :    Inputs:
     229             : 
     230             :      r1 - ignored
     231             :      r2 - ignored
     232             :      r3 - ignored
     233             :      r4 - ignored
     234             :      r5 - ignored
     235             : 
     236             :    Return:
     237             : 
     238             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     239             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     240             : 
     241             :      FD_VM_SUCCESS: success.  vm->reg[0]=0.  vm->cu decremented
     242             :      and vm->cu>=0.  The value logged will be the value of cu when
     243             :      between when the syscall completed and the next iteration starts
     244             :      and will be >=0.
     245             : 
     246             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     247             :      if there was not enough room for the message in the syscall log
     248             :      when called. */
     249             : 
     250             : FD_VM_SYSCALL_DECL( sol_log_compute_units );
     251             : 
     252             : /* syscall(7317b434) "sol_log_data"
     253             :    Write the base64 encoded cnt data slices to the log.
     254             : 
     255             :    Inputs:
     256             : 
     257             :      r1 - slice, ulong pair VM pointer, indexed [0,cnt),
     258             :      r2 - cnt, may be 0,
     259             :      r3 - ignored
     260             :      r4 - ignored
     261             :      r5 - ignored
     262             : 
     263             :      slice[i] holds the ulong pair:
     264             :        mem, byte VM pointer, indexed [0,sz),
     265             :        sz, may be 0
     266             : 
     267             :    Return:
     268             : 
     269             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     270             :      vm->reg[0] unchanged. vm->cu==0.
     271             : 
     272             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0] unchanged.  vm->cu
     273             :      decremented and vm->cu>0.
     274             : 
     275             :      FD_VM_SUCCESS: success.  vm->reg[0]=0.  vm->cu decremented and vm->cu>0.
     276             : 
     277             :      IMPORTANT SAFETY TIP!  The log message will be silently truncated
     278             :      if there was not enough room for the message in the syscall log
     279             :      when called. */
     280             : 
     281             : FD_VM_SYSCALL_DECL( sol_log_data );
     282             : 
     283             : /* syscall(83f00e8f) "sol_alloc_free_"
     284             :    DEPRECATED ... dynamic heap allocation support
     285             : 
     286             :    Inputs:
     287             : 
     288             :      r1 - sz, ignored if vaddr is not 0
     289             :      r2 - free_vaddr, byte VM pointer
     290             :      r3 - ignored
     291             :      r4 - ignored
     292             :      r5 - ignored
     293             : 
     294             :    Return:
     295             : 
     296             :      All cases return FD_VM_SUCCESS and leave vm->cu unchanged.
     297             : 
     298             :      If free_vaddr is 0, this is "malloc"-like:
     299             : 
     300             :        Let the VM heap region cover bytes [heap_start,heap_end) with
     301             :        heap_start<=heap_end.  If the request was satisfied, on return,
     302             :        vm->reg[0] will point to a range of heap bytes [vm->reg[0],vm->reg[0]+sz) that
     303             :        does not overlap with any other current allocation such that
     304             :        heap_start<=vm->reg[0]<=vm->reg[0]+sz<=heap_end.  This includes the zero sz
     305             :        case (note that the zero sz case might return the same value as a
     306             :        previous zero sz case and/or return the exact value of heap_end).
     307             : 
     308             :        If the request cannot be satisfied, vm->reg[0]=0 on return and the
     309             :        heap unchanged.
     310             : 
     311             :        IMPORTANT SAFETY TIP!  If the VM has check_align set, this
     312             :        location will have at least 8 byte alignment.  Otherwise, this
     313             :        location will have no particular alignment.  Note that this
     314             :        implies allocations done by this syscall do not conform to the
     315             :        usual alignment requirements of a standard malloc call for older
     316             :        VM code.
     317             : 
     318             :      If vaddr is not-zero, this is "free"-like.  Since the underlying
     319             :      implementation is necessarily a bump allocator (see implementation
     320             :      for more details), the specific value is ignored and vm->reg[0]=0 on
     321             :      return. */
     322             : 
     323             : FD_VM_SYSCALL_DECL( sol_alloc_free );
     324             : 
     325             : /* syscall(717cc4a3) "sol_memcpy_"
     326             :    Copy sz bytes from src to dst.  src and dst should not overlap.
     327             : 
     328             :    Inputs:
     329             : 
     330             :      r1 - dst, byte VM pointer, indexed [0,sz),
     331             :      r2 - src, byte VM pointer, indexed [0,sz),
     332             :      r3 - sz,
     333             :      r4 - ignored
     334             :      r5 - ignored
     335             : 
     336             :   Return:
     337             : 
     338             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     339             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     340             : 
     341             :      FD_VM_SYSCALL_ERR_COPY_OVERLAPPING: address ranges for src and dst
     342             :      overlap (either partially or fully).  Empty address ranges are
     343             :      considered to **never** overlap.  vm->reg[0]==0.  vm->cu decremented and
     344             :      vm->cu>=0.
     345             : 
     346             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0]==0.  vm->cu
     347             :      decremented and vm->cu>=0.
     348             : 
     349             :      FD_VM_SUCCESS: success.  vm->reg[0]==0.  vm->cu decremented and
     350             :      vm->cu>=0. On return, dst[i]==src[i] for i in [0,sz). */
     351             : 
     352             : FD_VM_SYSCALL_DECL( sol_memcpy );
     353             : 
     354             : /* syscall(5fdcde31) "sol_memcmp_"
     355             :    Compare sz bytes at m0 to m1
     356             : 
     357             :    Inputs:
     358             : 
     359             :      r1 - m0, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
     360             :      r2 - m1, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
     361             :      r3 - sz, FIXME: IS SZ 0 OKAY?
     362             :      r4 - out, int VM pointer
     363             :      r5 - ignored
     364             : 
     365             :   Return:
     366             : 
     367             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     368             :      vm->reg[0]==0. vm->cu==0.
     369             : 
     370             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range (including out not 4 byte
     371             :      aligned).  vm->reg[0]==0.  vm->cu decremented and vm->cu>0.
     372             :      Strict alignment is only required when the VM has check_align set.
     373             : 
     374             :      FD_VM_SUCCESS: success.  vm->reg[0]=0.  vm->cu decremented and vm->cu>0.
     375             :      On return, *_out will hold a positive / zero / negative number if
     376             :      the region at m0 lexicographically compares strictly greater than /
     377             :      equal to / strictly less than the region at m1 when treated as
     378             :      uchars.  Specifically, if the regions are different, *_out will be
     379             :      (int)m0[i] - (int)m1[i] where i is the first differing byte.
     380             : 
     381             :      IMPORTANT SAFETY TIP!  Note that, strangely, this returns the result
     382             :      in memory instead of via vm->reg[0] like a libc-style memcmp would. */
     383             : 
     384             : FD_VM_SYSCALL_DECL( sol_memcmp );
     385             : 
     386             : /* syscall(3770fb22) "sol_memset_"
     387             :    Set sz bytes at dst to the byte value c.
     388             : 
     389             :    Inputs:
     390             : 
     391             :      r1 - dst, byte VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
     392             :      r2 - c, bits [8,64) ignored (FIXME: CHECK SOLANA DOES THIS)
     393             :      r3 - sz, may be 0,
     394             :      r4 - ignored
     395             :      r5 - ignored
     396             : 
     397             :   Return:
     398             : 
     399             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     400             :      vm->reg[0]==0. vm->cu==0.
     401             : 
     402             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0]==0.  vm->cu
     403             :      decremented and vm->cu>0.
     404             : 
     405             :      FD_VM_SUCCESS: success.  vm->reg[0]=0.  vm->cu decremented and vm->cu>0.
     406             :      On return, dst[i]==(uchar)(c & 255UL) for i in [0,sz). */
     407             : 
     408             : FD_VM_SYSCALL_DECL( sol_memset );
     409             : 
     410             : /* syscall(434371f8) "sol_memmove_"
     411             :    Copy sz bytes from src to dst.  src and dst can overlap.
     412             : 
     413             :    Inputs:
     414             : 
     415             :      r1 - dst, byte VM pointer, indexed [0,sz),
     416             :      r2 - src, byte VM pointer, indexed [0,sz),
     417             :      r3 - sz, may be 0,
     418             :      r4 - ignored
     419             :      r5 - ignored
     420             : 
     421             :   Return:
     422             : 
     423             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     424             :      vm->reg[0] unchanged. vm->cu==0.
     425             : 
     426             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0]==0.  vm->cu
     427             :      decremented and vm->cu>0.
     428             : 
     429             :      FD_VM_SUCCESS: success.  vm->reg[0]=0.  vm->cu decremented and vm->cu>0.
     430             :      On return, dst[i]==src_as_it_was_before_the_call[i] for i in
     431             :      [0,sz). */
     432             : 
     433             : FD_VM_SYSCALL_DECL( sol_memmove );
     434             : 
     435             : /* fd_vm_syscall_runtime **********************************************/
     436             : 
     437             : /* syscall(d56b5fe9) "sol_get_clock_sysvar"
     438             :    syscall(23a29a61) "sol_get_epoch_schedule_sysvar"
     439             :    syscall(bf7188f6) "sol_get_rent_sysvar"
     440             :    syscall(188a0031) "sol_get_last_restart_slot"
     441             :    Get various sysvar values
     442             : 
     443             :    Inputs:
     444             : 
     445             :      r1 - out, {clock,schedule,fees,rent,last_restart_slot} VM pointer
     446             :      r2 - ignored
     447             :      r3 - ignored
     448             :      r4 - ignored
     449             :      r5 - ignored
     450             : 
     451             :    Return:
     452             : 
     453             :      FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the
     454             :      Solana runtime.  vm->reg[0] unchanged.  vm->cu unchanged.
     455             : 
     456             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     457             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     458             : 
     459             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0] unchanged.
     460             :      vm->cu decremented and vm->cu>=0.  out should have:
     461             :                           | align | sz
     462             :        clock              |     8 | 40
     463             :        schedule           |     8 | 40
     464             :        rent               |     8 | 24
     465             :        last restart slot  |     8 | 8
     466             :      Strict alignment is only required when the VM has check_align set.
     467             : 
     468             :      FD_VM_SUCCESS: success.  vm->reg[0]=0.  vm->cu decremented and vm->cu>0.
     469             :      On return, *out will hold the value of the appropriate sysvar. */
     470             : 
     471             : FD_VM_SYSCALL_DECL( sol_get_clock_sysvar             );
     472             : FD_VM_SYSCALL_DECL( sol_get_epoch_schedule_sysvar    );
     473             : FD_VM_SYSCALL_DECL( sol_get_rent_sysvar              );
     474             : FD_VM_SYSCALL_DECL( sol_get_last_restart_slot_sysvar );
     475             : FD_VM_SYSCALL_DECL( sol_get_epoch_rewards_sysvar     );
     476             : 
     477             : /* syscall(13c1b505) "sol_get_sysvar"
     478             : 
     479             :    Get a slice of a sysvar account's data.
     480             : 
     481             :    Inputs:
     482             : 
     483             :      r1 - sysvar_id_vaddr, sysvar pubkey VM pointer
     484             :      r2 - out_vaddr, byte VM pointer
     485             :      r3 - offset, ulong
     486             :      r4 - sz, num bytes to store
     487             :      r5 - ignored
     488             : 
     489             :    Return:
     490             : 
     491             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     492             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     493             : 
     494             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad sysvar_id_vaddr, bad out_vaddr,
     495             :      requested slice outside of sysvar data buffer.  vm->reg[0] unchanged.
     496             :      vm->cu decremented and vm->cu>=0.
     497             : 
     498             :      FD_VM_SYSCALL_ERR_ABORT: offset+sz overflow.  vm->reg[0] unchanged.
     499             :      vm->cu decremented and vm->cu>=0.
     500             : 
     501             :      FD_VM_SUCCESS: success. vm->cu decremented and vm->cu>=0.
     502             :       - vm->reg[0] = 2 if sysvar id is not in {clock,schedule,rewards,rent,
     503             :                   slot hashes,stake history, last restart slot}
     504             :                   OR sysvar account does not exist.
     505             :       - vm->reg[0] = 1 if [offset,offset+sz) is outside of sysvar data
     506             :                   buffer.
     507             :       - vm->reg[0] = 0 if success.
     508             : 
     509             :      On return, sz bytes of appropriate offset sysvar data will be
     510             :      copied into haddr belonging to out_vaddr. */
     511             : FD_VM_SYSCALL_DECL( sol_get_sysvar );
     512             : 
     513             : /* syscall(5be92f4a) "sol_get_epoch_stake"
     514             : 
     515             :    This syscall is meant to return the latest frozen stakes at an epoch
     516             :    boundary.  So for instance, when we are executing in epoch 7, this
     517             :    should return the stakes at the end of epoch 6.  Note that this is
     518             :    also the stakes that determined the leader schedule for the upcoming
     519             :    epoch, namely epoch 8.
     520             : 
     521             :    Inputs:
     522             : 
     523             :      r1 - var_addr, vote pubkey VM pointer, or zero to get the total
     524             :           active stake on the cluster.
     525             :      r2 - ignored
     526             :      r3 - ignored
     527             :      r4 - ignored
     528             :      r5 - ignored
     529             : 
     530             :    Return:
     531             : 
     532             :      FD_VM_ERR_SIGCOST: insufficient compute budget.  vm->reg[0] unchanged.
     533             :      vm->cu==0.
     534             : 
     535             :      FD_VM_ERR_SIGSEGV: bad var_addr.  vm->reg[0] unchanged.  vm->cu
     536             :      decremented and vm->cu>=0.
     537             : 
     538             :      FD_VM_ERR_ABORT: offset+sz overflow.  vm->reg[0] unchanged.
     539             : 
     540             :      FD_VM_SUCCESS: success. vm->cu decremented and vm->cu>=0.
     541             :       If var_addr == 0, vm->reg[0] is the total active stake on the
     542             :       cluster.  Else, it is the vote account's delegated stake if
     543             :       var_addr is an existing vote account, and 0 otherwise. */
     544             : 
     545             : FD_VM_SYSCALL_DECL( sol_get_epoch_stake );
     546             : 
     547             : /* syscall(85532d94) "sol_get_stack_height"
     548             : 
     549             :    Inputs:
     550             : 
     551             :      r1 - ignored
     552             :      r2 - ignored
     553             :      r3 - ignored
     554             :      r4 - ignored
     555             :      r5 - ignored
     556             : 
     557             :    Return:
     558             : 
     559             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     560             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     561             : 
     562             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0] unchanged.
     563             :      vm->cu decremented and vm->cu>=0.
     564             : 
     565             :      FD_VM_SUCCESS: success.  vm->reg[0]==stack_height.  vm->cu decremented
     566             :      and vm->cu>=0. */
     567             : 
     568             : FD_VM_SYSCALL_DECL( sol_get_stack_height );
     569             : 
     570             : /* syscall(5d2245e4) "sol_get_return_data"
     571             :    Get the return data and program id associated with it.
     572             : 
     573             :    Inputs:
     574             : 
     575             :      r1 - dst, byte VM pointer, indexed [0,dst_max),
     576             :      r2 - dst_max, may be 0,
     577             :      r3 - program_id, byte VM pointer, indexed [0,32)
     578             :      r4 - ignored
     579             :      r5 - ignored
     580             : 
     581             :    Return:
     582             : 
     583             :      FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within
     584             :      the Solana runtime.  vm->reg[0] unchanged.  vm->cu unchanged.
     585             : 
     586             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     587             :      budget.  vm->reg[0] unchanged. vm->cu==0.
     588             : 
     589             :      FD_VM_SYSCALL_ERR_COPY_OVERLAPPING: dst and program_id address
     590             :      ranges overlap.  vm->reg[0] unchanged.   vm->cu decremented and
     591             :      vm->cu>=0.
     592             : 
     593             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for dst and/or
     594             :      program_id. vm->reg[0] unchanged.  Compute budget decremented.
     595             : 
     596             :      FD_VM_SUCCESS: success.  vm->reg[0]=return_data_sz.  vm->cu decremented
     597             :      and vm->cu>=0.  On return, if dst_max was non-zero, dst holds the
     598             :      leading min(return_data_sz,dst_max) bytes of return data (as such,
     599             :      if return_data_sz>dst_max, the value returned in the buffer was
     600             :      truncated).  Any trailing bytes of dst are unchanged.  program_id
     601             :      holds the program_id associated with the return data.
     602             : 
     603             :      If dst_max was zero, dst and program_id are untouched. */
     604             : 
     605             : FD_VM_SYSCALL_DECL( sol_get_return_data );
     606             : 
     607             : /* syscall(a226d3eb) "sol_set_return_data"
     608             :    Set the return data.  The return data will be associated with the
     609             :    caller's program ID.
     610             : 
     611             :    Inputs:
     612             : 
     613             :      r1 - src, byte VM pointer, indexed [0,src_sz),
     614             :      r2 - src_sz, may be 0,
     615             :      r3 - ignored
     616             :      r4 - ignored
     617             :      r5 - ignored
     618             : 
     619             :    Return:
     620             :      FD_VM_SYSCALL_ERR_OUTSIDE_RUNTIME: the VM is not running within the
     621             :      Solana runtime.  vm->reg[0] unchanged.  vm->cu unchanged.
     622             : 
     623             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     624             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     625             : 
     626             :      FD_VM_SYSCALL_ERR_RETURN_DATA_TOO_LARGE: src_sz too large.  vm->reg[0]
     627             :      unchanged.  vm->cu decremented and vm->cu>0.
     628             : 
     629             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for src.  vm->reg[0] unchanged.
     630             :      vm->cu decremented and vm->cu>=0.
     631             : 
     632             :      FD_VM_SUCCESS: success.  vm->reg[0]=0.  vm->cu decremented and vm->cu>0. */
     633             : 
     634             : FD_VM_SYSCALL_DECL( sol_set_return_data );
     635             : 
     636             : /* syscall(adb8efc8) "sol_get_processed_sibling_instruction"
     637             :    Returns the last element from a reverse-ordered list of successfully
     638             :    processed sibling instructions: the "processed sibling instruction
     639             :    list".
     640             : 
     641             :    For example, given the call flow:
     642             :    A
     643             :    B -> C -> D
     644             :    B -> E
     645             :    B -> F      (current execution point)
     646             : 
     647             :    B's processed sibling instruction list is [A]
     648             :    F's processed sibling instruction list is [E, C]
     649             : 
     650             :    This allows the current instruction to know what the last processed
     651             :    sibling instruction was.  This is useful to check that critical
     652             :    preceding instructions have actually executed: for example, ensuring
     653             :    that an assert instruction has successfully executed.
     654             : 
     655             :    Inputs:
     656             : 
     657             :      r1 - index
     658             :      r2 - result_meta_vaddr, byte VM pointer of the object where
     659             :           metadata about the last processed sibling instruction will be
     660             :           stored upon successful execution (the length of the arrays in
     661             :           the result). Has the type
     662             :           solana_program::instruction::ProcessedSiblingInstruction
     663             :           https://github.com/anza-xyz/agave/blob/70089cce5119c9afaeb2986e2ecaa6d4505ec15d/sdk/program/src/instruction.rs#L672-L681
     664             :      r3 - result_program_id_vaddr, byte VM pointer where the pubkey of
     665             :           the program ID of the last processed sibling instruction will
     666             :           be stored upon successful execution
     667             :      r4 - result_data_vaddr, byte VM pointer where the instruction
     668             :           data of the last processed sibling instruction will be stored
     669             :           upon successful execution. The length of the data will be
     670             :           stored in ProcessedSiblingInstruction.data_len
     671             :      r5 - result_accounts_vaddr, byte VM pointer where an array of
     672             :           account meta structures will be stored into upon successful
     673             :           execution.  The length of the data will be stored in
     674             :           ProcessedSiblingInstruction.accounts_len.  Each account meta
     675             :           has the type solana_program::instruction::AccountMeta
     676             :           https://github.com/anza-xyz/agave/blob/70089cce5119c9afaeb2986e2ecaa6d4505ec15d/sdk/program/src/instruction.rs#L525-L548
     677             : 
     678             :     Return:
     679             : 
     680             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     681             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     682             : 
     683             :      FD_VM_SUCCESS: vm->reg[0]==1 if the instruction was found and, vm->reg[0]==0
     684             :      otherwise.  vm->cu decremented and vm->cu>=0. */
     685             : 
     686             : 
     687             : FD_VM_SYSCALL_DECL( sol_get_processed_sibling_instruction );
     688             : 
     689             : /* fd_vm_syscall_pda **************************************************/
     690             : 
     691             : /* syscall(9377323c) "sol_create_program_address"
     692             : 
     693             :    Compute SHA-256 hash of &[&[u8]] .. <program ID> .. <PDA Marker>
     694             :    and check whether result is an Ed25519 curve point.
     695             : 
     696             :    Inputs:
     697             : 
     698             :      r1 - seeds, bytes VM pointer, indexed [0,seed_cnt),
     699             :      r2 - seed_cnt, may be 0,
     700             :      r3 - program_id, byte VM pointer, indexed [0,32), 8 byte aligned
     701             :      r4 - out, byte VM pointer, indexed [0,32), 8 byte aligned
     702             :      r5 - ignored
     703             : 
     704             :      seed[i] holds the ulong pair
     705             :        mem, byte VM pointer, indexed [0,sz),
     706             :        sz, may be 0
     707             : 
     708             :    Return:
     709             : 
     710             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     711             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     712             : 
     713             :      FD_VM_SYSCALL_ERR_BAD_SEEDS: seed_cnt and/or seed[i].sz too large,
     714             :      bad address range for program_id, seed,
     715             :      seed[i].mem and/or out (including 8-byte alignment for seed if the
     716             :      VM has check_align set). vm->reg[0] unchanged.  Compute budget
     717             :      decremented.
     718             : 
     719             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0] unchanged.
     720             :      vm->cu decremented and vm->cu>=0.
     721             : 
     722             :      FD_VM_SUCCESS: success.  If vm->reg[0]==0, a PDA was created and
     723             :      stored at out.  If vm->reg[0]==1, create failed and out was unchanged.
     724             :      Compute budget decremented. */
     725             : 
     726             : FD_VM_SYSCALL_DECL( sol_create_program_address );
     727             : 
     728             : /* syscall(48504a38) "sol_try_find_program_address"
     729             : 
     730             :    Repeatedly derive program address while incrementing nonce in seed
     731             :    list until a point is found that is not a valid Ed25519 curve point.
     732             : 
     733             :    Inputs:
     734             : 
     735             :      r1 - seed, ulong pair VM pointer, indexed [0,seed_cnt),
     736             :      r2 - seed_cnt, may be 0,
     737             :      r3 - program_id, byte VM pointer, indexed [0,32), 8 byte aligned
     738             :      r4 - out, byte VM pointer, indexed [0,32), 8 byte aligned
     739             :      r5 - bump_seed, byte VM pointer, indexed [0,1)
     740             : 
     741             :      seed[i] holds the ulong pair
     742             :        mem, byte VM pointer, indexed [0,sz),
     743             :        sz, may be 0
     744             : 
     745             :    Return:
     746             : 
     747             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute
     748             :      budget.  vm->reg[0] unchanged.  vm->cu==0.
     749             : 
     750             :      FD_VM_SYSCALL_ERR_BAD_SEEDS: seed_cnt and/or seed[i].sz too large,
     751             :      bad address range for program_id, seed,
     752             :      seed[i].mem, out and/or bump_seed (including 8-byte alignment for
     753             :      seed if the VM has check_align set). vm->reg[0] unchanged.  Compute
     754             :      budget decremented.
     755             : 
     756             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range.  vm->reg[0] unchanged.
     757             :      vm->cu decremented and vm->cu>=0.
     758             : 
     759             :      FD_VM_SUCCESS: success.  If vm->reg[0]==0, a PDA was found and stored at
     760             :      out and the suffix stored at bump_seed.  If vm->reg[0]==1, no PDA was
     761             :      found and out and bump_seed were unchanged.  Compute budget
     762             :      decremented. */
     763             : 
     764             : FD_VM_SYSCALL_DECL( sol_try_find_program_address );
     765             : 
     766             : /* fd_vm_syscall_cpi **************************************************/
     767             : 
     768             : /* Prepare instruction method */
     769             : /* FIXME: DOES THIS GO HERE?  MAYBE GROUP WITH ADMIN OR OUTSIDE SYSCALL? */
     770             : 
     771             : int
     772             : fd_vm_prepare_instruction( fd_instr_info_t *        callee_instr,
     773             :                            fd_exec_instr_ctx_t *    instr_ctx,
     774             :                            fd_pubkey_t const *      callee_program_id_pubkey,
     775             :                            fd_pubkey_t const        instr_acct_keys[ FD_TXN_INSTR_ACCT_MAX ],
     776             :                            fd_instruction_account_t instruction_accounts[ FD_TXN_INSTR_ACCT_MAX ],
     777             :                            ulong *                  instruction_accounts_cnt,
     778             :                            fd_pubkey_t const *      signers,
     779             :                            ulong                    signers_cnt );
     780             : 
     781             : /* syscall(a22b9c85) "sol_invoke_signed_c"
     782             :    Dispatch a cross program invocation.  Inputs are in C ABI.
     783             : 
     784             :    FIXME: BELT SAND AND DOCUMENT */
     785             : 
     786             : FD_VM_SYSCALL_DECL( cpi_c );
     787             : 
     788             : /* syscall(d7449092) "sol_invoke_signed_rust"
     789             :    Dispatch a cross program invocation.  Inputs are in Rust ABI.
     790             : 
     791             :    FIXME: BELT SAND AND DOCUMENT */
     792             : 
     793             : FD_VM_SYSCALL_DECL( cpi_rust );
     794             : 
     795             : /* fd_vm_syscall_crypto ***********************************************/
     796             : 
     797             : /* FD_VM_SYSCALL_SOL_ALT_BN128_{ADD,SUB,MUL,PAIRING} specifies the curve operation. */
     798             : 
     799         310 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_ADD_BE           (  0UL) /* add */
     800             : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_SUB_BE           (  1UL) /* add inverse */
     801        7333 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_MUL_BE           (  2UL) /* scalar mult */
     802        2156 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_BE          (  3UL) /* pairing */
     803         187 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_ADD_BE           (  4UL) /* add */
     804             : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_SUB_BE           (  5UL) /* add inverse */
     805         153 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_MUL_BE           (  6UL) /* scalar mult */
     806       11422 : #define FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG  ( 0x80) /* little endian (SIMD-0284) */
     807         187 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_ADD_LE           ( FD_VM_SYSCALL_SOL_ALT_BN128_G1_ADD_BE  | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     808        3701 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_MUL_LE           ( FD_VM_SYSCALL_SOL_ALT_BN128_G1_MUL_BE  | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     809        1108 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_LE          ( FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     810         125 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_ADD_LE           ( FD_VM_SYSCALL_SOL_ALT_BN128_G2_ADD_BE  | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     811         105 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_MUL_LE           ( FD_VM_SYSCALL_SOL_ALT_BN128_G2_MUL_BE  | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     812             : 
     813             : /* FD_VM_SYSCALL_SOL_ALT_BN128_{...}COMPRESS specifies the (de)compress operation. */
     814             : 
     815        1019 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS_BE      (  0UL) /* compress point in G1 */
     816        1010 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS_BE    (  1UL) /* decompress point in G1 */
     817        1250 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS_BE      (  2UL) /* compress point in G2 */
     818        1282 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS_BE    (  3UL) /* decompress point in G2 */
     819         544 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS_LE      ( FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESS_BE   | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     820         537 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS_LE    ( FD_VM_SYSCALL_SOL_ALT_BN128_G1_DECOMPRESS_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     821         660 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS_LE      ( FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESS_BE   | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     822         669 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS_LE    ( FD_VM_SYSCALL_SOL_ALT_BN128_G2_DECOMPRESS_BE | FD_VM_SYSCALL_SOL_ALT_BN128_LITTLE_ENDIAN_FLAG )
     823             : 
     824             : /* FD_VM_SYSCALL_SOL_ALT_BN128_{...}_SZ specifies the size of inputs/outputs for the Alt_BN128 curve. */
     825             : 
     826        2213 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_SZ               ( 64UL) /* size of a point in G1 */
     827         275 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G1_COMPRESSED_SZ    ( 32UL) /* size of a compressed point in G2 */
     828         454 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_SZ               (128UL) /* size of a point in G2 */
     829         332 : #define FD_VM_SYSCALL_SOL_ALT_BN128_G2_COMPRESSED_SZ    ( 64UL) /* size of a compressed point in G2 */
     830         559 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_INPUT_EL_SZ (192UL) /* size of G1 + G2 */
     831        1118 : #define FD_VM_SYSCALL_SOL_ALT_BN128_PAIRING_OUTPUT_SZ   ( 32UL) /* size of pairing syscall result, i.e. 0 or 1 as 256-bit int ¯\_(ツ)_/¯ */
     832             : 
     833             : /* syscall(ae0c318b) sol_alt_bn128_group_op computes operations on the Alt_BN128 curve,
     834             :    including point addition in G1, scalar multiplication in G1, and pairing.
     835             :    See SIMD-0129.
     836             : 
     837             :    FIXME: DOCUMENT */
     838             : 
     839             : FD_VM_SYSCALL_DECL( sol_alt_bn128_group_op    );
     840             : 
     841             : /* syscall(334fd5ed) sol_alt_bn128_compression allows to compress or decompress points
     842             :    in G1 or G2 groups over the Alt_BN128 curve.
     843             :    See SIMD-0129.
     844             : 
     845             :    FIXME: DOCUMENT */
     846             : 
     847             : FD_VM_SYSCALL_DECL( sol_alt_bn128_compression );
     848             : 
     849             : /* syscall(d7793abb) "sol_keccak256"
     850             :    syscall(11f49d86) "sol_sha256"
     851             : 
     852             :    Inputs:
     853             : 
     854             :      arg0 - slice, ulong pair VM pointer, indexed [0,cnt), FIXME: WHEN IS NULL OKAY?
     855             :      arg1 - cnt, FIXME: IS 0 OKAY?
     856             :      arg2 - hash, byte VM pointer, indexed [0,32)
     857             :      arg3 - ignored
     858             :      arg4 - ignored
     859             : 
     860             :      slice[i] holds the ulong pair:
     861             :        mem, byte vector VM pointer, indexed [0,sz), FIXME: WHEN IS NULL OKAY?
     862             :        sz, FIXME: IS 0 OKAY?
     863             : 
     864             :    Return:
     865             : 
     866             :      FD_VM_ERR_INVAL: cnt too large.  vm->reg[0] unchanged.
     867             : 
     868             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     869             :      vm->reg[0] unchanged. Compute budget decremented.
     870             : 
     871             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for slice, hash and/or
     872             :      slice[i].addr (including slice not 8 byte aligned if the VM has
     873             :      check_align set).  vm->reg[0] unchanged.  Compute budget decremented.
     874             : 
     875             :      FD_VM_SUCCESS: success.  vm->reg[0]=0 and hash[i] holds the hash of the
     876             :      concatenation of the slices.  Compute budget decremented. */
     877             : 
     878             : FD_VM_SYSCALL_DECL( sol_keccak256 );
     879             : FD_VM_SYSCALL_DECL( sol_sha256    );
     880             : FD_VM_SYSCALL_DECL( sol_sha512    );
     881             : 
     882             : /* syscall(c4947c21) sol_poseidon computes the Poseidon hash on an array of input values.
     883             :    See SIMD-0129.
     884             : 
     885             :    FIXME: DOCUMENT */
     886             : 
     887             : #define FD_VM_SYSCALL_SOL_POSEIDON_MAX_VALS 12UL
     888             : 
     889             : FD_VM_SYSCALL_DECL( sol_poseidon ); /* Light protocol flavor */
     890             : 
     891             : /* syscall(17e40350) "sol_secp256k1_recover"
     892             : 
     893             :    FIXME: BELT SAND AND DOCUMENT */
     894             : 
     895             : FD_VM_SYSCALL_DECL( sol_secp256k1_recover );
     896             : 
     897             : /* syscall "sol_big_mod_exp" (SIMD-0529)
     898             : 
     899             :    result := (base ^ exponent) mod modulus, where all operands are
     900             :    little-endian and the modulus is odd and > 1.  r1 is a vaddr to a
     901             :    BigModExpParams record; r2 is a vaddr to the result buffer.  Gated
     902             :    behind the enable_big_mod_exp_syscall feature. */
     903             : 
     904             : FD_VM_SYSCALL_DECL( sol_big_mod_exp );
     905             : 
     906             : /* fd_vm_syscall_curve ************************************************/
     907             : 
     908             : /* FD_VM_SYSCALL_SOL_CURVE_CURVE25519_{...} specifies the curve ID */
     909             : 
     910         810 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_EDWARDS   ( 0UL        ) /* ed25519 */
     911         768 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_RISTRETTO ( 1UL        ) /* ristretto255 */
     912          65 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_BE         ( 4UL | 0x80 ) /* bls12-381 big endian */
     913         138 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_LE         ( 4UL        ) /* bls12-381 little endian */
     914         147 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_BE      ( 5UL | 0x80 ) /* bls12-381 G1 big endian */
     915         313 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_LE      ( 5UL        ) /* bls12-381 G1 little endian */
     916         145 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_BE      ( 6UL | 0x80 ) /* bls12-381 G2 big endian */
     917         319 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_LE      ( 6UL        ) /* bls12-381 G2 little endian */
     918             : 
     919             : /* FD_VM_SYSCALL_SOL_CURVE_{...} specifies the curve operation */
     920             : 
     921         194 : #define FD_VM_SYSCALL_SOL_CURVE_ADD                  ( 0UL) /* add */
     922         197 : #define FD_VM_SYSCALL_SOL_CURVE_SUB                  ( 1UL) /* add inverse */
     923         248 : #define FD_VM_SYSCALL_SOL_CURVE_MUL                  ( 2UL) /* scalar mul */
     924             : 
     925             : /* FD_VM_SYSCALL_SOL_CURVE_{...}_SZ specifies the size of inputs/outputs. */
     926             : 
     927         315 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_POINT_SZ           (32UL)   /* point (compressed) */
     928         315 : #define FD_VM_SYSCALL_SOL_CURVE_CURVE25519_SCALAR_SZ          (32UL)   /* scalar */
     929           0 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_COMPRESSED_SZ    (48UL)   /* G1 point (compressed) */
     930         518 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G1_POINT_SZ         (96UL)   /* G1 point (uncompressed) */
     931           0 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_COMPRESSED_SZ  (2*48UL)   /* G2 point (compressed) */
     932         514 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_G2_POINT_SZ       (2*96UL)   /* G2 point (uncompressed) */
     933          90 : #define FD_VM_SYSCALL_SOL_CURVE_BLS12_381_GT_ELE_SZ        (12*48UL)   /* GT element */
     934             : 
     935             : /* syscall(aa2607ca) sol_curve_validate_point
     936             : 
     937             :    Inputs:
     938             : 
     939             :      arg0 - curve_id
     940             :      arg1 - point_addr
     941             :      arg2 - ignored
     942             :      arg3 - ignored
     943             :      arg4 - ignored
     944             : 
     945             :    Return:
     946             : 
     947             :      FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id.
     948             : 
     949             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     950             :      vm->reg[0] unchanged. Compute budget decremented.
     951             : 
     952             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for point_addr
     953             :      vm->reg[0] unchanged.  Compute budget decremented.
     954             : 
     955             :      FD_VM_SUCCESS: success.  vm->reg[0]=0 point is valid.
     956             :                               vm->reg[0]=1 point is invalid. */
     957             : 
     958             : FD_VM_SYSCALL_DECL( sol_curve_validate_point  );
     959             : 
     960             : /* syscall(dd1c41a6) sol_curve_group_op
     961             : 
     962             :    Inputs:
     963             : 
     964             :      arg0 - curve_id
     965             :      arg1 - group_op
     966             :      arg2 - left_input_addr
     967             :      arg3 - right_input_addr
     968             :      arg4 - result_point_addr
     969             : 
     970             :    Return:
     971             : 
     972             :      FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id/group_op.
     973             : 
     974             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
     975             :      vm->reg[0] unchanged. Compute budget decremented.
     976             : 
     977             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for left_input_addr,
     978             :      right_input_addr or result_point_addr.
     979             :      vm->reg[0] unchanged.  Compute budget decremented.
     980             : 
     981             :      FD_VM_SUCCESS: success.  vm->reg[0]=0 success, result written at result_point_addr.
     982             :                               vm->reg[0]=1 input validation failed, memory at
     983             :                                       result_point_addr unchanged. */
     984             : 
     985             : FD_VM_SYSCALL_DECL( sol_curve_group_op );
     986             : 
     987             : /* syscall(60a40880) sol_curve_multiscalar_mul
     988             : 
     989             :    Inputs:
     990             : 
     991             :      arg0 - curve_id
     992             :      arg1 - scalars_addr
     993             :      arg2 - points_addr
     994             :      arg3 - points_len
     995             :      arg4 - result_point_addr
     996             : 
     997             :    Return:
     998             : 
     999             :      FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id/group_op.
    1000             : 
    1001             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
    1002             :      vm->reg[0] unchanged. Compute budget decremented.
    1003             : 
    1004             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for scalars_addr or
    1005             :      points_addr.
    1006             :      vm->reg[0] unchanged.  Compute budget decremented.
    1007             : 
    1008             :      FD_VM_SUCCESS: success.  vm->reg[0]=0 success, result written at result_point_addr.
    1009             :                               vm->reg[0]=1 input validation failed, memory at
    1010             :                                       result_point_addr unchanged. */
    1011             : 
    1012             : FD_VM_SYSCALL_DECL( sol_curve_multiscalar_mul );
    1013             : 
    1014             : /* syscall(80c98b0) sol_curve_decompress
    1015             : 
    1016             :    Inputs:
    1017             : 
    1018             :      arg0 - curve_id
    1019             :      arg1 - point_addr, compressed BLS12-381 point selected by curve_id
    1020             :      arg2 - result_addr, uncompressed BLS12-381 point
    1021             :      arg3 - ignored
    1022             :      arg4 - ignored
    1023             : 
    1024             :    Return:
    1025             : 
    1026             :      FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id/group_op.
    1027             : 
    1028             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
    1029             :      vm->reg[0] unchanged. Compute budget decremented.
    1030             : 
    1031             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for point_addr or
    1032             :      result_addr.
    1033             :      vm->reg[0] unchanged.  Compute budget decremented.
    1034             : 
    1035             :      FD_VM_SUCCESS: success.  vm->reg[0]=0 success, result written at result_addr.
    1036             :                               vm->reg[0]=1 input validation failed, memory at
    1037             :                                       result_addr unchanged. */
    1038             : 
    1039             : FD_VM_SYSCALL_DECL( sol_curve_decompress );
    1040             : 
    1041             : /* syscall(f111a47e) sol_curve_pairing_map
    1042             : 
    1043             :    Inputs:
    1044             : 
    1045             :      arg0 - curve_id
    1046             :      arg1 - num_pairs
    1047             :      arg2 - g1_points_addr
    1048             :      arg3 - g2_points_addr
    1049             :      arg4 - result_addr
    1050             : 
    1051             :    Return:
    1052             : 
    1053             :      FD_VM_SYSCALL_ERR_INVALID_ATTRIBUTE: invalid curve_id/group_op.
    1054             : 
    1055             :      FD_VM_SYSCALL_ERR_COMPUTE_BUDGET_EXCEEDED: insufficient compute budget.
    1056             :      vm->reg[0] unchanged. Compute budget decremented.
    1057             : 
    1058             :      FD_VM_SYSCALL_ERR_SEGFAULT: bad address range for g1_points_addr,
    1059             :      g2_points_addr or result_addr.
    1060             :      vm->reg[0] unchanged.  Compute budget decremented.
    1061             : 
    1062             :      FD_VM_SUCCESS: success.  vm->reg[0]=0 success, result written at result_addr.
    1063             :                               vm->reg[0]=1 input validation failed, memory at
    1064             :                                       result_addr unchanged. */
    1065             : 
    1066             : FD_VM_SYSCALL_DECL( sol_curve_pairing_map );
    1067             : 
    1068             : int
    1069             : fd_vm_derive_pda( fd_vm_t *           vm,
    1070             :                   fd_pubkey_t const * program_id,
    1071             :                   void const * *      seed_haddrs,
    1072             :                   ulong *             seed_szs,
    1073             :                   ulong               seeds_cnt,
    1074             :                   uchar *             bump_seed,
    1075             :                   fd_pubkey_t *       out );
    1076             : 
    1077             : int
    1078             : fd_vm_translate_and_check_program_address_inputs( fd_vm_t *             vm,
    1079             :                                                   ulong                 seeds_vaddr,
    1080             :                                                   ulong                 seeds_cnt,
    1081             :                                                   ulong                 program_id_vaddr,
    1082             :                                                   void const * *        out_seed_haddrs,
    1083             :                                                   ulong *               out_seed_szs,
    1084             :                                                   fd_pubkey_t const * * out_program_id,
    1085             :                                                   uchar                 is_syscall );
    1086             : FD_PROTOTYPES_END
    1087             : 
    1088             : #endif /* HEADER_src_flamenco_vm_syscall_fd_vm_syscall_h */

Generated by: LCOV version 1.14