Skip to content

Commit

Permalink
cannon: Define 64-bit syscalls (ethereum-optimism#12256)
Browse files Browse the repository at this point in the history
* cannon: Define 64-bit syscalls

Also add SYS_FSTAT to the list of no-op syscalls emulated by MT-Cannon

* update semver-lock
  • Loading branch information
Inphi authored Oct 2, 2024
1 parent d1f6501 commit 2c7de99
Show file tree
Hide file tree
Showing 16 changed files with 222 additions and 156 deletions.
55 changes: 55 additions & 0 deletions cannon/mipsevm/arch/arch32.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,61 @@ const (
HighMemoryStart = 0x7f_ff_d0_00
)

// 32-bit Syscall codes
const (
SysMmap = 4090
SysBrk = 4045
SysClone = 4120
SysExitGroup = 4246
SysRead = 4003
SysWrite = 4004
SysFcntl = 4055
SysExit = 4001
SysSchedYield = 4162
SysGetTID = 4222
SysFutex = 4238
SysOpen = 4005
SysNanosleep = 4166
SysClockGetTime = 4263
SysGetpid = 4020
)

// Noop Syscall codes
const (
SysMunmap = 4091
SysGetAffinity = 4240
SysMadvise = 4218
SysRtSigprocmask = 4195
SysSigaltstack = 4206
SysRtSigaction = 4194
SysPrlimit64 = 4338
SysClose = 4006
SysPread64 = 4200
SysFstat = 4108
SysFstat64 = 4215
SysOpenAt = 4288
SysReadlink = 4085
SysReadlinkAt = 4298
SysIoctl = 4054
SysEpollCreate1 = 4326
SysPipe2 = 4328
SysEpollCtl = 4249
SysEpollPwait = 4313
SysGetRandom = 4353
SysUname = 4122
SysStat64 = 4213
SysGetuid = 4024
SysGetgid = 4047
SysLlseek = 4140
SysMinCore = 4217
SysTgkill = 4266
// Profiling-related syscalls
SysSetITimer = 4104
SysTimerCreate = 4257
SysTimerSetTime = 4258
SysTimerDelete = 4261
)

var ByteOrderWord = byteOrder32{}

type byteOrder32 struct{}
Expand Down
61 changes: 61 additions & 0 deletions cannon/mipsevm/arch/arch64.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,67 @@ const (
HighMemoryStart = 0x7F_FF_FF_FF_D0_00_00_00
)

// MIPS64 syscall table - https://github.com/torvalds/linux/blob/3efc57369a0ce8f76bf0804f7e673982384e4ac9/arch/mips/kernel/syscalls/syscall_n64.tbl. Generate the syscall numbers using the Makefile in that directory.
// See https://gpages.juszkiewicz.com.pl/syscalls-table/syscalls.html for the generated syscalls

// 64-bit Syscall numbers - new
const (
SysMmap = 5009
SysBrk = 5012
SysClone = 5055
SysExitGroup = 5205
SysRead = 5000
SysWrite = 5001
SysFcntl = 5070
SysExit = 5058
SysSchedYield = 5023
SysGetTID = 5178
SysFutex = 5194
SysOpen = 5002
SysNanosleep = 5034
SysClockGetTime = 5222
SysGetpid = 5038
)

// Noop Syscall numbers
const (
// UndefinedSysNr is the value used for 32-bit syscall numbers that aren't supported for 64-bits
UndefinedSysNr = ^Word(0)

SysMunmap = 5011
SysGetAffinity = 5196
SysMadvise = 5027
SysRtSigprocmask = 5014
SysSigaltstack = 5129
SysRtSigaction = 5013
SysPrlimit64 = 5297
SysClose = 5003
SysPread64 = 5016
SysFstat = 5005
SysFstat64 = UndefinedSysNr
SysOpenAt = 5247
SysReadlink = 5087
SysReadlinkAt = 5257
SysIoctl = 5015
SysEpollCreate1 = 5285
SysPipe2 = 5287
SysEpollCtl = 5208
SysEpollPwait = 5272
SysGetRandom = 5313
SysUname = 5061
SysStat64 = UndefinedSysNr
SysGetuid = 5100
SysGetgid = 5102
SysLlseek = UndefinedSysNr
SysMinCore = 5026
SysTgkill = 5225
// Profiling-related syscalls
SysSetITimer = 5036
SysTimerCreate = 5216
SysTimerSetTime = 5217
SysTimerDelete = 5220
)

var ByteOrderWord = byteOrder64{}

type byteOrder64 struct{}
Expand Down
55 changes: 0 additions & 55 deletions cannon/mipsevm/exec/mips_syscalls.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,61 +19,6 @@ const (
AddressMask = arch.AddressMask
)

// TODO(#12205): redefine syscalls for MIPS64
// Syscall codes
const (
SysMmap = 4090
SysBrk = 4045
SysClone = 4120
SysExitGroup = 4246
SysRead = 4003
SysWrite = 4004
SysFcntl = 4055
SysExit = 4001
SysSchedYield = 4162
SysGetTID = 4222
SysFutex = 4238
SysOpen = 4005
SysNanosleep = 4166
SysClockGetTime = 4263
SysGetpid = 4020
)

// Noop Syscall codes
const (
SysMunmap = 4091
SysGetAffinity = 4240
SysMadvise = 4218
SysRtSigprocmask = 4195
SysSigaltstack = 4206
SysRtSigaction = 4194
SysPrlimit64 = 4338
SysClose = 4006
SysPread64 = 4200
SysFstat64 = 4215
SysOpenAt = 4288
SysReadlink = 4085
SysReadlinkAt = 4298
SysIoctl = 4054
SysEpollCreate1 = 4326
SysPipe2 = 4328
SysEpollCtl = 4249
SysEpollPwait = 4313
SysGetRandom = 4353
SysUname = 4122
SysStat64 = 4213
SysGetuid = 4024
SysGetgid = 4047
SysLlseek = 4140
SysMinCore = 4217
SysTgkill = 4266
// Profiling-related syscalls
SysSetITimer = 4104
SysTimerCreate = 4257
SysTimerSetTime = 4258
SysTimerDelete = 4261
)

// File descriptors
const (
FdStdin = 0
Expand Down
5 changes: 3 additions & 2 deletions cannon/mipsevm/multithreaded/instrumented_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ func TestInstrumentedState_Alloc(t *testing.T) {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
state, _ := testutil.LoadELFProgram(t, "../../testdata/example/bin/alloc.elf", CreateInitialState, false)
state, meta := testutil.LoadELFProgram(t, "../../testdata/example/bin/alloc.elf", CreateInitialState, false)
oracle := testutil.AllocOracle(t, test.numAllocs, test.allocSize)

us := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), nil)
us := NewInstrumentedState(state, oracle, os.Stdout, os.Stderr, testutil.CreateLogger(), meta)
require.NoError(t, us.InitDebug())
// emulation shouldn't take more than 20 B steps
for i := 0; i < 20_000_000_000; i++ {
if us.GetState().GetExited() {
Expand Down
97 changes: 49 additions & 48 deletions cannon/mipsevm/multithreaded/mips.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ func (m *InstrumentedState) handleSyscall() error {

//fmt.Printf("syscall: %d\n", syscallNum)
switch syscallNum {
case exec.SysMmap:
case arch.SysMmap:
var newHeap Word
v0, v1, newHeap = exec.HandleSysMmap(a0, a1, m.state.Heap)
m.state.Heap = newHeap
case exec.SysBrk:
case arch.SysBrk:
v0 = program.PROGRAM_BREAK
case exec.SysClone: // clone
case arch.SysClone: // clone
// a0 = flag bitmask, a1 = stack pointer
if exec.ValidCloneFlags != a0 {
m.state.Exited = true
Expand Down Expand Up @@ -72,11 +72,11 @@ func (m *InstrumentedState) handleSyscall() error {
// to ensure we are tracking in the context of the new thread
m.stackTracker.PushStack(stackCaller, stackTarget)
return nil
case exec.SysExitGroup:
case arch.SysExitGroup:
m.state.Exited = true
m.state.ExitCode = uint8(a0)
return nil
case exec.SysRead:
case arch.SysRead:
var newPreimageOffset Word
var memUpdated bool
var memAddr Word
Expand All @@ -85,28 +85,28 @@ func (m *InstrumentedState) handleSyscall() error {
if memUpdated {
m.handleMemoryUpdate(memAddr)
}
case exec.SysWrite:
case arch.SysWrite:
var newLastHint hexutil.Bytes
var newPreimageKey common.Hash
var newPreimageOffset Word
v0, v1, newLastHint, newPreimageKey, newPreimageOffset = exec.HandleSysWrite(a0, a1, a2, m.state.LastHint, m.state.PreimageKey, m.state.PreimageOffset, m.preimageOracle, m.state.Memory, m.memoryTracker, m.stdOut, m.stdErr)
m.state.LastHint = newLastHint
m.state.PreimageKey = newPreimageKey
m.state.PreimageOffset = newPreimageOffset
case exec.SysFcntl:
case arch.SysFcntl:
v0, v1 = exec.HandleSysFcntl(a0, a1)
case exec.SysGetTID:
case arch.SysGetTID:
v0 = thread.ThreadId
v1 = 0
case exec.SysExit:
case arch.SysExit:
thread.Exited = true
thread.ExitCode = uint8(a0)
if m.lastThreadRemaining() {
m.state.Exited = true
m.state.ExitCode = uint8(a0)
}
return nil
case exec.SysFutex:
case arch.SysFutex:
// args: a0 = addr, a1 = op, a2 = val, a3 = timeout
effAddr := a0 & arch.AddressMask
switch a1 {
Expand Down Expand Up @@ -143,16 +143,16 @@ func (m *InstrumentedState) handleSyscall() error {
v0 = exec.SysErrorSignal
v1 = exec.MipsEINVAL
}
case exec.SysSchedYield, exec.SysNanosleep:
case arch.SysSchedYield, arch.SysNanosleep:
v0 = 0
v1 = 0
exec.HandleSyscallUpdates(&thread.Cpu, &thread.Registers, v0, v1)
m.preemptThread(thread)
return nil
case exec.SysOpen:
case arch.SysOpen:
v0 = exec.SysErrorSignal
v1 = exec.MipsEBADF
case exec.SysClockGetTime:
case arch.SysClockGetTime:
switch a0 {
case exec.ClockGettimeRealtimeFlag, exec.ClockGettimeMonotonicFlag:
v0, v1 = 0, 0
Expand All @@ -175,44 +175,45 @@ func (m *InstrumentedState) handleSyscall() error {
v0 = exec.SysErrorSignal
v1 = exec.MipsEINVAL
}
case exec.SysGetpid:
case arch.SysGetpid:
v0 = 0
v1 = 0
case exec.SysMunmap:
case exec.SysGetAffinity:
case exec.SysMadvise:
case exec.SysRtSigprocmask:
case exec.SysSigaltstack:
case exec.SysRtSigaction:
case exec.SysPrlimit64:
// TODO(#12205): may be needed for 64-bit Cannon
// case exec.SysGetRtLimit:
case exec.SysClose:
case exec.SysPread64:
case exec.SysFstat64:
case exec.SysOpenAt:
case exec.SysReadlink:
case exec.SysReadlinkAt:
case exec.SysIoctl:
case exec.SysEpollCreate1:
case exec.SysPipe2:
case exec.SysEpollCtl:
case exec.SysEpollPwait:
case exec.SysGetRandom:
case exec.SysUname:
case exec.SysStat64:
case exec.SysGetuid:
case exec.SysGetgid:
case exec.SysLlseek:
case exec.SysMinCore:
case exec.SysTgkill:
case exec.SysSetITimer:
case exec.SysTimerCreate:
case exec.SysTimerSetTime:
case exec.SysTimerDelete:
case arch.SysMunmap:
case arch.SysGetAffinity:
case arch.SysMadvise:
case arch.SysRtSigprocmask:
case arch.SysSigaltstack:
case arch.SysRtSigaction:
case arch.SysPrlimit64:
case arch.SysClose:
case arch.SysPread64:
case arch.SysFstat:
case arch.SysOpenAt:
case arch.SysReadlink:
case arch.SysReadlinkAt:
case arch.SysIoctl:
case arch.SysEpollCreate1:
case arch.SysPipe2:
case arch.SysEpollCtl:
case arch.SysEpollPwait:
case arch.SysGetRandom:
case arch.SysUname:
case arch.SysGetuid:
case arch.SysGetgid:
case arch.SysMinCore:
case arch.SysTgkill:
case arch.SysSetITimer:
case arch.SysTimerCreate:
case arch.SysTimerSetTime:
case arch.SysTimerDelete:
default:
m.Traceback()
panic(fmt.Sprintf("unrecognized syscall: %d", syscallNum))
// These syscalls have the same values on 64-bit. So we use if-stmts here to avoid "duplicate case" compiler error for the cannon64 build
if arch.IsMips32 && syscallNum == arch.SysFstat64 || syscallNum == arch.SysStat64 || syscallNum == arch.SysLlseek {
// noop
} else {
m.Traceback()
panic(fmt.Sprintf("unrecognized syscall: %d", syscallNum))
}
}

exec.HandleSyscallUpdates(&thread.Cpu, &thread.Registers, v0, v1)
Expand Down
Loading

0 comments on commit 2c7de99

Please sign in to comment.