diff --git a/src/preload/rrcalls.h b/src/preload/rrcalls.h index be11210d454..72868a51b63 100644 --- a/src/preload/rrcalls.h +++ b/src/preload/rrcalls.h @@ -78,3 +78,7 @@ * process tree, such that it may run without seccomp. */ #define SYS_rrcall_detach_teleport (RR_CALL_BASE + 9) +/** + * Requests the current rr tick. + */ +#define SYS_rrcall_current_time (RR_CALL_BASE + 10) diff --git a/src/record_syscall.cc b/src/record_syscall.cc index c254c1c1593..54493a9352a 100644 --- a/src/record_syscall.cc +++ b/src/record_syscall.cc @@ -4771,6 +4771,19 @@ static Switchable rec_prepare_syscall_arch(RecordTask* t, return ALLOW_SWITCH; } + case SYS_rrcall_current_time: { + // Since this is "user" facing, we follow best practices for regular + // syscalls and make sure that unused arguments (in this case all of them) + // are zero. + bool arguments_are_zero = true; + Registers r = t->regs(); + for (int i = 1; i <= 6; ++i) { + arguments_are_zero &= r.arg(i) == 0; + } + syscall_state.emulate_result(arguments_are_zero ? t->trace_time() : (uintptr_t)-EINVAL); + syscall_state.expect_errno = ENOSYS; + return PREVENT_SWITCH; + } case Arch::brk: case Arch::munmap: diff --git a/src/test/util_internal.h b/src/test/util_internal.h index 56f5833b14d..eab0b7c9941 100644 --- a/src/test/util_internal.h +++ b/src/test/util_internal.h @@ -15,4 +15,8 @@ void rr_detach_teleport(void) { test_assert(err == 0); } +int rr_current_time(void) { + return syscall(SYS_rrcall_current_time, 0, 0, 0, 0, 0, 0); +} + #endif /* RRUTIL_INTERNAL_H */