Exemple #1
0
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;
}
Exemple #2
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";
  }
}
Exemple #3
0
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());
}
Exemple #4
0
/// \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;
}
Exemple #5
0
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;
}
Exemple #6
0
/// 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;
    }
  }
}
Exemple #7
0
 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());
 }
Exemple #8
0
  // 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;
  }
Exemple #9
0
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;
}
Exemple #10
0
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);
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
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();
}
Exemple #15
0
/// 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();
}
Exemple #16
0
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; 
}
Exemple #17
0
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)));
      }
    }
  }
}
Exemple #18
0
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);
}
Exemple #19
0
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;
  }
}
Exemple #20
0
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;
  }
}