about summary refs log tree commit diff homepage
path: root/lib/Core
diff options
context:
space:
mode:
authorMartin Nowack <m.nowack@imperial.ac.uk>2024-02-27 16:05:19 +0000
committerCristian Cadar <c.cadar@imperial.ac.uk>2024-02-29 19:57:08 +0000
commit2cae55383a11fbcb3fcc1a8bac67949e2245d451 (patch)
tree9795b5a026b61fc32e1783503de8060fff7811d9 /lib/Core
parent46b4c4885c0162893835081e2d9d731ca7a8341c (diff)
downloadklee-2cae55383a11fbcb3fcc1a8bac67949e2245d451.tar.gz
Support external call concretisation policies for referenced objects
Provide an additional argument to select the concretisation policy.

Fix a bug where the concretisation of a shared memory object was visible
across different states by retrieving a writable object state first.
Diffstat (limited to 'lib/Core')
-rw-r--r--lib/Core/Executor.cpp14
1 files changed, 9 insertions, 5 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index e37045ee..1af88d88 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -4020,12 +4020,16 @@ void Executor::callExternalFunction(ExecutionState &state, KInstruction *target,
           state, a, "external call", ExternalCalls == ExternalCallPolicy::All);
       cvalue->toMemory(&args[wordIndex]);
 
-      ObjectPair op;
-      // Checking to see if the argument is a pointer to something
-      if (cvalue->getWidth() == Context::get().getPointerWidth() &&
-          state.addressSpace.resolveOne(cvalue, op)) {
-        op.second->flushToConcreteStore(solver.get(), state);
+      // If the argument points to a valid and writable object, concretise it
+      // according to the selected policy
+      if (ObjectPair op;
+          cvalue->getWidth() == Context::get().getPointerWidth() &&
+          state.addressSpace.resolveOne(cvalue, op) && !op.second->readOnly) {
+        auto *os = state.addressSpace.getWriteable(op.first, op.second);
+        os->flushToConcreteStore(*this, state,
+                                 ExternalCalls == ExternalCallPolicy::All);
       }
+
       wordIndex += (cvalue->getWidth() + 63) / 64;
     } else {
       ref<Expr> arg = toUnique(state, a);