aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Module
diff options
context:
space:
mode:
authorAndrea Mattavelli <andreamattavelli@users.noreply.github.com>2017-02-21 22:23:52 +0000
committerGitHub <noreply@github.com>2017-02-21 22:23:52 +0000
commit62ee2e574b9f920e6679c91da25f8941552277d9 (patch)
treeb476d2df666340ad26f63d8fd3c4e07b2a248f11 /lib/Module
parent27f414cc48bf086552ee4cba7784354c162a8301 (diff)
parent70715151746a24c4c6919292956111b00fcd3a26 (diff)
downloadklee-62ee2e574b9f920e6679c91da25f8941552277d9.tar.gz
Merge pull request #514 from delcypher/fix_klee_get_direct_call_bitcast_weak_alias
Fix assertion failure when klee::getDirectCallTarget() is used on call to bitcasted weak alias
Diffstat (limited to 'lib/Module')
-rw-r--r--lib/Module/ModuleUtil.cpp42
1 files changed, 26 insertions, 16 deletions
diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp
index a5394067..2cd41c89 100644
--- a/lib/Module/ModuleUtil.cpp
+++ b/lib/Module/ModuleUtil.cpp
@@ -436,23 +436,33 @@ Module *klee::linkWithLibrary(Module *module,
#endif
}
-
-
-Function *klee::getDirectCallTarget(CallSite cs) {
+Function *klee::getDirectCallTarget(CallSite cs, bool moduleIsFullyLinked) {
Value *v = cs.getCalledValue();
- if (Function *f = dyn_cast<Function>(v)) {
- return f;
- } else if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(v)) {
- if (ce->getOpcode()==Instruction::BitCast)
- if (Function *f = dyn_cast<Function>(ce->getOperand(0)->stripPointerCasts()))
- return f;
-
- // NOTE: This assert may fire, it isn't necessarily a problem and
- // can be disabled, I just wanted to know when and if it happened.
- assert(0 && "FIXME: Unresolved direct target for a constant expression.");
- }
-
- return 0;
+ bool viaConstantExpr = false;
+ // Walk through aliases and bitcasts to try to find
+ // the function being called.
+ do {
+ if (Function *f = dyn_cast<Function>(v)) {
+ return f;
+ } else if (llvm::GlobalAlias *ga = dyn_cast<GlobalAlias>(v)) {
+ if (moduleIsFullyLinked || !(ga->mayBeOverridden())) {
+ v = ga->getAliasee();
+ } else {
+ v = NULL;
+ }
+ } else if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(v)) {
+ viaConstantExpr = true;
+ v = ce->getOperand(0)->stripPointerCasts();
+ } else {
+ v = NULL;
+ }
+ } while (v != NULL);
+
+ // NOTE: This assert may fire, it isn't necessarily a problem and
+ // can be disabled, I just wanted to know when and if it happened.
+ assert((!viaConstantExpr) &&
+ "FIXME: Unresolved direct target for a constant expression");
+ return NULL;
}
static bool valueIsOnlyCalled(const Value *v) {