diff options
-rw-r--r-- | .travis.yml | 5 | ||||
-rw-r--r-- | include/klee/Internal/Module/LLVMPassManager.h | 22 | ||||
-rw-r--r-- | include/klee/Internal/Support/ModuleUtil.h | 37 | ||||
-rw-r--r-- | lib/Core/Executor.cpp | 5 | ||||
-rw-r--r-- | lib/Module/InstructionInfoTable.cpp | 2 | ||||
-rw-r--r-- | lib/Module/KModule.cpp | 6 | ||||
-rw-r--r-- | lib/Module/ModuleUtil.cpp | 89 | ||||
-rw-r--r-- | lib/Module/Optimize.cpp | 8 | ||||
-rw-r--r-- | lib/Solver/Z3Solver.h | 2 | ||||
-rw-r--r-- | tools/klee/main.cpp | 61 |
10 files changed, 145 insertions, 92 deletions
diff --git a/.travis.yml b/.travis.yml index 9a337952..09147e38 100644 --- a/.travis.yml +++ b/.travis.yml @@ -107,7 +107,10 @@ addons: - libselinux1-dev - cmake -cache: apt +cache: + apt: true + directories: + - $HOME/Library/Caches/Homebrew before_install: ########################################################################### # Set up the locations to get various packages from diff --git a/include/klee/Internal/Module/LLVMPassManager.h b/include/klee/Internal/Module/LLVMPassManager.h new file mode 100644 index 00000000..5a1b8927 --- /dev/null +++ b/include/klee/Internal/Module/LLVMPassManager.h @@ -0,0 +1,22 @@ +//===-- InstructionInfoTable.h ----------------------------------*- C++ -*-===// +// +// The KLEE Symbolic Virtual Machine +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) +#include "llvm/IR/LegacyPassManager.h" +#else +#include "llvm/PassManager.h" +#endif + +namespace klee { +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) +typedef llvm::legacy::PassManager LegacyLLVMPassManagerTy; +#else +typedef llvm::PassManager LegacyLLVMPassManagerTy; +#endif +} diff --git a/include/klee/Internal/Support/ModuleUtil.h b/include/klee/Internal/Support/ModuleUtil.h index c85ba591..78998051 100644 --- a/include/klee/Internal/Support/ModuleUtil.h +++ b/include/klee/Internal/Support/ModuleUtil.h @@ -7,22 +7,37 @@ // //===----------------------------------------------------------------------===// -#ifndef KLEE_TRANSFORM_UTIL_H -#define KLEE_TRANSFORM_UTIL_H +#ifndef KLEE_MODULE_UTIL_H +#define KLEE_MODULE_UTIL_H + +#include "klee/Config/Version.h" + +#if LLVM_VERSION_CODE > LLVM_VERSION(3, 2) +#include "llvm/IR/Module.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/LLVMContext.h" +#else +#include "llvm/Module.h" +#include "llvm/Function.h" +#include "llvm/LLVMContext.h" +#endif -#include <string> +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) +#include "llvm/IR/CallSite.h" +#else +#include "llvm/Support/CallSite.h" +#endif -namespace llvm { - class Function; - class Instruction; - class Module; - class CallSite; -} +#include <string> namespace klee { - + /// Load llvm module from a bitcode archive file. + llvm::Module *loadModule(llvm::LLVMContext &ctx, + const std::string &path, + std::string &errorMsg); + /// Link a module with a specified bitcode archive. - llvm::Module *linkWithLibrary(llvm::Module *module, + llvm::Module *linkWithLibrary(llvm::Module *module, const std::string &libraryName); /// Return the Function* target of a Call or Invoke instruction, or diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index d34f394d..dc2bca4e 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -3034,7 +3034,7 @@ void Executor::callExternalFunction(ExecutionState &state, return; if (NoExternals && !okExternals.count(function->getName())) { - klee_warning("Calling not-OK external function : %s\n", + klee_warning("Disallowed call to external function: %s\n", function->getName().str().c_str()); terminateStateOnError(state, "externals disallowed", User); return; @@ -3083,7 +3083,8 @@ void Executor::callExternalFunction(ExecutionState &state, if (i != arguments.size()-1) os << ", "; } - os << ")"; + os << ") at "; + state.pc->printFileLine(os); if (AllExternalWarnings) klee_warning("%s", os.str().c_str()); diff --git a/lib/Module/InstructionInfoTable.cpp b/lib/Module/InstructionInfoTable.cpp index be5ceba1..3ba4895e 100644 --- a/lib/Module/InstructionInfoTable.cpp +++ b/lib/Module/InstructionInfoTable.cpp @@ -87,7 +87,7 @@ static void buildInstructionToLineMap(Module *m, } } -static std::string getDSPIPath(DILocation Loc) { +static std::string getDSPIPath(const DILocation &Loc) { std::string dir = Loc.getDirectory(); std::string file = Loc.getFilename(); if (dir.empty() || file[0] == '/') { diff --git a/lib/Module/KModule.cpp b/lib/Module/KModule.cpp index 4acda09a..aafabacc 100644 --- a/lib/Module/KModule.cpp +++ b/lib/Module/KModule.cpp @@ -47,7 +47,7 @@ #include "llvm/IR/CallSite.h" #endif -#include "llvm/PassManager.h" +#include "klee/Internal/Module/LLVMPassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_os_ostream.h" @@ -305,7 +305,7 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts, // invariant transformations that we will end up doing later so that // optimize is seeing what is as close as possible to the final // module. - PassManager pm; + LegacyLLVMPassManagerTy pm; pm.add(new RaiseAsmPass()); if (opts.CheckDivZero) pm.add(new DivCheckPass()); if (opts.CheckOvershift) pm.add(new OvershiftCheckPass()); @@ -373,7 +373,7 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts, // linked in something with intrinsics but any external calls are // going to be unresolved. We really need to handle the intrinsics // directly I think? - PassManager pm3; + LegacyLLVMPassManagerTy pm3; pm3.add(createCFGSimplificationPass()); switch(SwitchType) { case eSwitchTypeInternal: break; diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp index c7f1c6d9..1642f6d7 100644 --- a/lib/Module/ModuleUtil.cpp +++ b/lib/Module/ModuleUtil.cpp @@ -19,7 +19,6 @@ #endif #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) -#include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" @@ -47,16 +46,17 @@ #include "llvm/IR/AssemblyAnnotationWriter.h" #endif -#include "llvm/Support/raw_ostream.h" +#if LLVM_VERSION_CODE <= LLVM_VERSION(2, 9) +// for llvm::error_code +#include "llvm/Support/system_error.h" +#endif + #include "llvm/Analysis/ValueTracking.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" -#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) -#include "llvm/Support/CallSite.h" -#else -#include "llvm/IR/CallSite.h" -#endif - #include <map> #include <set> #include <fstream> @@ -399,7 +399,7 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er #endif -Module *klee::linkWithLibrary(Module *module, +Module *klee::linkWithLibrary(Module *module, const std::string &libraryName) { KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Linking file " << libraryName << "\n"); #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) @@ -519,11 +519,11 @@ Module *klee::linkWithLibrary(Module *module, llvm::sys::Path libraryPath(libraryName); bool native = false; - + if (linker.LinkInFile(libraryPath, native)) { klee_error("Linking library %s failed", libraryName.c_str()); } - + return linker.releaseModule(); #endif } @@ -566,12 +566,12 @@ static bool valueIsOnlyCalled(const Value *v) { // Make sure the instruction is a call or invoke. CallSite cs(const_cast<Instruction *>(instr)); if (!cs) return false; - + // Make sure that the value is only the target of this call and // not an argument. if (cs.hasArgument(v)) return false; - } else if (const llvm::ConstantExpr *ce = + } else if (const llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(*it)) { if (ce->getOpcode()==Instruction::BitCast) if (valueIsOnlyCalled(ce)) @@ -592,3 +592,66 @@ static bool valueIsOnlyCalled(const Value *v) { bool klee::functionEscapes(const Function *f) { return !valueIsOnlyCalled(f); } + +#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) + +Module *klee::loadModule(LLVMContext &ctx, const std::string &path, std::string &errorMsg) { + OwningPtr<MemoryBuffer> bufferPtr; + error_code ec = MemoryBuffer::getFileOrSTDIN(path.c_str(), bufferPtr); + if (ec) { + errorMsg = ec.message(); + return 0; + } + + Module *module = getLazyBitcodeModule(bufferPtr.get(), ctx, &errorMsg); + + if (!module) { + return 0; + } + if (module->MaterializeAllPermanently(&errorMsg)) { + delete module; + return 0; + } + + // In the case of success LLVM will take ownership of the module. + // Therefore we need to take ownership away from the `bufferPtr` otherwise the + // allocated memory will be deleted twice. + bufferPtr.take(); + + errorMsg = ""; + return module; +} + +#else + +Module *klee::loadModule(LLVMContext &ctx, const std::string &path, std::string &errorMsg) { + auto buffer = MemoryBuffer::getFileOrSTDIN(path.c_str()); + if (!buffer) { + errorMsg = buffer.getError().message().c_str(); + return nullptr; + } + +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) + auto errorOrModule = getLazyBitcodeModule(std::move(buffer.get()), ctx); +#else + auto errorOrModule = getLazyBitcodeModule(buffer->get(), ctx); +#endif + + if (!errorOrModule) { + errorMsg = errorOrModule.getError().message().c_str(); + return nullptr; + } + // The module has taken ownership of the MemoryBuffer so release it + // from the std::unique_ptr + buffer->release(); + auto module = *errorOrModule; + + if (auto ec = module->materializeAllPermanently()) { + errorMsg = ec.message(); + return nullptr; + } + + errorMsg = ""; + return module; +} +#endif diff --git a/lib/Module/Optimize.cpp b/lib/Module/Optimize.cpp index c0f3f34c..21c77c04 100644 --- a/lib/Module/Optimize.cpp +++ b/lib/Module/Optimize.cpp @@ -16,7 +16,7 @@ //===----------------------------------------------------------------------===// #include "klee/Config/Version.h" -#include "llvm/PassManager.h" +#include "klee/Internal/Module/LLVMPassManager.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Support/CommandLine.h" @@ -80,7 +80,7 @@ static cl::alias A1("S", cl::desc("Alias for --strip-debug"), // A utility function that adds a pass to the pass manager but will also add // a verifier pass after if we're supposed to verify. -static inline void addPass(PassManager &PM, Pass *P) { +static inline void addPass(klee::LegacyLLVMPassManagerTy &PM, Pass *P) { // Add the pass to the pass manager... PM.add(P); @@ -92,7 +92,7 @@ static inline void addPass(PassManager &PM, Pass *P) { namespace llvm { -static void AddStandardCompilePasses(PassManager &PM) { +static void AddStandardCompilePasses(klee::LegacyLLVMPassManagerTy &PM) { PM.add(createVerifierPass()); // Verify that input is correct #if LLVM_VERSION_CODE < LLVM_VERSION(3, 0) @@ -166,7 +166,7 @@ static void AddStandardCompilePasses(PassManager &PM) { void Optimize(Module *M, const std::string &EntryPoint) { // Instantiate the pass manager to organize the passes. - PassManager Passes; + klee::LegacyLLVMPassManagerTy Passes; // If we're verifying, start off with a verification pass. if (VerifyEach) diff --git a/lib/Solver/Z3Solver.h b/lib/Solver/Z3Solver.h index 8dc97e06..105c7c75 100644 --- a/lib/Solver/Z3Solver.h +++ b/lib/Solver/Z3Solver.h @@ -14,7 +14,7 @@ #include "klee/Solver.h" namespace klee { -/// Z3Solver - A solver complete solver based on Z3 +/// Z3Solver - A complete solver based on Z3 class Z3Solver : public Solver { public: /// Z3Solver - Construct a new Z3Solver. diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp index e7f79243..d04963e1 100644 --- a/tools/klee/main.cpp +++ b/tools/klee/main.cpp @@ -25,7 +25,6 @@ #if LLVM_VERSION_CODE > LLVM_VERSION(3, 2) #include "llvm/IR/Constants.h" -#include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Instruction.h" @@ -33,7 +32,6 @@ #include "llvm/IR/LLVMContext.h" #else #include "llvm/Constants.h" -#include "llvm/Module.h" #include "llvm/Type.h" #include "llvm/InstrTypes.h" #include "llvm/Instruction.h" @@ -606,7 +604,7 @@ std::string KleeHandler::getRunTimeLibraryPath(const char *argv0) { { KLEE_DEBUG_WITH_TYPE("klee_runtime", llvm::dbgs() << "Using installed KLEE library runtime: "); - libDir = toolRoot.str().substr(0, + libDir = toolRoot.str().substr(0, toolRoot.str().size() - strlen( KLEE_INSTALL_BIN_DIR )); llvm::sys::path::append(libDir, KLEE_INSTALL_RUNTIME_DIR); } @@ -1235,56 +1233,13 @@ int main(int argc, char **argv, char **envp) { sys::SetInterruptFunction(interrupt_handle); // Load the bytecode... - std::string ErrorMsg; + std::string errorMsg; LLVMContext ctx; - Module *mainModule = 0; -#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) - OwningPtr<MemoryBuffer> BufferPtr; - error_code ec=MemoryBuffer::getFileOrSTDIN(InputFile.c_str(), BufferPtr); - if (ec) { + Module *mainModule = klee::loadModule(ctx, InputFile, errorMsg); + if (!mainModule) { klee_error("error loading program '%s': %s", InputFile.c_str(), - ec.message().c_str()); - } - - mainModule = getLazyBitcodeModule(BufferPtr.get(), ctx, &ErrorMsg); - - if (mainModule) { - if (mainModule->MaterializeAllPermanently(&ErrorMsg)) { - delete mainModule; - mainModule = 0; - } + errorMsg.c_str()); } - if (!mainModule) - klee_error("error loading program '%s': %s", InputFile.c_str(), - ErrorMsg.c_str()); -#else - auto Buffer = MemoryBuffer::getFileOrSTDIN(InputFile.c_str()); - if (!Buffer) - klee_error("error loading program '%s': %s", InputFile.c_str(), - Buffer.getError().message().c_str()); - -#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) - auto mainModuleOrError = getLazyBitcodeModule(std::move(Buffer.get()), ctx); -#else - auto mainModuleOrError = getLazyBitcodeModule(Buffer->get(), ctx); -#endif - - if (!mainModuleOrError) { - klee_error("error loading program '%s': %s", InputFile.c_str(), - mainModuleOrError.getError().message().c_str()); - } - else { - // The module has taken ownership of the MemoryBuffer so release it - // from the std::unique_ptr - Buffer->release(); - } - - mainModule = *mainModuleOrError; - if (auto ec = mainModule->materializeAllPermanently()) { - klee_error("error loading program '%s': %s", InputFile.c_str(), - ec.message().c_str()); - } -#endif if (WithPOSIXRuntime) { int r = initEnv(mainModule); @@ -1578,12 +1533,6 @@ int main(int argc, char **argv, char **envp) { handler->getInfoStream() << stats.str(); -#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) - // FIXME: This really doesn't look right - // This is preventing the module from being - // deleted automatically - BufferPtr.take(); -#endif delete handler; return 0; |