TEST_F(VFSFromYAMLTest, MappedFiles) { IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); Lower->addRegularFile("//root/foo/bar/a"); IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString("{ 'roots': [\n" "{\n" " 'type': 'directory',\n" " 'name': '//root/',\n" " 'contents': [ {\n" " 'type': 'file',\n" " 'name': 'file1',\n" " 'external-contents': '//root/foo/bar/a'\n" " },\n" " {\n" " 'type': 'file',\n" " 'name': 'file2',\n" " 'external-contents': '//root/foo/b'\n" " }\n" " ]\n" "}\n" "]\n" "}", Lower); ASSERT_TRUE(FS.getPtr() != nullptr); IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( new vfs::OverlayFileSystem(Lower)); O->pushOverlay(FS); // file ErrorOr<vfs::Status> S = O->status("//root/file1"); ASSERT_FALSE(S.getError()); EXPECT_EQ("//root/foo/bar/a", S->getName()); ErrorOr<vfs::Status> SLower = O->status("//root/foo/bar/a"); EXPECT_EQ("//root/foo/bar/a", SLower->getName()); EXPECT_TRUE(S->equivalent(*SLower)); // directory S = O->status("//root/"); ASSERT_FALSE(S.getError()); EXPECT_TRUE(S->isDirectory()); EXPECT_TRUE(S->equivalent(*O->status("//root/"))); // non-volatile UniqueID // broken mapping EXPECT_EQ(std::errc::no_such_file_or_directory, O->status("//root/file2").getError()); EXPECT_EQ(0, NumDiagnostics); }
ErrorOr<Status> VFSFromYAML::status(const Twine &Path) { ErrorOr<Entry *> Result = lookupPath(Path); if (!Result) return Result.getError(); std::string PathStr(Path.str()); if (FileEntry *F = dyn_cast<FileEntry>(*Result)) { ErrorOr<Status> S = ExternalFS->status(F->getExternalContentsPath()); assert(!S || S->getName() == F->getExternalContentsPath()); if (S && !F->useExternalName(UseExternalNames)) S->setName(PathStr); return S; } else { // directory DirectoryEntry *DE = cast<DirectoryEntry>(*Result); Status S = DE->getStatus(); S.setName(PathStr); return S; } }
bool Decoder::dumpPackedEntry(const object::COFFObjectFile &COFF, const SectionRef Section, uint64_t Offset, unsigned Index, const RuntimeFunction &RF) { assert((RF.Flag() == RuntimeFunctionFlag::RFF_Packed || RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment) && "unpacked entry cannot be treated as a packed entry"); ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset); if (!Function) Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true); StringRef FunctionName; uint64_t FunctionAddress; if (Function) { Function->getName(FunctionName); Function->getAddress(FunctionAddress); } else { const pe32_header *PEHeader; if (COFF.getPE32Header(PEHeader)) return false; FunctionAddress = PEHeader->ImageBase + RF.BeginAddress; } SW.printString("Function", formatSymbol(FunctionName, FunctionAddress)); SW.printBoolean("Fragment", RF.Flag() == RuntimeFunctionFlag::RFF_PackedFragment); SW.printNumber("FunctionLength", RF.FunctionLength()); SW.startLine() << "ReturnType: " << RF.Ret() << '\n'; SW.printBoolean("HomedParameters", RF.H()); SW.startLine() << "SavedRegisters: "; printRegisters(SavedRegisterMask(RF)); OS << '\n'; SW.printNumber("StackAdjustment", StackAdjustment(RF) << 2); return true; }
bool Decoder::dumpUnpackedEntry(const COFFObjectFile &COFF, const SectionRef Section, uint64_t Offset, unsigned Index, const RuntimeFunction &RF) { assert(RF.Flag() == RuntimeFunctionFlag::RFF_Unpacked && "packed entry cannot be treated as an unpacked entry"); ErrorOr<SymbolRef> Function = getRelocatedSymbol(COFF, Section, Offset); if (!Function) Function = getSymbol(COFF, RF.BeginAddress, /*FunctionOnly=*/true); ErrorOr<SymbolRef> XDataRecord = getRelocatedSymbol(COFF, Section, Offset + 4); if (!XDataRecord) XDataRecord = getSymbol(COFF, RF.ExceptionInformationRVA()); if (!RF.BeginAddress && !Function) return false; if (!RF.UnwindData && !XDataRecord) return false; StringRef FunctionName; uint64_t FunctionAddress; if (Function) { Function->getName(FunctionName); Function->getAddress(FunctionAddress); } else { const pe32_header *PEHeader; if (COFF.getPE32Header(PEHeader)) return false; FunctionAddress = PEHeader->ImageBase + RF.BeginAddress; } SW.printString("Function", formatSymbol(FunctionName, FunctionAddress)); if (XDataRecord) { StringRef Name; uint64_t Address; XDataRecord->getName(Name); XDataRecord->getAddress(Address); SW.printString("ExceptionRecord", formatSymbol(Name, Address)); section_iterator SI = COFF.section_end(); if (XDataRecord->getSection(SI)) return false; return dumpXDataRecord(COFF, *SI, FunctionAddress, Address); } else { const pe32_header *PEHeader; if (COFF.getPE32Header(PEHeader)) return false; uint64_t Address = PEHeader->ImageBase + RF.ExceptionInformationRVA(); SW.printString("ExceptionRecord", formatSymbol("", Address)); ErrorOr<SectionRef> Section = getSectionContaining(COFF, RF.ExceptionInformationRVA()); if (!Section) return false; return dumpXDataRecord(COFF, *Section, FunctionAddress, RF.ExceptionInformationRVA()); } }
bool Decoder::dumpXDataRecord(const COFFObjectFile &COFF, const SectionRef &Section, uint64_t FunctionAddress, uint64_t VA) { ArrayRef<uint8_t> Contents; if (COFF.getSectionContents(COFF.getCOFFSection(Section), Contents)) return false; uint64_t SectionVA = Section.getAddress(); uint64_t Offset = VA - SectionVA; const ulittle32_t *Data = reinterpret_cast<const ulittle32_t *>(Contents.data() + Offset); const ExceptionDataRecord XData(Data); DictScope XRS(SW, "ExceptionData"); SW.printNumber("FunctionLength", XData.FunctionLength() << 1); SW.printNumber("Version", XData.Vers()); SW.printBoolean("ExceptionData", XData.X()); SW.printBoolean("EpiloguePacked", XData.E()); SW.printBoolean("Fragment", XData.F()); SW.printNumber(XData.E() ? "EpilogueOffset" : "EpilogueScopes", XData.EpilogueCount()); SW.printNumber("ByteCodeLength", static_cast<uint64_t>(XData.CodeWords() * sizeof(uint32_t))); if (XData.E()) { ArrayRef<uint8_t> UC = XData.UnwindByteCode(); if (!XData.F()) { ListScope PS(SW, "Prologue"); decodeOpcodes(UC, 0, /*Prologue=*/true); } if (XData.EpilogueCount()) { ListScope ES(SW, "Epilogue"); decodeOpcodes(UC, XData.EpilogueCount(), /*Prologue=*/false); } } else { ArrayRef<ulittle32_t> EpilogueScopes = XData.EpilogueScopes(); ListScope ESS(SW, "EpilogueScopes"); for (const EpilogueScope ES : EpilogueScopes) { DictScope ESES(SW, "EpilogueScope"); SW.printNumber("StartOffset", ES.EpilogueStartOffset()); SW.printNumber("Condition", ES.Condition()); SW.printNumber("EpilogueStartIndex", ES.EpilogueStartIndex()); ListScope Opcodes(SW, "Opcodes"); decodeOpcodes(XData.UnwindByteCode(), ES.EpilogueStartIndex(), /*Prologue=*/false); } } if (XData.X()) { const uint32_t Address = XData.ExceptionHandlerRVA(); const uint32_t Parameter = XData.ExceptionHandlerParameter(); const size_t HandlerOffset = HeaderWords(XData) + (XData.E() ? 0 : XData.EpilogueCount()) + XData.CodeWords(); ErrorOr<SymbolRef> Symbol = getRelocatedSymbol(COFF, Section, HandlerOffset * sizeof(uint32_t)); if (!Symbol) Symbol = getSymbol(COFF, Address, /*FunctionOnly=*/true); StringRef Name; if (Symbol) Symbol->getName(Name); ListScope EHS(SW, "ExceptionHandler"); SW.printString("Routine", formatSymbol(Name, Address)); SW.printHex("Parameter", Parameter); } return true; }
static void dumpSymbolNamesFromFile(std::string &Filename) { ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = MemoryBuffer::getFileOrSTDIN(Filename); if (error(BufferOrErr.getError(), Filename)) return; LLVMContext &Context = getGlobalContext(); ErrorOr<std::unique_ptr<Binary>> BinaryOrErr = createBinary( BufferOrErr.get()->getMemBufferRef(), NoLLVMBitcode ? nullptr : &Context); if (error(BinaryOrErr.getError(), Filename)) return; Binary &Bin = *BinaryOrErr.get(); if (Archive *A = dyn_cast<Archive>(&Bin)) { if (ArchiveMap) { Archive::symbol_iterator I = A->symbol_begin(); Archive::symbol_iterator E = A->symbol_end(); if (I != E) { outs() << "Archive map\n"; for (; I != E; ++I) { ErrorOr<Archive::Child> C = I->getMember(); if (error(C.getError())) return; ErrorOr<StringRef> FileNameOrErr = C->getName(); if (error(FileNameOrErr.getError())) return; StringRef SymName = I->getName(); outs() << SymName << " in " << FileNameOrErr.get() << "\n"; } outs() << "\n"; } } for (Archive::child_iterator I = A->child_begin(), E = A->child_end(); I != E; ++I) { if (error(I->getError())) return; auto &C = I->get(); ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { if (!checkMachOAndArchFlags(O, Filename)) return; if (!PrintFileName) { outs() << "\n"; if (isa<MachOObjectFile>(O)) { outs() << Filename << "(" << O->getFileName() << ")"; } else outs() << O->getFileName(); outs() << ":\n"; } dumpSymbolNamesFromObject(*O, false, Filename); } } return; } if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(&Bin)) { // If we have a list of architecture flags specified dump only those. if (!ArchAll && ArchFlags.size() != 0) { // Look for a slice in the universal binary that matches each ArchFlag. bool ArchFound; for (unsigned i = 0; i < ArchFlags.size(); ++i) { ArchFound = false; for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { if (ArchFlags[i] == I->getArchTypeName()) { ArchFound = true; ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; std::string ArchitectureName; ArchiveName.clear(); ArchitectureName.clear(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); if (ArchFlags.size() > 1) { if (PrintFileName) ArchitectureName = I->getArchTypeName(); else outs() << "\n" << Obj.getFileName() << " (for architecture " << I->getArchTypeName() << ")" << ":\n"; } dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { std::unique_ptr<Archive> &A = *AOrErr; for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { if (error(AI->getError())) return; auto &C = AI->get(); ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { if (PrintFileName) { ArchiveName = A->getFileName(); if (ArchFlags.size() > 1) ArchitectureName = I->getArchTypeName(); } else { outs() << "\n" << A->getFileName(); outs() << "(" << O->getFileName() << ")"; if (ArchFlags.size() > 1) { outs() << " (for architecture " << I->getArchTypeName() << ")"; } outs() << ":\n"; } dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName); } } } } } if (!ArchFound) { error(ArchFlags[i], "file: " + Filename + " does not contain architecture"); return; } } return; } // No architecture flags were specified so if this contains a slice that // matches the host architecture dump only that. if (!ArchAll) { StringRef HostArchName = MachOObjectFile::getHostArch().getArchName(); for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { if (HostArchName == I->getArchTypeName()) { ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; ArchiveName.clear(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); dumpSymbolNamesFromObject(Obj, false); } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { std::unique_ptr<Archive> &A = *AOrErr; for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { if (error(AI->getError())) return; auto &C = AI->get(); ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { if (PrintFileName) ArchiveName = A->getFileName(); else outs() << "\n" << A->getFileName() << "(" << O->getFileName() << ")" << ":\n"; dumpSymbolNamesFromObject(*O, false, ArchiveName); } } } return; } } } // Either all architectures have been specified or none have been specified // and this does not contain the host architecture so dump all the slices. bool moreThanOneArch = UB->getNumberOfObjects() > 1; for (MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { ErrorOr<std::unique_ptr<ObjectFile>> ObjOrErr = I->getAsObjectFile(); std::string ArchiveName; std::string ArchitectureName; ArchiveName.clear(); ArchitectureName.clear(); if (ObjOrErr) { ObjectFile &Obj = *ObjOrErr.get(); if (PrintFileName) { if (isa<MachOObjectFile>(Obj) && moreThanOneArch) ArchitectureName = I->getArchTypeName(); } else { if (moreThanOneArch) outs() << "\n"; outs() << Obj.getFileName(); if (isa<MachOObjectFile>(Obj) && moreThanOneArch) outs() << " (for architecture " << I->getArchTypeName() << ")"; outs() << ":\n"; } dumpSymbolNamesFromObject(Obj, false, ArchiveName, ArchitectureName); } else if (ErrorOr<std::unique_ptr<Archive>> AOrErr = I->getAsArchive()) { std::unique_ptr<Archive> &A = *AOrErr; for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end(); AI != AE; ++AI) { if (error(AI->getError())) return; auto &C = AI->get(); ErrorOr<std::unique_ptr<Binary>> ChildOrErr = C.getAsBinary(&Context); if (ChildOrErr.getError()) continue; if (SymbolicFile *O = dyn_cast<SymbolicFile>(&*ChildOrErr.get())) { if (PrintFileName) { ArchiveName = A->getFileName(); if (isa<MachOObjectFile>(O) && moreThanOneArch) ArchitectureName = I->getArchTypeName(); } else { outs() << "\n" << A->getFileName(); if (isa<MachOObjectFile>(O)) { outs() << "(" << O->getFileName() << ")"; if (moreThanOneArch) outs() << " (for architecture " << I->getArchTypeName() << ")"; } else outs() << ":" << O->getFileName(); outs() << ":\n"; } dumpSymbolNamesFromObject(*O, false, ArchiveName, ArchitectureName); } } } } return; } if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) { if (!checkMachOAndArchFlags(O, Filename)) return; dumpSymbolNamesFromObject(*O, true); } }
static bool valueIsOnlyCalled(const Value *v) { #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5) for (auto it = v->use_begin(), ie = v->use_end(); it != ie; ++it) { auto user = *it; #else for (auto user : v->users()) { #endif if (const auto *instr = dyn_cast<Instruction>(user)) { // 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 auto *ce = dyn_cast<ConstantExpr>(user)) { if (ce->getOpcode() == Instruction::BitCast) if (valueIsOnlyCalled(ce)) continue; return false; } else if (const auto *ga = dyn_cast<GlobalAlias>(user)) { if (v == ga->getAliasee() && !valueIsOnlyCalled(ga)) return false; } else if (isa<BlockAddress>(user)) { // only valid as operand to indirectbr or comparison against null continue; } else { return false; } } return true; } bool klee::functionEscapes(const Function *f) { return !valueIsOnlyCalled(f); } bool klee::loadFile(const std::string &fileName, LLVMContext &context, std::vector<std::unique_ptr<llvm::Module>> &modules, std::string &errorMsg) { KLEE_DEBUG_WITH_TYPE("klee_loader", dbgs() << "Load file " << fileName << "\n"); #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) ErrorOr<std::unique_ptr<MemoryBuffer>> bufferErr = MemoryBuffer::getFileOrSTDIN(fileName); std::error_code ec = bufferErr.getError(); #else OwningPtr<MemoryBuffer> Buffer; error_code ec = MemoryBuffer::getFileOrSTDIN(fileName, Buffer); #endif if (ec) { klee_error("Loading file %s failed: %s", fileName.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 if (magic == sys::fs::file_magic::bitcode) { SMDiagnostic Err; #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) std::unique_ptr<llvm::Module> module(parseIR(Buffer, Err, context)); #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) std::unique_ptr<llvm::Module> module(ParseIR(Buffer, Err, context)); #else std::unique_ptr<llvm::Module> module(ParseIR(Buffer.take(), Err, context)); #endif if (!module) { klee_error("Loading file %s failed: %s", fileName.c_str(), Err.getMessage().str().c_str()); } modules.push_back(std::move(module)); return true; } if (magic == sys::fs::file_magic::archive) { #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) ErrorOr<std::unique_ptr<object::Binary>> archOwner = object::createBinary(Buffer, &context); ec = archOwner.getError(); llvm::object::Binary *arch = archOwner.get().get(); #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) ErrorOr<object::Binary *> archOwner = object::createBinary(std::move(bufferErr.get()), &context); ec = archOwner.getError(); llvm::object::Binary *arch = archOwner.get(); #else OwningPtr<object::Binary> archOwner; ec = object::createBinary(Buffer.take(), archOwner); llvm::object::Binary *arch = archOwner.get(); #endif if (ec) klee_error("Loading file %s failed: %s", fileName.c_str(), ec.message().c_str()); if (auto archive = dyn_cast<object::Archive>(arch)) { // Load all bitcode files into memory #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) std::error_code ec; #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) ErrorOr<object::Archive::Child> childOrErr = *AI; ec = childOrErr.getError(); if (ec) { errorMsg = ec.message(); return false; } #else object::Archive::child_iterator childOrErr = AI; #endif ErrorOr<StringRef> memberNameErr = childOrErr->getName(); 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 { errorMsg = "Archive member does not have a name!\n"; return false; } #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) ErrorOr<std::unique_ptr<llvm::object::Binary>> child = childOrErr->getAsBinary(); ec = child.getError(); #else OwningPtr<object::Binary> child; ec = AI->getAsBinary(child); #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 = childOrErr->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; ec = AI->getMemoryBuffer(buff); #endif if (ec) { errorMsg = "Failed to get MemoryBuffer: " + ec.message(); return false; } if (buff) { // FIXME: Maybe load bitcode file lazily? Then if we need to link, // materialise // the module SMDiagnostic Err; #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) std::unique_ptr<llvm::Module> module = parseIR(buff.get(), Err, context); #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) std::unique_ptr<llvm::Module> module( ParseIR(buff.get(), Err, context)); #else std::unique_ptr<llvm::Module> module( ParseIR(buff.take(), Err, context)); #endif if (!module) { klee_error("Loading file %s failed: %s", fileName.c_str(), Err.getMessage().str().c_str()); } modules.push_back(std::move(module)); } else { errorMsg = "Buffer was NULL!"; return false; } } else if (child.get()->isObject()) { errorMsg = "Object file " + child.get()->getFileName().str() + " in archive is not supported"; return false; } else { errorMsg = "Loading archive child with error " + ec.message(); return false; } } } return true; } if (magic.is_object()) { errorMsg = "Loading file " + fileName + " Object file as input is currently not supported"; return false; } // This might still be an assembly file. Let's try to parse it. SMDiagnostic Err; #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) std::unique_ptr<llvm::Module> module(parseIR(Buffer, Err, context)); #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) std::unique_ptr<llvm::Module> module(ParseIR(Buffer, Err, context)); #else std::unique_ptr<llvm::Module> module(ParseIR(Buffer.take(), Err, context)); #endif if (!module) { klee_error("Loading file %s failed: Unrecognized file type.", fileName.c_str()); } modules.push_back(std::move(module)); return true; } void klee::checkModule(llvm::Module *m) { LegacyLLVMPassManagerTy pm; pm.add(createVerifierPass()); pm.run(*m); }