Skip to content

Commit

Permalink
simd-0166: sbpf dynamic stack frames
Browse files Browse the repository at this point in the history
  • Loading branch information
0x0ece committed Nov 27, 2024
1 parent 767eafb commit 513e325
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 11 deletions.
22 changes: 17 additions & 5 deletions src/flamenco/vm/fd_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,22 @@ fd_vm_validate( fd_vm_t const * vm ) {
case FD_INVALID: default: return FD_VM_ERR_INVALID_OPCODE;
}

if( FD_UNLIKELY( instr.src_reg>10 ) ) return FD_VM_ERR_INVALID_SRC_REG; /* FIXME: MAGIC NUMBER */

int is_invalid_dst_reg = instr.dst_reg > ((validation_code == FD_CHECK_ST) ? 10 : 9); /* FIXME: MAGIC NUMBER */
if( FD_UNLIKELY( is_invalid_dst_reg ) ) return FD_VM_ERR_INVALID_DST_REG;
/* Check registers
https://github.com/solana-labs/rbpf/blob/v0.8.5/src/verifier.rs#L177 */

/* Source register */
if( FD_UNLIKELY( instr.src_reg>10 ) ) return FD_VM_ERR_INVALID_SRC_REG;

/* Special R11 register */
if( instr.dst_reg==11U
&& FD_VM_SBPF_DYNAMIC_STACK_FRAMES( sbpf_version )
&& instr.opcode.raw == 0x07
&& ( instr.imm % FD_VM_SBPF_DYNAMIC_STACK_FRAMES_ALIGN )==0 )
continue;

/* Destination register. */
if( FD_UNLIKELY( instr.dst_reg==10U && validation_code != FD_CHECK_ST ) ) return FD_VM_ERR_INVALID_DST_REG;
if( FD_UNLIKELY( instr.dst_reg > 10U ) ) return FD_VM_ERR_INVALID_DST_REG;
}

return FD_VM_SUCCESS;
Expand Down Expand Up @@ -603,7 +615,7 @@ fd_vm_setup_state_for_execution( fd_vm_t * vm ) {
/* FIXME: Zero out shadow, stack and heap here? */
fd_memset( vm->reg, 0, FD_VM_REG_MAX * sizeof(ulong) );
vm->reg[ 1] = FD_VM_MEM_MAP_INPUT_REGION_START;
vm->reg[10] = FD_VM_MEM_MAP_STACK_REGION_START + 0x1000;
vm->reg[11] = vm->reg[10] = FD_VM_MEM_MAP_STACK_REGION_START + 0x1000;

/* Set execution state */
vm->pc = vm->entry_pc;
Expand Down
4 changes: 2 additions & 2 deletions src/flamenco/vm/fd_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ typedef struct fd_vm fd_vm_t;
/* A fd_vm_shadow_t holds stack frame information not accessible from
within a program. */

struct fd_vm_shadow { ulong r6; ulong r7; ulong r8; ulong r9; ulong pc; };
struct fd_vm_shadow { ulong r6; ulong r7; ulong r8; ulong r9; ulong r10; ulong pc; };
typedef struct fd_vm_shadow fd_vm_shadow_t;

/* fd_vm_input_region_t holds information about fragmented memory regions
Expand Down Expand Up @@ -220,7 +220,7 @@ FD_PROTOTYPES_BEGIN
integer power of 2. FOOTPRINT is a multiple of align.
These are provided to facilitate compile time declarations. */
#define FD_VM_ALIGN FD_VM_HOST_REGION_ALIGN
#define FD_VM_FOOTPRINT (527296UL)
#define FD_VM_FOOTPRINT (527808UL)

/* fd_vm_{align,footprint} give the needed alignment and footprint
of a memory region suitable to hold an fd_vm_t.
Expand Down
9 changes: 6 additions & 3 deletions src/flamenco/vm/fd_vm_interp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,11 @@
shadow[ frame_cnt ].r7 = reg[7]; \
shadow[ frame_cnt ].r8 = reg[8]; \
shadow[ frame_cnt ].r9 = reg[9]; \
shadow[ frame_cnt ].r10= reg[10]; \
shadow[ frame_cnt ].pc = pc; \
if( FD_UNLIKELY( ++frame_cnt>=frame_max ) ) goto sigstack; /* Note: untaken branches don't consume BTB */ \
reg[10] += vm->stack_frame_size
if( !FD_VM_SBPF_DYNAMIC_STACK_FRAMES( sbpf_version ) ) reg[11] += vm->stack_frame_size; \
reg[10] = reg[11];

/* We subtract the heap cost in the BPF loader */

Expand Down Expand Up @@ -801,7 +803,7 @@

FD_VM_INTERP_STACK_PUSH;

ulong vaddr = reg[ src ];
ulong vaddr = reg_src;
ulong region = vaddr >> 32;
ulong align = vaddr & 7UL;
pc = ((vaddr & FD_VM_OFFSET_MASK)/8UL) - text_word_off;
Expand Down Expand Up @@ -872,8 +874,9 @@
reg[7] = shadow[ frame_cnt ].r7;
reg[8] = shadow[ frame_cnt ].r8;
reg[9] = shadow[ frame_cnt ].r9;
reg[10] = shadow[ frame_cnt ].r10;
pc = shadow[ frame_cnt ].pc;
reg[10] -= vm->stack_frame_size;
if( !FD_VM_SBPF_DYNAMIC_STACK_FRAMES( sbpf_version ) ) reg[11] -= vm->stack_frame_size;
FD_VM_INTERP_BRANCH_END;

FD_VM_INTERP_INSTR_BEGIN(0x96) /* FD_SBPF_OP_LMUL64_IMM */
Expand Down
2 changes: 2 additions & 0 deletions src/flamenco/vm/fd_vm_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ typedef struct fd_vm_vec fd_vm_vec_t;
#define FD_VM_SBPF_REJECT_RODATA_STACK_OVERLAP(v) ( v >= FD_SBPF_V3 )
#define FD_VM_SBPF_ENABLE_ELF_VADDR(v) ( v >= FD_SBPF_V3 )

#define FD_VM_SBPF_DYNAMIC_STACK_FRAMES_ALIGN (64U)

#define FD_VM_OFFSET_MASK (0xffffffffUL)

FD_PROTOTYPES_BEGIN
Expand Down
5 changes: 4 additions & 1 deletion src/flamenco/vm/instr_test/v2/int_math.instr
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ $ op=07 dst=4 src=8 off=5a5a r4= 7ffffffff imm=ffffffff : ok r4= 7f
$ op=07 dst=5 src=7 off=5a5a r5= 80000000 imm=80000000 : ok r5= 0 # zero
$ op=07 dst=6 src=6 off=5a5a r6= 0 imm=80000000 : ok r6=ffffffff80000000 # subtract, underflow
$ op=07 dst=9 src=a off=0000 r9= 0 imm= 0 : ok r9= 0 # zero
$ op=07 dst=b src=0 off=0000 r11= 40 imm= 3 : ok vfy # unaligned dynamic stack frame - SIMD-0166
$ op=07 dst=b src=0 off=0000 r11= 40 imm= 0 : ok r11= 40 # dynamic stack frame - SIMD-0166
$ op=07 dst=b src=0 off=0000 r11= 40 imm= 40 : ok r11= 80 # dynamic stack frame - SIMD-0166
$ op=07 dst=b src=0 off=0000 r11= 40 imm=ffffffc0 : ok r11= 0 # dynamic stack frame - SIMD-0166
$ op=07 dst=9 src=b : vfy # invalid src
$ op=07 dst=a src=1 : vfy # invalid dst
$ op=07 dst=b src=1 : vfy # invalid dst

# add64 reg, reg
$ op=0f dst=0 src=0 off=a5a5 r0= 101010101010101 : ok r0= 202020202020202 # src==dst
Expand Down

0 comments on commit 513e325

Please sign in to comment.