Commit cce7f9c3 authored by mbaxter's avatar mbaxter Committed by GitHub

cannon: Extract MIPS step helper functions (#11017)

* cannon: Extract step helpers

* cannon: Wrap step helper logic in unchecked

* cannon: Use consistent var name between solidity and go (fun)

* cannon: Dedupe `opcode` and `fun` calculations

* cannon: Bump MIPS.sol version

* cannon: Run semver-lock, snapshots

* cannon: Address slither warnings

* cannon: Make sure all lib functions are unchecked
parent 1f64dd6d
...@@ -8,6 +8,8 @@ import ( ...@@ -8,6 +8,8 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
) )
type MemTracker func(addr uint32)
func (m *InstrumentedState) readPreimage(key [32]byte, offset uint32) (dat [32]byte, datLen uint32) { func (m *InstrumentedState) readPreimage(key [32]byte, offset uint32) (dat [32]byte, datLen uint32) {
preimage := m.lastPreimage preimage := m.lastPreimage
if key != m.lastPreimageKey { if key != m.lastPreimageKey {
...@@ -123,117 +125,14 @@ func (m *InstrumentedState) mipsStep() error { ...@@ -123,117 +125,14 @@ func (m *InstrumentedState) mipsStep() error {
} }
m.state.Step += 1 m.state.Step += 1
// instruction fetch // instruction fetch
insn := m.state.Memory.GetMemory(m.state.Cpu.PC) insn, opcode, fun := getInstructionDetails(m.state.Cpu.PC, m.state.Memory)
opcode := insn >> 26 // 6-bits
// j-type j/jal
if opcode == 2 || opcode == 3 {
linkReg := uint32(0)
if opcode == 3 {
linkReg = 31
}
// Take top 4 bits of the next PC (its 256 MB region), and concatenate with the 26-bit offset
target := (m.state.Cpu.NextPC & 0xF0000000) | ((insn & 0x03FFFFFF) << 2)
m.pushStack(target)
return handleJump(&m.state.Cpu, &m.state.Registers, linkReg, target)
}
// register fetch
rs := uint32(0) // source register 1 value
rt := uint32(0) // source register 2 / temp value
rtReg := (insn >> 16) & 0x1F
// R-type or I-type (stores rt)
rs = m.state.Registers[(insn>>21)&0x1F]
rdReg := rtReg
if opcode == 0 || opcode == 0x1c {
// R-type (stores rd)
rt = m.state.Registers[rtReg]
rdReg = (insn >> 11) & 0x1F
} else if opcode < 0x20 {
// rt is SignExtImm
// don't sign extend for andi, ori, xori
if opcode == 0xC || opcode == 0xD || opcode == 0xe {
// ZeroExtImm
rt = insn & 0xFFFF
} else {
// SignExtImm
rt = signExtend(insn&0xFFFF, 16)
}
} else if opcode >= 0x28 || opcode == 0x22 || opcode == 0x26 {
// store rt value with store
rt = m.state.Registers[rtReg]
// store actual rt with lwl and lwr
rdReg = rtReg
}
if (opcode >= 4 && opcode < 8) || opcode == 1 {
return handleBranch(&m.state.Cpu, &m.state.Registers, opcode, insn, rtReg, rs)
}
storeAddr := uint32(0xFF_FF_FF_FF)
// memory fetch (all I-type)
// we do the load for stores also
mem := uint32(0)
if opcode >= 0x20 {
// M[R[rs]+SignExtImm]
rs += signExtend(insn&0xFFFF, 16)
addr := rs & 0xFFFFFFFC
m.trackMemAccess(addr)
mem = m.state.Memory.GetMemory(addr)
if opcode >= 0x28 && opcode != 0x30 {
// store
storeAddr = addr
// store opcodes don't write back to a register
rdReg = 0
}
}
// ALU
val := executeMipsInstruction(insn, rs, rt, mem)
fun := insn & 0x3f // 6-bits
if opcode == 0 && fun >= 8 && fun < 0x1c {
if fun == 8 || fun == 9 { // jr/jalr
linkReg := uint32(0)
if fun == 9 {
linkReg = rdReg
}
m.popStack()
return handleJump(&m.state.Cpu, &m.state.Registers, linkReg, rs)
}
if fun == 0xa { // movz
return handleRd(&m.state.Cpu, &m.state.Registers, rdReg, rs, rt == 0)
}
if fun == 0xb { // movn
return handleRd(&m.state.Cpu, &m.state.Registers, rdReg, rs, rt != 0)
}
// Handle syscall separately
// syscall (can read and write) // syscall (can read and write)
if fun == 0xC { if opcode == 0 && fun == 0xC {
return m.handleSyscall() return m.handleSyscall()
} }
// lo and hi registers // Exec the rest of the step logic
// can write back return execMipsCoreStepLogic(&m.state.Cpu, &m.state.Registers, m.state.Memory, insn, opcode, fun, m.trackMemAccess, m)
if fun >= 0x10 && fun < 0x1c {
return handleHiLo(&m.state.Cpu, &m.state.Registers, fun, rs, rt, rdReg)
}
}
// stupid sc, write a 1 to rt
if opcode == 0x38 && rtReg != 0 {
m.state.Registers[rtReg] = 1
}
// write memory
if storeAddr != 0xFF_FF_FF_FF {
m.trackMemAccess(storeAddr)
m.state.Memory.SetMemory(storeAddr, val)
}
// write back the value to destination register
return handleRd(&m.state.Cpu, &m.state.Registers, rdReg, val, true)
} }
package mipsevm package mipsevm
func executeMipsInstruction(insn uint32, rs uint32, rt uint32, mem uint32) uint32 { type StackTracker interface {
opcode := insn >> 26 // 6-bits pushStack(target uint32)
popStack()
}
func getInstructionDetails(pc uint32, memory *Memory) (insn, opcode, fun uint32) {
insn = memory.GetMemory(pc)
opcode = insn >> 26 // First 6-bits
fun = insn & 0x3f // Last 6-bits
return insn, opcode, fun
}
func execMipsCoreStepLogic(cpu *CpuScalars, registers *[32]uint32, memory *Memory, insn, opcode, fun uint32, memTracker MemTracker, stackTracker StackTracker) error {
// j-type j/jal
if opcode == 2 || opcode == 3 {
linkReg := uint32(0)
if opcode == 3 {
linkReg = 31
}
// Take top 4 bits of the next PC (its 256 MB region), and concatenate with the 26-bit offset
target := (cpu.NextPC & 0xF0000000) | ((insn & 0x03FFFFFF) << 2)
stackTracker.pushStack(target)
return handleJump(cpu, registers, linkReg, target)
}
// register fetch
rs := uint32(0) // source register 1 value
rt := uint32(0) // source register 2 / temp value
rtReg := (insn >> 16) & 0x1F
// R-type or I-type (stores rt)
rs = registers[(insn>>21)&0x1F]
rdReg := rtReg
if opcode == 0 || opcode == 0x1c {
// R-type (stores rd)
rt = registers[rtReg]
rdReg = (insn >> 11) & 0x1F
} else if opcode < 0x20 {
// rt is SignExtImm
// don't sign extend for andi, ori, xori
if opcode == 0xC || opcode == 0xD || opcode == 0xe {
// ZeroExtImm
rt = insn & 0xFFFF
} else {
// SignExtImm
rt = signExtend(insn&0xFFFF, 16)
}
} else if opcode >= 0x28 || opcode == 0x22 || opcode == 0x26 {
// store rt value with store
rt = registers[rtReg]
// store actual rt with lwl and lwr
rdReg = rtReg
}
if (opcode >= 4 && opcode < 8) || opcode == 1 {
return handleBranch(cpu, registers, opcode, insn, rtReg, rs)
}
storeAddr := uint32(0xFF_FF_FF_FF)
// memory fetch (all I-type)
// we do the load for stores also
mem := uint32(0)
if opcode >= 0x20 {
// M[R[rs]+SignExtImm]
rs += signExtend(insn&0xFFFF, 16)
addr := rs & 0xFFFFFFFC
memTracker(addr)
mem = memory.GetMemory(addr)
if opcode >= 0x28 && opcode != 0x30 {
// store
storeAddr = addr
// store opcodes don't write back to a register
rdReg = 0
}
}
// ALU
val := executeMipsInstruction(insn, opcode, fun, rs, rt, mem)
if opcode == 0 && fun >= 8 && fun < 0x1c {
if fun == 8 || fun == 9 { // jr/jalr
linkReg := uint32(0)
if fun == 9 {
linkReg = rdReg
}
stackTracker.popStack()
return handleJump(cpu, registers, linkReg, rs)
}
if fun == 0xa { // movz
return handleRd(cpu, registers, rdReg, rs, rt == 0)
}
if fun == 0xb { // movn
return handleRd(cpu, registers, rdReg, rs, rt != 0)
}
// lo and hi registers
// can write back
if fun >= 0x10 && fun < 0x1c {
return handleHiLo(cpu, registers, fun, rs, rt, rdReg)
}
}
// store conditional, write a 1 to rt
if opcode == 0x38 && rtReg != 0 {
registers[rtReg] = 1
}
// write memory
if storeAddr != 0xFF_FF_FF_FF {
memTracker(storeAddr)
memory.SetMemory(storeAddr, val)
}
// write back the value to destination register
return handleRd(cpu, registers, rdReg, val, true)
}
func executeMipsInstruction(insn, opcode, fun, rs, rt, mem uint32) uint32 {
if opcode == 0 || (opcode >= 8 && opcode < 0xF) { if opcode == 0 || (opcode >= 8 && opcode < 0xF) {
fun := insn & 0x3f // 6-bits
// transform ArithLogI to SPECIAL // transform ArithLogI to SPECIAL
switch opcode { switch opcode {
case 8: case 8:
...@@ -101,7 +218,6 @@ func executeMipsInstruction(insn uint32, rs uint32, rt uint32, mem uint32) uint3 ...@@ -101,7 +218,6 @@ func executeMipsInstruction(insn uint32, rs uint32, rt uint32, mem uint32) uint3
switch opcode { switch opcode {
// SPECIAL2 // SPECIAL2
case 0x1C: case 0x1C:
fun := insn & 0x3f // 6-bits
switch fun { switch fun {
case 0x2: // mul case 0x2: // mul
return uint32(int32(rs) * int32(rt)) return uint32(int32(rs) * int32(rt))
......
...@@ -34,7 +34,6 @@ const ( ...@@ -34,7 +34,6 @@ const (
) )
type PreimageReader func(key [32]byte, offset uint32) (dat [32]byte, datLen uint32) type PreimageReader func(key [32]byte, offset uint32) (dat [32]byte, datLen uint32)
type MemTracker func(addr uint32)
func getSyscallArgs(registers *[32]uint32) (syscallNum, a0, a1, a2 uint32) { func getSyscallArgs(registers *[32]uint32) (syscallNum, a0, a1, a2 uint32) {
syscallNum = registers[2] // v0 syscallNum = registers[2] // v0
......
...@@ -124,8 +124,8 @@ ...@@ -124,8 +124,8 @@
"sourceCodeHash": "0x3ff4a3f21202478935412d47fd5ef7f94a170402ddc50e5c062013ce5544c83f" "sourceCodeHash": "0x3ff4a3f21202478935412d47fd5ef7f94a170402ddc50e5c062013ce5544c83f"
}, },
"src/cannon/MIPS.sol": { "src/cannon/MIPS.sol": {
"initCodeHash": "0xe9183ee3b69d9ec9594d6b3923d78c86c996cd738ccbc09675bb281284c060af", "initCodeHash": "0xe2cfbfa5d8587a6c3cf52686e29fb0d07e2764af0ef728825529f42ebdeacb5d",
"sourceCodeHash": "0x7c2eab73da8b2eeadba30eadb39f20e91307bc29218938fadfc5f73fadcf13bc" "sourceCodeHash": "0x231f42a05f0c8e5784eb112518afca0bb16a3689f317ce021b8390a0aa70377b"
}, },
"src/cannon/PreimageOracle.sol": { "src/cannon/PreimageOracle.sol": {
"initCodeHash": "0xe5db668fe41436f53995e910488c7c140766ba8745e19743773ebab508efd090", "initCodeHash": "0xe5db668fe41436f53995e910488c7c140766ba8745e19743773ebab508efd090",
......
...@@ -48,7 +48,7 @@ contract MIPS is ISemver { ...@@ -48,7 +48,7 @@ contract MIPS is ISemver {
/// @notice The semantic version of the MIPS contract. /// @notice The semantic version of the MIPS contract.
/// @custom:semver 1.0.1 /// @custom:semver 1.0.1
string public constant version = "1.1.0-beta.4"; string public constant version = "1.1.0-beta.5";
/// @notice The preimage oracle contract. /// @notice The preimage oracle contract.
IPreimageOracle internal immutable ORACLE; IPreimageOracle internal immutable ORACLE;
...@@ -262,178 +262,30 @@ contract MIPS is ISemver { ...@@ -262,178 +262,30 @@ contract MIPS is ISemver {
// instruction fetch // instruction fetch
uint256 insnProofOffset = MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 0); uint256 insnProofOffset = MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 0);
uint32 insn = MIPSMemory.readMem(state.memRoot, state.pc, insnProofOffset); (uint32 insn, uint32 opcode, uint32 fun) =
uint32 opcode = insn >> 26; // 6-bits ins.getInstructionDetails(state.pc, state.memRoot, insnProofOffset);
// j-type j/jal
if (opcode == 2 || opcode == 3) {
// Take top 4 bits of the next PC (its 256 MB region), and concatenate with the 26-bit offset
uint32 target = (state.nextPC & 0xF0000000) | (insn & 0x03FFFFFF) << 2;
return handleJumpAndReturnOutput(state, opcode == 2 ? 0 : 31, target);
}
// register fetch
uint32 rs; // source register 1 value
uint32 rt; // source register 2 / temp value
uint32 rtReg = (insn >> 16) & 0x1F;
// R-type or I-type (stores rt)
rs = state.registers[(insn >> 21) & 0x1F];
uint32 rdReg = rtReg;
if (opcode == 0 || opcode == 0x1c) {
// R-type (stores rd)
rt = state.registers[rtReg];
rdReg = (insn >> 11) & 0x1F;
} else if (opcode < 0x20) {
// rt is SignExtImm
// don't sign extend for andi, ori, xori
if (opcode == 0xC || opcode == 0xD || opcode == 0xe) {
// ZeroExtImm
rt = insn & 0xFFFF;
} else {
// SignExtImm
rt = ins.signExtend(insn & 0xFFFF, 16);
}
} else if (opcode >= 0x28 || opcode == 0x22 || opcode == 0x26) {
// store rt value with store
rt = state.registers[rtReg];
// store actual rt with lwl and lwr
rdReg = rtReg;
}
if ((opcode >= 4 && opcode < 8) || opcode == 1) {
st.CpuScalars memory cpu = getCpuScalars(state);
ins.handleBranch({
_cpu: cpu,
_registers: state.registers,
_opcode: opcode,
_insn: insn,
_rtReg: rtReg,
_rs: rs
});
setStateCpuScalars(state, cpu);
return outputState();
}
uint32 storeAddr = 0xFF_FF_FF_FF;
// memory fetch (all I-type)
// we do the load for stores also
uint32 mem;
if (opcode >= 0x20) {
// M[R[rs]+SignExtImm]
rs += ins.signExtend(insn & 0xFFFF, 16);
uint32 addr = rs & 0xFFFFFFFC;
uint256 memProofOffset = MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 1);
mem = MIPSMemory.readMem(state.memRoot, addr, memProofOffset);
if (opcode >= 0x28 && opcode != 0x30) {
// store
storeAddr = addr;
// store opcodes don't write back to a register
rdReg = 0;
}
}
// ALU
// Note: swr outputs more than 4 bytes without the mask 0xffFFffFF
uint32 val = ins.executeMipsInstruction(insn, rs, rt, mem) & 0xffFFffFF;
uint32 func = insn & 0x3f; // 6-bits
if (opcode == 0 && func >= 8 && func < 0x1c) {
if (func == 8 || func == 9) {
// jr/jalr
return handleJumpAndReturnOutput(state, func == 8 ? 0 : rdReg, rs);
}
if (func == 0xa) {
// movz
return handleRdAndReturnOutput(state, rdReg, rs, rt == 0);
}
if (func == 0xb) {
// movn
return handleRdAndReturnOutput(state, rdReg, rs, rt != 0);
}
// Handle syscall separately
// syscall (can read and write) // syscall (can read and write)
if (func == 0xC) { if (opcode == 0 && fun == 0xC) {
return handleSyscall(_localContext); return handleSyscall(_localContext);
} }
// lo and hi registers // Exec the rest of the step logic
// can write back
if (func >= 0x10 && func < 0x1c) {
st.CpuScalars memory cpu = getCpuScalars(state); st.CpuScalars memory cpu = getCpuScalars(state);
(state.memRoot) = ins.execMipsCoreStepLogic({
ins.handleHiLo({
_cpu: cpu, _cpu: cpu,
_registers: state.registers, _registers: state.registers,
_func: func, _memRoot: state.memRoot,
_rs: rs, _memProofOffset: MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 1),
_rt: rt, _insn: insn,
_storeReg: rdReg _opcode: opcode,
_fun: fun
}); });
setStateCpuScalars(state, cpu); setStateCpuScalars(state, cpu);
return outputState();
}
}
// stupid sc, write a 1 to rt
if (opcode == 0x38 && rtReg != 0) {
state.registers[rtReg] = 1;
}
// write memory
if (storeAddr != 0xFF_FF_FF_FF) {
uint256 memProofOffset = MIPSMemory.memoryProofOffset(STEP_PROOF_OFFSET, 1);
state.memRoot = MIPSMemory.writeMem(storeAddr, memProofOffset, val);
}
// write back the value to destination register
return handleRdAndReturnOutput(state, rdReg, val, true);
}
}
function handleJumpAndReturnOutput(
State memory _state,
uint32 _linkReg,
uint32 _dest
)
internal
returns (bytes32 out_)
{
st.CpuScalars memory cpu = getCpuScalars(_state);
ins.handleJump({ _cpu: cpu, _registers: _state.registers, _linkReg: _linkReg, _dest: _dest });
setStateCpuScalars(_state, cpu);
return outputState(); return outputState();
} }
function handleRdAndReturnOutput(
State memory _state,
uint32 _storeReg,
uint32 _val,
bool _conditional
)
internal
returns (bytes32 out_)
{
st.CpuScalars memory cpu = getCpuScalars(_state);
ins.handleRd({
_cpu: cpu,
_registers: _state.registers,
_storeReg: _storeReg,
_val: _val,
_conditional: _conditional
});
setStateCpuScalars(_state, cpu);
return outputState();
} }
function getCpuScalars(State memory _state) internal pure returns (st.CpuScalars memory) { function getCpuScalars(State memory _state) internal pure returns (st.CpuScalars memory) {
......
...@@ -93,9 +93,9 @@ library MIPSMemory { ...@@ -93,9 +93,9 @@ library MIPSMemory {
newMemRoot_ := node newMemRoot_ := node
} }
}
return newMemRoot_; return newMemRoot_;
} }
}
/// @notice Computes the offset of a memory proof in the calldata. /// @notice Computes the offset of a memory proof in the calldata.
/// @param _proofDataOffset The offset of the set of all memory proof data within calldata (proof.offset) /// @param _proofDataOffset The offset of the set of all memory proof data within calldata (proof.offset)
...@@ -114,6 +114,7 @@ library MIPSMemory { ...@@ -114,6 +114,7 @@ library MIPSMemory {
/// @notice Validates that enough calldata is available to hold a full memory proof at the given offset /// @notice Validates that enough calldata is available to hold a full memory proof at the given offset
/// @param _proofStartOffset The index of the first byte of the target memory proof in calldata /// @param _proofStartOffset The index of the first byte of the target memory proof in calldata
function validateMemoryProofAvailability(uint256 _proofStartOffset) internal pure { function validateMemoryProofAvailability(uint256 _proofStartOffset) internal pure {
unchecked {
uint256 s = 0; uint256 s = 0;
assembly { assembly {
s := calldatasize() s := calldatasize()
...@@ -121,4 +122,5 @@ library MIPSMemory { ...@@ -121,4 +122,5 @@ library MIPSMemory {
// A memory proof consists of 28 bytes32 values - verify we have enough calldata // A memory proof consists of 28 bytes32 values - verify we have enough calldata
require(s >= (_proofStartOffset + 28 * 32), "check that there is enough calldata"); require(s >= (_proofStartOffset + 28 * 32), "check that there is enough calldata");
} }
}
} }
...@@ -37,6 +37,7 @@ library MIPSSyscalls { ...@@ -37,6 +37,7 @@ library MIPSSyscalls {
pure pure
returns (uint32 sysCallNum_, uint32 a0_, uint32 a1_, uint32 a2_) returns (uint32 sysCallNum_, uint32 a0_, uint32 a1_, uint32 a2_)
{ {
unchecked {
sysCallNum_ = _registers[2]; sysCallNum_ = _registers[2];
a0_ = _registers[4]; a0_ = _registers[4];
...@@ -45,6 +46,7 @@ library MIPSSyscalls { ...@@ -45,6 +46,7 @@ library MIPSSyscalls {
return (sysCallNum_, a0_, a1_, a2_); return (sysCallNum_, a0_, a1_, a2_);
} }
}
/// @notice Like a Linux mmap syscall. Allocates a page from the heap. /// @notice Like a Linux mmap syscall. Allocates a page from the heap.
/// @param _a0 The address for the new mapping /// @param _a0 The address for the new mapping
...@@ -62,6 +64,7 @@ library MIPSSyscalls { ...@@ -62,6 +64,7 @@ library MIPSSyscalls {
pure pure
returns (uint32 v0_, uint32 v1_, uint32 newHeap_) returns (uint32 v0_, uint32 v1_, uint32 newHeap_)
{ {
unchecked {
v1_ = uint32(0); v1_ = uint32(0);
newHeap_ = _heap; newHeap_ = _heap;
...@@ -79,6 +82,7 @@ library MIPSSyscalls { ...@@ -79,6 +82,7 @@ library MIPSSyscalls {
return (v0_, v1_, newHeap_); return (v0_, v1_, newHeap_);
} }
}
/// @notice Like a Linux read syscall. Splits unaligned reads into aligned reads. /// @notice Like a Linux read syscall. Splits unaligned reads into aligned reads.
/// @param _a0 The file descriptor. /// @param _a0 The file descriptor.
...@@ -109,6 +113,7 @@ library MIPSSyscalls { ...@@ -109,6 +113,7 @@ library MIPSSyscalls {
view view
returns (uint32 v0_, uint32 v1_, uint32 newPreimageOffset_, bytes32 newMemRoot_) returns (uint32 v0_, uint32 v1_, uint32 newPreimageOffset_, bytes32 newMemRoot_)
{ {
unchecked {
v0_ = uint32(0); v0_ = uint32(0);
v1_ = uint32(0); v1_ = uint32(0);
newMemRoot_ = _memRoot; newMemRoot_ = _memRoot;
...@@ -164,6 +169,7 @@ library MIPSSyscalls { ...@@ -164,6 +169,7 @@ library MIPSSyscalls {
return (v0_, v1_, newPreimageOffset_, newMemRoot_); return (v0_, v1_, newPreimageOffset_, newMemRoot_);
} }
}
/// @notice Like a Linux write syscall. Splits unaligned writes into aligned writes. /// @notice Like a Linux write syscall. Splits unaligned writes into aligned writes.
/// @param _a0 The file descriptor. /// @param _a0 The file descriptor.
...@@ -190,6 +196,7 @@ library MIPSSyscalls { ...@@ -190,6 +196,7 @@ library MIPSSyscalls {
pure pure
returns (uint32 v0_, uint32 v1_, bytes32 newPreimageKey_, uint32 newPreimageOffset_) returns (uint32 v0_, uint32 v1_, bytes32 newPreimageKey_, uint32 newPreimageOffset_)
{ {
unchecked {
// args: _a0 = fd, _a1 = addr, _a2 = count // args: _a0 = fd, _a1 = addr, _a2 = count
// returns: v0_ = written, v1_ = err code // returns: v0_ = written, v1_ = err code
v0_ = uint32(0); v0_ = uint32(0);
...@@ -229,6 +236,7 @@ library MIPSSyscalls { ...@@ -229,6 +236,7 @@ library MIPSSyscalls {
return (v0_, v1_, newPreimageKey_, newPreimageOffset_); return (v0_, v1_, newPreimageKey_, newPreimageOffset_);
} }
}
/// @notice Like Linux fcntl (file control) syscall, but only supports minimal file-descriptor control commands, to /// @notice Like Linux fcntl (file control) syscall, but only supports minimal file-descriptor control commands, to
/// retrieve the file-descriptor R/W flags. /// retrieve the file-descriptor R/W flags.
...@@ -237,6 +245,7 @@ library MIPSSyscalls { ...@@ -237,6 +245,7 @@ library MIPSSyscalls {
/// @param v0_ The file status flag (only supported command is F_GETFL), or -1 on error. /// @param v0_ The file status flag (only supported command is F_GETFL), or -1 on error.
/// @param v1_ An error number, or 0 if there is no error. /// @param v1_ An error number, or 0 if there is no error.
function handleSysFcntl(uint32 _a0, uint32 _a1) internal pure returns (uint32 v0_, uint32 v1_) { function handleSysFcntl(uint32 _a0, uint32 _a1) internal pure returns (uint32 v0_, uint32 v1_) {
unchecked {
v0_ = uint32(0); v0_ = uint32(0);
v1_ = uint32(0); v1_ = uint32(0);
...@@ -258,6 +267,7 @@ library MIPSSyscalls { ...@@ -258,6 +267,7 @@ library MIPSSyscalls {
return (v0_, v1_); return (v0_, v1_);
} }
}
function handleSyscallUpdates( function handleSyscallUpdates(
st.CpuScalars memory _cpu, st.CpuScalars memory _cpu,
...@@ -268,6 +278,7 @@ library MIPSSyscalls { ...@@ -268,6 +278,7 @@ library MIPSSyscalls {
internal internal
pure pure
{ {
unchecked {
// Write the results back to the state registers // Write the results back to the state registers
_registers[2] = _v0; _registers[2] = _v0;
_registers[7] = _v1; _registers[7] = _v1;
...@@ -276,4 +287,5 @@ library MIPSSyscalls { ...@@ -276,4 +287,5 @@ library MIPSSyscalls {
_cpu.pc = _cpu.nextPC; _cpu.pc = _cpu.nextPC;
_cpu.nextPC = _cpu.nextPC + 4; _cpu.nextPC = _cpu.nextPC + 4;
} }
}
} }
...@@ -25,7 +25,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode { ...@@ -25,7 +25,7 @@ contract DeploymentSummaryFaultProofs is DeploymentSummaryFaultProofsCode {
address internal constant l1ERC721BridgeProxyAddress = 0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865; address internal constant l1ERC721BridgeProxyAddress = 0xD31598c909d9C935a9e35bA70d9a3DD47d4D5865;
address internal constant l1StandardBridgeAddress = 0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b; address internal constant l1StandardBridgeAddress = 0xb7900B27Be8f0E0fF65d1C3A4671e1220437dd2b;
address internal constant l1StandardBridgeProxyAddress = 0xDeF3bca8c80064589E6787477FFa7Dd616B5574F; address internal constant l1StandardBridgeProxyAddress = 0xDeF3bca8c80064589E6787477FFa7Dd616B5574F;
address internal constant mipsAddress = 0x28bF1582225713139c0E898326Db808B6484cFd4; address internal constant mipsAddress = 0xcdAdd729ca2319E8955240bDb61A6A6A956A7664;
address internal constant optimismPortal2Address = 0xfcbb237388CaF5b08175C9927a37aB6450acd535; address internal constant optimismPortal2Address = 0xfcbb237388CaF5b08175C9927a37aB6450acd535;
address internal constant optimismPortalProxyAddress = 0x978e3286EB805934215a88694d80b09aDed68D90; address internal constant optimismPortalProxyAddress = 0x978e3286EB805934215a88694d80b09aDed68D90;
address internal constant preimageOracleAddress = 0x3bd7E801E51d48c5d94Ea68e8B801DFFC275De75; address internal constant preimageOracleAddress = 0x3bd7E801E51d48c5d94Ea68e8B801DFFC275De75;
......
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