From 35f5d25cca58c78cd79178abeed8122cc1ec9d89 Mon Sep 17 00:00:00 2001 From: alan <652732310@qq.com> Date: Wed, 9 Oct 2024 17:23:18 +0800 Subject: [PATCH 1/4] use constant instead of magic value --- cannon/mipsevm/exec/calling_convention.go | 56 +++++++++++++++++++++++ cannon/mipsevm/exec/mips_syscalls.go | 14 +++--- cannon/mipsevm/multithreaded/mips.go | 4 +- 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 cannon/mipsevm/exec/calling_convention.go diff --git a/cannon/mipsevm/exec/calling_convention.go b/cannon/mipsevm/exec/calling_convention.go new file mode 100644 index 00000000000..59e19c41ff2 --- /dev/null +++ b/cannon/mipsevm/exec/calling_convention.go @@ -0,0 +1,56 @@ +package exec + +// FYI: https://en.wikibooks.org/wiki/MIPS_Assembly/Register_File +const ( + Reg0 = 0 + RegAt = 1 + // syscall number; 1st return value + RegV0 = 2 + // 2nd return value + RegV1 = 3 + // syscall arguments; returned unmodified + RegA0 = 4 + RegA1 = 5 + RegA2 = 6 + // 4th syscall argument; set to 0/1 for success/error + RegA3 = 7 + // caller saved + RegT0 = 8 + RegT1 = 9 + RegT2 = 10 + RegT3 = 11 + RegT4 = 12 + RegT5 = 13 + RegT6 = 14 + RegT7 = 15 + // callee saved + RegS0 = 16 + RegS1 = 17 + RegS2 = 18 + RegS3 = 19 + RegS4 = 20 + RegS5 = 21 + RegS6 = 22 + RegS7 = 23 + + RegT8 = 24 + RegT9 = 25 + RegK0 = 26 + RegK1 = 27 + RegGP = 28 + RegSP = 29 + RegFP = 30 + RegRA = 31 +) + +// FYI: https://web.archive.org/web/20231223163047/https://www.linux-mips.org/wiki/Syscall +const ( + RegSyscallNum = RegV0 + RegSyscallRet1 = RegV0 + RegSyscallRet2 = RegV1 + RegSyscallResult = RegA3 + RegSyscallParam1 = RegA0 + RegSyscallParam2 = RegA1 + RegSyscallParam3 = RegA2 + RegSyscallParam4 = RegA3 +) diff --git a/cannon/mipsevm/exec/mips_syscalls.go b/cannon/mipsevm/exec/mips_syscalls.go index 8679a39b773..24e466f6f04 100644 --- a/cannon/mipsevm/exec/mips_syscalls.go +++ b/cannon/mipsevm/exec/mips_syscalls.go @@ -99,12 +99,12 @@ const ( ) func GetSyscallArgs(registers *[32]Word) (syscallNum, a0, a1, a2, a3 Word) { - syscallNum = registers[2] // v0 + syscallNum = registers[RegSyscallNum] // v0 - a0 = registers[4] - a1 = registers[5] - a2 = registers[6] - a3 = registers[7] + a0 = registers[RegSyscallParam1] + a1 = registers[RegSyscallParam2] + a2 = registers[RegSyscallParam3] + a3 = registers[RegSyscallParam4] return syscallNum, a0, a1, a2, a3 } @@ -281,8 +281,8 @@ func HandleSysFcntl(a0, a1 Word) (v0, v1 Word) { } func HandleSyscallUpdates(cpu *mipsevm.CpuScalars, registers *[32]Word, v0, v1 Word) { - registers[2] = v0 - registers[7] = v1 + registers[RegSyscallRet1] = v0 + registers[RegSyscallResult] = v1 cpu.PC = cpu.NextPC cpu.NextPC = cpu.NextPC + 4 diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index f738ecf38d7..412dce1e01c 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -59,8 +59,8 @@ func (m *InstrumentedState) handleSyscall() error { newThread.Registers[29] = a1 // the child will perceive a 0 value as returned value instead, and no error - newThread.Registers[2] = 0 - newThread.Registers[7] = 0 + newThread.Registers[exec.RegSyscallRet1] = 0 + newThread.Registers[exec.RegSyscallResult] = 0 m.state.NextThreadId++ // Preempt this thread for the new one. But not before updating PCs From a1af8c24f2d1a982d459dbd9e50ba6d7411dd9d1 Mon Sep 17 00:00:00 2001 From: alan <652732310@qq.com> Date: Sat, 12 Oct 2024 10:38:37 +0800 Subject: [PATCH 2/4] address comments --- cannon/mipsevm/exec/calling_convention.go | 65 ++++++++++++----------- cannon/mipsevm/exec/mips_syscalls.go | 2 +- cannon/mipsevm/multithreaded/mips.go | 2 +- 3 files changed, 35 insertions(+), 34 deletions(-) diff --git a/cannon/mipsevm/exec/calling_convention.go b/cannon/mipsevm/exec/calling_convention.go index 59e19c41ff2..732fbf31655 100644 --- a/cannon/mipsevm/exec/calling_convention.go +++ b/cannon/mipsevm/exec/calling_convention.go @@ -1,13 +1,15 @@ package exec // FYI: https://en.wikibooks.org/wiki/MIPS_Assembly/Register_File +// +// https://refspecs.linuxfoundation.org/elf/mipsabi.pdf const ( - Reg0 = 0 - RegAt = 1 + // Reg0 = 0 + // RegAt = 1 // syscall number; 1st return value RegV0 = 2 // 2nd return value - RegV1 = 3 + // RegV1 = 3 // syscall arguments; returned unmodified RegA0 = 4 RegA1 = 5 @@ -15,40 +17,39 @@ const ( // 4th syscall argument; set to 0/1 for success/error RegA3 = 7 // caller saved - RegT0 = 8 - RegT1 = 9 - RegT2 = 10 - RegT3 = 11 - RegT4 = 12 - RegT5 = 13 - RegT6 = 14 - RegT7 = 15 + // RegT0 = 8 + // RegT1 = 9 + // RegT2 = 10 + // RegT3 = 11 + // RegT4 = 12 + // RegT5 = 13 + // RegT6 = 14 + // RegT7 = 15 // callee saved - RegS0 = 16 - RegS1 = 17 - RegS2 = 18 - RegS3 = 19 - RegS4 = 20 - RegS5 = 21 - RegS6 = 22 - RegS7 = 23 + // RegS0 = 16 + // RegS1 = 17 + // RegS2 = 18 + // RegS3 = 19 + // RegS4 = 20 + // RegS5 = 21 + // RegS6 = 22 + // RegS7 = 23 - RegT8 = 24 - RegT9 = 25 - RegK0 = 26 - RegK1 = 27 - RegGP = 28 - RegSP = 29 - RegFP = 30 - RegRA = 31 + // RegT8 = 24 + // RegT9 = 25 + // RegK0 = 26 + // RegK1 = 27 + // RegGP = 28 + // RegSP = 29 + // RegFP = 30 + // RegRA = 31 ) -// FYI: https://web.archive.org/web/20231223163047/https://www.linux-mips.org/wiki/Syscall const ( - RegSyscallNum = RegV0 - RegSyscallRet1 = RegV0 - RegSyscallRet2 = RegV1 - RegSyscallResult = RegA3 + RegSyscallNum = RegV0 + RegSyscallRet1 = RegV0 + // RegSyscallRet2 = RegV1 + RegSyscallError = RegA3 RegSyscallParam1 = RegA0 RegSyscallParam2 = RegA1 RegSyscallParam3 = RegA2 diff --git a/cannon/mipsevm/exec/mips_syscalls.go b/cannon/mipsevm/exec/mips_syscalls.go index 24e466f6f04..e1410a95066 100644 --- a/cannon/mipsevm/exec/mips_syscalls.go +++ b/cannon/mipsevm/exec/mips_syscalls.go @@ -282,7 +282,7 @@ func HandleSysFcntl(a0, a1 Word) (v0, v1 Word) { func HandleSyscallUpdates(cpu *mipsevm.CpuScalars, registers *[32]Word, v0, v1 Word) { registers[RegSyscallRet1] = v0 - registers[RegSyscallResult] = v1 + registers[RegSyscallError] = v1 cpu.PC = cpu.NextPC cpu.NextPC = cpu.NextPC + 4 diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index 412dce1e01c..68209cdc697 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -60,7 +60,7 @@ func (m *InstrumentedState) handleSyscall() error { newThread.Registers[29] = a1 // the child will perceive a 0 value as returned value instead, and no error newThread.Registers[exec.RegSyscallRet1] = 0 - newThread.Registers[exec.RegSyscallResult] = 0 + newThread.Registers[exec.RegSyscallError] = 0 m.state.NextThreadId++ // Preempt this thread for the new one. But not before updating PCs From 97f412b0164a92341a4eeee3d0fafc0802a6d503 Mon Sep 17 00:00:00 2001 From: alan <652732310@qq.com> Date: Wed, 16 Oct 2024 14:35:36 +0800 Subject: [PATCH 3/4] address comments --- cannon/mipsevm/exec/calling_convention.go | 39 +++-------------------- cannon/mipsevm/exec/mips_syscalls.go | 2 +- cannon/mipsevm/multithreaded/mips.go | 2 +- 3 files changed, 6 insertions(+), 37 deletions(-) diff --git a/cannon/mipsevm/exec/calling_convention.go b/cannon/mipsevm/exec/calling_convention.go index 732fbf31655..76795517ff5 100644 --- a/cannon/mipsevm/exec/calling_convention.go +++ b/cannon/mipsevm/exec/calling_convention.go @@ -4,52 +4,21 @@ package exec // // https://refspecs.linuxfoundation.org/elf/mipsabi.pdf const ( - // Reg0 = 0 - // RegAt = 1 // syscall number; 1st return value RegV0 = 2 - // 2nd return value - // RegV1 = 3 // syscall arguments; returned unmodified RegA0 = 4 RegA1 = 5 RegA2 = 6 // 4th syscall argument; set to 0/1 for success/error RegA3 = 7 - // caller saved - // RegT0 = 8 - // RegT1 = 9 - // RegT2 = 10 - // RegT3 = 11 - // RegT4 = 12 - // RegT5 = 13 - // RegT6 = 14 - // RegT7 = 15 - // callee saved - // RegS0 = 16 - // RegS1 = 17 - // RegS2 = 18 - // RegS3 = 19 - // RegS4 = 20 - // RegS5 = 21 - // RegS6 = 22 - // RegS7 = 23 - - // RegT8 = 24 - // RegT9 = 25 - // RegK0 = 26 - // RegK1 = 27 - // RegGP = 28 - // RegSP = 29 - // RegFP = 30 - // RegRA = 31 ) +// FYI: https://web.archive.org/web/20231223163047/https://www.linux-mips.org/wiki/Syscall + const ( - RegSyscallNum = RegV0 - RegSyscallRet1 = RegV0 - // RegSyscallRet2 = RegV1 - RegSyscallError = RegA3 + RegSyscallNum = RegV0 + RegSyscallRet1 = RegV0 RegSyscallParam1 = RegA0 RegSyscallParam2 = RegA1 RegSyscallParam3 = RegA2 diff --git a/cannon/mipsevm/exec/mips_syscalls.go b/cannon/mipsevm/exec/mips_syscalls.go index e1410a95066..49f4855f74f 100644 --- a/cannon/mipsevm/exec/mips_syscalls.go +++ b/cannon/mipsevm/exec/mips_syscalls.go @@ -282,7 +282,7 @@ func HandleSysFcntl(a0, a1 Word) (v0, v1 Word) { func HandleSyscallUpdates(cpu *mipsevm.CpuScalars, registers *[32]Word, v0, v1 Word) { registers[RegSyscallRet1] = v0 - registers[RegSyscallError] = v1 + registers[RegA3] = v1 cpu.PC = cpu.NextPC cpu.NextPC = cpu.NextPC + 4 diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index 68209cdc697..605e85e70e7 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -60,7 +60,7 @@ func (m *InstrumentedState) handleSyscall() error { newThread.Registers[29] = a1 // the child will perceive a 0 value as returned value instead, and no error newThread.Registers[exec.RegSyscallRet1] = 0 - newThread.Registers[exec.RegSyscallError] = 0 + newThread.Registers[exec.RegA3] = 0 m.state.NextThreadId++ // Preempt this thread for the new one. But not before updating PCs From 00bfabfea623626f32ad27ca435c3e86a2329c22 Mon Sep 17 00:00:00 2001 From: alan <652732310@qq.com> Date: Wed, 16 Oct 2024 21:35:34 +0800 Subject: [PATCH 4/4] add RegSyscallErrno --- cannon/mipsevm/exec/calling_convention.go | 1 + cannon/mipsevm/exec/mips_syscalls.go | 2 +- cannon/mipsevm/multithreaded/mips.go | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cannon/mipsevm/exec/calling_convention.go b/cannon/mipsevm/exec/calling_convention.go index 76795517ff5..8cbb963a964 100644 --- a/cannon/mipsevm/exec/calling_convention.go +++ b/cannon/mipsevm/exec/calling_convention.go @@ -18,6 +18,7 @@ const ( const ( RegSyscallNum = RegV0 + RegSyscallErrno = RegA3 RegSyscallRet1 = RegV0 RegSyscallParam1 = RegA0 RegSyscallParam2 = RegA1 diff --git a/cannon/mipsevm/exec/mips_syscalls.go b/cannon/mipsevm/exec/mips_syscalls.go index 49f4855f74f..6387a2a2b91 100644 --- a/cannon/mipsevm/exec/mips_syscalls.go +++ b/cannon/mipsevm/exec/mips_syscalls.go @@ -282,7 +282,7 @@ func HandleSysFcntl(a0, a1 Word) (v0, v1 Word) { func HandleSyscallUpdates(cpu *mipsevm.CpuScalars, registers *[32]Word, v0, v1 Word) { registers[RegSyscallRet1] = v0 - registers[RegA3] = v1 + registers[RegSyscallErrno] = v1 cpu.PC = cpu.NextPC cpu.NextPC = cpu.NextPC + 4 diff --git a/cannon/mipsevm/multithreaded/mips.go b/cannon/mipsevm/multithreaded/mips.go index 605e85e70e7..72ab6720bf3 100644 --- a/cannon/mipsevm/multithreaded/mips.go +++ b/cannon/mipsevm/multithreaded/mips.go @@ -60,7 +60,7 @@ func (m *InstrumentedState) handleSyscall() error { newThread.Registers[29] = a1 // the child will perceive a 0 value as returned value instead, and no error newThread.Registers[exec.RegSyscallRet1] = 0 - newThread.Registers[exec.RegA3] = 0 + newThread.Registers[exec.RegSyscallErrno] = 0 m.state.NextThreadId++ // Preempt this thread for the new one. But not before updating PCs