diff options
author | Julian Büning <julian.buening@rwth-aachen.de> | 2020-02-09 20:14:35 +0100 |
---|---|---|
committer | MartinNowack <2443641+MartinNowack@users.noreply.github.com> | 2020-06-25 16:30:10 +0100 |
commit | 248be605d192abf425eae6d14fc206e507b48380 (patch) | |
tree | 6cd8cf95dacf2e41ec78af28b2a673ae9758fbf0 /lib | |
parent | 21d2134dbd4ffe9f4252becf575969b78a43e1b8 (diff) | |
download | klee-248be605d192abf425eae6d14fc206e507b48380.tar.gz |
fix Executor: initializeGlobalAliases
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Core/Executor.cpp | 53 | ||||
-rw-r--r-- | lib/Core/Executor.h | 1 |
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); |