GaloisInc / saw-script

The SAW scripting language.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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:

  1. Allocated with llvm_alloc_global in the preconditions
  2. 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, mirroring llvm_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).