MIR: Add `mir_alloc_static` command to better track mutable statics
RyanGlScott opened this issue · comments
After #1959 lands, in order to use a MIR compositional override as part of verifying a Rust program that defines a mutable static item, you must specify what its value is in the override's postcondition. This proves to be quite burdensome in practice, as most overrides will have nothing to do at all with mutable static variables. This is especially true when dealing with code that involves the standard Rust libraries, as the library internals define these four mutable static items, which all overrides must now explicitly specify:
std::panicking::panic_count::LOCAL_PANIC_COUNT::__getit::VAL
std::panicking::panic_count::LOCAL_PANIC_COUNT::__getit::STATE
std::sync::remutex::current_thread_unique_ptr::X::__getit::VAL
std::sync::remutex::current_thread_unique_ptr::X::__getit::STATE
A much nicer alternative would be to track the mutable static items that are specifically used within a particular function and allow the function's specification to leave all other mutable static items unspecified. This is exactly the approach that the SAW LLVM backend uses. In order to use a mutable global variable in an LLVM specification, the preconditions must explicitly indicate this using the llvm_alloc_global
command. When that specification is used as a compositional override, any mutable global variables that were:
- Allocated with
llvm_alloc_global
in the preconditions - Lack corresponding
llvm_points_to
statements in the postconditions
Will have their underlying memory invalidated. If the LLVM function doesn't make use of the invalidated mutable globals, this is not a problem, but crucible-llvm
will fail to simulate any function that does make use of invalidated globals.
This issue proposes re-engineering the design of the SAW MIR backend to support tracking mutable statics in the way that the LLVM backend does. More specifically, we will need to:
- Introduce a
mir_alloc_static
command, mirroringllvm_alloc_global
- Tweak the
crucible-mir
memory model to support memory invalidation. At a minimum, this will first require fixing GaloisInc/crucible#1109. - Revising the logic described in
Note [MIR compositional verification and mutable allocations]
.
While this is primarily motivated by the MIR backend's treatment of mutable static items, the same memory invalidation approach would also work for local mutable allocations (i.e., things allocated with mir_alloc_mut
).