State.lean
Declarations on this page (82)
- structure PState
- def zero
- def ofBits4
- structure RegFile
- def empty
- def read
- def write
- structure VRegFile
- def empty
- def read
- def write
- inductive OutputStream
- def ofFd
- inductive TraceEvent
- def ofBytes
- inductive ExecStatus
- structure Timespec
- structure Oracle
- inductive FsEntry
- inductive FdAccessMode
- def canRead
- def canWrite
- inductive FdKind
- def MAX_LFS_FILESIZE
- abbrev FsPath
- def splitSlash
- def hasLeadingSlash
- def hasDotDot
- def normalizePath
-
def FsPath.
nonEmptyPrefixes - def joinSlashChars
-
def FsPath.
toPathString - structure FdEntry
- structure FsState
- def maxOpenFds
- def getEntry
- def setEntry
- def files
- def setFile
- def fdBytes
- def setFd
- def allocFd
- def fpsrMask
- def fpsrIOC
- def fpsrDZC
- def fpsrOFC
- def fpsrUFC
- def fpsrIXC
- def fpsrQC
- structure SigAction
- structure SigAltStack
- structure State
- def readVReg128
- def writeVReg128
- def readVReg64
- def writeVReg64
- def readVReg32
- def writeVReg32
- def readReg64
- def writeReg64
- def readReg32
- def writeReg32
- def readReg
- def writeReg
- def advancePC
- def setPC
- def setPState
- def setFpsr
- def orFpsr
- def setMem
- def setStatus
- def setBrk
- def setPhysMemAvail
- def setFs
- def getSigAction
- def setSigAction
- def setSigAltStack
- def nextOracle
- def exclWillFail
- def stepExclOracle
- def appendTrace
- def spAligned
ARM64 Architectural State (Arm64.)
-
Layer / Role:
Arm64Trusted Computing Base (Role::Spec, definitions only, 0 theorems). -
Purpose & Key Exports: Programmer-visible AArch64 machine state (
State), including condition flags (PState:n,z,c,v), 64-bit general-purpose registers (RegFile), 128-bit SIMD/FP registers (VRegFile), execution status (ExecStatus), nondeterministic oracle (Oracle,Timespec), recorded signal dispositions and alternate signal stack (SigAction,SigAltStack), and state accessors (readReg64,writeReg64,readReg32,writeReg32,readVReg128,writeVReg128,advancePC,setPC). -
When to read: Read when writing or auditing
Statefield projections inSpec.leanor checking register/flag/oracle representations; useProofLib/for rewrite lemmas.State.lean
@[expose] public sectionnamespace Arm64structure PState
Processor condition flags (N, Z, C, V).
@[ext]
structure PState where
n : Bool := false
z : Bool := false
c : Bool := false
v : Bool := false
deriving DecidableEq, Repr, Inhabited, BEqnamespace PStatedef zero
All condition flags clear (NZCV = 0b0000).
def ofBits4
Construct PState from a 4-bit nzcv immediate (N=bit 3, Z=bit 2, C=bit 1, V=bit 0).
end PStatestructure RegFile
General-purpose register file (X0..X30, indexed by BitVec 5).
@[ext]
structure RegFile where
regs : BitVec 5 → BitVec 64namespace RegFiledef empty
The all-zero general-purpose register file.
def read
Read general-purpose register idx. Note this is the raw indexed read; XZR/SP disambiguation happens in State..
def write
Write general-purpose register idx. Note this is the raw indexed write; XZR/SP disambiguation happens in State..
end RegFilestructure VRegFile
128-bit SIMD/FP register file (V0..V31 / Q0..Q31 / D0..D31 / S0..S31 / H0..H31 / B0..B31, indexed by BitVec 5).
@[ext]
structure VRegFile where
regs : BitVec 5 → BitVec 128namespace VRegFiledef read
Read the full 128 bits of SIMD/FP register idx.
def write
Write the full 128 bits of SIMD/FP register idx.
end VRegFileinductive OutputStream
Output stream destination for byte-granular write events (stdout = fd 1, stderr = fd 2, or an arbitrary file descriptor fd).
inductive OutputStream where
| stdout
| stderr
| fd (num : BitVec 64)
deriving DecidableEq, Repr, Inhabited, BEqnamespace OutputStreamdef ofFd
Map a Linux file descriptor (1 = stdout, 2 = stderr) to its OutputStream.
def ofFd (fd : BitVec 64) : OutputStream :=
if fd == 1#64 then .stdout
else if fd == 2#64 then .stderr
else .fd fdend OutputStreaminductive TraceEvent
Observable event in the execution trace.
inductive TraceEvent where
/-- A byte written by the `write` system call (byte granularity). -/
| writeByte (stream : OutputStream) (byte : BitVec 8)
/-- An event defined by a user of the semantics. The semantics never produces it; it is for
externs (`Program.externs`) to record observable effects that the semantics does not model
(e.g. bytes received from the network, or random bytes generated). -/
| userDefined (tag : String) (payload : List (BitVec 8))
/-- `openat` changed the contents of regular file `path` without writing bytes: it created the
missing file (`O_CREAT`) or truncated an existing one (`O_TRUNC`, also when it was already
empty). Not output (`traceStreamBytes` drops it). With the `writeByte (.fd _)` events of
`write`, it is an event of every system call that changes `FsState.files`, so a trace
segment without either event tells that the system calls left the files alone. -/
| fileChanged (path : String)
deriving DecidableEq, Repr, Inhabited, BEqnamespace TraceEvent2 declarations not shown (lines 140–144): theorems, which Lean checks, or definitions that no headline statement uses
Arm64., Arm64.
def ofBytes
Convert a sequence of bytes written to stream into byte-granular TraceEvents.
def ofBytes (stream : OutputStream) (bytes : List (BitVec 8)) : List TraceEvent :=
bytes.map (.writeByte stream)end TraceEventinductive ExecStatus
Execution status of the machine state.
inductive ExecStatus where
| Running
| Halted
| Exited (code : BitVec 64)
/-- Fatal signal termination (for example `tkill`/`tgkill` delivering `SIGABRT = 6` to the
calling thread in `abort()`). A POSIX parent shell or `qemu-aarch64` observes wait status
`128 + sig.toNat` (`134` for `SIGABRT = 6`). -/
| Signaled (sig : BitVec 7)
/-- A Rust panic entry point was reached (see `Arm64.Rust.panicExterns`). With
`panic = abort` a panic never returns, so it ends execution like `exit`. -/
| Panicked
/-- A virtual-memory or physical-memory exhaustion condition occurred in `brk`, `mmap`,
`mprotect`, or `mremap` (either no free 48-bit user virtual-address gap of the requested
size exists in `mmap`, or the net new `Perm.rw` bytes required exceed `State.physMemAvail`).
Ends execution like `exit` or `panic`. -/
| OutOfMemory
| Exception (msg : String)
deriving DecidableEq, Repr, Inhabited, BEqstructure Timespec
Per-call result of a Linux AArch64 clock_gettime syscall (struct __kernel_timespec in include/, written by put_timespec64 in kernel/).
Per-call invariants guaranteed by the Linux kernel across all modeled clock IDs 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 in kernel/ and lib/):
-
Normalized nanoseconds (
0 ≤ tv_nsec < 1_000_000_000, enforced byFin 1000000000): high-resolution getters (ktime_get_real_ts64,ktime_get_ts64,ktime_get_raw_ts64inkernel/and vDSOtime/ timekeeping.c do_hresinlib/) reduce nanoseconds viavdso/ gettimeofday.c __iter_div_u64_rem(..., NSEC_PER_SEC, &ns); coarse getters (ktime_get_coarse_real_ts64,ktime_get_coarse_ts64and vDSOdo_coarse) and time-namespace offset additions (timens_add_monotonic,timens_add_boottimeininclude/) normalize vialinux/ time_namespace.h set_normalized_timespec64(kernel/), which adjuststime/ time.c tv_secin both loopswhile (nsec >= NSEC_PER_SEC)andwhile (nsec < 0)so0 ≤ tv_nsec < 1_000_000_000even whentv_sec < 0; andCLOCK_BOOTTIME(ktime_get_boottime_ts64) and CPU clocks (posix_cpu_clock_getinkernel/) converttime/ posix-cpu-timers.c s64nanoseconds vians_to_timespec64(kernel/), which likewise guaranteestime/ time.c 0 ≤ tv_nsec < 1_000_000_000. -
Seconds (
sec : BitVec 64, unconstrained):CLOCK_REALTIME(0) andCLOCK_REALTIME_COARSE(5) cannot be set before the 1970 epoch (timespec64_validininclude/rejectslinux/ time64.h ts->tv_sec < 0, andtimespec64_valid_settodis enforced bydo_settimeofday64,timekeeping_inject_offset, andtimekeeping_initinkernel/, as well astime/ timekeeping.c do_sys_settimeofday64inkernel/). In the initial time namespace (time/ posix-stubs.c init_time_ns), all eight clocks0..7satisfytv_sec ≥ 0. However, underCONFIG_TIME_NS(CLONE_NEWTIME),proc_timens_set_offset(kernel/) validates a negativetime/ namespace.c CLOCK_MONOTONICoffset against high-resolutionktime_get_ts64(tp.), whereastv_sec ≥ 0 posix_get_monotonic_coarse(CLOCK_MONOTONIC_COARSE = 6) andposix_get_monotonic_raw(CLOCK_MONOTONIC_RAW = 4) apply that samens->offsets.viamonotonic timens_add_monotonic(kernel/,time/ posix-timers.c lib/): becausevdso/ gettimeofday.c ktime_get_coarse_ts64omits the sub-ticktimekeeping_get_ns(&tk->tkr_mono)delta andktime_get_raw_ts64omits NTP slewing,timens_add_monotoniccan normalizetv_secto a negative value (e.g.-1) while keeping0 ≤ tv_nsec < 1_000_000_000. Moreover, even for single calls,CLOCK_REALTIMEcan jump backward across calls (clock_settime/adjtimex). Leavingsec : BitVec 64unconstrained withnsec : Fin 1000000000therefore captures the exact per-call invariant guaranteed across all clocks0..7.
structure Timespec where
sec : BitVec 64 := 0#64
nsec : Fin 1000000000 := ⟨0, Nat.zero_lt_succ _⟩
deriving DecidableEq, Repr, Inhabited, BEqstructure Oracle
Results of the nondeterministic system calls. Query n is the n-th nondeterministic syscall of the run, counting from zero (State.).
Step stays deterministic. The nondeterminism comes from the initial state: specs such as subroutine_ok quantify over every entry state s0, so they hold for every s0., i.e. for every possible kernel behaviour. Indexing by the query count loses nothing: given s0, the whole history before query n is determined, so a kernel that looks at that history (including the clock ID passed to clock_gettime) is still just some function of n.
-
mmap n: preferred address candidate for then-th query if it is an anonymousmmapor mremap(...,MREMAP_MAYMOVE).execMmapandexecMremapsanitize the candidate (mm/mmap.c get_unmapped_area): if it is belowMMAP_MIN_ADDR, not page-aligned, exceeds the 48-bit user virtual address space (2 ^ 48), or overlaps an already-mapped byte, they deterministically substitute the lowest free page-aligned gap in [MMAP_MIN_ADDR, 2 ^ 48) that fits, failing only when no free gap of the requested size exists, -
mremapFailn: whether then-th query refuses an mremap(...,MREMAP_MAYMOVE) with-ENOMEM(leaving the existing mapping intact), conservatively retained to over-approximate nondeterministicmremaprefusal (e.g.RLIMIT_AS/vm.or allocator fallback paths frommax_map_count mremaptommap), -
getrandom n i: byteiof the buffer filled by then-th query if it is agetrandom, -
clockGettimen: normalizedstruct timespec(0 ≤ nsec < 1_000_000_000) written by then-th query if it is a successfulclock_gettime, with no monotonicity relation between successive queries, -
exclFails: finite schedule of spurious store-exclusive (STXR*/STLXR*/STXP/STLXP) failures copied intoState.at process load time (exclFails ElfImage.). Every execution has finitely many spurious failures, adversarially placed (loadState headD false, consumed per non-faulting store-exclusive). This models eventual LL/SC progress without an exclusive monitor; a retry-lessstxris unprovable becauseexclFails = [true]is a valid initial state.
structure Oracle where
mmap : Nat → BitVec 64 := fun _ => 0#64
mremapFail : Nat → Bool := fun _ => false
getrandom : Nat → Nat → BitVec 8 := fun _ _ => 0#8
clockGettime : Nat → Timespec := fun _ => {}
exclFails : List Bool := []inductive FsEntry
Inode payload in the local file system (file byte sequence or dir directory entry).
inductive FsEntry where
| file (bytes : List (BitVec 8))
| dir
deriving DecidableEq, Repr, Inhabited, BEqinductive FdAccessMode
File-descriptor access mode (O_RDONLY, O_WRONLY, O_RDWR).
inductive FdAccessMode where
| rdonly
| wronly
| rdwr
deriving DecidableEq, Repr, Inhabited, BEqnamespace FdAccessModedef canRead
True when the open file description permits reading (O_RDONLY or O_RDWR).
def canRead : FdAccessMode → Bool
| .rdonly | .rdwr => true
| .wronly => falsedef canWrite
True when the open file description permits writing (O_WRONLY or O_RDWR).
def canWrite : FdAccessMode → Bool
| .wronly | .rdwr => true
| .rdonly => falseend FdAccessModeinductive FdKind
Descriptor backend tag for entries in FsState.:
-
localFile: regular file backed byFsState..files -
localDir: read-only directory descriptor (O_RDONLY,S_IFDIR | 0755) backed byFsState.(files fstatreturnsencodeLinuxStat .dir,readreturns-EISDIR,writereturns-EBADF,closereturns0, andpread64/lseekfail closed). -
stdio: standard stream (stdin/stdout/stderr), stored out of band from the working-directory file namespace (FsState.) inentries FsState./stdin State..trace -
custom (tag : Nat): extension slot for future loopback socket / pipe / peer-oracle backends sharingFsState.without changing anyfds FdEntryfield or invalidating file-descriptor proofs.
inductive FdKind where
| localFile
| localDir
| stdio
| custom (tag : Nat)
deriving DecidableEq, Repr, Inhabited, BEqdef MAX_LFS_FILESIZE
Linux 64-bit MAX_LFS_FILESIZE (include/, LLONG_MAX = 2 ^ 63 - 1): maximum file size and byte offset (loff_t) representable in a signed 64-bit file offset.
def MAX_LFS_FILESIZE : Nat := 2 ^ 63 - 1abbrev FsPath
Canonical relative path in the working-directory file-system model ([] = ".").
abbrev FsPath := List Stringdef splitSlash
Split s on '/ into raw path segments using pure List Char recursion so path normalization reduces directly in the Lean kernel (rfl / decide +kernel) across module boundaries.
def hasLeadingSlash
True when path begins with '/.
def hasLeadingSlash (path : String) : Bool :=
path.toList.head? == some '/'def hasDotDot
True when path contains a ".." path segment.
def hasDotDot (path : String) : Bool :=
(splitSlash path).contains ".."def normalizePath
Normalize a relative POSIX pathname into its canonical non-empty, non-"." path segments (normalizePath "./, normalizePath ".//a/, normalizePath "." = [], normalizePath "./).
def normalizePath (path : String) : FsPath :=
(splitSlash path).filter fun seg => !seg.isEmpty && seg != "."
def FsPath.
Non-empty path prefixes of segs in top-down order (FsPath. ["a", "b", "c"] = [["a"], ["a", "b"], ["a", "b", "c"]]).
def FsPath.nonEmptyPrefixes : FsPath → List FsPath
| [] => []
| s :: rest => [s] :: (nonEmptyPrefixes rest).map (s :: ·)def joinSlashChars
Join List (List Char) segments with '/ using pure List Char recursion.
def joinSlashChars : List (List Char) → List Char
| [] => []
| [s] => s
| s :: rest => s ++ ('/' :: joinSlashChars rest)
def FsPath.
Canonical String form of p : FsPath ([] ↦ ".", ["a", "b"] ↦ "a/).
def FsPath.toPathString : FsPath → String
| [] => "."
| segs => String.ofList (joinSlashChars (segs.map String.toList))structure FdEntry
Open file description entry in the process file-descriptor table (regular files, read-only directories, and standard streams).
structure FdEntry where
path : String
accMode : FdAccessMode
append : Bool := false
cloexec : Bool := false
offset : Nat := 0
kind : FdKind := .localFile
deriving DecidableEq, Repr, Inhabited, BEqstructure FsState
Process working-directory file-system tree (entries, keyed by canonical FsPath relative to AT_FDCWD, with [] denoting "."), out-of-band standard input stream bytes (stdin), and open file-descriptor table (fd ∈ [3, 1024) plus standard streams 0, 1, 2).
namespace FsStatedef maxOpenFds
Maximum open file descriptor number + 1 (RLIMIT_NOFILE = 1024).
def maxOpenFds : Nat := 1024def getEntry
Look up canonical relative path p in fs, treating CWD ([]) as always .dir.
def setEntry
Update canonical relative path p in fs..
def files
Look up path in fs under its canonical normalizePath key.
def files (fs : FsState) (path : String) : Option FsEntry :=
fs.getEntry (normalizePath path)def setFile
Update path in fs under its canonical normalizePath key ((fs. by rfl).
def setFile (fs : FsState) (path : String) (e : Option FsEntry) : FsState :=
fs.setEntry (normalizePath path) edef fdBytes
def setFd
Update descriptor fd in fs..
def allocFd
Allocate the lowest unused file descriptor fd ∈ [3, maxOpenFds).
def allocFd (fs : FsState) : Option (BitVec 64) :=
((List.range (maxOpenFds - 3)).find? fun i =>
fs.fds (BitVec.ofNat 64 (i + 3)) == none).map fun i => BitVec.ofNat 64 (i + 3)end FsStatedef fpsrMask
Modeled FPSR mask (0x0800009f): cumulative IEEE 754 exception flags IOC (bit 0), DZC (bit 1), OFC (bit 2), UFC (bit 3), IXC (bit 4), IDC (bit 7), and cumulative SIMD saturation flag QC (bit 27). All other bits ([6:5], [26:8], and AArch32-only NZCV [31:28]) are RES0.
def fpsrMask : BitVec 32 := 0x0800009f#32def fpsrIOC
FPSR. (bit 0): Invalid Operation cumulative exception flag.
def fpsrIOC : BitVec 32 := 0x00000001#32def fpsrDZC
FPSR. (bit 1): Divide by Zero cumulative exception flag.
def fpsrDZC : BitVec 32 := 0x00000002#32def fpsrOFC
FPSR. (bit 2): Overflow cumulative exception flag.
def fpsrOFC : BitVec 32 := 0x00000004#32def fpsrUFC
FPSR. (bit 3): Underflow cumulative exception flag.
def fpsrUFC : BitVec 32 := 0x00000008#32def fpsrIXC
FPSR. (bit 4): Inexact cumulative exception flag.
def fpsrIXC : BitVec 32 := 0x00000010#321 declaration not shown (lines 427–428): theorems, which Lean checks, or definitions that no headline statement uses
Arm64.
def fpsrQC
FPSR. (bit 27): Cumulative SIMD saturation flag.
def fpsrQC : BitVec 32 := 0x08000000#32structure SigAction
Per-signal 32-byte kernel disposition entry (struct k_sigaction on AArch64 Linux, include/ and arch/): handler (0 = SIG_DFL, 1 = SIG_IGN, or a recorded user-space handler address for synchronous fault signals SIGSEGV / SIGBUS), flags, restorer, and 64-bit mask. Signal dispositions are recorded and returned by rt_sigaction; asynchronous signal delivery is not modeled, and hardware faults terminate fail-closed with .Exception.
structure SigAction where
handler : BitVec 64 := 0#64
flags : BitVec 64 := 0#64
restorer : BitVec 64 := 0#64
mask : BitVec 64 := 0#64
deriving DecidableEq, Repr, Inhabited, BEqstructure SigAltStack
Per-thread alternate signal stack configuration (current->sas_ss_sp, current->sas_ss_size, current->sas_ss_flags in include/, include/, and kernel/): sp (0 when disabled), size (0 when disabled, reporting SS_DISABLE = 2), and the raw stored ssFlags word (sas_ss_flags, written verbatim by do_sigaltstack in kernel/; its SS_AUTODISARM = 1 << 31 bit suppresses on_sig_stack). Alternate-stack settings are recorded and returned by sigaltstack; signal delivery is not modeled.
@[ext]
structure SigAltStack where
sp : BitVec 64 := 0#64
size : BitVec 64 := 0#64
ssFlags : BitVec 32 := 0#32
deriving DecidableEq, Repr, Inhabited, BEqstructure State
Complete AArch64 architectural machine state, plus the process state this model keeps for Linux syscalls and hardware nondeterminism (brkStart, brk, fs, oracle, oracleIdx, exclFails, trace, status, sigActions, sigAltStack).
@[ext]
structure State where
regs : RegFile := RegFile.empty
vregs : VRegFile := VRegFile.empty
sp : BitVec 64 := 0#64
pc : BitVec 64 := 0#64
pstate : PState := PState.zero
mem : Memory := Memory.empty
tpidrEl0 : BitVec 64 := 0#64
/-- Floating-point status register (`FPSR`), storing sticky IEEE 754 exception flags
(`IOC`, `DZC`, `OFC`, `UFC`, `IXC`, `IDC`) and cumulative SIMD saturation (`QC`). -/
fpsr : BitVec 32 := 0#32
/-- Initial program break (`mm->start_brk`), fixed at load or snapshot time.
Execution (`Step`) never modifies `brkStart`. -/
brkStart : BitVec 64 := 0#64
brk : BitVec 64 := 0#64
/-- Cooperative local-disk file system and open file-descriptor table. -/
fs : FsState := {}
/-- Results of nondeterministic syscalls. Execution never modifies it. -/
oracle : Oracle := {}
/-- Number of `oracle` queries so far, i.e. the index of the next query. -/
oracleIdx : Nat := 0
/-- Remaining schedule of spurious store-exclusive (`STXR*`/`STLXR*`/`STXP`/`STLXP`) failures.
Every execution has finitely many spurious failures, adversarially placed: each
non-faulting store-exclusive consumes the head (`headD false`), failing (`Ws := 1`,
memory unchanged) on `true` and succeeding (`Ws := 0`, performing the store) on `false`
or once `exclFails` is empty. This models eventual LL/SC progress without an exclusive
monitor; a retry-less `stxr` is unprovable because `exclFails = [true]` is a valid
initial state. -/
exclFails : List Bool := []
trace : List TraceEvent := []
status : ExecStatus := .Running
/-- Per-object symbol address table: `symtab obj name` is the runtime address of
symbol `name` in object `obj` (`none` if absent or non-unique). For extern stubs
and extern data (not owned by any loaded object), pass `""` as `obj` (or any name
not matching a loaded object).
Execution (`Step`) never modifies `symtab`. -/
symtab : String → String → Option (BitVec 64) := fun _ _ => none
/-- Per-signal recorded kernel `k_sigaction` table (`1..64`), initialized to `SIG_DFL` (`0`)
with zero flags, restorer, and mask (`exec_init_sighand` / `flush_signal_handlers` in
`kernel/signal.c` for default dispositions). -/
sigActions : BitVec 32 → SigAction := fun _ => {}
/-- Per-thread alternate signal stack configuration, initialized to `{}` (`sp = 0`, `size = 0`,
raw `ssFlags = 0`, reporting `ss_flags = SS_DISABLE = 2` per `sas_ss_flags` in
`include/linux/sched/signal.h:602-608`; see `E1` in `Arm64/Trusted/Process/Assumptions.lean`
for why the raw flags are `0` rather than the `sas_ss_reset` value `SS_DISABLE`). -/
sigAltStack : SigAltStack := {}
/-- Remaining dynamic physical `Perm.rw` byte budget (`mm/mmap.c` `accountable_mapping` /
`__vm_enough_memory`). Initialized from `inputs.init.physMemAvail` in `ElfImage.loadState`
after ELF `PT_LOAD` segments and the initial stack are mapped; pure ISA steps and I/O
syscalls leave `physMemAvail` unchanged, while VM syscalls (`brk`, `mmap`, `mprotect`,
`munmap`, `mremap`) deduct newly mapped/promoted `Perm.rw` bytes and refund unmapped or
`PROT_NONE`-demoted `Perm.rw` bytes. -/
physMemAvail : Nat := 0
deriving Inhabitednamespace State1 declaration not shown (lines 521–523): theorems, which Lean checks, or definitions that no headline statement uses
Arm64.
def readVReg128
Read a 128-bit SIMD/FP register (V0..V31 / Q0..Q31).
def writeVReg128
Write a 128-bit SIMD/FP register (V0..V31 / Q0..Q31).
def readVReg64
Read the low 64 bits (D0..D31) of SIMD/FP register idx.
def readVReg64 (s : State) (idx : BitVec 5) : BitVec 64 :=
(s.readVReg128 idx).truncate 64def writeVReg64
Write a 64-bit value (D0..D31 or 64-bit vector v./v./v./v.), zero-extending to 128 bits per AArch64 architecture.
def writeVReg64 (s : State) (idx : BitVec 5) (val : BitVec 64) : State :=
s.writeVReg128 idx (val.zeroExtend 128)def readVReg32
Read the low 32 bits (S0..S31) of SIMD/FP register idx.
def readVReg32 (s : State) (idx : BitVec 5) : BitVec 32 :=
(s.readVReg128 idx).truncate 32def writeVReg32
Write a 32-bit value (S0..S31), zero-extending to 128 bits per AArch64 architecture.
def writeVReg32 (s : State) (idx : BitVec 5) (val : BitVec 32) : State :=
s.writeVReg128 idx (val.zeroExtend 128)def readReg64
Read a 64-bit register (X0..X30, SP, or XZR).
def writeReg64
Write a 64-bit register (X0..X30, SP, or XZR). Writes to XZR are ignored.
def readReg32
Read the low 32 bits of a register (W0..W30, WSP, or WZR).
def writeReg32
Write a 32-bit value to a register (W0..W30, WSP, or WZR), zero-extending to 64 bits per AArch64 architecture.
def writeReg32 (s : State) (r : Reg) (val : BitVec 32) : State :=
s.writeReg64 r (val.zeroExtend 64)def readReg
Read register at width w (W32 zero-extended to 64 bits, or W64).
def writeReg
Write register at width w (W32 truncates to 32 bits and zero-extends to 64 bits; W64 writes all 64 bits).
def advancePC
Advance PC by 4 bytes (s.).
def setPC
Set PC to newPC.
def setPState
Update PState flags.
def setFpsr
Set FPSR to fpsr.
def orFpsr
Accumulate exception or saturation flags into FPSR (s.).
def setStatus
Update execution status.
def setStatus (s : State) (st : ExecStatus) : State :=
{ s with status := st }def setBrk
Update the program break (brk).
def setPhysMemAvail
Update the remaining dynamic physical Perm. byte budget (physMemAvail).
def setPhysMemAvail (s : State) (n : Nat) : State :=
{ s with physMemAvail := n }def setFs
Update the local file system and file-descriptor state (fs).
def getSigAction
Read the recorded kernel signal disposition for signal sig.
def getSigAction (s : State) (sig : BitVec 32) : SigAction :=
s.sigActions sigdef setSigAction
Update the recorded kernel signal disposition for signal sig.
def setSigAction (s : State) (sig : BitVec 32) (act : SigAction) : State :=
{ s with sigActions := fun k => if k == sig then act else s.sigActions k }def setSigAltStack
Update the recorded alternate signal stack (sigAltStack).
def setSigAltStack (s : State) (sas : SigAltStack) : State :=
{ s with sigAltStack := sas }def nextOracle
def exclWillFail
Whether the next non-faulting store-exclusive (STXR*/STLXR*/STXP/STLXP) will spuriously fail (s.). Once the finite list s. is exhausted, store-exclusives succeed (false).
def stepExclOracle
Consume one store-exclusive failure decision (s.).
def appendTrace
Append byte-level events to the observable execution trace (s.).
def appendTrace (s : State) (evs : List TraceEvent) : State :=
{ s with trace := s.trace ++ evs }2 declarations not shown (lines 654–664): theorems, which Lean checks, or definitions that no headline statement uses
Arm64., Arm64.
def spAligned
Architectural stack pointer alignment predicate (CheckSPAlignment() in ARMv8-A pseudocode): whenever SP is used as the base register of a memory access, SP must be 16-byte aligned (SP[3:0] == 0b0000).
Structured ASL: arm-asl-extract query CheckSPAlignment (shared_pseudocode., see .agents/).
See the ARM Architecture Reference Manual (DDI 0487):
-- ARM Architecture Reference Manual (DDI 0487) HTML links for SP alignment:
-- - Section D1.4.10 ("Program Counter and stack pointer alignment", D1.4.10.2 "SP alignment checking"):
-- https://developer.arm.com/documentation/ddi0487/latest/-Part-D-The-AArch64-System-Level-Architecture/-Chapter-D1-The-AArch64-System-Level-Programmers--Model/-D1-4-Exceptions/-D1-4-10-Program-Counter-and-stack-pointer-alignment
-- - Section C6.1.3 ("Use of the stack pointer"):
-- https://developer.arm.com/documentation/ddi0487/latest/-Part-C-The-AArch64-Instruction-Set/-Chapter-C6-A64-Base-Instruction-Descriptions/-C6-1-About-the-A64-base-instructions/-C6-1-3-Use-of-the-stack-pointer
-- - Section J1.2.305 (`CheckSPAlignment` pseudocode):
-- https://developer.arm.com/documentation/ddi0487/latest/-Part-J-Architectural-Pseudocode/-Chapter-J1-A-profile-Architecture-Pseudocode/-J1-2-Pseudocode-for-AArch64-operation/-J1-2-305-CheckSPAlignment
@[inline] def spAligned (s : State) : Bool :=
(s.sp &&& 0b1111#64) == 0#64end Stateend Arm64