Commit fab95d15 authored by protolambda's avatar protolambda

mipsevm: implement mips in Go, no unicorn required anymore

parent 2ab1eb7e
......@@ -170,13 +170,13 @@ func Run(ctx *cli.Context) error {
if err != nil {
return err
}
mu, err := mipsevm.NewUnicorn()
if err != nil {
return fmt.Errorf("failed to create unicorn emulator: %w", err)
}
if err := mipsevm.LoadUnicorn(state, mu); err != nil {
return fmt.Errorf("failed to load state into unicorn emulator: %w", err)
}
//mu, err := mipsevm.NewUnicorn()
//if err != nil {
// return fmt.Errorf("failed to create unicorn emulator: %w", err)
//}
//if err := mipsevm.LoadUnicorn(state, mu); err != nil {
// return fmt.Errorf("failed to load state into unicorn emulator: %w", err)
//}
l := Logger(os.Stderr, log.LvlInfo)
outLog := &mipsevm.LoggingWriter{Name: "program std-out", Log: l}
errLog := &mipsevm.LoggingWriter{Name: "program std-err", Log: l}
......@@ -207,14 +207,15 @@ func Run(ctx *cli.Context) error {
proofAt := ctx.Generic(RunProofAtFlag.Name).(*StepMatcherFlag).Matcher()
snapshotAt := ctx.Generic(RunSnapshotAtFlag.Name).(*StepMatcherFlag).Matcher()
us, err := mipsevm.NewUnicornState(mu, state, po, outLog, errLog)
if err != nil {
return fmt.Errorf("failed to setup instrumented VM state: %w", err)
}
//us, err := mipsevm.NewUnicornState(mu, state, po, outLog, errLog)
//if err != nil {
// return fmt.Errorf("failed to setup instrumented VM state: %w", err)
//}
us := mipsevm.NewNonUnicornState(state, po, outLog, errLog)
proofFmt := ctx.String(RunProofFmtFlag.Name)
snapshotFmt := ctx.String(RunSnapshotFmtFlag.Name)
stepFn := us.Step
stepFn := us.NonUnicornStep
if po.cmd != nil {
stepFn = Guard(po.cmd.ProcessState, stepFn)
}
......@@ -262,7 +263,7 @@ func Run(ctx *cli.Context) error {
return fmt.Errorf("failed to write proof data: %w", err)
}
} else {
_, err = us.Step(false)
_, err = stepFn(false)
if err != nil {
return fmt.Errorf("failed at step %d (PC: %08x): %w", step, state.PC, err)
}
......
......@@ -84,7 +84,7 @@ func TestEVM(t *testing.T) {
insn := state.Memory.GetMemory(state.PC)
t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn)
stepWitness, err := us.Step(true)
stepWitness, err := us.NonUnicornStep(true)
require.NoError(t, err)
input := stepWitness.EncodeStepInput()
startingGas := uint64(30_000_000)
......@@ -156,7 +156,7 @@ func TestHelloEVM(t *testing.T) {
t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn)
}
stepWitness, err := us.Step(true)
stepWitness, err := us.NonUnicornStep(true)
require.NoError(t, err)
input := stepWitness.EncodeStepInput()
startingGas := uint64(30_000_000)
......@@ -232,7 +232,7 @@ func TestClaimEVM(t *testing.T) {
t.Logf("step: %4d pc: 0x%08x insn: 0x%08x", state.Step, state.PC, insn)
}
stepWitness, err := us.Step(true)
stepWitness, err := us.NonUnicornStep(true)
require.NoError(t, err)
input := stepWitness.EncodeStepInput()
startingGas := uint64(30_000_000)
......
This diff is collapsed.
......@@ -74,7 +74,7 @@ func TestState(t *testing.T) {
if us.state.PC == endAddr {
break
}
_, err := us.Step(false)
_, err := us.NonUnicornStep(false)
require.NoError(t, err)
}
require.Equal(t, uint32(endAddr), us.state.PC, "must reach end")
......@@ -110,7 +110,7 @@ func TestHello(t *testing.T) {
if us.state.Exited {
break
}
_, err := us.Step(false)
_, err := us.NonUnicornStep(false)
require.NoError(t, err)
}
......@@ -217,7 +217,7 @@ func TestClaim(t *testing.T) {
if us.state.Exited {
break
}
_, err := us.Step(false)
_, err := us.NonUnicornStep(false)
require.NoError(t, err)
}
......
......@@ -55,6 +55,15 @@ const (
MipsEINVAL = 0x16
)
func NewNonUnicornState(state *State, po PreimageOracle, stdOut, stdErr io.Writer) *UnicornState {
return &UnicornState{
state: state,
stdOut: stdOut,
stdErr: stdErr,
preimageOracle: po,
}
}
func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, stdErr io.Writer) (*UnicornState, error) {
m := &UnicornState{
mu: mu,
......@@ -299,6 +308,34 @@ func NewUnicornState(mu uc.Unicorn, state *State, po PreimageOracle, stdOut, std
return m, nil
}
func (m *UnicornState) NonUnicornStep(proof bool) (wit *StepWitness, err error) {
m.memProofEnabled = proof
m.lastMemAccess = ^uint32(0)
m.lastPreimageOffset = ^uint32(0)
if proof {
insnProof := m.state.Memory.MerkleProof(m.state.PC)
wit = &StepWitness{
state: m.state.EncodeWitness(),
memProof: insnProof[:],
}
}
err = m.mipsStep()
if err != nil {
return nil, err
}
if proof {
wit.memProof = append(wit.memProof, m.memProof[:]...)
if m.lastPreimageOffset != ^uint32(0) {
wit.preimageOffset = m.lastPreimageOffset
wit.preimageKey = m.lastPreimageKey
wit.preimageValue = m.lastPreimage
}
}
return
}
func (m *UnicornState) Step(proof bool) (wit *StepWitness, err error) {
defer func() { // pre-image oracle or emulator hooks might panic
if a := recover(); a != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment