Commit 2fe59f43 authored by George Hotz's avatar George Hotz

there's bugs in the mips

parent b0454fa2
...@@ -66,6 +66,7 @@ contract MIPS { ...@@ -66,6 +66,7 @@ contract MIPS {
return stepNextPC(stateHash, pc, pc+4); return stepNextPC(stateHash, pc, pc+4);
} }
// TODO: test ll and sc
function stepNextPC(bytes32 stateHash, uint32 pc, uint64 nextPC) public view returns (bytes32) { function stepNextPC(bytes32 stateHash, uint32 pc, uint64 nextPC) public view returns (bytes32) {
uint32 insn = m.ReadMemory(stateHash, pc); uint32 insn = m.ReadMemory(stateHash, pc);
uint32 opcode = insn >> 26; // 6-bits uint32 opcode = insn >> 26; // 6-bits
...@@ -194,6 +195,7 @@ contract MIPS { ...@@ -194,6 +195,7 @@ contract MIPS {
} }
} }
// write back // write back
if (storeAddr != REG_ZERO) { if (storeAddr != REG_ZERO) {
stateHash = m.WriteMemory(stateHash, storeAddr, val); stateHash = m.WriteMemory(stateHash, storeAddr, val);
...@@ -204,6 +206,11 @@ contract MIPS { ...@@ -204,6 +206,11 @@ contract MIPS {
} }
stateHash = m.WriteMemory(stateHash, REG_PC, uint32(nextPC)); stateHash = m.WriteMemory(stateHash, REG_PC, uint32(nextPC));
if (opcode == 0 && func == 0xC) {
revert("unhandled syscall");
}
return stateHash; return stateHash;
} }
...@@ -261,7 +268,7 @@ contract MIPS { ...@@ -261,7 +268,7 @@ contract MIPS {
uint32 val = mem << ((rs&3)*8); uint32 val = mem << ((rs&3)*8);
uint32 mask = uint32(0xFFFFFFFF) << ((rs&3)*8); uint32 mask = uint32(0xFFFFFFFF) << ((rs&3)*8);
return (rt & ~mask) | val; return (rt & ~mask) | val;
} else if (opcode == 0x23) { return mem; // lw } else if (opcode == 0x23 || opcode == 0x30) { return mem; // lw (or ll)
} else if (opcode == 0x24) { // lbu } else if (opcode == 0x24) { // lbu
return (mem >> (24-(rs&3)*8)) & 0xFF; return (mem >> (24-(rs&3)*8)) & 0xFF;
} else if (opcode == 0x25) { // lhu } else if (opcode == 0x25) { // lhu
...@@ -282,7 +289,7 @@ contract MIPS { ...@@ -282,7 +289,7 @@ contract MIPS {
uint32 val = rt >> ((rs&3)*8); uint32 val = rt >> ((rs&3)*8);
uint32 mask = uint32(0xFFFFFFFF) >> ((rs&3)*8); uint32 mask = uint32(0xFFFFFFFF) >> ((rs&3)*8);
return (mem & ~mask) | val; return (mem & ~mask) | val;
} else if (opcode == 0x2b) { // sw } else if (opcode == 0x2b || opcode == 0x38) { // sw (or sc, not right?)
return rt; return rt;
} else if (opcode == 0x2e) { // swr } else if (opcode == 0x2e) { // swr
uint32 val = rt << (24-(rs&3)*8); uint32 val = rt << (24-(rs&3)*8);
......
...@@ -94,6 +94,7 @@ type jsoncontract struct { ...@@ -94,6 +94,7 @@ type jsoncontract struct {
//var ram []byte //var ram []byte
//var regs [4096]byte //var regs [4096]byte
var pcCount int = 0
var debug int = 0 var debug int = 0
var ram map[uint64](uint32) var ram map[uint64](uint32)
...@@ -123,7 +124,8 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon ...@@ -123,7 +124,8 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
fmt.Println("HOOKED READ! ", fmt.Sprintf("%x = %x", addr, nret)) fmt.Println("HOOKED READ! ", fmt.Sprintf("%x = %x", addr, nret))
} }
if addr == 0xc0000080 && debug >= 1 { if addr == 0xc0000080 && debug >= 1 {
fmt.Printf("PC %x\n", nret) fmt.Printf("%7d: PC %x\n", pcCount, nret)
pcCount += 1
} }
scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret)
} else if args[0] == 184 { } else if args[0] == 184 {
...@@ -144,7 +146,40 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon ...@@ -144,7 +146,40 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
return common.Hash{}.Bytes(), nil return common.Hash{}.Bytes(), nil
} }
func runTest(fn string, steps int, interpreter *vm.EVMInterpreter, bytecode []byte) { func runMinigeth(fn string, interpreter *vm.EVMInterpreter, bytecode []byte) {
ram = make(map[uint64](uint32))
dat, _ := ioutil.ReadFile(fn)
for i := 0; i < len(dat); i += 4 {
ram[uint64(i)] = uint32(dat[i])<<24 |
uint32(dat[i+1])<<16 |
uint32(dat[i+2])<<8 |
uint32(dat[i+3])<<0
}
steps := 100000
gas := 10000 * uint64(steps)
// 0xdb7df598
from := common.Address{}
to := common.HexToAddress("0x1337")
input := []byte{0xdb, 0x7d, 0xf5, 0x98} // Steps(bytes32, uint256)
input = append(input, common.BigToHash(common.Big0).Bytes()...)
input = append(input, common.BigToHash(big.NewInt(int64(steps))).Bytes()...)
debug = 1
for i := 0; i < 1; i++ {
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, gas)
contract.SetCallCode(&to, crypto.Keccak256Hash(bytecode), bytecode)
_, err := interpreter.Run(contract, input, false)
fmt.Printf("step:%d pc:0x%x v0:%d ", i, ram[0xc0000080], ram[0xc0000008])
fmt.Println(err)
ram[0xc0000008] = 0
ram[0xc0000000+7*4] = 0
}
}
func runTest(fn string, steps int, interpreter *vm.EVMInterpreter, bytecode []byte, gas uint64) {
ram = make(map[uint64](uint32)) ram = make(map[uint64](uint32))
ram[0xC000007C] = 0xDEAD0000 ram[0xC000007C] = 0xDEAD0000
//fmt.Println("starting", fn) //fmt.Println("starting", fn)
...@@ -162,7 +197,7 @@ func runTest(fn string, steps int, interpreter *vm.EVMInterpreter, bytecode []by ...@@ -162,7 +197,7 @@ func runTest(fn string, steps int, interpreter *vm.EVMInterpreter, bytecode []by
input := []byte{0xdb, 0x7d, 0xf5, 0x98} // Steps(bytes32, uint256) input := []byte{0xdb, 0x7d, 0xf5, 0x98} // Steps(bytes32, uint256)
input = append(input, common.BigToHash(common.Big0).Bytes()...) input = append(input, common.BigToHash(common.Big0).Bytes()...)
input = append(input, common.BigToHash(big.NewInt(int64(steps))).Bytes()...) input = append(input, common.BigToHash(big.NewInt(int64(steps))).Bytes()...)
contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, 1000000) contract := vm.NewContract(vm.AccountRef(from), vm.AccountRef(to), common.Big0, gas)
//fmt.Println(bytecodehash, bytecode) //fmt.Println(bytecodehash, bytecode)
contract.SetCallCode(&to, crypto.Keccak256Hash(bytecode), bytecode) contract.SetCallCode(&to, crypto.Keccak256Hash(bytecode), bytecode)
...@@ -222,11 +257,13 @@ func main() { ...@@ -222,11 +257,13 @@ func main() {
if len(os.Args) > 1 { if len(os.Args) > 1 {
if os.Args[1] == "/tmp/minigeth.bin" { if os.Args[1] == "/tmp/minigeth.bin" {
debug = 1 /*debug = 1
runTest(os.Args[1], 20, interpreter, bytecode) steps := 1000000
runTest(os.Args[1], steps, interpreter, bytecode, uint64(steps)*10000)*/
runMinigeth(os.Args[1], interpreter, bytecode)
} else { } else {
debug = 2 debug = 2
runTest(os.Args[1], 20, interpreter, bytecode) runTest(os.Args[1], 20, interpreter, bytecode, 1000000)
} }
} else { } else {
files, err := ioutil.ReadDir("test/bin") files, err := ioutil.ReadDir("test/bin")
...@@ -234,7 +271,7 @@ func main() { ...@@ -234,7 +271,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
for _, f := range files { for _, f := range files {
runTest("test/bin/"+f.Name(), 100, interpreter, bytecode) runTest("test/bin/"+f.Name(), 100, interpreter, bytecode, 1000000)
} }
} }
......
...@@ -75,11 +75,14 @@ def start_instrumenting(): ...@@ -75,11 +75,14 @@ def start_instrumenting():
tfd = 10 tfd = 10
files = {} files = {}
fcnt = 0 fcnt = 0
step = 0
def hook_interrupt(uc, intno, user_data): def hook_interrupt(uc, intno, user_data):
global heap_start, fcnt, files, tfd global heap_start, fcnt, files, tfd, step
pc = uc.reg_read(UC_MIPS_REG_PC) pc = uc.reg_read(UC_MIPS_REG_PC)
if intno == 17: if intno == 17:
syscall_no = uc.reg_read(UC_MIPS_REG_V0) syscall_no = uc.reg_read(UC_MIPS_REG_V0)
#print("step:%d pc:%0x v0:%d" % (step, pc, syscall_no))
step += 1
uc.reg_write(UC_MIPS_REG_V0, 0) uc.reg_write(UC_MIPS_REG_V0, 0)
uc.reg_write(UC_MIPS_REG_A3, 0) uc.reg_write(UC_MIPS_REG_A3, 0)
......
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