aboutsummaryrefslogtreecommitdiffstats
path: root/vm
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-11-05 01:18:57 +0800
committerobscuren <geffobscura@gmail.com>2014-11-05 01:18:57 +0800
commit1b1fa049fa483b3996d3582ad247638045657282 (patch)
tree3a43f6baa5e990410c60df46fcfe5cbcb2e7c894 /vm
parent8cfbf1836d68c49242703e3f59e4d0a06754c02b (diff)
downloaddexon-1b1fa049fa483b3996d3582ad247638045657282.tar
dexon-1b1fa049fa483b3996d3582ad247638045657282.tar.gz
dexon-1b1fa049fa483b3996d3582ad247638045657282.tar.bz2
dexon-1b1fa049fa483b3996d3582ad247638045657282.tar.lz
dexon-1b1fa049fa483b3996d3582ad247638045657282.tar.xz
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.go33
-rw-r--r--vm/vm_debug.go37
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
}