diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp index bf63f898b9..e7626e58a6 100644 --- a/lib/Module/ModuleUtil.cpp +++ b/lib/Module/ModuleUtil.cpp @@ -207,6 +207,7 @@ klee::linkModules(std::vector> &modules, for (auto &module : modules) { if (!module || !containsUsedSymbols(module.get())) continue; + if (!linkTwoModules(composite.get(), std::move(module), errorMsg)) { // Linking failed errorMsg = "Linking module containing '__attribute__((used))'" diff --git a/lib/Runner/run_klee.cpp b/lib/Runner/run_klee.cpp index a4b5a063eb..937e2f1974 100644 --- a/lib/Runner/run_klee.cpp +++ b/lib/Runner/run_klee.cpp @@ -766,8 +766,9 @@ preparePOSIX(std::vector> &loadedModules, break; } - if (!mainFn) + if (!mainFn) { klee_error("Entry function '%s' not found in module.", EntryPoint.c_str()); + } mainFn->setName("__klee_posix_wrapped_main"); // Add a definition of the entry function if needed. This is the case if we @@ -1091,7 +1092,12 @@ createLibCWrapper(std::vector> &modules, // argv), since it does not explicitly take an envp argument. auto &ctx = modules[0]->getContext(); Function *userMainFn = modules[0]->getFunction(intendedFunction); - assert(userMainFn && "unable to get user main"); + + if (!userMainFn) { + klee_error("Entry function '%s' not found in module.", + intendedFunction.str().c_str()); + } + // Rename entry point using a prefix userMainFn->setName("__user_" + intendedFunction); diff --git a/test/Runtime/Uclibc/FunctionNotFound.c b/test/Runtime/Uclibc/FunctionNotFound.c new file mode 100644 index 0000000000..d332352305 --- /dev/null +++ b/test/Runtime/Uclibc/FunctionNotFound.c @@ -0,0 +1,9 @@ +// RUN: %clang %s -emit-llvm %O0opt -c -o %t1.bc +// RUN: rm -rf %t.klee-out +// RUN: not %klee --entry-point=main --output-dir=%t.klee-out --libc=uclibc --exit-on-error %t1.bc 2>&1 | FileCheck %s + +int foo(int argc, char *argv[]) { + return 0; +} + +// CHECK: KLEE: ERROR: Entry function 'main' not found in module.