about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorRichard Trembecký <richardt@centrum.sk>2016-05-01 16:38:21 +0200
committerDan Liew <delcypher@gmail.com>2017-05-24 14:24:47 +0100
commitd3a467d8999e6e52892b13c2bc93ac829ee1b7c9 (patch)
tree99493da4b33f50eb0c27a237213c615520efbd95
parent92367dec2ee00cb708454e4c33ff34d80eddb878 (diff)
downloadklee-d3a467d8999e6e52892b13c2bc93ac829ee1b7c9.tar.gz
llvm: make KLEE compile against LLVM 3.5 and 3.6
Based on work by @ccadeptic23 and @delcypher.
Formatting fixed by @snf.
Fix compiler warning by @martijnthe.
Further fixes by @mchalupa.

Refactored, so that changes can be reviewed -- no massive changes in
whitespace and in the surrounding code.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
-rw-r--r--lib/Core/Executor.cpp25
-rw-r--r--lib/Core/ExternalDispatcher.cpp18
-rw-r--r--lib/Core/ExternalDispatcher.h6
-rw-r--r--lib/Core/StatsTracker.cpp11
-rw-r--r--lib/Module/KModule.cpp13
-rw-r--r--lib/Module/ModuleUtil.cpp117
-rw-r--r--lib/Module/Optimize.cpp14
-rw-r--r--lib/Module/RaiseAsm.cpp13
-rw-r--r--lib/Solver/QueryLoggingSolver.cpp8
-rw-r--r--lib/Support/CompressionStream.cpp10
-rw-r--r--tools/klee/Makefile10
-rw-r--r--tools/klee/main.cpp16
12 files changed, 226 insertions, 35 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index 1930cdc3..1cdb770b 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -81,6 +81,7 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -383,7 +384,13 @@ Executor::Executor(LLVMContext &ctx, const InterpreterOptions &opts,
     if (!DebugCompressInstructions) {
 #endif
 
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+    std::error_code ec;
+    debugInstFile = new llvm::raw_fd_ostream(debug_file_name.c_str(), ec,
+                                             llvm::sys::fs::OpenFlags::F_Text);
+    if (ec)
+	    ErrorInfo = ec.message();
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
     debugInstFile = new llvm::raw_fd_ostream(debug_file_name.c_str(), ErrorInfo,
                                              llvm::sys::fs::OpenFlags::F_Text);
 #else
@@ -1479,9 +1486,13 @@ Function* Executor::getTargetFunction(Value *calledVal, ExecutionState &state) {
 
   while (true) {
     if (GlobalValue *gv = dyn_cast<GlobalValue>(c)) {
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+      if (!Visited.insert(gv).second)
+        return 0;
+#else
       if (!Visited.insert(gv))
         return 0;
-
+#endif
       std::string alias = state.getFnAlias(gv->getName());
       if (alias != "") {
         llvm::Module* currModule = kmodule->module;
@@ -3080,8 +3091,16 @@ void Executor::callExternalFunction(ExecutionState &state,
     else
       klee_warning_once(function, "%s", os.str().c_str());
   }
-  
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  // MCJIT needs unique module, so we create quick external dispatcher for call.
+  // reference:
+  // http://blog.llvm.org/2013/07/using-mcjit-with-kaleidoscope-tutorial.html
+  ExternalDispatcher *e = new ExternalDispatcher(function->getContext());
+  bool success = e->executeCall(function, target->inst, args);
+  delete e;
+#else
   bool success = externalDispatcher->executeCall(function, target->inst, args);
+#endif
   if (!success) {
     terminateStateOnError(state, "failed external call: " + function->getName(),
                           External);
diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp
index 984e3ab2..9701d35a 100644
--- a/lib/Core/ExternalDispatcher.cpp
+++ b/lib/Core/ExternalDispatcher.cpp
@@ -23,7 +23,12 @@
 #include "llvm/Instructions.h"
 #include "llvm/LLVMContext.h"
 #endif
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+#include "llvm/ExecutionEngine/MCJIT.h"
+#else
 #include "llvm/ExecutionEngine/JIT.h"
+#endif
+
 #include "llvm/ExecutionEngine/GenericValue.h"
 #include "llvm/Support/DynamicLibrary.h"
 #include "llvm/Support/raw_ostream.h"
@@ -89,7 +94,12 @@ ExternalDispatcher::ExternalDispatcher(LLVMContext &ctx) {
   dispatchModule = new Module("ExternalDispatcher", ctx);
 
   std::string error;
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  dispatchModule_uniptr.reset(dispatchModule);
+  executionEngine = EngineBuilder(std::move(dispatchModule_uniptr)).create();
+#else
   executionEngine = ExecutionEngine::createJIT(dispatchModule, &error);
+#endif
   if (!executionEngine) {
     llvm::errs() << "unable to make jit: " << error << "\n";
     abort();
@@ -98,6 +108,10 @@ ExternalDispatcher::ExternalDispatcher(LLVMContext &ctx) {
   // If we have a native target, initialize it to ensure it is linked in and
   // usable by the JIT.
   llvm::InitializeNativeTarget();
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  llvm::InitializeNativeTargetAsmParser();
+  llvm::InitializeNativeTargetAsmPrinter();
+#endif
 
   // from ExecutionEngine::create
   if (executionEngine) {
@@ -146,7 +160,11 @@ bool ExternalDispatcher::executeCall(Function *f, Instruction *i, uint64_t *args
       // ensures that any errors or assertions in the compilation process will
       // trigger crashes instead of being caught as aborts in the external
       // function.
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+      executionEngine->finalizeObject();
+#else
       executionEngine->recompileAndRelinkFunction(dispatcher);
+#endif
     }
   } else {
     dispatcher = it->second;
diff --git a/lib/Core/ExternalDispatcher.h b/lib/Core/ExternalDispatcher.h
index 94363bab..d869eb6f 100644
--- a/lib/Core/ExternalDispatcher.h
+++ b/lib/Core/ExternalDispatcher.h
@@ -10,7 +10,10 @@
 #ifndef KLEE_EXTERNALDISPATCHER_H
 #define KLEE_EXTERNALDISPATCHER_H
 
+#include "klee/Config/Version.h"
+
 #include <map>
+#include <memory>
 #include <string>
 #include <stdint.h>
 
@@ -28,6 +31,9 @@ namespace klee {
   private:
     typedef std::map<const llvm::Instruction*,llvm::Function*> dispatchers_ty;
     dispatchers_ty dispatchers;
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+    std::unique_ptr<llvm::Module> dispatchModule_uniptr;
+#endif
     llvm::Module *dispatchModule;
     llvm::ExecutionEngine *executionEngine;
     std::map<std::string, void*> preboundFunctions;
diff --git a/lib/Core/StatsTracker.cpp b/lib/Core/StatsTracker.cpp
index e8192a8e..b93796ec 100644
--- a/lib/Core/StatsTracker.cpp
+++ b/lib/Core/StatsTracker.cpp
@@ -206,13 +206,16 @@ StatsTracker::StatsTracker(Executor &_executor, std::string _objectFilename,
   if (!sys::path::is_absolute(objectFilename)) {
     SmallString<128> current(objectFilename);
     if(sys::fs::make_absolute(current)) {
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+      Twine current_twine(current.str()); // requires a twine for this
+      if (!sys::fs::exists(current_twine)) {
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+      bool exists = false;
+      if (!sys::fs::exists(current.str(), exists)) {
+#else
       bool exists = false;
-
-#if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
       error_code ec = sys::fs::exists(current.str(), exists);
       if (ec == errc::success && exists) {
-#else
-      if (!sys::fs::exists(current.str(), exists)) {
 #endif
         objectFilename = current.c_str();
       }
diff --git a/lib/Module/KModule.cpp b/lib/Module/KModule.cpp
index 08ec28ef..45dc34bf 100644
--- a/lib/Module/KModule.cpp
+++ b/lib/Module/KModule.cpp
@@ -158,8 +158,14 @@ static Function *getStubFunctionForCtorList(Module *m,
   if (arr) {
     for (unsigned i=0; i<arr->getNumOperands(); i++) {
       ConstantStruct *cs = cast<ConstantStruct>(arr->getOperand(i));
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+      // There is a third *optional* element in global_ctor elements (``i8
+      // @data``).
+      assert((cs->getNumOperands() == 2 || cs->getNumOperands() == 3) &&
+             "unexpected element in ctor initializer list");
+#else
       assert(cs->getNumOperands()==2 && "unexpected element in ctor initializer list");
-      
+#endif
       Constant *fp = cs->getOperand(1);      
       if (!fp->isNullValue()) {
         if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(fp))
@@ -513,8 +519,13 @@ static int getOperandNum(Value *v,
     return registerMap[inst];
   } else if (Argument *a = dyn_cast<Argument>(v)) {
     return a->getArgNo();
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+    // Metadata is no longer a Value
+  } else if (isa<BasicBlock>(v) || isa<InlineAsm>(v)) {
+#else
   } else if (isa<BasicBlock>(v) || isa<InlineAsm>(v) ||
              isa<MDNode>(v)) {
+#endif
     return -1;
   } else {
     assert(isa<Constant>(v));
diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp
index 83dc5045..c7f1c6d9 100644
--- a/lib/Module/ModuleUtil.cpp
+++ b/lib/Module/ModuleUtil.cpp
@@ -212,15 +212,27 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er
 
   KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Loading modules\n");
   // Load all bitcode files in to memory so we can examine their symbols
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+  for (object::Archive::child_iterator AI = archive->child_begin(),
+       AE = archive->child_end(); AI != AE; ++AI)
+#else
   for (object::Archive::child_iterator AI = archive->begin_children(),
        AE = archive->end_children(); AI != AE; ++AI)
+#endif
   {
 
     StringRef memberName;
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+    ErrorOr<StringRef> memberNameErr = AI->getName();
+    std::error_code ec = memberNameErr.getError();
+    if (!ec) {
+      memberName = memberNameErr.get();
+#else
     error_code ec = AI->getName(memberName);
 
     if ( ec == errc::success )
     {
+#endif
       KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Loading archive member " << memberName << "\n");
     }
     else
@@ -229,17 +241,29 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er
       return false;
     }
 
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+    ErrorOr<std::unique_ptr<llvm::object::Binary> > child = AI->getAsBinary();
+    ec = child.getError();
+#else
     OwningPtr<object::Binary> child;
     ec = AI->getAsBinary(child);
-    if (ec != object::object_error::success)
-    {
+#endif
+    if (ec) {
       // If we can't open as a binary object file its hopefully a bitcode file
-
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+      ErrorOr<MemoryBufferRef> buff = AI->getMemoryBufferRef();
+      ec = buff.getError();
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+      ErrorOr<std::unique_ptr<MemoryBuffer> > buffErr = AI->getMemoryBuffer();
+      std::unique_ptr<MemoryBuffer> buff = nullptr;
+      ec = buffErr.getError();
+      if (!ec)
+        buff = std::move(buffErr.get());
+#else
       OwningPtr<MemoryBuffer> buff; // Once this is destroyed will Module still be valid??
-      Module *Result = 0;
-
-      if (error_code ec = AI->getMemoryBuffer(buff))
-      {
+      ec = AI->getMemoryBuffer(buff);
+#endif
+      if (ec) {
         SS << "Failed to get MemoryBuffer: " <<ec.message();
         SS.flush();
         return false;
@@ -247,10 +271,20 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er
 
       if (buff)
       {
+        Module *Result = 0;
         // FIXME: Maybe load bitcode file lazily? Then if we need to link, materialise the module
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+        ErrorOr<Module *> resultErr = parseBitcodeFile(buff.get(),
+	    composite->getContext());
+        ec = resultErr.getError();
+        if (ec)
+          errorMessage = ec.message();
+        else
+          Result = resultErr.get();
+#else
         Result = ParseBitcodeFile(buff.get(), composite->getContext(),
 	    &errorMessage);
-
+#endif
         if(!Result)
         {
           SS << "Loading module failed : " << errorMessage << "\n";
@@ -317,8 +351,11 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er
           KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Found " << GV->getName() <<
               " in " << M->getModuleIdentifier() << "\n");
 
-
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+          if (Linker::LinkModules(composite, M))
+#else
           if (Linker::LinkModules(composite, M, Linker::DestroySource, &errorMessage))
+#endif
           {
             // Linking failed
             SS << "Linking archive module with composite failed:" << errorMessage;
@@ -371,36 +408,86 @@ Module *klee::linkWithLibrary(Module *module,
         libraryName.c_str());
   }
 
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+  ErrorOr<std::unique_ptr<MemoryBuffer> > bufferErr =
+      MemoryBuffer::getFile(libraryName);
+  std::error_code ec = bufferErr.getError();
+#else
   OwningPtr<MemoryBuffer> Buffer;
-  if (error_code ec = MemoryBuffer::getFile(libraryName,Buffer)) {
+  error_code ec = MemoryBuffer::getFile(libraryName,Buffer);
+#endif
+  if (ec) {
     klee_error("Link with library %s failed: %s", libraryName.c_str(),
         ec.message().c_str());
   }
 
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  MemoryBufferRef Buffer = bufferErr.get()->getMemBufferRef();
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+  MemoryBuffer *Buffer = bufferErr->get();
+#endif
+
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  sys::fs::file_magic magic = sys::fs::identify_magic(Buffer.getBuffer());
+#else
   sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer());
+#endif
 
   LLVMContext &Context = module->getContext();
   std::string ErrorMessage;
 
   if (magic == sys::fs::file_magic::bitcode) {
     Module *Result = 0;
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+    ErrorOr<Module *> ResultErr = parseBitcodeFile(Buffer, Context);
+    if ((ec = ResultErr.getError())) {
+      ErrorMessage = ec.message();
+#else
     Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);
+    if (!Result) {
+#endif
+      klee_error("Link with library %s failed: %s", libraryName.c_str(),
+          ErrorMessage.c_str());
+    }
 
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+    Result = ResultErr.get();
+#endif
 
-    if (!Result || Linker::LinkModules(module, Result, Linker::DestroySource,
-        &ErrorMessage))
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+    if (Linker::LinkModules(module, Result)) {
+      ErrorMessage = "linking error";
+#else
+    if (Linker::LinkModules(module, Result, Linker::DestroySource, &ErrorMessage)) {
+#endif
       klee_error("Link with library %s failed: %s", libraryName.c_str(),
           ErrorMessage.c_str());
+    }
 
     delete Result;
 
   } else if (magic == sys::fs::file_magic::archive) {
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+    ErrorOr<std::unique_ptr<object::Binary> > arch =
+        object::createBinary(Buffer, &Context);
+    ec = arch.getError();
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+    ErrorOr<object::Binary *> arch =
+        object::createBinary(std::move(bufferErr.get()), &Context);
+    ec = arch.getError();
+#else
     OwningPtr<object::Binary> arch;
-    if (error_code ec = object::createBinary(Buffer.take(), arch))
+    ec = object::createBinary(Buffer.take(), arch);
+#endif
+    if (ec)
       klee_error("Link with library %s failed: %s", libraryName.c_str(),
           ec.message().c_str());
 
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+    if (object::Archive *a = dyn_cast<object::Archive>(arch->get())) {
+#else
     if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) {
+#endif
       // Handle in helper
       if (!linkBCA(a, module, ErrorMessage))
         klee_error("Link with library %s failed: %s", libraryName.c_str(),
@@ -411,7 +498,11 @@ Module *klee::linkWithLibrary(Module *module,
     }
 
   } else if (magic.is_object()) {
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+    std::unique_ptr<object::Binary> obj;
+#else
     OwningPtr<object::Binary> obj;
+#endif
     if (obj.get()->isObject()) {
       klee_warning("Link with library: Object file %s in archive %s found. "
           "Currently not supported.",
diff --git a/lib/Module/Optimize.cpp b/lib/Module/Optimize.cpp
index 3d9c8cc1..c0f3f34c 100644
--- a/lib/Module/Optimize.cpp
+++ b/lib/Module/Optimize.cpp
@@ -172,15 +172,17 @@ void Optimize(Module *M, const std::string &EntryPoint) {
   if (VerifyEach)
     Passes.add(createVerifierPass());
 
-#if LLVM_VERSION_CODE <= LLVM_VERSION(3, 1)
-  // Add an appropriate TargetData instance for this module...
-  addPass(Passes, new TargetData(M));
-#elif LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
   // Add an appropriate DataLayout instance for this module...
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  DataLayoutPass *dlpass = new DataLayoutPass();
+  dlpass->doInitialization(*M);
+  addPass(Passes, dlpass);
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+  addPass(Passes, new DataLayoutPass(M));
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 2)
   addPass(Passes, new DataLayout(M));
 #else
-  // Add an appropriate DataLayout instance for this module...
-  addPass(Passes, new DataLayoutPass(M));
+  addPass(Passes, new TargetData(M));
 #endif
 
   // DWD - Run the opt standard pass list as well.
diff --git a/lib/Module/RaiseAsm.cpp b/lib/Module/RaiseAsm.cpp
index af92b74b..5fc54ef1 100644
--- a/lib/Module/RaiseAsm.cpp
+++ b/lib/Module/RaiseAsm.cpp
@@ -24,6 +24,10 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Target/TargetLowering.h"
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
+#endif
 #if LLVM_VERSION_CODE < LLVM_VERSION(3, 0)
 #include "llvm/Target/TargetRegistry.h"
 #else
@@ -99,15 +103,20 @@ bool RaiseAsmPass::runOnModule(Module &M) {
     klee_warning("Warning: unable to select native target: %s", Err.c_str());
     TLI = 0;
   } else {
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 1)
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+    TM = NativeTarget->createTargetMachine(HostTriple, "", "", TargetOptions());
+    TLI = TM->getSubtargetImpl()->getTargetLowering();
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 1)
     TM = NativeTarget->createTargetMachine(HostTriple, "", "",
                                                           TargetOptions());
+    TLI = TM->getTargetLowering();
 #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 0)
     TM = NativeTarget->createTargetMachine(HostTriple, "", "");
+    TLI = TM->getTargetLowering();
 #else
     TM = NativeTarget->createTargetMachine(HostTriple, "");
-#endif
     TLI = TM->getTargetLowering();
+#endif
 
     triple = llvm::Triple(HostTriple);
   }
diff --git a/lib/Solver/QueryLoggingSolver.cpp b/lib/Solver/QueryLoggingSolver.cpp
index a858a7d7..cf4966cd 100644
--- a/lib/Solver/QueryLoggingSolver.cpp
+++ b/lib/Solver/QueryLoggingSolver.cpp
@@ -42,7 +42,13 @@ QueryLoggingSolver::QueryLoggingSolver(Solver *_solver, std::string path,
 #ifdef HAVE_ZLIB_H
   if (!CreateCompressedQueryLog) {
 #endif
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+    std::error_code ec;
+    os = new llvm::raw_fd_ostream(path.c_str(), ec,
+                                  llvm::sys::fs::OpenFlags::F_Text);
+    if (ec)
+      ErrorInfo = ec.message();
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
     os = new llvm::raw_fd_ostream(path.c_str(), ErrorInfo,
                                   llvm::sys::fs::OpenFlags::F_Text);
 #else
diff --git a/lib/Support/CompressionStream.cpp b/lib/Support/CompressionStream.cpp
index eb208edf..36303878 100644
--- a/lib/Support/CompressionStream.cpp
+++ b/lib/Support/CompressionStream.cpp
@@ -10,9 +10,11 @@
 #include "klee/Config/Version.h"
 #ifdef HAVE_ZLIB_H
 #include "klee/Internal/Support/CompressionStream.h"
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
+#if (LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) \
+    && LLVM_VERSION_CODE <= LLVM_VERSION(3, 4))
 #include "llvm/Support/system_error.h"
 #else
+#include "llvm/Support/FileSystem.h"
 #include <fcntl.h>
 #include <errno.h>
 #include <sys/types.h>
@@ -27,9 +29,13 @@ compressed_fd_ostream::compressed_fd_ostream(const char *Filename,
   ErrorInfo = "";
 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
   // Open file in binary mode
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
+  std::error_code EC =
+      llvm::sys::fs::openFileForWrite(Filename, FD, llvm::sys::fs::F_None);
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
   llvm::error_code EC =
       llvm::sys::fs::openFileForWrite(Filename, FD, llvm::sys::fs::F_Binary);
-
+#endif
   if (EC) {
     ErrorInfo = EC.message();
     FD = -1;
diff --git a/tools/klee/Makefile b/tools/klee/Makefile
index 8d50403f..2930427c 100644
--- a/tools/klee/Makefile
+++ b/tools/klee/Makefile
@@ -13,7 +13,13 @@ TOOLNAME = klee
 include $(LEVEL)/Makefile.config
 
 USEDLIBS = kleeCore.a kleeBasic.a kleeModule.a  kleaverSolver.a kleaverExpr.a kleeSupport.a 
-LINK_COMPONENTS = jit bitreader bitwriter ipo linker engine
+LINK_COMPONENTS = bitreader bitwriter ipo linker engine
+
+ifeq ($(shell python -c "print($(LLVM_VERSION_MAJOR).$(LLVM_VERSION_MINOR) >= 3.6)"), True)
+LINK_COMPONENTS += mcjit
+else
+LINK_COMPONENTS += jit
+endif
 
 ifeq ($(shell python -c "print($(LLVM_VERSION_MAJOR).$(LLVM_VERSION_MINOR) >= 3.3)"), True)
 LINK_COMPONENTS += irreader
@@ -36,4 +42,4 @@ endif
 
 ifeq ($(HAVE_ZLIB),1)
   LIBS += -lz
-endif
\ No newline at end of file
+endif
diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp
index 1ac33617..a91c9fd1 100644
--- a/tools/klee/main.cpp
+++ b/tools/klee/main.cpp
@@ -385,7 +385,12 @@ llvm::raw_fd_ostream *KleeHandler::openOutputFile(const std::string &filename) {
   llvm::raw_fd_ostream *f;
   std::string Error;
   std::string path = getOutputFilename(filename);
-#if LLVM_VERSION_CODE >= LLVM_VERSION(3,5)
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  std::error_code ec;
+  f = new llvm::raw_fd_ostream(path.c_str(), ec, llvm::sys::fs::F_None);
+  if (ec)
+    Error = ec.message();
+#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5)
   f = new llvm::raw_fd_ostream(path.c_str(), Error, llvm::sys::fs::F_None);
 #elif LLVM_VERSION_CODE >= LLVM_VERSION(3,4)
   f = new llvm::raw_fd_ostream(path.c_str(), Error, llvm::sys::fs::F_Binary);
@@ -1038,9 +1043,14 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir)
   SmallString<128> uclibcBCA(libDir);
   llvm::sys::path::append(uclibcBCA, KLEE_UCLIBC_BCA_NAME);
 
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
+  Twine uclibcBCA_twine(uclibcBCA.c_str());
+  if (!llvm::sys::fs::exists(uclibcBCA_twine))
+#else
   bool uclibcExists=false;
   llvm::sys::fs::exists(uclibcBCA.c_str(), uclibcExists);
   if (!uclibcExists)
+#endif
     klee_error("Cannot find klee-uclibc : %s", uclibcBCA.c_str());
 
   Function *f;
@@ -1265,7 +1275,11 @@ int main(int argc, char **argv, char **envp) {
     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(),