ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile( MemoryBufferRef Object, sys::fs::file_magic Type, LLVMContext *Context) { StringRef Data = Object.getBuffer(); if (Type == sys::fs::file_magic::unknown) Type = sys::fs::identify_magic(Data); switch (Type) { case sys::fs::file_magic::bitcode: if (Context) return IRObjectFile::create(Object, *Context); // Fallthrough case sys::fs::file_magic::unknown: case sys::fs::file_magic::archive: case sys::fs::file_magic::macho_universal_binary: case sys::fs::file_magic::windows_resource: return object_error::invalid_file_type; case sys::fs::file_magic::elf: case sys::fs::file_magic::elf_executable: case sys::fs::file_magic::elf_shared_object: case sys::fs::file_magic::elf_core: case sys::fs::file_magic::macho_executable: case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: case sys::fs::file_magic::macho_core: case sys::fs::file_magic::macho_preload_executable: case sys::fs::file_magic::macho_dynamically_linked_shared_lib: case sys::fs::file_magic::macho_dynamic_linker: case sys::fs::file_magic::macho_bundle: case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: case sys::fs::file_magic::macho_dsym_companion: case sys::fs::file_magic::macho_kext_bundle: case sys::fs::file_magic::pecoff_executable: return ObjectFile::createObjectFile(Object, Type); case sys::fs::file_magic::coff_import_library: return std::unique_ptr<SymbolicFile>(new COFFImportFile(Object)); case sys::fs::file_magic::elf_relocatable: case sys::fs::file_magic::macho_object: case sys::fs::file_magic::coff_object: { ErrorOr<std::unique_ptr<ObjectFile>> Obj = ObjectFile::createObjectFile(Object, Type); if (!Obj || !Context) return std::move(Obj); ErrorOr<MemoryBufferRef> BCData = IRObjectFile::findBitcodeInObject(*Obj->get()); if (!BCData) return std::move(Obj); return IRObjectFile::create( MemoryBufferRef(BCData->getBuffer(), Object.getBufferIdentifier()), *Context); } } llvm_unreachable("Unexpected Binary File Type"); }
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, 6) if (!sys::fs::exists(libraryName)) { klee_error("Link with library %s failed. No such file.", libraryName.c_str()); } ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = MemoryBuffer::getFile(libraryName); std::error_code ec; if ((ec = Buffer.getError())) { klee_error("Link with library %s failed: %s", libraryName.c_str(), ec.message().c_str()); } sys::fs::file_magic magic = sys::fs::identify_magic(Buffer.get()->getBuffer()); MemoryBufferRef BufferRef = Buffer.get()->getMemBufferRef(); LLVMContext &Context = getGlobalContext(); std::string ErrorMessage; if (magic == sys::fs::file_magic::bitcode) { ErrorOr<Module *> Result = parseBitcodeFile(BufferRef, Context); if ((ec = Buffer.getError()) || Linker::LinkModules(module, Result.get())) klee_error("Link with library %s failed: %s", libraryName.c_str(), ErrorMessage.c_str()); delete Result.get(); } else if (magic == sys::fs::file_magic::archive) { ErrorOr<std::unique_ptr<object::Binary>> arch = object::createBinary(BufferRef, &Context); if ((ec = arch.getError())) klee_error("Link with library %s failed: %s", libraryName.c_str(), arch.getError().message().c_str()); if (object::Archive *a = dyn_cast<object::Archive>(arch.get().get())) { // Handle in helper if (!linkBCA(a, module, ErrorMessage)) klee_error("Link with library %s failed: %s", libraryName.c_str(), ErrorMessage.c_str()); } else { klee_error("Link with library %s failed: Cast to archive failed", libraryName.c_str()); } } else if (magic.is_object()) { std::unique_ptr<object::Binary> obj; if (object::ObjectFile *o = dyn_cast<object::ObjectFile>(obj.get())) { klee_warning("Link with library: Object file %s in archive %s found. " "Currently not supported.", o->getFileName().data(), libraryName.c_str()); } } else { klee_error("Link with library %s failed: Unrecognized file type.", libraryName.c_str()); } return module; #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 3) if (!sys::fs::exists(libraryName)) { klee_error("Link with library %s failed. No such file.", libraryName.c_str()); } OwningPtr<MemoryBuffer> Buffer; if (error_code ec = MemoryBuffer::getFile(libraryName, Buffer)) { klee_error("Link with library %s failed: %s", libraryName.c_str(), ec.message().c_str()); } sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer()); LLVMContext &Context = getGlobalContext(); std::string ErrorMessage; if (magic == sys::fs::file_magic::bitcode) { Module *Result = 0; Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage); if (!Result || Linker::LinkModules(module, Result, Linker::DestroySource, &ErrorMessage)) klee_error("Link with library %s failed: %s", libraryName.c_str(), ErrorMessage.c_str()); delete Result; } else if (magic == sys::fs::file_magic::archive) { OwningPtr<object::Binary> arch; if (error_code ec = object::createBinary(Buffer.take(), arch)) klee_error("Link with library %s failed: %s", libraryName.c_str(), ec.message().c_str()); if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) { // Handle in helper if (!linkBCA(a, module, ErrorMessage)) klee_error("Link with library %s failed: %s", libraryName.c_str(), ErrorMessage.c_str()); } else { klee_error("Link with library %s failed: Cast to archive failed", libraryName.c_str()); } } else if (magic.is_object()) { OwningPtr<object::Binary> obj; if (object::ObjectFile *o = dyn_cast<object::ObjectFile>(obj.get())) { klee_warning("Link with library: Object file %s in archive %s found. " "Currently not supported.", o->getFileName().data(), libraryName.c_str()); } } else { klee_error("Link with library %s failed: Unrecognized file type.", libraryName.c_str()); } return module; #else Linker linker("klee", module, false); 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 }