diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Core/Executor.cpp | 16 | ||||
-rw-r--r-- | lib/Core/ExternalDispatcher.cpp | 277 | ||||
-rw-r--r-- | lib/Core/ExternalDispatcher.h | 53 | ||||
-rw-r--r-- | lib/Core/StatsTracker.cpp | 11 | ||||
-rw-r--r-- | lib/Module/KModule.cpp | 13 | ||||
-rw-r--r-- | lib/Module/ModuleUtil.cpp | 117 | ||||
-rw-r--r-- | lib/Module/Optimize.cpp | 14 | ||||
-rw-r--r-- | lib/Module/RaiseAsm.cpp | 13 | ||||
-rw-r--r-- | lib/Solver/QueryLoggingSolver.cpp | 8 | ||||
-rw-r--r-- | lib/Support/CompressionStream.cpp | 10 |
10 files changed, 384 insertions, 148 deletions
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 1930cdc3..d71d767d 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,7 +3091,6 @@ void Executor::callExternalFunction(ExecutionState &state, else klee_warning_once(function, "%s", os.str().c_str()); } - bool success = externalDispatcher->executeCall(function, target->inst, args); if (!success) { terminateStateOnError(state, "failed external call: " + function->getName(), diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp index 984e3ab2..df0dd9a9 100644 --- a/lib/Core/ExternalDispatcher.cpp +++ b/lib/Core/ExternalDispatcher.cpp @@ -11,19 +11,24 @@ #include "klee/Config/Version.h" #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) -#include "llvm/IR/Module.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #else -#include "llvm/Module.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Instructions.h" #include "llvm/LLVMContext.h" +#include "llvm/Module.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" @@ -55,12 +60,48 @@ extern "C" { static void sigsegv_handler(int signal, siginfo_t *info, void *context) { longjmp(escapeCallJmpBuf, 1); } +} +namespace klee { + +class ExternalDispatcherImpl { +private: + typedef std::map<const llvm::Instruction *, llvm::Function *> dispatchers_ty; + dispatchers_ty dispatchers; + llvm::Function *createDispatcher(llvm::Function *f, llvm::Instruction *i, + llvm::Module *module); + llvm::ExecutionEngine *executionEngine; + LLVMContext &ctx; + std::map<std::string, void *> preboundFunctions; + bool runProtectedCall(llvm::Function *f, uint64_t *args); + llvm::Module *singleDispatchModule; + std::vector<std::string> moduleIDs; + std::string &getFreshModuleID(); + +public: + ExternalDispatcherImpl(llvm::LLVMContext &ctx); + ~ExternalDispatcherImpl(); + bool executeCall(llvm::Function *function, llvm::Instruction *i, + uint64_t *args); + void *resolveSymbol(const std::string &name); +}; + +std::string &ExternalDispatcherImpl::getFreshModuleID() { + // We store the module IDs because `llvm::Module` constructor takes the + // module ID as a StringRef so it doesn't own the ID. Therefore we need to + // own the ID. + static uint64_t counter = 0; + std::string underlyingString; + llvm::raw_string_ostream ss(underlyingString); + ss << "ExternalDispatcherModule_" << counter; + moduleIDs.push_back(ss.str()); // moduleIDs now has a copy + ++counter; // Increment for next call + return moduleIDs.back(); } -void *ExternalDispatcher::resolveSymbol(const std::string &name) { +void *ExternalDispatcherImpl::resolveSymbol(const std::string &name) { assert(executionEngine); - + const char *str = name.c_str(); // We use this to validate that function names can be resolved so we @@ -74,10 +115,10 @@ void *ExternalDispatcher::resolveSymbol(const std::string &name) { void *addr = sys::DynamicLibrary::SearchForAddressOfSymbol(str); if (addr) return addr; - + // If it has an asm specifier and starts with an underscore we retry // without the underscore. I (DWD) don't know why. - if (name[0] == 1 && str[0]=='_') { + if (name[0] == 1 && str[0] == '_') { ++str; addr = sys::DynamicLibrary::SearchForAddressOfSymbol(str); } @@ -85,11 +126,24 @@ void *ExternalDispatcher::resolveSymbol(const std::string &name) { return addr; } -ExternalDispatcher::ExternalDispatcher(LLVMContext &ctx) { - dispatchModule = new Module("ExternalDispatcher", ctx); - +ExternalDispatcherImpl::ExternalDispatcherImpl(LLVMContext &ctx) : ctx(ctx) { std::string error; - executionEngine = ExecutionEngine::createJIT(dispatchModule, &error); + singleDispatchModule = new Module(getFreshModuleID(), ctx); +#if LLVM_VERSION_CODE < LLVM_VERSION(3, 6) + // Use old JIT + executionEngine = ExecutionEngine::createJIT(singleDispatchModule, &error); +#else + // Use MCJIT. + // The MCJIT JITs whole modules at a time rather than individual functions + // so we will let it manage the modules. + // Note that we don't do anything with `singleDispatchModule`. This is just + // so we can use the EngineBuilder API. + auto dispatchModuleUniq = std::unique_ptr<Module>(singleDispatchModule); + executionEngine = EngineBuilder(std::move(dispatchModuleUniq)) + .setEngineKind(EngineKind::JIT) + .create(); +#endif + if (!executionEngine) { llvm::errs() << "unable to make jit: " << error << "\n"; abort(); @@ -98,6 +152,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) { @@ -107,61 +165,90 @@ ExternalDispatcher::ExternalDispatcher(LLVMContext &ctx) { } #ifdef WINDOWS - preboundFunctions["getpid"] = (void*) (long) getpid; - preboundFunctions["putchar"] = (void*) (long) putchar; - preboundFunctions["printf"] = (void*) (long) printf; - preboundFunctions["fprintf"] = (void*) (long) fprintf; - preboundFunctions["sprintf"] = (void*) (long) sprintf; + preboundFunctions["getpid"] = (void *)(long)getpid; + preboundFunctions["putchar"] = (void *)(long)putchar; + preboundFunctions["printf"] = (void *)(long)printf; + preboundFunctions["fprintf"] = (void *)(long)fprintf; + preboundFunctions["sprintf"] = (void *)(long)sprintf; #endif } -ExternalDispatcher::~ExternalDispatcher() { +ExternalDispatcherImpl::~ExternalDispatcherImpl() { delete executionEngine; + // NOTE: the `executionEngine` owns all modules so + // we don't need to delete any of them. } -bool ExternalDispatcher::executeCall(Function *f, Instruction *i, uint64_t *args) { +bool ExternalDispatcherImpl::executeCall(Function *f, Instruction *i, + uint64_t *args) { dispatchers_ty::iterator it = dispatchers.find(i); - Function *dispatcher; + if (it != dispatchers.end()) { + // Code already JIT'ed for this + return runProtectedCall(it->second, args); + } - if (it == dispatchers.end()) { + // Code for this not JIT'ed. Do this now. + Function *dispatcher; #ifdef WINDOWS - std::map<std::string, void*>::iterator it2 = - preboundFunctions.find(f->getName())); - - if (it2 != preboundFunctions.end()) { - // only bind once - if (it2->second) { - executionEngine->addGlobalMapping(f, it2->second); - it2->second = 0; - } + std::map<std::string, void *>::iterator it2 = + preboundFunctions.find(f->getName()); + + if (it2 != preboundFunctions.end()) { + // only bind once + if (it2->second) { + executionEngine->addGlobalMapping(f, it2->second); + it2->second = 0; } + } #endif - dispatcher = createDispatcher(f,i); - - dispatchers.insert(std::make_pair(i, dispatcher)); - - if (dispatcher) { - // Force the JIT execution engine to go ahead and build the function. This - // ensures that any errors or assertions in the compilation process will - // trigger crashes instead of being caught as aborts in the external - // function. - executionEngine->recompileAndRelinkFunction(dispatcher); - } + Module *dispatchModule = NULL; +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) + // The MCJIT generates whole modules at a time so for every call that we + // haven't made before we need to create a new Module. + dispatchModule = new Module(getFreshModuleID(), ctx); +#else + dispatchModule = this->singleDispatchModule; +#endif + dispatcher = createDispatcher(f, i, dispatchModule); + dispatchers.insert(std::make_pair(i, dispatcher)); + +// Force the JIT execution engine to go ahead and build the function. This +// 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) + if (dispatcher) { + // The dispatchModule is now ready so tell MCJIT to generate the code for + // it. + auto dispatchModuleUniq = std::unique_ptr<Module>(dispatchModule); + executionEngine->addModule( + std::move(dispatchModuleUniq)); // MCJIT takes ownership + // Force code generation + uint64_t fnAddr = + executionEngine->getFunctionAddress(dispatcher->getName()); + executionEngine->finalizeObject(); + assert(fnAddr && "failed to get function address"); + (void)fnAddr; } else { - dispatcher = it->second; + // MCJIT didn't take ownership of the module so delete it. + delete dispatchModule; } - +#else + if (dispatcher) { + // Old JIT works on a function at a time so compile the function. + executionEngine->recompileAndRelinkFunction(dispatcher); + } +#endif return runProtectedCall(dispatcher, args); } // FIXME: This is not reentrant. static uint64_t *gTheArgsP; - -bool ExternalDispatcher::runProtectedCall(Function *f, uint64_t *args) { +bool ExternalDispatcherImpl::runProtectedCall(Function *f, uint64_t *args) { struct sigaction segvAction, segvActionOld; bool res; - + if (!f) return false; @@ -185,86 +272,87 @@ bool ExternalDispatcher::runProtectedCall(Function *f, uint64_t *args) { return res; } +// FIXME: This might have been relevant for the old JIT but the MCJIT +// has a completly different implementation so this comment below is +// likely irrelevant and misleading. +// // For performance purposes we construct the stub in such a way that the // arguments pointer is passed through the static global variable gTheArgsP in // this file. This is done so that the stub function prototype trivially matches // the special cases that the JIT knows how to directly call. If this is not // done, then the jit will end up generating a nullary stub just to call our // stub, for every single function call. -Function *ExternalDispatcher::createDispatcher(Function *target, Instruction *inst) { +Function *ExternalDispatcherImpl::createDispatcher(Function *target, + Instruction *inst, + Module *module) { if (!resolveSymbol(target->getName())) return 0; - LLVMContext &ctx = target->getContext(); CallSite cs; - if (inst->getOpcode()==Instruction::Call) { + if (inst->getOpcode() == Instruction::Call) { cs = CallSite(cast<CallInst>(inst)); } else { cs = CallSite(cast<InvokeInst>(inst)); } - Value **args = new Value*[cs.arg_size()]; + Value **args = new Value *[cs.arg_size()]; - std::vector<LLVM_TYPE_Q Type*> nullary; - - // MCJIT functions need unique names, or wrong function can be called - Function *dispatcher = Function::Create(FunctionType::get(Type::getVoidTy(ctx), - nullary, false), - GlobalVariable::ExternalLinkage, - "dispatcher_" + target->getName().str(), - dispatchModule); + std::vector<LLVM_TYPE_Q Type *> nullary; + // MCJIT functions need unique names, or wrong function can be called. + // The module identifier is included because for the MCJIT we need + // unique function names across all `llvm::Modules`s. + std::string fnName = + "dispatcher_" + target->getName().str() + module->getModuleIdentifier(); + Function *dispatcher = + Function::Create(FunctionType::get(Type::getVoidTy(ctx), nullary, false), + GlobalVariable::ExternalLinkage, fnName, module); BasicBlock *dBB = BasicBlock::Create(ctx, "entry", dispatcher); // Get a Value* for &gTheArgsP, as an i64**. - Instruction *argI64sp = - new IntToPtrInst(ConstantInt::get(Type::getInt64Ty(ctx), - (uintptr_t) (void*) &gTheArgsP), - PointerType::getUnqual(PointerType::getUnqual(Type::getInt64Ty(ctx))), - "argsp", dBB); - Instruction *argI64s = new LoadInst(argI64sp, "args", dBB); - + Instruction *argI64sp = new IntToPtrInst( + ConstantInt::get(Type::getInt64Ty(ctx), (uintptr_t)(void *)&gTheArgsP), + PointerType::getUnqual(PointerType::getUnqual(Type::getInt64Ty(ctx))), + "argsp", dBB); + Instruction *argI64s = new LoadInst(argI64sp, "args", dBB); + // Get the target function type. - LLVM_TYPE_Q FunctionType *FTy = - cast<FunctionType>(cast<PointerType>(target->getType())->getElementType()); + LLVM_TYPE_Q FunctionType *FTy = cast<FunctionType>( + cast<PointerType>(target->getType())->getElementType()); // Each argument will be passed by writing it into gTheArgsP[i]. unsigned i = 0, idx = 2; - for (CallSite::arg_iterator ai = cs.arg_begin(), ae = cs.arg_end(); - ai!=ae; ++ai, ++i) { + for (CallSite::arg_iterator ai = cs.arg_begin(), ae = cs.arg_end(); ai != ae; + ++ai, ++i) { // Determine the type the argument will be passed as. This accomodates for // the corresponding code in Executor.cpp for handling calls to bitcasted // functions. - LLVM_TYPE_Q Type *argTy = (i < FTy->getNumParams() ? FTy->getParamType(i) : - (*ai)->getType()); - Instruction *argI64p = - GetElementPtrInst::Create(argI64s, - ConstantInt::get(Type::getInt32Ty(ctx), idx), - "", dBB); - - Instruction *argp = new BitCastInst(argI64p, PointerType::getUnqual(argTy), - "", dBB); + LLVM_TYPE_Q Type *argTy = + (i < FTy->getNumParams() ? FTy->getParamType(i) : (*ai)->getType()); + Instruction *argI64p = GetElementPtrInst::Create( + argI64s, ConstantInt::get(Type::getInt32Ty(ctx), idx), "", dBB); + + Instruction *argp = + new BitCastInst(argI64p, PointerType::getUnqual(argTy), "", dBB); args[i] = new LoadInst(argp, "", dBB); unsigned argSize = argTy->getPrimitiveSizeInBits(); - idx += ((!!argSize ? argSize : 64) + 63)/64; + idx += ((!!argSize ? argSize : 64) + 63) / 64; } - Constant *dispatchTarget = - dispatchModule->getOrInsertFunction(target->getName(), FTy, - target->getAttributes()); + Constant *dispatchTarget = module->getOrInsertFunction( + target->getName(), FTy, target->getAttributes()); #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 0) - Instruction *result = CallInst::Create(dispatchTarget, - llvm::ArrayRef<Value *>(args, args+i), - "", dBB); + Instruction *result = CallInst::Create( + dispatchTarget, llvm::ArrayRef<Value *>(args, args + i), "", dBB); #else - Instruction *result = CallInst::Create(dispatchTarget, args, args+i, "", dBB); + Instruction *result = + CallInst::Create(dispatchTarget, args, args + i, "", dBB); #endif if (result->getType() != Type::getVoidTy(ctx)) { - Instruction *resp = - new BitCastInst(argI64s, PointerType::getUnqual(result->getType()), - "", dBB); + Instruction *resp = new BitCastInst( + argI64s, PointerType::getUnqual(result->getType()), "", dBB); new StoreInst(result, resp, dBB); } @@ -274,3 +362,18 @@ Function *ExternalDispatcher::createDispatcher(Function *target, Instruction *in return dispatcher; } + +ExternalDispatcher::ExternalDispatcher(llvm::LLVMContext &ctx) + : impl(new ExternalDispatcherImpl(ctx)) {} + +ExternalDispatcher::~ExternalDispatcher() { delete impl; } + +bool ExternalDispatcher::executeCall(llvm::Function *function, + llvm::Instruction *i, uint64_t *args) { + return impl->executeCall(function, i, args); +} + +void *ExternalDispatcher::resolveSymbol(const std::string &name) { + return impl->resolveSymbol(name); +} +} diff --git a/lib/Core/ExternalDispatcher.h b/lib/Core/ExternalDispatcher.h index 94363bab..c64dc7d8 100644 --- a/lib/Core/ExternalDispatcher.h +++ b/lib/Core/ExternalDispatcher.h @@ -10,42 +10,37 @@ #ifndef KLEE_EXTERNALDISPATCHER_H #define KLEE_EXTERNALDISPATCHER_H +#include "klee/Config/Version.h" + #include <map> -#include <string> +#include <memory> #include <stdint.h> +#include <string> namespace llvm { - class ExecutionEngine; - class Instruction; - class LLVMContext; - class Function; - class FunctionType; - class Module; +class Instruction; +class LLVMContext; +class Function; } namespace klee { - class ExternalDispatcher { - private: - typedef std::map<const llvm::Instruction*,llvm::Function*> dispatchers_ty; - dispatchers_ty dispatchers; - llvm::Module *dispatchModule; - llvm::ExecutionEngine *executionEngine; - std::map<std::string, void*> preboundFunctions; - - llvm::Function *createDispatcher(llvm::Function *f, llvm::Instruction *i); - bool runProtectedCall(llvm::Function *f, uint64_t *args); - - public: - ExternalDispatcher(llvm::LLVMContext &ctx); - ~ExternalDispatcher(); - - /* Call the given function using the parameter passing convention of - * ci with arguments in args[1], args[2], ... and writing the result - * into args[0]. - */ - bool executeCall(llvm::Function *function, llvm::Instruction *i, uint64_t *args); - void *resolveSymbol(const std::string &name); - }; +class ExternalDispatcherImpl; +class ExternalDispatcher { +private: + ExternalDispatcherImpl *impl; + +public: + ExternalDispatcher(llvm::LLVMContext &ctx); + ~ExternalDispatcher(); + + /* Call the given function using the parameter passing convention of + * ci with arguments in args[1], args[2], ... and writing the result + * into args[0]. + */ + bool executeCall(llvm::Function *function, llvm::Instruction *i, + uint64_t *args); + void *resolveSymbol(const std::string &name); +}; } #endif 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; |