diff --git a/rvgo/fast/vm.go b/rvgo/fast/vm.go index d4591493..64a009ee 100644 --- a/rvgo/fast/vm.go +++ b/rvgo/fast/vm.go @@ -486,6 +486,26 @@ func (inst *InstrumentedState) riscvStep() (outErr error) { var out U64 var errCode U64 switch cmd { + case 0x1: // F_GETFD: get file descriptor flags + switch fd { + case 0: // stdin + out = toU64(0) // no flag set + case 1: // stdout + out = toU64(0) // no flag set + case 2: // stderr + out = toU64(0) // no flag set + case 3: // hint-read + out = toU64(0) // no flag set + case 4: // hint-write + out = toU64(0) // no flag set + case 5: // pre-image read + out = toU64(0) // no flag set + case 6: // pre-image write + out = toU64(0) // no flag set + default: + out = u64Mask() + errCode = toU64(0x4d) //EBADF + } case 0x3: // F_GETFL: get file descriptor flags switch fd { case 0: // stdin diff --git a/rvgo/slow/vm.go b/rvgo/slow/vm.go index c94a0e19..90ba0f17 100644 --- a/rvgo/slow/vm.go +++ b/rvgo/slow/vm.go @@ -666,6 +666,26 @@ func Step(calldata []byte, po PreimageOracle) (stateHash common.Hash, outErr err var out U64 var errCode U64 switch cmd.val() { + case 0x1: // F_GETFD: get file descriptor flags + switch fd.val() { + case 0: // stdin + out = toU64(0) // no flag set + case 1: // stdout + out = toU64(0) // no flag set + case 2: // stderr + out = toU64(0) // no flag set + case 3: // hint-read + out = toU64(0) // no flag set + case 4: // hint-write + out = toU64(0) // no flag set + case 5: // pre-image read + out = toU64(0) // no flag set + case 6: // pre-image write + out = toU64(0) // no flag set + default: + out = u64Mask() + errCode = toU64(0x4d) //EBADF + } case 0x3: // F_GETFL: get file descriptor flags switch fd.val() { case 0: // stdin diff --git a/rvgo/test/syscall_test.go b/rvgo/test/syscall_test.go index d23886d2..93362977 100644 --- a/rvgo/test/syscall_test.go +++ b/rvgo/test/syscall_test.go @@ -476,8 +476,17 @@ func FuzzStateSyscallFcntl(f *testing.F) { // Add 7 to fd to ensure fd > 6 testFcntl(t, fd+7, 3, pc, step, 0xFFFF_FFFF_FFFF_FFFF, 0x4d) + // Test F_GETFD + for _, fd := range []uint64{0, 1, 2, 3, 4, 5, 6} { + testFcntl(t, fd, 1, pc, step, 0, 0) + } + + // Test F_GETFD for unsupported fds + // Add 7 to fd to ensure fd > 6 + testFcntl(t, fd+7, 1, pc, step, 0xFFFF_FFFF_FFFF_FFFF, 0x4d) + // Test other commands - if cmd == 3 { + if cmd == 3 || cmd == 1 { // Set arbitrary commands if cmd is F_GETFL cmd = 4 } diff --git a/rvsol/src/RISCV.sol b/rvsol/src/RISCV.sol index 7dfcdb59..4467c0f0 100644 --- a/rvsol/src/RISCV.sol +++ b/rvsol/src/RISCV.sol @@ -994,6 +994,42 @@ contract RISCV { let out := 0 let errCode := 0 switch cmd + case 0x1 { + // F_GETFD: get file descriptor flags + switch fd + case 0 { + // stdin + out := toU64(0) // no flag set + } + case 1 { + // stdout + out := toU64(0) // no flag set + } + case 2 { + // stderr + out := toU64(0) // no flag set + } + case 3 { + // hint-read + out := toU64(0) // no flag set + } + case 4 { + // hint-write + out := toU64(0) // no flag set + } + case 5 { + // pre-image read + out := toU64(0) // no flag set + } + case 6 { + // pre-image write + out := toU64(0) // no flag set + } + default { + out := u64Mask() + errCode := toU64(0x4d) //EBADF + } + } case 0x3 { // F_GETFL: get file descriptor flags switch fd