Time.lean
Clock and Time Syscalls
Trusted model of the Linux AArch64 clock_gettime syscall (kernel/, include/), defining SYS_CLOCK_GETTIME, the 16-byte struct timespec encoder encodeTimespec, and execClockGettime.
@[expose] public sectionnamespace Arm64def SYS_CLOCK_GETTIME
Linux AArch64 clock_gettime syscall number (__NR_clock_gettime = 113, include/, kernel/).
def SYS_CLOCK_GETTIME : BitVec 64 := 113#64def encodeTimespec
16-byte little-endian Linux AArch64 struct timespec (tv_sec at +0, tv_nsec at +8, matching put_timespec64 in kernel/).
def execClockGettime
clock_gettime(clk_id, tp) (__NR_clock_gettime = 113, kernel/): models SYSCALL_DEFINE2(clock_gettime, ...) and the AArch64 vDSO __kernel_clock_gettime (lib/) for static POSIX clocks 0..7 (CLOCK_REALTIME = 0, CLOCK_MONOTONIC = 1, CLOCK_PROCESS_CPUTIME_ID = 2, CLOCK_THREAD_CPUTIME_ID = 3, CLOCK_MONOTONIC_RAW = 4, CLOCK_REALTIME_COARSE = 5, CLOCK_MONOTONIC_COARSE = 6, CLOCK_BOOTTIME = 7):
-
[INTENTIONAL_SCOPE]: ifclk., fails closed with .toNat > 7 Exception"unmodeled clock_gettime clockid" without consuming an oracle entry; -
if
!s., returnsmem. canWrite tp 16 EFAULT_RET(-EFAULT, matchingput_timespec64copy_to_userinkernel/) without consuming an oracle entry;time/ time.c -
[INTENTIONAL_OVERAPPROX]: queriests := s., writes the 16-byte little-endianoracle. clockGettime s. oracleIdx struct timespec(encodeTimespects), consumes one oracle entry vias., and returnsnextOracle 0. No monotonicity is assumed across successive calls.
def execClockGettime (s : State) : State :=
let clk := s.readReg32 Reg.x0
let tp := s.readReg64 Reg.x1
if clk.toNat > 7 then
s.setStatus (.Exception "unmodeled clock_gettime clockid")
else if !s.mem.canWrite tp 16 then
(s.writeReg64 Reg.x0 EFAULT_RET).advancePC
else
let ts := s.oracle.clockGettime s.oracleIdx
(((s.setMem (s.mem.writeBytes tp (encodeTimespec ts))).nextOracle).writeReg64 Reg.x0 0#64).advancePCend Arm64