Documentation

Solanalib.SBPF.Interpreter

SBPF.Interpreter — the small-step sBPF semantics #

The operational semantics of the Solana eBPF interpreter, ported from Interpreter.thy: the per-class evaluators (evalAlu32/64, evalPqr*, evalJmp, evalLoad/Store, the call/exit frame machinery), the single-step function step, and the fuel-bounded driver bpfInterp.

Registers are raw U64; signed behaviour is expressed with BitVec's signed operations (sdiv/srem/slt/sshiftRight) and sign-extension, faithful to the source theory. Note the sBPF-specific quirk (Challenge 1 of the paper): the 32-bit ADD/SUB/MUL results are sign-extended into the 64-bit register, whereas the logical/shift results are zero-extended.

Main definitions #

Operand evaluation #

The second operand as a 32-bit value: immediate verbatim, or the low 32 bits of the source register (eval_snd_op_{i,u}32 — same bits either way).

Equations
Instances For

    The second operand as a 64-bit value: a sign-extended immediate, or the source register verbatim (eval_snd_op_{i,u}64 — same bits either way).

    Equations
    Instances For

      ALU #

      def Solanalib.SBPF.evalAlu32 (bop : Binop) (dst : BpfIReg) (sop : SndOp) (rs : RegMap) (isV1 : Bool) :

      32-bit ALU (eval_alu32). Add/sub/mul sign-extend the 32-bit result; the rest zero-extend. mul/div/mod are v1-only.

      Equations
      Instances For
        def Solanalib.SBPF.evalAlu64 (bop : Binop) (dst : BpfIReg) (sop : SndOp) (rs : RegMap) (isV1 : Bool) :

        64-bit ALU (eval_alu64). mul/div/mod are v1-only; the shift amount is masked to 6 bits.

        Equations
        Instances For

          Add a (sign-extended) immediate to the stack pointer (eval_add64_imm_R10). v2-only.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For

            32-bit negate (eval_neg32). v1-only.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For

              64-bit negate (eval_neg64). v1-only.

              Equations
              Instances For
                def Solanalib.SBPF.evalLe (dst : BpfIReg) (imm : U32) (rs : RegMap) (isV1 : Bool) :

                Little-endian byte swap / truncation (eval_le). v1-only.

                Equations
                • One or more equations did not get rendered due to their size.
                Instances For
                  def Solanalib.SBPF.evalBe (dst : BpfIReg) (imm : U32) (rs : RegMap) (isV1 : Bool) :

                  Big-endian byte swap (eval_be): reverse the bytes before reassembly. v1-only.

                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For
                    def Solanalib.SBPF.evalHor64 (dst : BpfIReg) (imm : U32) (rs : RegMap) (isV1 : Bool) :

                    OR a high-order 32-bit immediate into the top half of dst (eval_hor64). v2-only.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For

                      PQR (product / quotient / remainder) #

                      A division/remainder guard: zero divisor faults as nok for an immediate operand (verifier should reject) and okn for a register operand.

                      Equations
                      Instances For
                        def Solanalib.SBPF.evalPqr32 (pop : Pqrop) (dst : BpfIReg) (sop : SndOp) (rs : RegMap) (isV1 : Bool) :

                        32-bit PQR (eval_pqr32). v2-only.

                        Equations
                        • One or more equations did not get rendered due to their size.
                        Instances For
                          def Solanalib.SBPF.evalPqr64 (pop : Pqrop) (dst : BpfIReg) (sop : SndOp) (rs : RegMap) (isV1 : Bool) :

                          64-bit PQR (eval_pqr64). v2-only.

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For
                            def Solanalib.SBPF.evalPqr64_2 (pop : Pqrop2) (dst : BpfIReg) (sop : SndOp) (rs : RegMap) (isV1 : Bool) :

                            High-half multiply (eval_pqr64_2). v2-only.

                            The standard high-multiply semantics: widen both operands to 128 bits (zero- extend for uhmul, sign-extend for shmul), multiply, and take the high 64 bits. (Interpreter.thy's eval_pqr64_2 appears to mis-source its signed operand from dst; we implement the intended semantics and let differential testing against the reference VM adjudicate.)

                            Equations
                            • One or more equations did not get rendered due to their size.
                            Instances For

                              Memory #

                              def Solanalib.SBPF.evalStore (chk : MemoryChunk) (dst : BpfIReg) (sop : SndOp) (off : U16) (rs : RegMap) (m : Mem) :

                              Store the second operand at dst + off (eval_store).

                              Equations
                              Instances For
                                def Solanalib.SBPF.evalLoad (chk : MemoryChunk) (dst src : BpfIReg) (off : U16) (rs : RegMap) (m : Mem) :

                                Load from src + off into dst, zero-extending narrow loads (eval_load).

                                Equations
                                • One or more equations did not get rendered due to their size.
                                Instances For
                                  def Solanalib.SBPF.evalLoadImm (dst : BpfIReg) (imm1 imm2 : U32) (rs : RegMap) :

                                  Load a 64-bit immediate assembled from two halves (eval_load_imm).

                                  Equations
                                  Instances For

                                    Jump #

                                    Call / exit #

                                    def Solanalib.SBPF.pushFrame (rs : RegMap) (ss : StackState) (isV1 : Bool) (pc : U64) (gaps : Bool) :

                                    Push a new call frame, saving BR6BR9 and the frame pointer (push_frame). Returns none (with rs unchanged) when the call stack is full.

                                    Equations
                                    • One or more equations did not get rendered due to their size.
                                    Instances For
                                      def Solanalib.SBPF.evalCallReg (src : BpfIReg) (imm : U32) (rs : RegMap) (ss : StackState) (isV1 : Bool) (pc : U64) (gaps : Bool) (programVmAddr : U64) :

                                      Call the function whose address is in a register (eval_callReg).

                                      Equations
                                      • One or more equations did not get rendered due to their size.
                                      Instances For
                                        def Solanalib.SBPF.evalCallImm (pc : U64) (src : BpfIReg) (imm : U32) (rs : RegMap) (ss : StackState) (isV1 : Bool) (fm : FuncMap) (gaps : Bool) :

                                        Call the function identified by an immediate, via the registry when the source register is BR0 (eval_callImm).

                                        Equations
                                        • One or more equations did not get rendered due to their size.
                                        Instances For

                                          The frame to return into (pop_frame).

                                          Equations
                                          Instances For

                                            Return from the current frame, restoring saved registers (eval_exit).

                                            Equations
                                            • One or more equations did not get rendered due to their size.
                                            Instances For

                                              Step #

                                              def Solanalib.SBPF.stepRegOutcome (o : RegOutcome) (pc : U64) (m : Mem) (ss : StackState) (sv : SBPFV) (fm : FuncMap) (curCu remainCu : U64) :

                                              Lift an ALU-style RegOutcome into the post-state of a pc + 1 step.

                                              Equations
                                              Instances For
                                                def Solanalib.SBPF.step (pc : U64) (ins : BpfInstruction) (rs : RegMap) (m : Mem) (ss : StackState) (sv : SBPFV) (fm : FuncMap) (gaps : Bool) (programVmAddr curCu remainCu : U64) :

                                                Execute a single instruction (step).

                                                Equations
                                                • One or more equations did not get rendered due to their size.
                                                Instances For

                                                  Run the program under a fuel bound (bpf_interp). Each step is gated on PC being in range and fuel remaining; exhaustion or an out-of-range PC yields a fault.

                                                  Equations
                                                  Instances For