diff --git a/Makefile b/Makefile index aa4590e079ab..41057910a489 100644 --- a/Makefile +++ b/Makefile @@ -148,7 +148,7 @@ cannon-prestate: op-program cannon ## Generates prestate using cannon and op-pro .PHONY: cannon-prestate cannon-prestate-mt: op-program cannon ## Generates prestate using cannon and op-program in the multithreaded cannon format - ./cannon/bin/cannon load-elf --type cannon-mt --patch stack --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json + ./cannon/bin/cannon load-elf --type cannon-mt --path op-program/bin/op-program-client.elf --out op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json ./cannon/bin/cannon run --proof-at '=0' --stop-at '=1' --input op-program/bin/prestate-mt.bin.gz --meta op-program/bin/meta-mt.json --proof-fmt 'op-program/bin/%d-mt.json' --output "" mv op-program/bin/0-mt.json op-program/bin/prestate-proof-mt.json .PHONY: cannon-prestate diff --git a/cannon/cmd/load_elf.go b/cannon/cmd/load_elf.go index d155be385feb..a6b9e0e5897a 100644 --- a/cannon/cmd/load_elf.go +++ b/cannon/cmd/load_elf.go @@ -29,15 +29,9 @@ var ( TakesFile: true, Required: true, } - LoadELFPatchFlag = &cli.StringSliceFlag{ - Name: "patch", - Usage: "Type of patching to do", - Value: cli.NewStringSlice("go", "stack"), - Required: false, - } LoadELFOutFlag = &cli.PathFlag{ Name: "out", - Usage: "Output path to write JSON state to. State is dumped to stdout if set to -. Not written if empty.", + Usage: "Output path to write state to. State is dumped to stdout if set to '-'. Not written if empty. Use file extension '.bin', '.bin.gz', or '.json' for binary, compressed binary, or JSON formats.", Value: "state.json", Required: false, } @@ -67,16 +61,31 @@ func vmTypeFromString(ctx *cli.Context) (VMType, error) { } func LoadELF(ctx *cli.Context) error { + elfPath := ctx.Path(LoadELFPathFlag.Name) + elfProgram, err := elf.Open(elfPath) + if err != nil { + return fmt.Errorf("failed to open ELF file %q: %w", elfPath, err) + } + if elfProgram.Machine != elf.EM_MIPS { + return fmt.Errorf("ELF is not big-endian MIPS R3000, but got %q", elfProgram.Machine.String()) + } + var createInitialState func(f *elf.File) (mipsevm.FPVMState, error) - allowGoGCPatch := false + var patcher = program.PatchStack if vmType, err := vmTypeFromString(ctx); err != nil { return err } else if vmType == cannonVMType { - allowGoGCPatch = true createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, singlethreaded.CreateInitialState) } + patcher = func(state mipsevm.FPVMState) error { + err := program.PatchGoGC(elfProgram, state) + if err != nil { + return err + } + return program.PatchStack(state) + } } else if vmType == mtVMType { createInitialState = func(f *elf.File) (mipsevm.FPVMState, error) { return program.LoadELF(f, multithreaded.CreateInitialState) @@ -84,34 +93,14 @@ func LoadELF(ctx *cli.Context) error { } else { return fmt.Errorf("invalid VM type: %q", vmType) } - elfPath := ctx.Path(LoadELFPathFlag.Name) - elfProgram, err := elf.Open(elfPath) - if err != nil { - return fmt.Errorf("failed to open ELF file %q: %w", elfPath, err) - } - if elfProgram.Machine != elf.EM_MIPS { - return fmt.Errorf("ELF is not big-endian MIPS R3000, but got %q", elfProgram.Machine.String()) - } + state, err := createInitialState(elfProgram) if err != nil { return fmt.Errorf("failed to load ELF data into VM state: %w", err) } - for _, typ := range ctx.StringSlice(LoadELFPatchFlag.Name) { - switch typ { - case "stack": - err = program.PatchStack(state) - case "go": - if allowGoGCPatch { - err = program.PatchGoGC(elfProgram, state) - } else { - err = fmt.Errorf("patch type %q not allowed for vm type %q", typ, ctx.String(LoadELFVMTypeFlag.Name)) - } - default: - return fmt.Errorf("unrecognized form of patching: %q", typ) - } - if err != nil { - return fmt.Errorf("failed to apply patch %s: %w", typ, err) - } + err = patcher(state) + if err != nil { + return fmt.Errorf("failed to patch state: %w", err) } meta, err := program.MakeMetadata(elfProgram) if err != nil { @@ -131,13 +120,12 @@ func LoadELF(ctx *cli.Context) error { var LoadELFCommand = &cli.Command{ Name: "load-elf", - Usage: "Load ELF file into Cannon JSON state", - Description: "Load ELF file into Cannon JSON state, optionally patch out functions", + Usage: "Load ELF file into Cannon state", + Description: "Load ELF file into Cannon state", Action: LoadELF, Flags: []cli.Flag{ LoadELFVMTypeFlag, LoadELFPathFlag, - LoadELFPatchFlag, LoadELFOutFlag, LoadELFMetaFlag, },