int main(int argc, char **argv) { llvm::cl::ParseCommandLineOptions(argc, argv); if (Input.getNumOccurrences()) { OwningPtr<MemoryBuffer> Buf; if (MemoryBuffer::getFileOrSTDIN(Input, Buf)) return 1; llvm::SourceMgr sm; if (DumpTokens) { yaml::dumpTokens(Buf->getBuffer(), outs()); } if (DumpCanonical) { yaml::Stream stream(Buf->getBuffer(), sm); dumpStream(stream); } } if (Verify) { llvm::TimerGroup Group("YAML parser benchmark"); benchmark(Group, "Fast", createJSONText(10, 500)); } else if (!DumpCanonical && !DumpTokens) { llvm::TimerGroup Group("YAML parser benchmark"); benchmark(Group, "Small Values", createJSONText(MemoryLimitMB, 5)); benchmark(Group, "Medium Values", createJSONText(MemoryLimitMB, 500)); benchmark(Group, "Large Values", createJSONText(MemoryLimitMB, 50000)); } return 0; }
void Pocc::printScop(raw_ostream &OS) const { OwningPtr<MemoryBuffer> stdoutBuffer; OwningPtr<MemoryBuffer> stderrBuffer; OS << "Command line: "; for (std::vector<const char *>::const_iterator AI = arguments.begin(), AE = arguments.end(); AI != AE; ++AI) if (*AI) OS << " " << *AI; OS << "\n"; if (error_code ec = MemoryBuffer::getFile(PlutoStdout, stdoutBuffer)) OS << "Could not open pocc stdout file: " + ec.message() << "\n"; else { OS << "pocc stdout: " << stdoutBuffer->getBufferIdentifier() << "\n"; OS << stdoutBuffer->getBuffer() << "\n"; } if (error_code ec = MemoryBuffer::getFile(PlutoStderr, stderrBuffer)) OS << "Could not open pocc stderr file: " + ec.message() << "\n"; else { OS << "pocc stderr: " << PlutoStderr << "\n"; OS << stderrBuffer->getBuffer() << "\n"; } }
int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv); sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. OwningPtr<MemoryBuffer> Buf; if (MemoryBuffer::getFileOrSTDIN(Input, Buf)) return 1; yaml::Input YIn(Buf->getBuffer()); COFFYAML::Object Doc; YIn >> Doc; if (YIn.error()) { errs() << "yaml2obj: Failed to parse YAML file!\n"; return 1; } COFFParser CP(Doc); if (!CP.parse()) { errs() << "yaml2obj: Failed to parse YAML file!\n"; return 1; } if (!layoutCOFF(CP)) { errs() << "yaml2obj: Failed to layout COFF file!\n"; return 1; } writeCOFF(CP, outs()); }
/// \brief Attempt to read the lock file with the given name, if it exists. /// /// \param LockFileName The name of the lock file to read. /// /// \returns The process ID of the process that owns this lock file Optional<std::pair<std::string, int> > LockFileManager::readLockFile(StringRef LockFileName) { // Check whether the lock file exists. If not, clearly there's nothing // to read, so we just return. if (!sys::fs::exists(LockFileName)) return None; // Read the owning host and PID out of the lock file. If it appears that the // owning process is dead, the lock file is invalid. OwningPtr<MemoryBuffer> MB; if (MemoryBuffer::getFile(LockFileName, MB)) return None; StringRef Hostname; StringRef PIDStr; std::tie(Hostname, PIDStr) = getToken(MB->getBuffer(), " "); PIDStr = PIDStr.substr(PIDStr.find_first_not_of(" ")); int PID; if (!PIDStr.getAsInteger(10, PID)) return std::make_pair(std::string(Hostname), PID); // Delete the lock file. It's invalid anyway. sys::fs::remove(LockFileName); return None; }
bool FileRemapper::initFromFile(StringRef filePath, DiagnosticsEngine &Diag, bool ignoreIfFilesChanged) { assert(FromToMappings.empty() && "initFromDisk should be called before any remap calls"); std::string infoFile = filePath; bool fileExists = false; llvm::sys::fs::exists(infoFile, fileExists); if (!fileExists) return false; std::vector<std::pair<const FileEntry *, const FileEntry *> > pairs; OwningPtr<llvm::MemoryBuffer> fileBuf; if (llvm::MemoryBuffer::getFile(infoFile.c_str(), fileBuf)) return report("Error opening file: " + infoFile, Diag); SmallVector<StringRef, 64> lines; fileBuf->getBuffer().split(lines, "\n"); for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) { StringRef fromFilename = lines[idx]; unsigned long long timeModified; if (lines[idx+1].getAsInteger(10, timeModified)) return report("Invalid file data: '" + lines[idx+1] + "' not a number", Diag); StringRef toFilename = lines[idx+2]; const FileEntry *origFE = FileMgr->getFile(fromFilename); if (!origFE) { if (ignoreIfFilesChanged) continue; return report("File does not exist: " + fromFilename, Diag); } const FileEntry *newFE = FileMgr->getFile(toFilename); if (!newFE) { if (ignoreIfFilesChanged) continue; return report("File does not exist: " + toFilename, Diag); } if ((uint64_t)origFE->getModificationTime() != timeModified) { if (ignoreIfFilesChanged) continue; return report("File was modified: " + fromFilename, Diag); } pairs.push_back(std::make_pair(origFE, newFE)); } for (unsigned i = 0, e = pairs.size(); i != e; ++i) remap(pairs[i].first, pairs[i].second); return false; }
/// print - Print source files with collected line count information. void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const { for (StringMap<LineData>::const_iterator I = LineInfo.begin(), E = LineInfo.end(); I != E; ++I) { StringRef Filename = I->first(); OwningPtr<MemoryBuffer> Buff; if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { errs() << Filename << ": " << ec.message() << "\n"; return; } StringRef AllLines = Buff->getBuffer(); std::string CovFilename = Filename.str() + ".llcov"; std::string ErrorInfo; raw_fd_ostream OS(CovFilename.c_str(), ErrorInfo); if (!ErrorInfo.empty()) errs() << ErrorInfo << "\n"; OS << " -: 0:Source:" << Filename << "\n"; OS << " -: 0:Graph:" << GCNOFile << "\n"; OS << " -: 0:Data:" << GCDAFile << "\n"; OS << " -: 0:Runs:" << RunCount << "\n"; OS << " -: 0:Programs:" << ProgramCount << "\n"; const LineData &Line = I->second; for (uint32_t i = 0; !AllLines.empty(); ++i) { LineData::const_iterator BlocksIt = Line.find(i); // Add up the block counts to form line counts. if (BlocksIt != Line.end()) { const BlockVector &Blocks = BlocksIt->second; uint64_t LineCount = 0; for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end(); I != E; ++I) { LineCount += (*I)->getCount(); } if (LineCount == 0) OS << " #####:"; else OS << format("%9" PRIu64 ":", LineCount); } else { OS << " -:"; } std::pair<StringRef, StringRef> P = AllLines.split('\n'); OS << format("%5u:", i+1) << P.first << "\n"; AllLines = P.second; } } }
virtual MemoryBuffer* getObject(const Module* M) { const std::string ModuleID = M->getModuleIdentifier(); std::string CacheName; if (!getCacheFilename(ModuleID, CacheName)) return NULL; // Load the object from the cache filename OwningPtr<MemoryBuffer> IRObjectBuffer; MemoryBuffer::getFile(CacheName.c_str(), IRObjectBuffer, -1, false); // If the file isn't there, that's OK. if (!IRObjectBuffer) return NULL; // MCJIT will want to write into this buffer, and we don't want that // because the file has probably just been mmapped. Instead we make // a copy. The filed-based buffer will be released when it goes // out of scope. return MemoryBuffer::getMemBufferCopy(IRObjectBuffer->getBuffer()); }
// MCJIT will call this function before compiling any module // MCJIT takes ownership of both the MemoryBuffer object and the memory // to which it refers. virtual MemoryBuffer* getObject(const Module* M) { // Get the ModuleID const std::string ModuleID = M->getModuleIdentifier(); // If we've flagged this as an IR file, cache it if (0 == ModuleID.compare(0, 3, "IR:")) { std::string IRFileName = ModuleID.substr(3); SmallString<128> IRCacheFile = CacheDir; sys::path::append(IRCacheFile, IRFileName); if (!sys::fs::exists(IRCacheFile.str())) { // This file isn't in our cache return NULL; } OwningPtr<MemoryBuffer> IRObjectBuffer; MemoryBuffer::getFile(IRCacheFile.c_str(), IRObjectBuffer, -1, false); // MCJIT will want to write into this buffer, and we don't want that // because the file has probably just been mmapped. Instead we make // a copy. The filed-based buffer will be released when it goes // out of scope. return MemoryBuffer::getMemBufferCopy(IRObjectBuffer->getBuffer()); } return NULL; }
static void performWriteOperation(ArchiveOperation Operation, object::Archive *OldArchive) { SmallString<128> TmpArchive; failIfError(sys::fs::createUniqueFile(ArchiveName + ".temp-archive-%%%%%%%.a", TmpArchiveFD, TmpArchive)); TemporaryOutput = TmpArchive.c_str(); tool_output_file Output(TemporaryOutput, TmpArchiveFD); raw_fd_ostream &Out = Output.os(); Out << "!<arch>\n"; std::vector<NewArchiveIterator> NewMembers = computeNewArchiveMembers(Operation, OldArchive); std::vector<std::pair<unsigned, unsigned> > MemberOffsetRefs; if (Symtab) { writeSymbolTable(Out, NewMembers, MemberOffsetRefs); } std::vector<unsigned> StringMapIndexes; writeStringTable(Out, NewMembers, StringMapIndexes); std::vector<std::pair<unsigned, unsigned> >::iterator MemberRefsI = MemberOffsetRefs.begin(); unsigned MemberNum = 0; unsigned LongNameMemberNum = 0; for (std::vector<NewArchiveIterator>::iterator I = NewMembers.begin(), E = NewMembers.end(); I != E; ++I, ++MemberNum) { unsigned Pos = Out.tell(); while (MemberRefsI != MemberOffsetRefs.end() && MemberRefsI->second == MemberNum) { Out.seek(MemberRefsI->first); print32BE(Out, Pos); ++MemberRefsI; } Out.seek(Pos); if (I->isNewMember()) { const char *FileName = I->getNew(); int FD; failIfError(sys::fs::openFileForRead(FileName, FD), FileName); sys::fs::file_status Status; failIfError(sys::fs::status(FD, Status), FileName); // Opening a directory doesn't make sense. Let it failed. // Linux cannot open directories with open(2), although // cygwin and *bsd can. if (Status.type() == sys::fs::file_type::directory_file) failIfError(error_code(errc::is_a_directory, posix_category()), FileName); OwningPtr<MemoryBuffer> File; failIfError(MemoryBuffer::getOpenFile(FD, FileName, File, Status.getSize(), false), FileName); StringRef Name = sys::path::filename(FileName); if (Name.size() < 16) printMemberHeader(Out, Name, Status.getLastModificationTime(), Status.getUser(), Status.getGroup(), Status.permissions(), Status.getSize()); else printMemberHeader(Out, StringMapIndexes[LongNameMemberNum++], Status.getLastModificationTime(), Status.getUser(), Status.getGroup(), Status.permissions(), Status.getSize()); Out << File->getBuffer(); } else { object::Archive::child_iterator OldMember = I->getOld(); StringRef Name = I->getName(); if (Name.size() < 16) printMemberHeader(Out, Name, OldMember->getLastModified(), OldMember->getUID(), OldMember->getGID(), OldMember->getAccessMode(), OldMember->getSize()); else printMemberHeader(Out, StringMapIndexes[LongNameMemberNum++], OldMember->getLastModified(), OldMember->getUID(), OldMember->getGID(), OldMember->getAccessMode(), OldMember->getSize()); Out << OldMember->getBuffer(); } if (Out.tell() % 2) Out << '\n'; } Output.keep(); Out.close(); sys::fs::rename(TemporaryOutput, ArchiveName); TemporaryOutput = NULL; }
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); }
FormatStyle getStyle(StringRef StyleName, StringRef FileName) { FormatStyle Style; getPredefinedStyle(FallbackStyle, &Style); if (StyleName.startswith("{")) { // Parse YAML/JSON style from the command line. if (error_code ec = parseConfiguration(StyleName, &Style)) { llvm::errs() << "Error parsing -style: " << ec.message() << ", using " << FallbackStyle << " style\n"; } return Style; } if (!StyleName.equals_lower("file")) { if (!getPredefinedStyle(StyleName, &Style)) llvm::errs() << "Invalid value for -style, using " << FallbackStyle << " style\n"; return Style; } if (FileName == "-") FileName = AssumeFilename; SmallString<128> Path(FileName); llvm::sys::fs::make_absolute(Path); for (StringRef Directory = Path; !Directory.empty(); Directory = llvm::sys::path::parent_path(Directory)) { if (!llvm::sys::fs::is_directory(Directory)) continue; SmallString<128> ConfigFile(Directory); llvm::sys::path::append(ConfigFile, ".clang-format"); DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); bool IsFile = false; // Ignore errors from is_regular_file: we only need to know if we can read // the file or not. llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile); if (!IsFile) { // Try _clang-format too, since dotfiles are not commonly used on Windows. ConfigFile = Directory; llvm::sys::path::append(ConfigFile, "_clang-format"); DEBUG(llvm::dbgs() << "Trying " << ConfigFile << "...\n"); llvm::sys::fs::is_regular_file(Twine(ConfigFile), IsFile); } if (IsFile) { OwningPtr<MemoryBuffer> Text; if (error_code ec = MemoryBuffer::getFile(ConfigFile, Text)) { llvm::errs() << ec.message() << "\n"; continue; } if (error_code ec = parseConfiguration(Text->getBuffer(), &Style)) { llvm::errs() << "Error reading " << ConfigFile << ": " << ec.message() << "\n"; continue; } DEBUG(llvm::dbgs() << "Using configuration file " << ConfigFile << "\n"); return Style; } } llvm::errs() << "Can't find usable .clang-format, using " << FallbackStyle << " style\n"; return Style; }
int main(int argc, char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; cl::ParseCommandLineOptions(argc, argv, "linker script randomizer\n"); sys::Path ldPath = sys::Program::FindProgramByName("ld"); if (ldPath.isEmpty()) { errs() << "Couldn't find system linker"; llvm_shutdown(); return 1; } sys::Path scriptPath = sys::Path::GetTemporaryDirectory(); if (scriptPath.isEmpty()) { errs() << "Error accessing temporary directory"; llvm_shutdown(); return 1; } scriptPath.appendComponent("ld_script"); scriptPath.makeUnique(false, NULL); sys::Path devNull; std::string errMsg; const char *ldArgs[] = { ldPath.c_str(), "--verbose", NULL }; const sys::Path *redirects[] = { &devNull, &scriptPath, &scriptPath, NULL }; if (sys::Program::ExecuteAndWait(ldPath, ldArgs, 0, redirects, 0, 0, &errMsg)) { errs() << "Error executing linker"; llvm_shutdown(); return 1; } OwningPtr< MemoryBuffer > scriptFile; error_code ec = MemoryBuffer::getFile(scriptPath.c_str(), scriptFile); if (ec) { errs() << "Error reading script file: " << ec.message(); llvm_shutdown(); return 1; } uint32_t minPage = (MinBaseAddress + PAGE_SIZE - 1) / PAGE_SIZE, maxPage = MaxBaseAddress / PAGE_SIZE; if (minPage > maxPage) { errs() << "Base address interval is empty"; llvm_shutdown(); return 1; } uint32_t newAddr = PAGE_SIZE * (minPage + RandomNumberGenerator::Generator().Random(maxPage - minPage + 1)); char oldAddrStr[12]; sprintf(oldAddrStr, "0x%08x", OldBaseAddress.getValue()); llvm::Regex oldAddrRegex(oldAddrStr); StringRef scriptText = scriptFile->getBuffer(); StringRef oldScriptText = scriptText; char newAddrStr[12]; sprintf(newAddrStr, "0x%08x", newAddr); do { // Replace one occurrence of old address with new one oldScriptText = scriptText; scriptText = oldAddrRegex.sub(newAddrStr, scriptText); } while (!scriptText.equals(oldScriptText)); std::cout << scriptText.str(); return 0; }
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) 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 }
error_code MemoryBuffer::getOpenFile(int FD, const char *Filename, OwningPtr<MemoryBuffer> &result, uint64_t FileSize, uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator) { static int PageSize = sys::Process::GetPageSize(); // Default is to map the full file. if (MapSize == uint64_t(-1)) { // If we don't know the file size, use fstat to find out. fstat on an open // file descriptor is cheaper than stat on a random path. if (FileSize == uint64_t(-1)) { struct stat FileInfo; // TODO: This should use fstat64 when available. if (fstat(FD, &FileInfo) == -1) { return error_code(errno, posix_category()); } FileSize = FileInfo.st_size; } MapSize = FileSize; } if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator, PageSize)) { off_t RealMapOffset = Offset & ~(PageSize - 1); off_t Delta = Offset - RealMapOffset; size_t RealMapSize = MapSize + Delta; if (const char *Pages = sys::Path::MapInFilePages(FD, RealMapSize, RealMapOffset)) { result.reset(GetNamedBuffer<MemoryBufferMMapFile>( StringRef(Pages + Delta, MapSize), Filename, RequiresNullTerminator)); if (RequiresNullTerminator && result->getBufferEnd()[0] != '\0') { // There could be a racing issue that resulted in the file being larger // than the FileSize passed by the caller. We already have an assertion // for this in MemoryBuffer::init() but have a runtime guarantee that // the buffer will be null-terminated here, so do a copy that adds a // null-terminator. result.reset(MemoryBuffer::getMemBufferCopy(result->getBuffer(), Filename)); } return error_code::success(); } } MemoryBuffer *Buf = MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename); if (!Buf) { // Failed to create a buffer. The only way it can fail is if // new(std::nothrow) returns 0. return make_error_code(errc::not_enough_memory); } OwningPtr<MemoryBuffer> SB(Buf); char *BufPtr = const_cast<char*>(SB->getBufferStart()); size_t BytesLeft = MapSize; #ifndef HAVE_PREAD if (lseek(FD, Offset, SEEK_SET) == -1) return error_code(errno, posix_category()); #endif while (BytesLeft) { #ifdef HAVE_PREAD ssize_t NumRead = ::pread(FD, BufPtr, BytesLeft, MapSize-BytesLeft+Offset); #else ssize_t NumRead = ::read(FD, BufPtr, BytesLeft); #endif if (NumRead == -1) { if (errno == EINTR) continue; // Error while reading. return error_code(errno, posix_category()); } if (NumRead == 0) { assert(0 && "We got inaccurate FileSize value or fstat reported an " "invalid file size."); *BufPtr = '\0'; // null-terminate at the actual size. break; } BytesLeft -= NumRead; BufPtr += NumRead; } result.swap(SB); return error_code::success(); }
/// print - Print source files with collected line count information. void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) { for (StringMap<LineData>::const_iterator I = LineInfo.begin(), E = LineInfo.end(); I != E; ++I) { StringRef Filename = I->first(); OwningPtr<MemoryBuffer> Buff; if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { errs() << Filename << ": " << ec.message() << "\n"; return; } StringRef AllLines = Buff->getBuffer(); std::string CovFilename = Filename.str() + ".gcov"; std::string ErrorInfo; raw_fd_ostream OS(CovFilename.c_str(), ErrorInfo); if (!ErrorInfo.empty()) errs() << ErrorInfo << "\n"; OS << " -: 0:Source:" << Filename << "\n"; OS << " -: 0:Graph:" << GCNOFile << "\n"; OS << " -: 0:Data:" << GCDAFile << "\n"; OS << " -: 0:Runs:" << RunCount << "\n"; OS << " -: 0:Programs:" << ProgramCount << "\n"; const LineData &Line = I->second; GCOVCoverage FileCoverage(Filename); for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) { if (Options.BranchInfo) { FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex); if (FuncsIt != Line.Functions.end()) printFunctionSummary(OS, FuncsIt->second); } BlockLines::const_iterator BlocksIt = Line.Blocks.find(LineIndex); if (BlocksIt == Line.Blocks.end()) { // No basic blocks are on this line. Not an executable line of code. OS << " -:"; std::pair<StringRef, StringRef> P = AllLines.split('\n'); OS << format("%5u:", LineIndex+1) << P.first << "\n"; AllLines = P.second; } else { const BlockVector &Blocks = BlocksIt->second; // Add up the block counts to form line counts. DenseMap<const GCOVFunction *, bool> LineExecs; uint64_t LineCount = 0; for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end(); I != E; ++I) { const GCOVBlock *Block = *I; if (Options.AllBlocks) { // Only take the highest block count for that line. uint64_t BlockCount = Block->getCount(); LineCount = LineCount > BlockCount ? LineCount : BlockCount; } else { // Sum up all of the block counts. LineCount += Block->getCount(); } if (Options.FuncCoverage) { // This is a slightly convoluted way to most accurately gather line // statistics for functions. Basically what is happening is that we // don't want to count a single line with multiple blocks more than // once. However, we also don't simply want to give the total line // count to every function that starts on the line. Thus, what is // happening here are two things: // 1) Ensure that the number of logical lines is only incremented // once per function. // 2) If there are multiple blocks on the same line, ensure that the // number of lines executed is incremented as long as at least // one of the blocks are executed. const GCOVFunction *Function = &Block->getParent(); if (FuncCoverages.find(Function) == FuncCoverages.end()) { std::pair<const GCOVFunction *, GCOVCoverage> KeyValue(Function, GCOVCoverage(Function->getName())); FuncCoverages.insert(KeyValue); } GCOVCoverage &FuncCoverage = FuncCoverages.find(Function)->second; if (LineExecs.find(Function) == LineExecs.end()) { if (Block->getCount()) { ++FuncCoverage.LinesExec; LineExecs[Function] = true; } else { LineExecs[Function] = false; } ++FuncCoverage.LogicalLines; } else if (!LineExecs[Function] && Block->getCount()) { ++FuncCoverage.LinesExec; LineExecs[Function] = true; } } } if (LineCount == 0) OS << " #####:"; else { OS << format("%9" PRIu64 ":", LineCount); ++FileCoverage.LinesExec; } ++FileCoverage.LogicalLines; std::pair<StringRef, StringRef> P = AllLines.split('\n'); OS << format("%5u:", LineIndex+1) << P.first << "\n"; AllLines = P.second; uint32_t BlockNo = 0; uint32_t EdgeNo = 0; for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end(); I != E; ++I) { const GCOVBlock *Block = *I; // Only print block and branch information at the end of the block. if (Block->getLastLine() != LineIndex+1) continue; if (Options.AllBlocks) printBlockInfo(OS, *Block, LineIndex, BlockNo); if (Options.BranchInfo) { size_t NumEdges = Block->getNumDstEdges(); if (NumEdges > 1) printBranchInfo(OS, *Block, FileCoverage, EdgeNo); else if (Options.UncondBranch && NumEdges == 1) printUncondBranchInfo(OS, EdgeNo, (*Block->dst_begin())->Count); } } } } FileCoverages.push_back(FileCoverage); } // FIXME: There is no way to detect calls given current instrumentation. if (Options.FuncCoverage) printFuncCoverage(); printFileCoverage(); }
static bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) { using namespace llvm; assert(!resultFiles.empty()); std::map<StringRef, StringRef> resultMap; for (ArrayRef<std::string>::iterator I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) { StringRef fname(*I); if (!fname.endswith(".result")) { errs() << "error: filename '" << fname << "' does not have '.result' extension\n"; return true; } resultMap[sys::path::stem(fname)] = fname; } OwningPtr<MemoryBuffer> inputBuf; if (RemappingsFile.empty()) MemoryBuffer::getSTDIN(inputBuf); else MemoryBuffer::getFile(RemappingsFile, inputBuf); if (!inputBuf) { errs() << "error: could not read remappings input\n"; return true; } SmallVector<StringRef, 8> strs; inputBuf->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false); if (strs.empty()) { errs() << "error: no files to verify from stdin\n"; return true; } if (strs.size() % 2 != 0) { errs() << "error: files to verify are not original/result pairs\n"; return true; } for (unsigned i = 0, e = strs.size(); i != e; i += 2) { StringRef inputOrigFname = strs[i]; StringRef inputResultFname = strs[i+1]; std::map<StringRef, StringRef>::iterator It; It = resultMap.find(sys::path::filename(inputOrigFname)); if (It == resultMap.end()) { errs() << "error: '" << inputOrigFname << "' is not in the list of " << "transformed files to verify\n"; return true; } bool exists = false; sys::fs::exists(It->second, exists); if (!exists) { errs() << "error: '" << It->second << "' does not exist\n"; return true; } sys::fs::exists(inputResultFname, exists); if (!exists) { errs() << "error: '" << inputResultFname << "' does not exist\n"; return true; } if (!filesCompareEqual(It->second, inputResultFname)) { errs() << "error: '" << It->second << "' is different than " << "'" << inputResultFname << "'\n"; return true; } resultMap.erase(It); } if (!resultMap.empty()) { for (std::map<StringRef, StringRef>::iterator I = resultMap.begin(), E = resultMap.end(); I != E; ++I) errs() << "error: '" << I->second << "' was not verified!\n"; return true; } return false; }
DWARFContextInMemory::DWARFContextInMemory(object::ObjectFile *Obj) : IsLittleEndian(Obj->isLittleEndian()), AddressSize(Obj->getBytesInAddress()) { error_code ec; for (object::section_iterator i = Obj->begin_sections(), e = Obj->end_sections(); i != e; i.increment(ec)) { StringRef name; i->getName(name); StringRef data; i->getContents(data); name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes. // Check if debug info section is compressed with zlib. if (name.startswith("zdebug_")) { uint64_t OriginalSize; if (!zlib::isAvailable() || !consumeCompressedDebugSectionHeader(data, OriginalSize)) continue; OwningPtr<MemoryBuffer> UncompressedSection; if (zlib::uncompress(data, UncompressedSection, OriginalSize) != zlib::StatusOK) continue; // Make data point to uncompressed section contents and save its contents. name = name.substr(1); data = UncompressedSection->getBuffer(); UncompressedSections.push_back(UncompressedSection.take()); } StringRef *Section = StringSwitch<StringRef*>(name) .Case("debug_info", &InfoSection) .Case("debug_abbrev", &AbbrevSection) .Case("debug_line", &LineSection) .Case("debug_aranges", &ARangeSection) .Case("debug_frame", &DebugFrameSection) .Case("debug_str", &StringSection) .Case("debug_ranges", &RangeSection) .Case("debug_pubnames", &PubNamesSection) .Case("debug_info.dwo", &InfoDWOSection) .Case("debug_abbrev.dwo", &AbbrevDWOSection) .Case("debug_str.dwo", &StringDWOSection) .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) .Case("debug_addr", &AddrSection) // Any more debug info sections go here. .Default(0); if (!Section) continue; *Section = data; if (name == "debug_ranges") { // FIXME: Use the other dwo range section when we emit it. RangeDWOSection = data; } // TODO: Add support for relocations in other sections as needed. // Record relocations for the debug_info and debug_line sections. RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(name) .Case("debug_info", &InfoRelocMap) .Case("debug_info.dwo", &InfoDWORelocMap) .Case("debug_line", &LineRelocMap) .Default(0); if (!Map) continue; if (i->begin_relocations() != i->end_relocations()) { uint64_t SectionSize; i->getSize(SectionSize); for (object::relocation_iterator reloc_i = i->begin_relocations(), reloc_e = i->end_relocations(); reloc_i != reloc_e; reloc_i.increment(ec)) { uint64_t Address; reloc_i->getOffset(Address); uint64_t Type; reloc_i->getType(Type); uint64_t SymAddr = 0; // ELF relocations may need the symbol address if (Obj->isELF()) { object::SymbolRef Sym; reloc_i->getSymbol(Sym); Sym.getAddress(SymAddr); } object::RelocVisitor V(Obj->getFileFormatName()); // The section address is always 0 for debug sections. object::RelocToApply R(V.visit(Type, *reloc_i, 0, SymAddr)); if (V.error()) { SmallString<32> Name; error_code ec(reloc_i->getTypeName(Name)); if (ec) { errs() << "Aaaaaa! Nameless relocation! Aaaaaa!\n"; } errs() << "error: failed to compute relocation: " << Name << "\n"; continue; } if (Address + R.Width > SectionSize) { errs() << "error: " << R.Width << "-byte relocation starting " << Address << " bytes into section " << name << " which is " << SectionSize << " bytes long.\n"; continue; } if (R.Width > 8) { errs() << "error: can't handle a relocation of more than 8 bytes at " "a time.\n"; continue; } DEBUG(dbgs() << "Writing " << format("%p", R.Value) << " at " << format("%p", Address) << " with width " << format("%d", R.Width) << "\n"); Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value))); } } } }
Manifest* Manifest::load(raw_ostream& ErrorStream, Automaton::Type T, StringRef Path) { llvm::SourceMgr SM; OwningPtr<MemoryBuffer> Buffer; error_code Error = MemoryBuffer::getFile(Path, Buffer); if (Error != 0) { ErrorStream << "Failed to open TESLA analysis file '" << Path << "': " << Error.message() << "\n" ; return NULL; } OwningPtr<ManifestFile> Protobuf(new ManifestFile); StringRef buf = Buffer->getBuffer(); const bool TextFormat = buf.ltrim().startswith("automaton") or buf.ltrim().startswith("#line 1") // for preprocessed manifests or buf.ltrim().startswith("# 1") // GNU cpp version of the above ; const bool success = TextFormat ? google::protobuf::TextFormat::ParseFromString(buf, Protobuf.get()) : Protobuf->ParseFromArray(buf.data(), buf.size()) ; if (!success) { ErrorStream << "Error parsing TESLA manifest '" << Path << "' (in " << (TextFormat ? "text" : "binary") << " format)\n" ; return NULL; } AutomataMap Descriptions; map<Identifier,const Automaton*> Automata; // Note the top-level automata that are explicitly named as roots. ArrayRef<const Usage*> Roots(Protobuf->root().data(), Protobuf->root_size()); map<Identifier,const Usage*> Uses; for (auto *U : Roots) Uses[U->identifier()] = U; for (auto& A : Protobuf->automaton()) Descriptions[A.identifier()] = &A; vector<Automaton::Lifetime> Lifetimes; int id = 0; for (auto i : Descriptions) { const Identifier& ID = i.first; const AutomatonDescription *Descrip = i.second; OwningPtr<NFA> N(NFA::Parse(Descrip, Uses[ID], id++)); if (!N) { for (auto i : Automata) delete i.second; for (auto i : Descriptions) delete i.second; return NULL; } OwningPtr<Automaton> Result; if (T == Automaton::Unlinked) Result.reset(N.take()); else { N.reset(N->Link(Descriptions)); if (T == Automaton::Linked) Result.reset(N.take()); else Result.reset(DFA::Convert(N.get())); } Automaton::Lifetime L = Result->getLifetime(); if (L.Init != NULL and find(Lifetimes.begin(), Lifetimes.end(), L) == Lifetimes.end()) { Lifetimes.push_back(L); assert(Lifetimes.back() == L); } Automata[ID] = Result.take(); } raw_ostream& debug = debugs("tesla.manifest.lifetimes"); debug << "--------\nUnique automata lifetimes:\n"; for (auto& Lifetime : Lifetimes) debug << " * " << Lifetime.String() << "\n"; debug << "--------\n"; return new Manifest(Protobuf, Descriptions, Automata, Roots, Lifetimes); }
static void DumpSymbolNamesFromFile(std::string &Filename) { if (Filename != "-" && !sys::fs::exists(Filename)) { errs() << ToolName << ": '" << Filename << "': " << "No such file\n"; return; } OwningPtr<MemoryBuffer> Buffer; if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename)) return; 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) { DumpSymbolNamesFromModule(Result); delete Result; } else { error(ErrorMessage, Filename); return; } } else if (magic == sys::fs::file_magic::archive) { OwningPtr<Binary> arch; if (error(object::createBinary(Buffer.take(), arch), Filename)) return; if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) { if (ArchiveMap) { outs() << "Archive map" << "\n"; for (object::Archive::symbol_iterator i = a->begin_symbols(), e = a->end_symbols(); i != e; ++i) { object::Archive::child_iterator c; StringRef symname; StringRef filename; if (error(i->getMember(c))) return; if (error(i->getName(symname))) return; if (error(c->getName(filename))) return; outs() << symname << " in " << filename << "\n"; } outs() << "\n"; } for (object::Archive::child_iterator i = a->begin_children(), e = a->end_children(); i != e; ++i) { OwningPtr<Binary> child; if (i->getAsBinary(child)) { // Try opening it as a bitcode file. OwningPtr<MemoryBuffer> buff(i->getBuffer()); Module *Result = 0; if (buff) Result = ParseBitcodeFile(buff.get(), Context, &ErrorMessage); if (Result) { DumpSymbolNamesFromModule(Result); delete Result; } continue; } if (object::ObjectFile *o = dyn_cast<ObjectFile>(child.get())) { outs() << o->getFileName() << ":\n"; DumpSymbolNamesFromObject(o); } } } } else if (magic.is_object()) { OwningPtr<Binary> obj; if (error(object::createBinary(Buffer.take(), obj), Filename)) return; if (object::ObjectFile *o = dyn_cast<ObjectFile>(obj.get())) DumpSymbolNamesFromObject(o); } else { errs() << ToolName << ": " << Filename << ": " << "unrecognizable file type\n"; return; } }
static void DumpSymbolNamesFromFile(std::string &Filename) { if (Filename != "-" && !sys::fs::exists(Filename)) { errs() << ToolName << ": '" << Filename << "': " << "No such file\n"; return; } OwningPtr<MemoryBuffer> Buffer; if (error(MemoryBuffer::getFileOrSTDIN(Filename, Buffer), Filename)) return; sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer()); LLVMContext &Context = getGlobalContext(); if (magic == sys::fs::file_magic::bitcode) { ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(Buffer.get(), Context); if (error(ModuleOrErr.getError(), Filename)) { return; } else { Module *Result = ModuleOrErr.get(); DumpSymbolNamesFromModule(Result); delete Result; } } else if (magic == sys::fs::file_magic::archive) { ErrorOr<Binary *> BinaryOrErr = object::createBinary(Buffer.take(), magic); if (error(BinaryOrErr.getError(), Filename)) return; OwningPtr<Binary> arch(BinaryOrErr.get()); if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) { if (ArchiveMap) { object::Archive::symbol_iterator I = a->symbol_begin(); object::Archive::symbol_iterator E = a->symbol_end(); if (I !=E) { outs() << "Archive map" << "\n"; for (; I != E; ++I) { object::Archive::child_iterator c; StringRef symname; StringRef filename; if (error(I->getMember(c))) return; if (error(I->getName(symname))) return; if (error(c->getName(filename))) return; outs() << symname << " in " << filename << "\n"; } outs() << "\n"; } } for (object::Archive::child_iterator i = a->child_begin(), e = a->child_end(); i != e; ++i) { OwningPtr<Binary> child; if (i->getAsBinary(child)) { // Try opening it as a bitcode file. OwningPtr<MemoryBuffer> buff; if (error(i->getMemoryBuffer(buff))) return; ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(buff.get(), Context); if (ModuleOrErr) { Module *Result = ModuleOrErr.get(); DumpSymbolNamesFromModule(Result); delete Result; } continue; } if (object::ObjectFile *o = dyn_cast<ObjectFile>(child.get())) { outs() << o->getFileName() << ":\n"; DumpSymbolNamesFromObject(o); } } } } else if (magic == sys::fs::file_magic::macho_universal_binary) { ErrorOr<Binary *> BinaryOrErr = object::createBinary(Buffer.take(), magic); if (error(BinaryOrErr.getError(), Filename)) return; OwningPtr<Binary> Bin(BinaryOrErr.get()); object::MachOUniversalBinary *UB = cast<object::MachOUniversalBinary>(Bin.get()); for (object::MachOUniversalBinary::object_iterator I = UB->begin_objects(), E = UB->end_objects(); I != E; ++I) { OwningPtr<ObjectFile> Obj; if (!I->getAsObjectFile(Obj)) { outs() << Obj->getFileName() << ":\n"; DumpSymbolNamesFromObject(Obj.get()); } } } else if (magic.is_object()) { ErrorOr<Binary *> BinaryOrErr = object::createBinary(Buffer.take(), magic); if (error(BinaryOrErr.getError(), Filename)) return; OwningPtr<Binary> obj(BinaryOrErr.get()); if (object::ObjectFile *o = dyn_cast<ObjectFile>(obj.get())) DumpSymbolNamesFromObject(o); } else { errs() << ToolName << ": " << Filename << ": " << "unrecognizable file type\n"; HadError = true; return; } }