-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mir_static
and mir_static_initializer
#1941
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are the highlights of the patch:
-- | Unlike @LLVMPointsTo@ and @JVMPointsTo@, 'MirPointsTo' contains a /list/ of | ||
-- 'MS.SetupValue's on the right-hand side. This is due to how slices are | ||
-- represented in @crucible-mir-comp@, which stores the list of values | ||
-- referenced by the slice. The @mir_points_to@ command, on the other hand, | ||
-- always creates 'MirPointsTo' values with exactly one value in the list (see | ||
-- the @firstPointsToReferent@ function in "SAWScript.Crucible.MIR.Override"). | ||
data MirPointsTo = MirPointsTo MS.ConditionMetadata MS.AllocIndex [MS.SetupValue MIR] | ||
data MirPointsTo = MirPointsTo MS.ConditionMetadata (MS.SetupValue MIR) [MS.SetupValue MIR] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first commit in this PR is all about this change, where we represent the reference value in a MirPointsTo
statement with a SetupValue
instead of an AllocIndex
. This is required to support things like mir_points_to (mir_static ...) ...
, as mir_static
references do not have an AllocIndex
. There is a bit of code churn that results from this change, but it's mostly straightforward. (I'll note one exception in another inline comment.)
-- | Take a 'MS.SetupValue' that is assumed to be a bare 'MS.SetupVar' and | ||
-- extract the underlying 'MS.AllocIndex'. If this assumption does not hold, | ||
-- this function will raise an error. | ||
-- | ||
-- This is used in conjunction with 'MirPointsTo' values. With the way that | ||
-- @crucible-mir-comp@ is currently set up, the only sort of 'MS.SetupValue' | ||
-- that will be put into a 'MirPointsTo' value's left-hand side is a | ||
-- 'MS.SetupVar', so we can safely use this function on such 'MS.SetupValue's. | ||
-- Other parts of SAW can break this assumption (e.g., if you wrote something | ||
-- like @mir_points_to (mir_global "X") ...@ in a SAW specification), but these | ||
-- parts of SAW are not used in @crucible-mir-comp@. | ||
setupVarAllocIndex :: Applicative m => MS.SetupValue MIR -> m MS.AllocIndex | ||
setupVarAllocIndex (MS.SetupVar idx) = pure idx | ||
setupVarAllocIndex val = | ||
error $ "setupVarAllocIndex: Expected SetupVar, received: " | ||
++ show (MS.ppSetupValue val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the one part of crucible-mir-comp
that was somewhat tricky to adapt to the AllocIndex
-> SetupValue
change. I believe it should be safe here to assume that this particular class of SetupValue
s should always be SetupVar
s (which have an AllocIndex
), but please double-check my understanding here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds right to me, and matches the changes I see elsewhere in the diff.
@@ -2892,6 +2896,68 @@ point of a call to `f`. This specification also constrains `y` to prevent | |||
signed integer overflow resulting from the `x + y` expression in `f`, | |||
which is undefined behavior in C. | |||
|
|||
### MIR static items |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation for mir_static
and mir_static_initializer
. There is more that could be said here about how mutable static items interact with overrides, but I need to implement overrides first before I can meaningfully talk about this :)
} | ||
|
||
{- | ||
Note [Translating MIR statics in SAW] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Translating static items is a somewhat involved process, so I wrote up a high-level description of this works in this Note.
-- There is quite a bit of faff below, all for the sake of translating | ||
-- top-level static values. See Note [Translating MIR statics in SAW] for | ||
-- a high-level description of what this code is doing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code below here is the implementation of Note [Translating MIR statics in SAW]
.
In an upcoming commit, we will want to be able to write things such as `mir_points_to (mir_global "X") ...`. This isn't currently possible with the way `MirPointsTo` is currently designed, as it expects the left-hand side of a `mir_points_to` statement to always be an `AllocIndex`, i.e., something created via `mir_alloc`/`mir_alloc_mut`. This patch generalizes the `AllocIndex` field in `MirPointsTo` to a `SetupValue` to allow other forms of references to be used in `mir_points_to` statements. In most places, this is a simple matter of wrapping the `AllocIndex` in a `SetupVar`. It was slightly tricky to update the code in `crucible-mir-comp` to accommodate this, as that code relies on a subtle assumption about the left-hand sides of `MirPointsTo` values only originating from `SetupVar`s. I have documented this assumption in the new `setupVarAllocIndex` function.
2c38dd4
to
c6af1c3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks generally reasonable to me.
command, just like with other forms of references. Immutable static items | ||
(e.g., `static X: u8 = 42`) are initialized implicitly in every SAW | ||
specification, so there is no need for users to do so manually. Mutable static | ||
items (e.g., `static mut Y: u8 = 27`), on the other hand, are *not* initialized | ||
implicitly, and users must explicitly pick a value to initialize them with. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eventually, this logic should be updated to treat statics that are non-mut
but also non-Freeze
statics, such as static Z: AtomicU8 = ...;
, the same way we treat mut
statics. These statics get compiled to mutable LLVM globals, and the values stored there can be modified at run time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened #1957 for this.
-- | Take a 'MS.SetupValue' that is assumed to be a bare 'MS.SetupVar' and | ||
-- extract the underlying 'MS.AllocIndex'. If this assumption does not hold, | ||
-- this function will raise an error. | ||
-- | ||
-- This is used in conjunction with 'MirPointsTo' values. With the way that | ||
-- @crucible-mir-comp@ is currently set up, the only sort of 'MS.SetupValue' | ||
-- that will be put into a 'MirPointsTo' value's left-hand side is a | ||
-- 'MS.SetupVar', so we can safely use this function on such 'MS.SetupValue's. | ||
-- Other parts of SAW can break this assumption (e.g., if you wrote something | ||
-- like @mir_points_to (mir_global "X") ...@ in a SAW specification), but these | ||
-- parts of SAW are not used in @crucible-mir-comp@. | ||
setupVarAllocIndex :: Applicative m => MS.SetupValue MIR -> m MS.AllocIndex | ||
setupVarAllocIndex (MS.SetupVar idx) = pure idx | ||
setupVarAllocIndex val = | ||
error $ "setupVarAllocIndex: Expected SetupVar, received: " | ||
++ show (MS.ppSetupValue val) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds right to me, and matches the changes I see elsewhere in the diff.
This adds support for the `mir_static` and `mir_static_initializer` functions in the MIR backend, which are used to write specifications involving top-level `static` values. These behave like the `llvm_global` and `llvm_global_initializer` functions in the LLVM backend, but with the following differences: 1. There is nor MIR counterpart to the `llvm_alloc_global` command, as MIR static values are not "allocated" in the same way that LLVM globals are. (We still require users to initialize mutable MIR statics, however.) 2. By design, static references created with `mir_static` cannot alias allocations created with `mir_alloc`, as the two forms of allocations are handled through different mechanisms in the `crucible-mir` memory model. This checks off one box in #1859.
c6af1c3
to
b0e7c25
Compare
This adds support for the
mir_static
andmir_static_initializer
functions in the MIR backend, which are used to write specifications involving top-levelstatic
values. These behave like thellvm_global
andllvm_global_initializer
functions in the LLVM backend, but with the following differences:There is nor MIR counterpart to the
llvm_alloc_global
command, as MIR static values are not "allocated" in the same way that LLVM globals are. (We still require users to initialize mutable MIR statics, however.)By design, static references created with
mir_static
cannot alias allocations created withmir_alloc
, as the two forms of allocations are handled through different mechanisms in thecrucible-mir
memory model.This checks off one box in #1859.