Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
c363ae39
Commit
c363ae39
authored
Oct 04, 2021
by
George Hotz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor emm read/write
parent
ec307ac5
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
41 additions
and
29 deletions
+41
-29
MIPS.sol
contracts/MIPS.sol
+29
-21
main.go
mipsevm/main.go
+11
-7
minigeth_test.go
mipsevm/minigeth_test.go
+1
-1
No files found.
contracts/MIPS.sol
View file @
c363ae39
...
@@ -34,6 +34,14 @@ contract MIPS {
...
@@ -34,6 +34,14 @@ contract MIPS {
m = new MIPSMemory();
m = new MIPSMemory();
}
}
function WriteMemory(bytes32 stateHash, uint32 addr, uint32 value) internal view returns (bytes32) {
return m.WriteMemory(stateHash, addr, value);
}
function ReadMemory(bytes32 stateHash, uint32 addr) internal view returns (uint32) {
return m.ReadMemory(stateHash, addr);
}
function Steps(bytes32 stateHash, uint count) public view returns (bytes32) {
function Steps(bytes32 stateHash, uint count) public view returns (bytes32) {
for (uint i = 0; i < count; i++) {
for (uint i = 0; i < count; i++) {
stateHash = Step(stateHash);
stateHash = Step(stateHash);
...
@@ -58,7 +66,7 @@ contract MIPS {
...
@@ -58,7 +66,7 @@ contract MIPS {
// will revert if any required input state is missing
// will revert if any required input state is missing
function Step(bytes32 stateHash) public view returns (bytes32) {
function Step(bytes32 stateHash) public view returns (bytes32) {
// instruction fetch
// instruction fetch
uint32 pc =
m.
ReadMemory(stateHash, REG_PC);
uint32 pc = ReadMemory(stateHash, REG_PC);
if (pc == 0xdead0000) {
if (pc == 0xdead0000) {
return stateHash;
return stateHash;
}
}
...
@@ -66,17 +74,17 @@ contract MIPS {
...
@@ -66,17 +74,17 @@ contract MIPS {
}
}
function handleSyscall(bytes32 stateHash) internal view returns (bytes32) {
function handleSyscall(bytes32 stateHash) internal view returns (bytes32) {
uint32 syscall_no =
m.
ReadMemory(stateHash, REG_OFFSET+2*4);
uint32 syscall_no = ReadMemory(stateHash, REG_OFFSET+2*4);
uint32 v0 = 0;
uint32 v0 = 0;
if (syscall_no == 4090) {
if (syscall_no == 4090) {
// mmap
// mmap
uint32 a0 =
m.
ReadMemory(stateHash, REG_OFFSET+4*4);
uint32 a0 = ReadMemory(stateHash, REG_OFFSET+4*4);
if (a0 == 0) {
if (a0 == 0) {
uint32 sz =
m.
ReadMemory(stateHash, REG_OFFSET+5*4);
uint32 sz = ReadMemory(stateHash, REG_OFFSET+5*4);
uint32 hr =
m.
ReadMemory(stateHash, REG_HEAP);
uint32 hr = ReadMemory(stateHash, REG_HEAP);
v0 = HEAP_START + hr;
v0 = HEAP_START + hr;
stateHash =
m.
WriteMemory(stateHash, REG_HEAP, hr+sz);
stateHash = WriteMemory(stateHash, REG_HEAP, hr+sz);
} else {
} else {
v0 = a0;
v0 = a0;
}
}
...
@@ -88,14 +96,14 @@ contract MIPS {
...
@@ -88,14 +96,14 @@ contract MIPS {
v0 = 1;
v0 = 1;
}
}
stateHash =
m.
WriteMemory(stateHash, REG_OFFSET+2*4, v0);
stateHash = WriteMemory(stateHash, REG_OFFSET+2*4, v0);
stateHash =
m.
WriteMemory(stateHash, REG_OFFSET+7*4, 0);
stateHash = WriteMemory(stateHash, REG_OFFSET+7*4, 0);
return stateHash;
return stateHash;
}
}
// TODO: test ll and sc
// TODO: test ll and sc
function stepNextPC(bytes32 stateHash, uint32 pc, uint64 nextPC) internal view returns (bytes32) {
function stepNextPC(bytes32 stateHash, uint32 pc, uint64 nextPC) internal view returns (bytes32) {
uint32 insn =
m.
ReadMemory(stateHash, pc);
uint32 insn = ReadMemory(stateHash, pc);
uint32 opcode = insn >> 26; // 6-bits
uint32 opcode = insn >> 26; // 6-bits
uint32 func = insn & 0x3f; // 6-bits
uint32 func = insn & 0x3f; // 6-bits
...
@@ -112,11 +120,11 @@ contract MIPS {
...
@@ -112,11 +120,11 @@ contract MIPS {
uint32 rt;
uint32 rt;
if (opcode != 2 && opcode != 3) { // J-type: j and jal have no register fetch
if (opcode != 2 && opcode != 3) { // J-type: j and jal have no register fetch
// R-type or I-type (stores rt)
// R-type or I-type (stores rt)
rs =
m.
ReadMemory(stateHash, REG_OFFSET + ((insn >> 19) & 0x7C));
rs = ReadMemory(stateHash, REG_OFFSET + ((insn >> 19) & 0x7C));
storeAddr = REG_OFFSET + ((insn >> 14) & 0x7C);
storeAddr = REG_OFFSET + ((insn >> 14) & 0x7C);
if (opcode == 0 || opcode == 0x1c) {
if (opcode == 0 || opcode == 0x1c) {
// R-type (stores rd)
// R-type (stores rd)
rt =
m.
ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
rt = ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
storeAddr = REG_OFFSET + ((insn >> 9) & 0x7C);
storeAddr = REG_OFFSET + ((insn >> 9) & 0x7C);
} else if (opcode < 0x20) {
} else if (opcode < 0x20) {
// rt is SignExtImm
// rt is SignExtImm
...
@@ -130,7 +138,7 @@ contract MIPS {
...
@@ -130,7 +138,7 @@ contract MIPS {
}
}
} else if (opcode >= 0x28 || opcode == 0x22 || opcode == 0x26) {
} else if (opcode >= 0x28 || opcode == 0x22 || opcode == 0x26) {
// store rt value with store
// store rt value with store
rt =
m.
ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
rt = ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
// store actual rt with lwl and lwr
// store actual rt with lwl and lwr
storeAddr = REG_OFFSET + ((insn >> 14) & 0x7C);
storeAddr = REG_OFFSET + ((insn >> 14) & 0x7C);
...
@@ -152,7 +160,7 @@ contract MIPS {
...
@@ -152,7 +160,7 @@ contract MIPS {
uint32 SignExtImm = SE(insn&0xFFFF, 16);
uint32 SignExtImm = SE(insn&0xFFFF, 16);
rs += SignExtImm;
rs += SignExtImm;
uint32 addr = rs & 0xFFFFFFFC;
uint32 addr = rs & 0xFFFFFFFC;
mem =
m.
ReadMemory(stateHash, addr);
mem = ReadMemory(stateHash, addr);
if (opcode >= 0x28 && opcode != 0x30) {
if (opcode >= 0x28 && opcode != 0x30) {
// store
// store
storeAddr = addr;
storeAddr = addr;
...
@@ -163,7 +171,7 @@ contract MIPS {
...
@@ -163,7 +171,7 @@ contract MIPS {
bool shouldBranch = false;
bool shouldBranch = false;
if (opcode == 4 || opcode == 5) { // beq/bne
if (opcode == 4 || opcode == 5) { // beq/bne
rt =
m.
ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
rt = ReadMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C));
shouldBranch = (rs == rt && opcode == 4) || (rs != rt && opcode == 5);
shouldBranch = (rs == rt && opcode == 4) || (rs != rt && opcode == 5);
} else if (opcode == 6) { shouldBranch = int32(rs) <= 0; // blez
} else if (opcode == 6) { shouldBranch = int32(rs) <= 0; // blez
} else if (opcode == 7) { shouldBranch = int32(rs) > 0; // bgtz
} else if (opcode == 7) { shouldBranch = int32(rs) > 0; // bgtz
...
@@ -204,9 +212,9 @@ contract MIPS {
...
@@ -204,9 +212,9 @@ contract MIPS {
// lo and hi registers
// lo and hi registers
// can write back
// can write back
if (opcode == 0) {
if (opcode == 0) {
if (func == 0x10) val =
m.
ReadMemory(stateHash, REG_HI); // mfhi
if (func == 0x10) val = ReadMemory(stateHash, REG_HI); // mfhi
else if (func == 0x11) storeAddr = REG_HI; // mthi
else if (func == 0x11) storeAddr = REG_HI; // mthi
else if (func == 0x12) val =
m.
ReadMemory(stateHash, REG_LO); // mflo
else if (func == 0x12) val = ReadMemory(stateHash, REG_LO); // mflo
else if (func == 0x13) storeAddr = REG_LO; // mtlo
else if (func == 0x13) storeAddr = REG_LO; // mtlo
uint32 hi;
uint32 hi;
...
@@ -229,26 +237,26 @@ contract MIPS {
...
@@ -229,26 +237,26 @@ contract MIPS {
// lo/hi writeback
// lo/hi writeback
// can't stepNextPC after this
// can't stepNextPC after this
if (func >= 0x18 && func < 0x1c) {
if (func >= 0x18 && func < 0x1c) {
stateHash =
m.
WriteMemory(stateHash, REG_HI, hi);
stateHash = WriteMemory(stateHash, REG_HI, hi);
storeAddr = REG_LO;
storeAddr = REG_LO;
}
}
}
}
// stupid sc, write a 1 to rt
// stupid sc, write a 1 to rt
if (opcode == 0x38) {
if (opcode == 0x38) {
stateHash =
m.
WriteMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C), 1);
stateHash = WriteMemory(stateHash, REG_OFFSET + ((insn >> 14) & 0x7C), 1);
}
}
// write back
// write back
if (storeAddr != REG_ZERO) {
if (storeAddr != REG_ZERO) {
stateHash =
m.
WriteMemory(stateHash, storeAddr, val);
stateHash = WriteMemory(stateHash, storeAddr, val);
}
}
if (nextPC & STORE_LINK == STORE_LINK) {
if (nextPC & STORE_LINK == STORE_LINK) {
stateHash =
m.
WriteMemory(stateHash, REG_LR, pc+4);
stateHash = WriteMemory(stateHash, REG_LR, pc+4);
}
}
stateHash =
m.
WriteMemory(stateHash, REG_PC, uint32(nextPC));
stateHash = WriteMemory(stateHash, REG_PC, uint32(nextPC));
return stateHash;
return stateHash;
}
}
...
...
mipsevm/main.go
View file @
c363ae39
...
@@ -135,9 +135,9 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
...
@@ -135,9 +135,9 @@ 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
{
if
addr
==
0xc0000080
{
if
nret
==
0xDEAD0000
{
/*
if nret == 0xDEAD0000 {
fmt
.
Printf
(
"exec is done"
)
fmt.Printf("exec is done
\n
")
}
}
*/
if
debug
>=
1
{
if
debug
>=
1
{
fmt
.
Printf
(
"%7d %8X %08X : %08X %08X %08X %08X %08X %08X %08X %08X %08X
\n
"
,
fmt
.
Printf
(
"%7d %8X %08X : %08X %08X %08X %08X %08X %08X %08X %08X %08X
\n
"
,
pcCount
,
nret
,
ram
[
nret
],
pcCount
,
nret
,
ram
[
nret
],
...
@@ -154,7 +154,7 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
...
@@ -154,7 +154,7 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
}
}
if
(
pcCount
%
10000
)
==
0
{
if
(
pcCount
%
10000
)
==
0
{
steps_per_sec
:=
float64
(
pcCount
)
*
1e9
/
float64
(
time
.
Now
()
.
Sub
(
ministart
)
.
Nanoseconds
())
steps_per_sec
:=
float64
(
pcCount
)
*
1e9
/
float64
(
time
.
Now
()
.
Sub
(
ministart
)
.
Nanoseconds
())
os
.
Stderr
.
WriteString
(
fmt
.
Sprintf
(
"step %7d steps per s %f
\n
"
,
pcCount
,
steps_per_sec
))
os
.
Stderr
.
WriteString
(
fmt
.
Sprintf
(
"step %7d steps per s %f
ram entries %d
\n
"
,
pcCount
,
steps_per_sec
,
len
(
ram
)
))
}
}
pcCount
+=
1
pcCount
+=
1
}
}
...
@@ -165,7 +165,11 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
...
@@ -165,7 +165,11 @@ func opStaticCall(pc *uint64, interpreter *vm.EVMInterpreter, scope *vm.ScopeCon
if
debug
>=
2
{
if
debug
>=
2
{
fmt
.
Println
(
"HOOKED WRITE! "
,
fmt
.
Sprintf
(
"%x = %x"
,
addr
,
dat
))
fmt
.
Println
(
"HOOKED WRITE! "
,
fmt
.
Sprintf
(
"%x = %x"
,
addr
,
dat
))
}
}
ram
[
addr
]
=
dat
if
dat
==
0
{
delete
(
ram
,
addr
)
}
else
{
ram
[
addr
]
=
dat
}
// pass through stateRoot
// pass through stateRoot
scope
.
Memory
.
Set
(
retOffset
.
Uint64
(),
retSize
.
Uint64
(),
args
[
0x4
:
0x24
])
scope
.
Memory
.
Set
(
retOffset
.
Uint64
(),
retSize
.
Uint64
(),
args
[
0x4
:
0x24
])
...
@@ -254,9 +258,9 @@ func GetInterpreterAndBytecode() (*vm.EVMInterpreter, []byte) {
...
@@ -254,9 +258,9 @@ func GetInterpreterAndBytecode() (*vm.EVMInterpreter, []byte) {
blockContext
:=
core
.
NewEVMBlockContext
(
&
header
,
bc
,
&
author
)
blockContext
:=
core
.
NewEVMBlockContext
(
&
header
,
bc
,
&
author
)
txContext
:=
vm
.
TxContext
{}
txContext
:=
vm
.
TxContext
{}
config
:=
vm
.
Config
{}
config
:=
vm
.
Config
{}
config
.
Debug
=
true
/*
config.Debug = true
tracer := Tracer{}
tracer := Tracer{}
config
.
Tracer
=
&
tracer
config.Tracer = &tracer
*/
evm
:=
vm
.
NewEVM
(
blockContext
,
txContext
,
statedb
,
params
.
MainnetChainConfig
,
config
)
evm
:=
vm
.
NewEVM
(
blockContext
,
txContext
,
statedb
,
params
.
MainnetChainConfig
,
config
)
interpreter
:=
vm
.
NewEVMInterpreter
(
evm
,
config
)
interpreter
:=
vm
.
NewEVMInterpreter
(
evm
,
config
)
...
...
mipsevm/minigeth_test.go
View file @
c363ae39
...
@@ -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
,
1
00000
)
RunMinigeth
(
"/tmp/minigeth.bin"
,
interpreter
,
bytecode
,
4
00000
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment