-
Notifications
You must be signed in to change notification settings - Fork 63
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
Proper handling of globals in crucible_llvm_verify #203
Comments
As part of the LLVM module translation step, there is a special Crucible function generated that specifically sets up the globals with their initial values. This is included in the returned To achieve what you want, the memory should be produced fresh each verification by calling Probably special support for |
I tried using the result of We need a variant of |
A related question: Would it make sense for the Crucible LLVM memory model to include a special read-only segment? It would be nice to have a way to ensure that the values of constant globals will never be overwritten at runtime. |
Yes, I think special handling for read-only values is a good idea. In particular, reads from read-only data should never alias with symbolic writes, so they can be made much more efficient. |
This has been partially addressed in It would be nice to be able to say "this global variable should be initialized to what it is initialized to in the code" as @robdockins suggests. Even if the variable is mutable, this could be done in a |
I was mistaken when I said that global values are not currently initialized. This is not currently implemented at all (all globals are allocated and initialized at the start of every verification), but I am working on the solution outlined above. |
Instead, add crucible_global_initializer. The current behavior of globals is unsound (ref: GaloisInc#203). Instead, we provide an option for the user to initialize globals as necessary. It would be best to have more informative error messages when the symbolic simulator accesses invalid memory because a global hasn't been initialized.
Instead, add crucible_global_initializer. The current behavior of globals is unsound (ref: GaloisInc#203). Instead, we provide an option for the user to initialize globals as necessary. It would be best to have more informative error messages when the symbolic simulator accesses invalid memory because a global hasn't been initialized. I initially assumed that `SetupGlobalInitializer name` should have the same type as `SetupGlobal name`. However, `SetupGlobal` adds a pointer wrapper (as it should). Instead, we now directly translate the type of the global's initializer from the LLVM AST.
This was fixed in #311 |
While #311 improved the situation, it's still easy to create an unsound proof. In the following, the preconditions are met for the override for /*
nix-shell --pure -p "with import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-19.03.tar.gz) {}; clang_7" --run "clang -O0 -emit-llvm -c *.c"
nix-shell --pure -p "with import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-19.03.tar.gz) {}; llvm_7" --run "llvm-dis *.bc"
*/
int glob = 42;
int f(int x) {
glob = 55;
return x + x;
}
int g(int x) {
f(x);
return glob;
}
int main() {
return g(5);
}
One solution would be to require specifications for global variables to come in pairs, so that whenever you have a precondition specifying the value of a global variable, there is an implicit postcondition that it remains constant, unless you specify explicitly how it changes. |
This happens to be true for all assignments that a function may make, not just those to globals. See #30. I think it's fine to release 0.3 without fixing that, but I want to fix it in time for 1.0. |
Yes, this seems like a special case of that issue. Let's continue the discussion there. |
Expose Simulator.What4 helper functions for use in compositional crux-mir
Currently, each run of the symbolic simulator in
crucible_llvm_verify
starts in a memory state where all declared globals are allocated and set to their initial values. This is fine for global constants, but is unsound for mutable global variables: Basically it's like having implicit, unchecked preconditions saying that when the function is called, all globals contain the same values they were initialized with.We need to run the symbolic simulator with a different initial memory state: Constant globals should all be initialized to their values, but the memory locations for mutable globals should be empty. If a function reads from a global variable
foo
, then its spec must contain a statementcrucible_points_to (crucible_global "foo") rhs
in its preconditions in order for the simulation to succeed.The text was updated successfully, but these errors were encountered: