mipsevm

package
v1.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2024 License: MIT, MIT Imports: 26 Imported by: 0

README

mipsevm

Supported 55 instructions:

Category Instruction Description
Arithmetic addi Add immediate (with sign-extension).
Arithmetic addiu Add immediate unsigned (no overflow).
Arithmetic addu Add unsigned (no overflow).
Logical and Bitwise AND.
Logical andi Bitwise AND immediate.
Branch b Unconditional branch.
Conditional Branch beq Branch on equal.
Conditional Branch beqz Branch if equal to zero.
Conditional Branch bgez Branch on greater than or equal to zero.
Conditional Branch bgtz Branch on greater than zero.
Conditional Branch blez Branch on less than or equal to zero.
Conditional Branch bltz Branch on less than zero.
Conditional Branch bne Branch on not equal.
Conditional Branch bnez Branch if not equal to zero.
Logical clz Count leading zeros.
Arithmetic divu Divide unsigned.
Unconditional Jump j Jump.
Unconditional Jump jal Jump and link.
Unconditional Jump jalr Jump and link register.
Unconditional Jump jr Jump register.
Data Transfer lb Load byte.
Data Transfer lbu Load byte unsigned.
Data Transfer lui Load upper immediate.
Data Transfer lw Load word.
Data Transfer lwr Load word right.
Data Transfer mfhi Move from HI register.
Data Transfer mflo Move from LO register.
Data Transfer move Move between registers.
Data Transfer movn Move conditional on not zero.
Data Transfer movz Move conditional on zero.
Data Transfer mtlo Move to LO register.
Arithmetic mul Multiply (to produce a word result).
Arithmetic multu Multiply unsigned.
Arithmetic negu Negate unsigned.
No Op nop No operation.
Logical not Bitwise NOT (pseudo-instruction in MIPS).
Logical or Bitwise OR.
Logical ori Bitwise OR immediate.
Data Transfer sb Store byte.
Logical sll Shift left logical.
Logical sllv Shift left logical variable.
Comparison slt Set on less than (signed).
Comparison slti Set on less than immediate.
Comparison sltiu Set on less than immediate unsigned.
Comparison sltu Set on less than unsigned.
Logical sra Shift right arithmetic.
Logical srl Shift right logical.
Logical srlv Shift right logical variable.
Arithmetic subu Subtract unsigned.
Data Transfer sw Store word.
Data Transfer swr Store word right.
Serialization sync Synchronize shared memory.
System Calls syscall System call.
Logical xor Bitwise XOR.
Logical xori Bitwise XOR immediate.

To run:

  1. Load a program into a state, e.g. using LoadELF.
  2. Patch the program if necessary: e.g. using PatchGo for Go programs, PatchStack for empty initial stack, etc.
  3. Implement the PreimageOracle interface
  4. Instrument the emulator with the state, and pre-image oracle, using NewInstrumentedState
  5. Step through the instrumented state with Step(proof), where proof==true if witness data should be generated. Steps are faster with proof==false.
  6. Optionally repeat the step on-chain by calling MIPS.sol and PreimageOracle.sol, using the above witness data.

Documentation

Index

Constants

View Source
const (
	MipsEBADF  = 0x9
	MipsEINVAL = 0x16
)
View Source
const (
	PageAddrSize = 12
	PageKeySize  = 32 - PageAddrSize
	PageSize     = 1 << PageAddrSize
	PageAddrMask = PageSize - 1
	MaxPageCount = 1 << PageKeySize
	PageKeyMask  = MaxPageCount - 1
)

Note: 2**12 = 4 KiB, the min phys page size in the Go runtime.

View Source
const (
	VMStatusValid      = 0
	VMStatusInvalid    = 1
	VMStatusPanic      = 2
	VMStatusUnfinished = 3
)

Variables

View Source
var StateWitnessSize = 226

StateWitnessSize is the size of the state witness encoding in bytes.

Functions

func HashPair

func HashPair(left, right [32]byte) [32]byte

func NewEVMEnv

func NewEVMEnv(contracts *Contracts, addrs *Addresses) (*vm.EVM, *state.StateDB)

func PatchGo

func PatchGo(f *elf.File, st *State) error

func PatchStack

func PatchStack(st *State) error

func SE

func SE(dat uint32, idx uint32) uint32

Types

type Addresses

type Addresses struct {
	MIPS         common.Address
	Oracle       common.Address
	Sender       common.Address
	FeeRecipient common.Address
}

type CachedPage

type CachedPage struct {
	Data *Page
	// intermediate nodes only
	Cache [PageSize / 32][32]byte
	// true if the intermediate node is valid
	Ok [PageSize / 32]bool
}

func (*CachedPage) Invalidate

func (p *CachedPage) Invalidate(pageAddr uint32)

func (*CachedPage) InvalidateFull

func (p *CachedPage) InvalidateFull()

func (*CachedPage) MerkleRoot

func (p *CachedPage) MerkleRoot() [32]byte

func (*CachedPage) MerkleizeSubtree

func (p *CachedPage) MerkleizeSubtree(gindex uint64) [32]byte

type Contract

type Contract struct {
	DeployedBytecode struct {
		Object    hexutil.Bytes `json:"object"`
		SourceMap string        `json:"sourceMap"`
	} `json:"deployedBytecode"`
}

type Contracts

type Contracts struct {
	MIPS   *Contract
	Oracle *Contract
}

func LoadContracts

func LoadContracts() (*Contracts, error)

LoadContracts loads the Cannon contracts, from op-bindings package

type HexU32

type HexU32 uint32

HexU32 to lazy-format integer attributes for logging

func (HexU32) MarshalText

func (v HexU32) MarshalText() ([]byte, error)

func (HexU32) String

func (v HexU32) String() string

type InstrumentedState

type InstrumentedState struct {
	// contains filtered or unexported fields
}

func NewInstrumentedState

func NewInstrumentedState(state *State, po PreimageOracle, stdOut, stdErr io.Writer) *InstrumentedState

func (*InstrumentedState) LastPreimage added in v1.5.1

func (m *InstrumentedState) LastPreimage() []byte

func (*InstrumentedState) Step

func (m *InstrumentedState) Step(proof bool) (wit *StepWitness, err error)

type LocalContext added in v1.4.2

type LocalContext common.Hash

type LoggingWriter

type LoggingWriter struct {
	Name string
	Log  log.Logger
}

LoggingWriter is a simple util to wrap a logger, and expose an io Writer interface, for the program running within the VM to write to.

func (*LoggingWriter) Write

func (lw *LoggingWriter) Write(b []byte) (int, error)

type Memory

type Memory struct {
	// contains filtered or unexported fields
}

func NewMemory

func NewMemory() *Memory

func (*Memory) AllocPage

func (m *Memory) AllocPage(pageIndex uint32) *CachedPage

func (*Memory) ForEachPage

func (m *Memory) ForEachPage(fn func(pageIndex uint32, page *Page) error) error

func (*Memory) GetMemory

func (m *Memory) GetMemory(addr uint32) uint32

func (*Memory) Invalidate

func (m *Memory) Invalidate(addr uint32)

func (*Memory) MarshalJSON

func (m *Memory) MarshalJSON() ([]byte, error)

func (*Memory) MerkleProof

func (m *Memory) MerkleProof(addr uint32) (out [28 * 32]byte)

func (*Memory) MerkleRoot

func (m *Memory) MerkleRoot() [32]byte

func (*Memory) MerkleizeSubtree

func (m *Memory) MerkleizeSubtree(gindex uint64) [32]byte

func (*Memory) PageCount

func (m *Memory) PageCount() int

func (*Memory) ReadMemoryRange

func (m *Memory) ReadMemoryRange(addr uint32, count uint32) io.Reader

func (*Memory) SetMemory

func (m *Memory) SetMemory(addr uint32, v uint32)

func (*Memory) SetMemoryRange

func (m *Memory) SetMemoryRange(addr uint32, r io.Reader) error

func (*Memory) UnmarshalJSON

func (m *Memory) UnmarshalJSON(data []byte) error

func (*Memory) Usage

func (m *Memory) Usage() string

type Metadata

type Metadata struct {
	Symbols []Symbol `json:"symbols"`
}

func MakeMetadata

func MakeMetadata(elfProgram *elf.File) (*Metadata, error)

func (*Metadata) LookupSymbol

func (m *Metadata) LookupSymbol(addr uint32) string

func (*Metadata) SymbolMatcher

func (m *Metadata) SymbolMatcher(name string) func(addr uint32) bool

type Page

type Page [PageSize]byte

func (*Page) MarshalJSON added in v1.1.6

func (p *Page) MarshalJSON() ([]byte, error)

func (*Page) UnmarshalJSON added in v1.1.6

func (p *Page) UnmarshalJSON(dat []byte) error

func (*Page) UnmarshalText

func (p *Page) UnmarshalText(dat []byte) error

type PreimageOracle

type PreimageOracle interface {
	Hint(v []byte)
	GetPreimage(k [32]byte) []byte
}

type State

type State struct {
	Memory *Memory `json:"memory"`

	PreimageKey    common.Hash `json:"preimageKey"`
	PreimageOffset uint32      `json:"preimageOffset"` // note that the offset includes the 8-byte length prefix

	PC     uint32 `json:"pc"`
	NextPC uint32 `json:"nextPC"`
	LO     uint32 `json:"lo"`
	HI     uint32 `json:"hi"`
	Heap   uint32 `json:"heap"` // to handle mmap growth

	ExitCode uint8 `json:"exit"`
	Exited   bool  `json:"exited"`

	Step uint64 `json:"step"`

	Registers [32]uint32 `json:"registers"`

	// LastHint is optional metadata, and not part of the VM state itself.
	// It is used to remember the last pre-image hint,
	// so a VM can start from any state without fetching prior pre-images,
	// and instead just repeat the last hint on setup,
	// to make sure pre-image requests can be served.
	// The first 4 bytes are a uin32 length prefix.
	// Warning: the hint MAY NOT BE COMPLETE. I.e. this is buffered,
	// and should only be read when len(LastHint) > 4 && uint32(LastHint[:4]) >= len(LastHint[4:])
	LastHint hexutil.Bytes `json:"lastHint,omitempty"`
}

func LoadELF

func LoadELF(f *elf.File) (*State, error)

func (*State) EncodeWitness

func (s *State) EncodeWitness() StateWitness

func (*State) GetStep added in v1.5.1

func (s *State) GetStep() uint64

func (*State) VMStatus added in v1.1.6

func (s *State) VMStatus() uint8

type StateWitness added in v1.1.6

type StateWitness []byte

func (StateWitness) StateHash added in v1.1.6

func (sw StateWitness) StateHash() (common.Hash, error)

type StepWitness

type StepWitness struct {
	// encoded state witness
	State []byte

	MemProof []byte

	PreimageKey    [32]byte // zeroed when no pre-image is accessed
	PreimageValue  []byte   // including the 8-byte length prefix
	PreimageOffset uint32
}

func (*StepWitness) HasPreimage

func (wit *StepWitness) HasPreimage() bool

type Symbol

type Symbol struct {
	Name  string `json:"name"`
	Start uint32 `json:"start"`
	Size  uint32 `json:"size"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL