diff options
author | obscuren <geffobscura@gmail.com> | 2014-11-05 01:18:57 +0800 |
---|---|---|
committer | obscuren <geffobscura@gmail.com> | 2014-11-05 01:18:57 +0800 |
commit | 1b1fa049fa483b3996d3582ad247638045657282 (patch) | |
tree | 3a43f6baa5e990410c60df46fcfe5cbcb2e7c894 /vm | |
parent | 8cfbf1836d68c49242703e3f59e4d0a06754c02b (diff) | |
download | dexon-1b1fa049fa483b3996d3582ad247638045657282.tar.gz dexon-1b1fa049fa483b3996d3582ad247638045657282.tar.zst dexon-1b1fa049fa483b3996d3582ad247638045657282.zip |
Fixed VM and added static analysis for EVM jumps
Diffstat (limited to 'vm')
-rw-r--r-- | vm/types.go | 33 | ||||
-rw-r--r-- | vm/vm_debug.go | 37 |
2 files changed, 39 insertions, 31 deletions
diff --git a/vm/types.go b/vm/types.go index 580c517d6..7dd167e0c 100644 --- a/vm/types.go +++ b/vm/types.go @@ -173,22 +173,23 @@ const ( // Since the opcodes aren't all in order we can't use a regular slice var opCodeToString = map[OpCode]string{ // 0x0 range - arithmetic ops - STOP: "STOP", - ADD: "ADD", - MUL: "MUL", - SUB: "SUB", - DIV: "DIV", - SDIV: "SDIV", - MOD: "MOD", - SMOD: "SMOD", - EXP: "EXP", - NOT: "NOT", - LT: "LT", - GT: "GT", - SLT: "SLT", - SGT: "SGT", - EQ: "EQ", - ISZERO: "ISZERO", + STOP: "STOP", + ADD: "ADD", + MUL: "MUL", + SUB: "SUB", + DIV: "DIV", + SDIV: "SDIV", + MOD: "MOD", + SMOD: "SMOD", + EXP: "EXP", + NOT: "NOT", + LT: "LT", + GT: "GT", + SLT: "SLT", + SGT: "SGT", + EQ: "EQ", + ISZERO: "ISZERO", + SIGNEXTEND: "SIGNEXTEND", // 0x10 range - bit ops AND: "AND", diff --git a/vm/vm_debug.go b/vm/vm_debug.go index b53949493..df5d7e346 100644 --- a/vm/vm_debug.go +++ b/vm/vm_debug.go @@ -59,32 +59,34 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { var ( op OpCode - mem = &Memory{} - stack = NewStack() - pc = big.NewInt(0) - step = 0 - prevStep = 0 - statedb = self.env.State() - require = func(m int) { + destinations = analyseJumpDests(closure.Code) + mem = &Memory{} + stack = NewStack() + pc = big.NewInt(0) + step = 0 + prevStep = 0 + statedb = self.env.State() + require = func(m int) { if stack.Len() < m { panic(fmt.Sprintf("%04v (%v) stack err size = %d, required = %d", pc, op, stack.Len(), m)) } } - jump = func(pos *big.Int) { - p := int(pos.Int64()) + jump = func(from, to *big.Int) { + p := int(to.Int64()) - self.Printf(" ~> %v", pos) + self.Printf(" ~> %v", to) // Return to start if p == 0 { pc = big.NewInt(0) } else { - nop := OpCode(closure.GetOp(p - 1)) - if nop != JUMPDEST { + nop := OpCode(closure.GetOp(p)) + if !(nop == JUMPDEST || destinations[from.Int64()] != nil) { panic(fmt.Sprintf("JUMP missed JUMPDEST (%v) %v", nop, p)) } - pc = pos + pc = to + } self.Endl() @@ -406,6 +408,11 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { } else { num.And(num, mask) } + + num = U256(num) + + self.Printf(" = %v", num) + stack.Push(num) } case NOT: @@ -765,14 +772,14 @@ func (self *DebugVm) RunClosure(closure *Closure) (ret []byte, err error) { self.Printf(" {0x%x : 0x%x}", loc.Bytes(), val.Bytes()) case JUMP: - jump(stack.Pop()) + jump(pc, stack.Pop()) continue case JUMPI: cond, pos := stack.Popn() if cond.Cmp(ethutil.BigTrue) >= 0 { - jump(pos) + jump(pc, pos) continue } |