예제 #1
0
ErrorOr<std::unique_ptr<SymbolicFile>> SymbolicFile::createSymbolicFile(
    MemoryBufferRef Object, sys::fs::file_magic Type, LLVMContext *Context) {
  StringRef Data = Object.getBuffer();
  if (Type == sys::fs::file_magic::unknown)
    Type = sys::fs::identify_magic(Data);

  switch (Type) {
  case sys::fs::file_magic::bitcode:
    if (Context)
      return IRObjectFile::create(Object, *Context);
  // Fallthrough
  case sys::fs::file_magic::unknown:
  case sys::fs::file_magic::archive:
  case sys::fs::file_magic::macho_universal_binary:
  case sys::fs::file_magic::windows_resource:
    return object_error::invalid_file_type;
  case sys::fs::file_magic::elf:
  case sys::fs::file_magic::elf_executable:
  case sys::fs::file_magic::elf_shared_object:
  case sys::fs::file_magic::elf_core:
  case sys::fs::file_magic::macho_executable:
  case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
  case sys::fs::file_magic::macho_core:
  case sys::fs::file_magic::macho_preload_executable:
  case sys::fs::file_magic::macho_dynamically_linked_shared_lib:
  case sys::fs::file_magic::macho_dynamic_linker:
  case sys::fs::file_magic::macho_bundle:
  case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
  case sys::fs::file_magic::macho_dsym_companion:
  case sys::fs::file_magic::macho_kext_bundle:
  case sys::fs::file_magic::pecoff_executable:
    return ObjectFile::createObjectFile(Object, Type);
  case sys::fs::file_magic::coff_import_library:
    return std::unique_ptr<SymbolicFile>(new COFFImportFile(Object));
  case sys::fs::file_magic::elf_relocatable:
  case sys::fs::file_magic::macho_object:
  case sys::fs::file_magic::coff_object: {
    ErrorOr<std::unique_ptr<ObjectFile>> Obj =
        ObjectFile::createObjectFile(Object, Type);
    if (!Obj || !Context)
      return std::move(Obj);

    ErrorOr<MemoryBufferRef> BCData =
        IRObjectFile::findBitcodeInObject(*Obj->get());
    if (!BCData)
      return std::move(Obj);

    return IRObjectFile::create(
        MemoryBufferRef(BCData->getBuffer(), Object.getBufferIdentifier()),
        *Context);
  }
  }
  llvm_unreachable("Unexpected Binary File Type");
}
예제 #2
0
파일: ModuleUtil.cpp 프로젝트: seahorn/klee
Module *klee::linkWithLibrary(Module *module, 
                              const std::string &libraryName) {
  KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Linking file " << libraryName << "\n");
#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6)
  if (!sys::fs::exists(libraryName)) {
    klee_error("Link with library %s failed. No such file.",
        libraryName.c_str());
  }

  ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer =
      MemoryBuffer::getFile(libraryName);
  std::error_code ec;
  if ((ec = Buffer.getError())) {
    klee_error("Link with library %s failed: %s", libraryName.c_str(),
               ec.message().c_str());
  }

  sys::fs::file_magic magic =
      sys::fs::identify_magic(Buffer.get()->getBuffer());
  MemoryBufferRef BufferRef = Buffer.get()->getMemBufferRef();
  LLVMContext &Context = getGlobalContext();
  std::string ErrorMessage;

  if (magic == sys::fs::file_magic::bitcode) {

    ErrorOr<Module *> Result = parseBitcodeFile(BufferRef, Context);

    if ((ec = Buffer.getError()) || Linker::LinkModules(module, Result.get()))
      klee_error("Link with library %s failed: %s", libraryName.c_str(),
                 ErrorMessage.c_str());

    delete Result.get();

  } else if (magic == sys::fs::file_magic::archive) {

    ErrorOr<std::unique_ptr<object::Binary>> arch =
        object::createBinary(BufferRef, &Context);
    if ((ec = arch.getError()))
      klee_error("Link with library %s failed: %s", libraryName.c_str(),
                 arch.getError().message().c_str());
    if (object::Archive *a = dyn_cast<object::Archive>(arch.get().get())) {
      // Handle in helper
      if (!linkBCA(a, module, ErrorMessage))
        klee_error("Link with library %s failed: %s", libraryName.c_str(),
                   ErrorMessage.c_str());
    } else {
      klee_error("Link with library %s failed: Cast to archive failed",
                 libraryName.c_str());
    }

  } else if (magic.is_object()) {
    std::unique_ptr<object::Binary> obj;
    if (object::ObjectFile *o = dyn_cast<object::ObjectFile>(obj.get())) {
      klee_warning("Link with library: Object file %s in archive %s found. "
                   "Currently not supported.",
                   o->getFileName().data(), libraryName.c_str());
    }
  } else {
    klee_error("Link with library %s failed: Unrecognized file type.",
               libraryName.c_str());
  }
  return module;

#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
  if (!sys::fs::exists(libraryName)) {
    klee_error("Link with library %s failed. No such file.",
               libraryName.c_str());
  }

  OwningPtr<MemoryBuffer> Buffer;
  if (error_code ec = MemoryBuffer::getFile(libraryName, Buffer)) {
    klee_error("Link with library %s failed: %s", libraryName.c_str(),
               ec.message().c_str());
  }

  sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer());

  LLVMContext &Context = getGlobalContext();
  std::string ErrorMessage;

  if (magic == sys::fs::file_magic::bitcode) {
    Module *Result = 0;
    Result = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage);

    if (!Result || Linker::LinkModules(module, Result, Linker::DestroySource,
                                       &ErrorMessage))
      klee_error("Link with library %s failed: %s", libraryName.c_str(),
                 ErrorMessage.c_str());

    delete Result;

  } else if (magic == sys::fs::file_magic::archive) {
    OwningPtr<object::Binary> arch;
    if (error_code ec = object::createBinary(Buffer.take(), arch))
      klee_error("Link with library %s failed: %s", libraryName.c_str(),
                 ec.message().c_str());

    if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) {
      // Handle in helper
      if (!linkBCA(a, module, ErrorMessage))
        klee_error("Link with library %s failed: %s", libraryName.c_str(),
                   ErrorMessage.c_str());
    } else {
      klee_error("Link with library %s failed: Cast to archive failed",
                 libraryName.c_str());
    }

  } else if (magic.is_object()) {
    OwningPtr<object::Binary> obj;
    if (object::ObjectFile *o = dyn_cast<object::ObjectFile>(obj.get())) {
      klee_warning("Link with library: Object file %s in archive %s found. "
                   "Currently not supported.",
                   o->getFileName().data(), libraryName.c_str());
    }
  } else {
    klee_error("Link with library %s failed: Unrecognized file type.",
               libraryName.c_str());
  }

  return module;
#else
  Linker linker("klee", module, false);

  llvm::sys::Path libraryPath(libraryName);
  bool native = false;

  if (linker.LinkInFile(libraryPath, native)) {
    klee_error("Linking library %s failed", libraryName.c_str());
  }

  return linker.releaseModule();
#endif
}