Ejemplo n.º 1
0
/// LinkInFile - opens a bitcode file and links in all objects which
/// provide symbols that are currently undefined.
///
/// Inputs:
///  File - The pathname of the bitcode file.
///
/// Outputs:
///  ErrorMessage - A C++ string detailing what error occurred, if any.
///
/// Return Value:
///  TRUE  - An error occurred.
///  FALSE - No errors.
///
bool Linker::LinkInFile(const sys::Path &File, bool &is_native) {
  is_native = false;
  
  // Check for a file of name "-", which means "read standard input"
  if (File.toString() == "-") {
    std::auto_ptr<Module> M;
    if (MemoryBuffer *Buffer = MemoryBuffer::getSTDIN()) {
      M.reset(ParseBitcodeFile(Buffer, Context, &Error));
      delete Buffer;
      if (M.get())
        if (!LinkInModule(M.get(), &Error))
          return false;
    } else 
      Error = "standard input is empty";
    return error("Cannot link stdin: " + Error);
  }

  // Make sure we can at least read the file
  if (!File.canRead())
    return error("Cannot find linker input '" + File.toString() + "'");

  // If its an archive, try to link it in
  std::string Magic;
  File.getMagicNumber(Magic, 64);
  switch (sys::IdentifyFileType(Magic.c_str(), 64)) {
    default: llvm_unreachable("Bad file type identification");
    case sys::Unknown_FileType:
      return warning("Ignoring file '" + File.toString() + 
                   "' because does not contain bitcode.");

    case sys::Archive_FileType:
      // A user may specify an ar archive without -l, perhaps because it
      // is not installed as a library. Detect that and link the archive.
      verbose("Linking archive file '" + File.toString() + "'");
      if (LinkInArchive(File, is_native))
        return true;
      break;

    case sys::Bitcode_FileType: {
      verbose("Linking bitcode file '" + File.toString() + "'");
      std::auto_ptr<Module> M(LoadObject(File));
      if (M.get() == 0)
        return error("Cannot load file '" + File.toString() + "': " + Error);
      if (LinkInModule(M.get(), &Error))
        return error("Cannot link file '" + File.toString() + "': " + Error);

      verbose("Linked in file '" + File.toString() + "'");
      break;
    }

    case sys::ELF_Relocatable_FileType:
    case sys::ELF_SharedObject_FileType:
    case sys::Mach_O_Object_FileType:
    case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
    case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
    case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
    case sys::COFF_FileType:
      is_native = true;
      break;
  }
  return false;
}
Ejemplo n.º 2
0
/// LinkInFile - opens a bitcode file and links in all objects which
/// provide symbols that are currently undefined.
///
/// Inputs:
///  File - The pathname of the bitcode file.
///
/// Outputs:
///  ErrorMessage - A C++ string detailing what error occurred, if any.
///
/// Return Value:
///  TRUE  - An error occurred.
///  FALSE - No errors.
///
bool Linker::LinkInFile(const sys::Path &File, bool &is_native) {
  is_native = false;
  
  // Check for a file of name "-", which means "read standard input"
  if (File.str() == "-") {
    std::auto_ptr<Module> M;
    OwningPtr<MemoryBuffer> Buffer;
    error_code ec;
    if (!(ec = MemoryBuffer::getSTDIN(Buffer))) {
      if (!Buffer->getBufferSize()) {
        Error = "standard input is empty";
      } else {
        M.reset(ParseBitcodeFile(Buffer.get(), Context, &Error));
        if (M.get())
          if (!LinkInModule(M.get(), &Error))
            return false;
      }
    }
    return error("Cannot link stdin: " + ec.message());
  }

  // Determine what variety of file it is.
  std::string Magic;
  if (!File.getMagicNumber(Magic, 512))
    return error("Cannot find linker input '" + File.str() + "'");

  switch (sys::IdentifyFileType(Magic.c_str(), 512)) {
    default: llvm_unreachable("Bad file type identification");
    case sys::Unknown_FileType:
      return warning("Ignoring file '" + File.str() + 
                   "' because does not contain bitcode.");

    case sys::Archive_FileType:
      // A user may specify an ar archive without -l, perhaps because it
      // is not installed as a library. Detect that and link the archive.
      if (LinkInArchive(File, is_native))
        return true;
      break;

    case sys::Bitcode_FileType: {
      verbose("Linking bitcode file '" + File.str() + "'");
      std::auto_ptr<Module> M(LoadObject(File));
      if (M.get() == 0)
        return error("Cannot load file '" + File.str() + "': " + Error);
      if (LinkInModule(M.get(), &Error))
        return error("Cannot link file '" + File.str() + "': " + Error);

      verbose("Linked in file '" + File.str() + "'");
      break;
    }

    case sys::ELF_Relocatable_FileType:
    case sys::ELF_SharedObject_FileType:
    case sys::Mach_O_Object_FileType:
    case sys::Mach_O_FixedVirtualMemorySharedLib_FileType:
    case sys::Mach_O_DynamicallyLinkedSharedLib_FileType:
    case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType:
    case sys::COFF_FileType:
      is_native = true;
      break;
  }
  return false;
}