about summary refs log tree commit diff homepage
path: root/lib
diff options
context:
space:
mode:
authorJulian Büning <julian.buening@rwth-aachen.de>2020-02-09 20:14:35 +0100
committerMartinNowack <2443641+MartinNowack@users.noreply.github.com>2020-06-25 16:30:10 +0100
commit248be605d192abf425eae6d14fc206e507b48380 (patch)
tree6cd8cf95dacf2e41ec78af28b2a673ae9758fbf0 /lib
parent21d2134dbd4ffe9f4252becf575969b78a43e1b8 (diff)
downloadklee-248be605d192abf425eae6d14fc206e507b48380.tar.gz
fix Executor: initializeGlobalAliases
Diffstat (limited to 'lib')
-rw-r--r--lib/Core/Executor.cpp53
-rw-r--r--lib/Core/Executor.h1
2 files changed, 39 insertions, 15 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index 9209be8a..3272201a 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -755,23 +755,46 @@ void Executor::allocateGlobalObjects(ExecutionState &state) {
   }
 }
 
-void Executor::initializeGlobalAliases() {
-  const Module *m = kmodule->module.get();
-
-  // link aliases to their definitions (if bound)
-  for (auto i = m->alias_begin(), ie = m->alias_end(); i != ie; ++i) {
-    // Map the alias to its aliasee's address. This works because we have
-    // addresses for everything, even undefined functions.
-
-    // Alias may refer to other alias, not necessarily known at this point.
-    // Thus, resolve to real alias directly.
-    const GlobalAlias *alias = &*i;
-    while (const auto *ga = dyn_cast<GlobalAlias>(alias->getAliasee())) {
-      assert(ga != alias && "alias pointing to itself");
-      alias = ga;
+void Executor::initializeGlobalAlias(const llvm::Constant *c) {
+  // aliasee may either be a global value or constant expression
+  const auto *ga = dyn_cast<GlobalAlias>(c);
+  if (ga) {
+    if (globalAddresses.count(ga)) {
+      // already resolved by previous invocation
+      return;
     }
+    const llvm::Constant *aliasee = ga->getAliasee();
+    if (const auto *gv = dyn_cast<GlobalValue>(aliasee)) {
+      // aliasee is global value
+      auto it = globalAddresses.find(gv);
+      // uninitialized only if aliasee is another global alias
+      if (it != globalAddresses.end()) {
+        globalAddresses.emplace(ga, it->second);
+        return;
+      }
+    }
+  }
+
+  // resolve aliases in all sub-expressions
+#if LLVM_VERSION_CODE >= LLVM_VERSION(4, 0)
+  for (const auto *op : c->operand_values()) {
+#else
+  for (auto &it : c->operands()) {
+    const auto *op = &*it;
+#endif
+    initializeGlobalAlias(cast<Constant>(op));
+  }
 
-    globalAddresses.insert(std::make_pair(&*i, evalConstant(alias->getAliasee())));
+  if (ga) {
+    // aliasee is constant expression (or global alias)
+    globalAddresses.emplace(ga, evalConstant(ga->getAliasee()));
+  }
+}
+
+void Executor::initializeGlobalAliases() {
+  const Module *m = kmodule->module.get();
+  for (const GlobalAlias &a : m->aliases()) {
+    initializeGlobalAlias(&a);
   }
 }
 
diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h
index 61664193..7acbc60f 100644
--- a/lib/Core/Executor.h
+++ b/lib/Core/Executor.h
@@ -226,6 +226,7 @@ private:
   MemoryObject *addExternalObject(ExecutionState &state, void *addr, 
                                   unsigned size, bool isReadOnly);
 
+  void initializeGlobalAlias(const llvm::Constant *c);
   void initializeGlobalObject(ExecutionState &state, ObjectState *os, 
 			      const llvm::Constant *c,
 			      unsigned offset);