Commit 3a195ba5 authored by George Hotz's avatar George Hotz

refactors

parent bd2ea5cb
__pycache__
go-ethereum go-ethereum
sysroot sysroot
test test
minigeth.bin
...@@ -8,3 +8,5 @@ cd ../mipigeth ...@@ -8,3 +8,5 @@ cd ../mipigeth
cp ../minigeth/go-ethereum go-ethereum cp ../minigeth/go-ethereum go-ethereum
file go-ethereum file go-ethereum
./compile.py
#!/bin/bash -e #!/bin/bash -e
echo "compiling" echo "compiling"
./build.sh ./build.sh
COMPILE=1 ./run.py
echo "running in go" echo "running in go"
export STEPS=100000 export STEPS=100000
$(cd ../mipsevm && DEBUG=1 ./evm.sh /tmp/minigeth.bin > /tmp/gethtrace) $(cd ../mipsevm && DEBUG=1 ./evm.sh ../mipigeth/minigeth.bin > /tmp/gethtrace)
echo "compare" echo "compare"
./simple.py ./simple.py
#!/usr/bin/env python3
import struct
from rangetree import RangeTree
from elftools.elf.elffile import ELFFile
from unicorn import *
from unicorn.mips_const import *
def load_minigeth(mu):
elf = open("go-ethereum", "rb")
data = elf.read()
elf.seek(0)
elffile = ELFFile(elf)
end_addr = 0
for seg in elffile.iter_segments():
end_addr = max(end_addr, seg.header.p_vaddr + seg.header.p_memsz)
# program memory (16 MB)
prog_size = (end_addr+0xFFF) & ~0xFFF
mu.mem_map(0, prog_size)
print("malloced 0x%x for program" % prog_size)
for seg in elffile.iter_segments():
print(seg.header, hex(seg.header.p_vaddr))
mu.mem_write(seg.header.p_vaddr, seg.data())
entry = elffile.header.e_entry
print("entrypoint: 0x%x" % entry)
# moved to MIPS
start = open("startup.bin", "rb").read() + struct.pack(">I", entry)
mu.mem_write(0, start)
entry = 0
r = RangeTree()
found = 0
for section in elffile.iter_sections():
try:
for nsym, symbol in enumerate(section.iter_symbols()):
ss = symbol['st_value']
se = ss+symbol['st_size']
if ss != se:
try:
r[ss:se] = symbol.name
except KeyError:
continue
#print(nsym, symbol.name, symbol['st_value'], symbol['st_size'])
if symbol.name == "runtime.gcenable":
print(nsym, symbol.name)
# nop gcenable
mu.mem_write(symbol['st_value'], b"\x03\xe0\x00\x08\x00\x00\x00\x00")
found += 1
if symbol.name == "github.com/ethereum/go-ethereum/oracle.Halt":
#00400000: 2004dead ; <input:0> li $a0, 57005
# 00400004: 00042400 ; <input:1> sll $a0, $a0, 16
# 00400008: 00800008 ; <input:2> jr $a0
mu.mem_write(symbol['st_value'], b"\x20\x04\xde\xad\x00\x04\x24\x00\x00\x80\x00\x08")
found += 1
except Exception:
#traceback.print_exc()
pass
assert(found == 2)
return prog_size, r
if __name__ == "__main__":
mu = Uc(UC_ARCH_MIPS, UC_MODE_32 + UC_MODE_BIG_ENDIAN)
prog_size, _ = load_minigeth(mu)
print("compiled %d bytes" % prog_size)
with open("minigeth.bin", "wb") as f:
f.write(mu.mem_read(0, prog_size))
\ No newline at end of file
...@@ -6,7 +6,6 @@ import struct ...@@ -6,7 +6,6 @@ import struct
import binascii import binascii
import traceback import traceback
from collections import defaultdict from collections import defaultdict
from elftools.elf.elffile import ELFFile
from capstone import * from capstone import *
md = Cs(CS_ARCH_MIPS, CS_MODE_32 + CS_MODE_BIG_ENDIAN) md = Cs(CS_ARCH_MIPS, CS_MODE_32 + CS_MODE_BIG_ENDIAN)
tracelevel = int(os.getenv("TRACE", 0)) tracelevel = int(os.getenv("TRACE", 0))
...@@ -17,6 +16,8 @@ from unicorn import * ...@@ -17,6 +16,8 @@ from unicorn import *
from unicorn.mips_const import * from unicorn.mips_const import *
from rangetree import RangeTree from rangetree import RangeTree
from compile import load_minigeth
mu = Uc(UC_ARCH_MIPS, UC_MODE_32 + UC_MODE_BIG_ENDIAN) mu = Uc(UC_ARCH_MIPS, UC_MODE_32 + UC_MODE_BIG_ENDIAN)
# memory trie # memory trie
...@@ -251,42 +252,6 @@ def hook_interrupt(uc, intno, user_data): ...@@ -251,42 +252,6 @@ def hook_interrupt(uc, intno, user_data):
raise unicorn.UcError(0) raise unicorn.UcError(0)
return True return True
cnt = 0
def hook_code(uc, address, size, user_data):
global cnt
cnt += 1
"""
dat = mu.mem_read(address, size)
if dat == "\x0c\x00\x00\x00" or dat == "\x00\x00\x00\x0c":
raise Exception("syscall")
"""
#if cnt == 2000:
# raise Exception("too many instructions")
try:
print(">>> Tracing instruction at 0x%x, instruction size = %u" % (address, size))
"""
jj = []
for i in range(16):
jj += "r%d: %x " % (i, uc.reg_read(i))
print(''.join(jj))
"""
#print(' code hook: pc=%08x sp=%08x' % (
# uc.reg_read(UC_MIPS_REG_PC),
# uc.reg_read(UC_MIPS_REG_SP)
# ))
except:
raise Exception("ctrl-c")
#elf = open("test", "rb")
elf = open("go-ethereum", "rb")
data = elf.read()
elf.seek(0)
#rte = data.find(b"\x08\x02\x2c\x95")
#print(hex(rte))
# heap (256 MB) @ 0x20000000 # heap (256 MB) @ 0x20000000
mu.mem_map(heap_start, 256*1024*1024) mu.mem_map(heap_start, 256*1024*1024)
...@@ -302,87 +267,7 @@ else: ...@@ -302,87 +267,7 @@ else:
inputs = open("/tmp/eth/13284469", "rb").read() inputs = open("/tmp/eth/13284469", "rb").read()
mu.mem_write(0x30000000, inputs) mu.mem_write(0x30000000, inputs)
# regs at 0xC0000000 in merkle _, r = load_minigeth(mu)
elffile = ELFFile(elf)
end_addr = 0
for seg in elffile.iter_segments():
end_addr = max(end_addr, seg.header.p_vaddr + seg.header.p_memsz)
# program memory (16 MB)
prog_size = (end_addr+0xFFF) & ~0xFFF
mu.mem_map(0, prog_size)
print("malloced 0x%x for program" % prog_size)
for seg in elffile.iter_segments():
print(seg.header, hex(seg.header.p_vaddr))
mu.mem_write(seg.header.p_vaddr, seg.data())
entry = elffile.header.e_entry
print("entrypoint: 0x%x" % entry)
#hexdump(mu.mem_read(entry, 0x10))
"""
mu.reg_write(UC_MIPS_REG_SP, stack_start-0x2000)
# http://articles.manugarg.com/aboutelfauxiliaryvectors.html
_AT_PAGESZ = 6
mu.mem_write(stack_start-0x2000, struct.pack(">IIIIII",
0, # argc
0, # argv
0, # envp
_AT_PAGESZ, 0x1000, 0)) # auxv
mu.mem_write(stack_start-0x400, b"GOGC=off\x00")
"""
# moved to MIPS
start = open("startup.bin", "rb").read() + struct.pack(">I", entry)
mu.mem_write(0, start)
entry = 0
r = RangeTree()
found = 0
for section in elffile.iter_sections():
try:
for nsym, symbol in enumerate(section.iter_symbols()):
ss = symbol['st_value']
se = ss+symbol['st_size']
if ss != se:
try:
r[ss:se] = symbol.name
except KeyError:
continue
#print(nsym, symbol.name, symbol['st_value'], symbol['st_size'])
if symbol.name == "runtime.gcenable":
print(nsym, symbol.name)
# nop gcenable
mu.mem_write(symbol['st_value'], b"\x03\xe0\x00\x08\x00\x00\x00\x00")
found += 1
"""
if symbol.name == "runtime.load_g":
# hardware?
mu.mem_write(symbol['st_value'], b"\x03\xe0\x00\x08\x00\x00\x00\x00")
found += 1
if symbol.name == "runtime.save_g":
# hardware?
mu.mem_write(symbol['st_value'], b"\x03\xe0\x00\x08\x00\x00\x00\x00")
found += 1
if symbol.name == "_cgo_sys_thread_start":
mu.mem_write(symbol['st_value'], b"\x03\xe0\x00\x08\x00\x00\x00\x00")
"""
if symbol.name == "github.com/ethereum/go-ethereum/oracle.Halt":
#00400000: 2004dead ; <input:0> li $a0, 57005
# 00400004: 00042400 ; <input:1> sll $a0, $a0, 16
# 00400008: 00800008 ; <input:2> jr $a0
mu.mem_write(symbol['st_value'], b"\x20\x04\xde\xad\x00\x04\x24\x00\x00\x80\x00\x08")
found += 1
except Exception:
#traceback.print_exc()
pass
assert(found == 2)
#mu.hook_add(UC_HOOK_BLOCK, hook_code, user_data=mu)
died_well = False died_well = False
...@@ -398,22 +283,12 @@ mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_inv ...@@ -398,22 +283,12 @@ mu.hook_add(UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, hook_mem_inv
mu.hook_add(UC_HOOK_MEM_FETCH_UNMAPPED, hook_mem_invalid) mu.hook_add(UC_HOOK_MEM_FETCH_UNMAPPED, hook_mem_invalid)
mu.hook_add(UC_HOOK_INTR, hook_interrupt) mu.hook_add(UC_HOOK_INTR, hook_interrupt)
#mu.hook_add(UC_HOOK_INSN, hook_interrupt, None, 1, 0, 0x0c000000)
if tracelevel >= 3: if tracelevel >= 3:
start_instrumenting() start_instrumenting()
with open("/tmp/minigeth.bin", "wb") as f:
f.write(mu.mem_read(0, prog_size))
if os.getenv("COMPILE", None) == "1":
exit(0)
# why do i need this?
#mu.mem_map(0xfffe0000, 0x20000)
try: try:
mu.emu_start(entry, -1) mu.emu_start(0, -1)
except unicorn.UcError: except unicorn.UcError:
pass pass
......
...@@ -69,7 +69,7 @@ def hook_interrupt(uc, intno, user_data): ...@@ -69,7 +69,7 @@ def hook_interrupt(uc, intno, user_data):
mu.hook_add(UC_HOOK_INTR, hook_interrupt) mu.hook_add(UC_HOOK_INTR, hook_interrupt)
# load memory # load memory
dat = open("/tmp/minigeth.bin", "rb").read() dat = open("minigeth.bin", "rb").read()
mu.mem_map(0, len(dat)) mu.mem_map(0, len(dat))
mu.mem_write(0, dat) mu.mem_write(0, dat)
......
...@@ -8,6 +8,8 @@ test: ...@@ -8,6 +8,8 @@ test:
lui $sp, 0x7fff lui $sp, 0x7fff
ori $sp, 0xd000 ori $sp, 0xd000
# http://articles.manugarg.com/aboutelfauxiliaryvectors.html
# _AT_PAGESZ = 6
ori $t0, $0, 6 ori $t0, $0, 6
sw $t0, 0xC($sp) sw $t0, 0xC($sp)
ori $t0, $0, 0x1000 ori $t0, $0, 0x1000
......
...@@ -271,7 +271,7 @@ func main() { ...@@ -271,7 +271,7 @@ func main() {
interpreter, bytecode := GetInterpreterAndBytecode() interpreter, bytecode := GetInterpreterAndBytecode()
if len(os.Args) > 1 { if len(os.Args) > 1 {
if os.Args[1] == "/tmp/minigeth.bin" { if os.Args[1] == "../mipigeth/minigeth.bin" {
debug, _ = strconv.Atoi(os.Getenv("DEBUG")) debug, _ = strconv.Atoi(os.Getenv("DEBUG"))
steps, _ := strconv.Atoi(os.Getenv("STEPS")) steps, _ := strconv.Atoi(os.Getenv("STEPS"))
if steps == 0 { if steps == 0 {
......
#!/bin/bash -e #!/bin/bash -e
(cd ../ && npx hardhat compile) (cd ../ && npx hardhat compile)
(cd ../risc && ./build.sh && COMPILE=1 ./run.py) (cd ../mipigeth && ./build.sh)
go build go build
./mipsevm /tmp/minigeth.bin ./mipsevm ../mipigeth/minigeth.bin
...@@ -6,5 +6,5 @@ import ( ...@@ -6,5 +6,5 @@ import (
func TestProfileMinigeth(t *testing.T) { func TestProfileMinigeth(t *testing.T) {
interpreter, bytecode := GetInterpreterAndBytecode() interpreter, bytecode := GetInterpreterAndBytecode()
RunMinigeth("/tmp/minigeth.bin", interpreter, bytecode, 400000) RunMinigeth("../mipigeth/minigeth.bin", interpreter, bytecode, 400000)
} }
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