// fileread.cc -- read files for gold

// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// This file is part of gold.

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.

#include "gold.h"

#include <cstring>
#include <cerrno>
#include <climits>
#include <fcntl.h>
#include <unistd.h>

#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif

#ifdef HAVE_READV
#include <sys/uio.h>
#endif

#include <sys/stat.h>
#include "filenames.h"

#include "debug.h"
#include "parameters.h"
#include "options.h"
#include "dirsearch.h"
#include "target.h"
#include "binary.h"
#include "descriptors.h"
#include "gold-threads.h"
#include "fileread.h"

// For systems without mmap support.
#ifndef HAVE_MMAP
# define mmap gold_mmap
# define munmap gold_munmap
# ifndef MAP_FAILED
#  define MAP_FAILED (reinterpret_cast<void*>(-1))
# endif
# ifndef PROT_READ
#  define PROT_READ 0
# endif
# ifndef MAP_PRIVATE
#  define MAP_PRIVATE 0
# endif

# ifndef ENOSYS
#  define ENOSYS EINVAL
# endif

static void *
gold_mmap(void *, size_t, int, int, int, off_t)
{
  errno = ENOSYS;
  return MAP_FAILED;
}

static int
gold_munmap(void *, size_t)
{
  errno = ENOSYS;
  return -1;
}

#endif

#ifndef HAVE_READV
struct iovec { void* iov_base; size_t iov_len; };
ssize_t
readv(int, const iovec*, int)
{
  gold_unreachable();
}
#endif

namespace gold
{

// Get the last modified time of an unopened file.

bool
get_mtime(const char* filename, Timespec* mtime)
{
  struct stat file_stat;

  if (stat(filename, &file_stat) < 0)
    return false;
#ifdef HAVE_STAT_ST_MTIM
  mtime->seconds = file_stat.st_mtim.tv_sec;
  mtime->nanoseconds = file_stat.st_mtim.tv_nsec;
#else
  mtime->seconds = file_stat.st_mtime;
  mtime->nanoseconds = 0;
#endif
  return true;
}

// Class File_read.

// A lock for the File_read static variables.
static Lock* file_counts_lock = NULL;
static Initialize_lock file_counts_initialize_lock(&file_counts_lock);

// The File_read static variables.
unsigned long long File_read::total_mapped_bytes;
unsigned long long File_read::current_mapped_bytes;
unsigned long long File_read::maximum_mapped_bytes;

// Class File_read::View.

File_read::View::~View()
{
  gold_assert(!this->is_locked());
  switch (this->data_ownership_)
    {
    case DATA_ALLOCATED_ARRAY:
      free(const_cast<unsigned char*>(this->data_));
      break;
    case DATA_MMAPPED:
      if (::munmap(const_cast<unsigned char*>(this->data_), this->size_) != 0)
        gold_warning(_("munmap failed: %s"), strerror(errno));
      if (!parameters->options_valid() || parameters->options().stats())
	{
	  file_counts_initialize_lock.initialize();
	  Hold_optional_lock hl(file_counts_lock);
	  File_read::current_mapped_bytes -= this->size_;
	}
      break;
    case DATA_NOT_OWNED:
      break;
    default:
      gold_unreachable();
    }
}

void
File_read::View::lock()
{
  ++this->lock_count_;
}

void
File_read::View::unlock()
{
  gold_assert(this->lock_count_ > 0);
  --this->lock_count_;
}

bool
File_read::View::is_locked()
{
  return this->lock_count_ > 0;
}

// Class File_read.

File_read::~File_read()
{
  gold_assert(this->token_.is_writable());
  if (this->is_descriptor_opened_)
    {
      release_descriptor(this->descriptor_, true);
      this->descriptor_ = -1;
      this->is_descriptor_opened_ = false;
    }
  this->name_.clear();
  this->clear_views(CLEAR_VIEWS_ALL);
}

// Open the file.

bool
File_read::open(const Task* task, const std::string& name)
{
  gold_assert(this->token_.is_writable()
	      && this->descriptor_ < 0
	      && !this->is_descriptor_opened_
	      && this->name_.empty());
  this->name_ = name;

  this->descriptor_ = open_descriptor(-1, this->name_.c_str(),
				      O_RDONLY);

  if (this->descriptor_ >= 0)
    {
      this->is_descriptor_opened_ = true;
      struct stat s;
      if (::fstat(this->descriptor_, &s) < 0)
	gold_error(_("%s: fstat failed: %s"),
		   this->name_.c_str(), strerror(errno));
      this->size_ = s.st_size;
      gold_debug(DEBUG_FILES, "Attempt to open %s succeeded",
                 this->name_.c_str());
      this->token_.add_writer(task);
    }

  return this->descriptor_ >= 0;
}

// Open the file with the contents in memory.

bool
File_read::open(const Task* task, const std::string& name,
		const unsigned char* contents, off_t size)
{
  gold_assert(this->token_.is_writable()
	      && this->descriptor_ < 0
	      && !this->is_descriptor_opened_
	      && this->name_.empty());
  this->name_ = name;
  this->whole_file_view_ = new View(0, size, contents, 0, false,
                                    View::DATA_NOT_OWNED);
  this->add_view(this->whole_file_view_);
  this->size_ = size;
  this->token_.add_writer(task);
  return true;
}

// Reopen a descriptor if necessary.

void
File_read::reopen_descriptor()
{
  if (!this->is_descriptor_opened_)
    {
      this->descriptor_ = open_descriptor(this->descriptor_,
					  this->name_.c_str(),
					  O_RDONLY);
      if (this->descriptor_ < 0)
	gold_fatal(_("could not reopen file %s"), this->name_.c_str());
      this->is_descriptor_opened_ = true;
    }
}

// Release the file.  This is called when we are done with the file in
// a Task.

void
File_read::release()
{
  gold_assert(this->is_locked());

  if (!parameters->options_valid() || parameters->options().stats())
    {
      file_counts_initialize_lock.initialize();
      Hold_optional_lock hl(file_counts_lock);
      File_read::total_mapped_bytes += this->mapped_bytes_;
      File_read::current_mapped_bytes += this->mapped_bytes_;
      if (File_read::current_mapped_bytes > File_read::maximum_mapped_bytes)
	File_read::maximum_mapped_bytes = File_read::current_mapped_bytes;
    }

  this->mapped_bytes_ = 0;

  // Only clear views if there is only one attached object.  Otherwise
  // we waste time trying to clear cached archive views.  Similarly
  // for releasing the descriptor.
  if (this->object_count_ <= 1)
    {
      this->clear_views(CLEAR_VIEWS_NORMAL);
      if (this->is_descriptor_opened_)
	{
	  release_descriptor(this->descriptor_, false);
	  this->is_descriptor_opened_ = false;
	}
    }

  this->released_ = true;
}

// Lock the file.

void
File_read::lock(const Task* task)
{
  gold_assert(this->released_);
  this->token_.add_writer(task);
  this->released_ = false;
}

// Unlock the file.

void
File_read::unlock(const Task* task)
{
  this->release();
  this->token_.remove_writer(task);
}

// Return whether the file is locked.

bool
File_read::is_locked() const
{
  if (!this->token_.is_writable())
    return true;
  // The file is not locked, so it should have been released.
  gold_assert(this->released_);
  return false;
}

// See if we have a view which covers the file starting at START for
// SIZE bytes.  Return a pointer to the View if found, NULL if not.
// If BYTESHIFT is not -1U, the returned View must have the specified
// byte shift; otherwise, it may have any byte shift.  If VSHIFTED is
// not NULL, this sets *VSHIFTED to a view which would have worked if
// not for the requested BYTESHIFT.

inline File_read::View*
File_read::find_view(off_t start, section_size_type size,
		     unsigned int byteshift, File_read::View** vshifted) const
{
  if (vshifted != NULL)
    *vshifted = NULL;

  // If we have the whole file mmapped, and the alignment is right,
  // we can return it.
  if (this->whole_file_view_)
    if (byteshift == -1U || byteshift == 0)
      return this->whole_file_view_;

  off_t page = File_read::page_offset(start);

  unsigned int bszero = 0;
  Views::const_iterator p = this->views_.upper_bound(std::make_pair(page - 1,
								    bszero));

  while (p != this->views_.end() && p->first.first <= page)
    {
      if (p->second->start() <= start
	  && (p->second->start() + static_cast<off_t>(p->second->size())
	      >= start + static_cast<off_t>(size)))
	{
	  if (byteshift == -1U || byteshift == p->second->byteshift())
	    {
	      p->second->set_accessed();
	      return p->second;
	    }

	  if (vshifted != NULL && *vshifted == NULL)
	    *vshifted = p->second;
	}

      ++p;
    }

  return NULL;
}

// Read SIZE bytes from the file starting at offset START.  Read into
// the buffer at P.

void
File_read::do_read(off_t start, section_size_type size, void* p)
{
  ssize_t bytes;
  if (this->whole_file_view_ != NULL)
    {
      bytes = this->size_ - start;
      if (static_cast<section_size_type>(bytes) >= size)
	{
	  memcpy(p, this->whole_file_view_->data() + start, size);
	  return;
	}
    }
  else
    {
      this->reopen_descriptor();
      bytes = ::pread(this->descriptor_, p, size, start);
      if (static_cast<section_size_type>(bytes) == size)
	return;

      if (bytes < 0)
	{
	  gold_fatal(_("%s: pread failed: %s"),
		     this->filename().c_str(), strerror(errno));
	  return;
	}
    }

  gold_fatal(_("%s: file too short: read only %lld of %lld bytes at %lld"),
	     this->filename().c_str(),
	     static_cast<long long>(bytes),
	     static_cast<long long>(size),
	     static_cast<long long>(start));
}

// Read data from the file.

void
File_read::read(off_t start, section_size_type size, void* p)
{
  const File_read::View* pv = this->find_view(start, size, -1U, NULL);
  if (pv != NULL)
    {
      memcpy(p, pv->data() + (start - pv->start() + pv->byteshift()), size);
      return;
    }

  this->do_read(start, size, p);
}

// Add a new view.  There may already be an existing view at this
// offset.  If there is, the new view will be larger, and should
// replace the old view.

void
File_read::add_view(File_read::View* v)
{
  std::pair<Views::iterator, bool> ins =
    this->views_.insert(std::make_pair(std::make_pair(v->start(),
						      v->byteshift()),
				       v));
  if (ins.second)
    return;

  // There was an existing view at this offset.  It must not be large
  // enough.  We can't delete it here, since something might be using
  // it; we put it on a list to be deleted when the file is unlocked.
  File_read::View* vold = ins.first->second;
  gold_assert(vold->size() < v->size());
  if (vold->should_cache())
    {
      v->set_cache();
      vold->clear_cache();
    }
  this->saved_views_.push_back(vold);

  ins.first->second = v;
}

// Make a new view with a specified byteshift, reading the data from
// the file.

File_read::View*
File_read::make_view(off_t start, section_size_type size,
		     unsigned int byteshift, bool cache)
{
  gold_assert(size > 0);

  // Check that start and end of the view are within the file.
  if (start > this->size_
      || (static_cast<unsigned long long>(size)
          > static_cast<unsigned long long>(this->size_ - start)))
    gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds "
                 "size of file; the file may be corrupt"),
		   this->filename().c_str(),
		   static_cast<long long>(size),
		   static_cast<long long>(start));

  off_t poff = File_read::page_offset(start);

  section_size_type psize = File_read::pages(size + (start - poff));

  if (poff + static_cast<off_t>(psize) >= this->size_)
    {
      psize = this->size_ - poff;
      gold_assert(psize >= size);
    }

  void* p;
  View::Data_ownership ownership;
  if (byteshift != 0)
    {
      p = malloc(psize + byteshift);
      if (p == NULL)
	gold_nomem();
      memset(p, 0, byteshift);
      this->do_read(poff, psize, static_cast<unsigned char*>(p) + byteshift);
      ownership = View::DATA_ALLOCATED_ARRAY;
    }
  else
    {
      this->reopen_descriptor();
      p = ::mmap(NULL, psize, PROT_READ, MAP_PRIVATE, this->descriptor_, poff);
      if (p != MAP_FAILED)
	{
	  ownership = View::DATA_MMAPPED;
	  this->mapped_bytes_ += psize;
	}
      else
	{
	  p = malloc(psize);
	  if (p == NULL)
	    gold_nomem();
	  this->do_read(poff, psize, p);
	  ownership = View::DATA_ALLOCATED_ARRAY;
	}
    }

  const unsigned char* pbytes = static_cast<const unsigned char*>(p);
  File_read::View* v = new File_read::View(poff, psize, pbytes, byteshift,
					   cache, ownership);

  this->add_view(v);

  return v;
}

// Find a View or make a new one, shifted as required by the file
// offset OFFSET and ALIGNED.

File_read::View*
File_read::find_or_make_view(off_t offset, off_t start,
			     section_size_type size, bool aligned, bool cache)
{
  unsigned int byteshift;
  if (offset == 0)
    byteshift = 0;
  else
    {
      unsigned int target_size = (!parameters->target_valid()
				  ? 64
				  : parameters->target().get_size());
      byteshift = offset & ((target_size / 8) - 1);

      // Set BYTESHIFT to the number of dummy bytes which must be
      // inserted before the data in order for this data to be
      // aligned.
      if (byteshift != 0)
	byteshift = (target_size / 8) - byteshift;
    }

  // If --map-whole-files is set, make sure we have a
  // whole file view.  Options may not yet be ready, e.g.,
  // when reading a version script.  We then default to
  // --no-map-whole-files.
  if (this->whole_file_view_ == NULL
      && parameters->options_valid()
      && parameters->options().map_whole_files())
    this->whole_file_view_ = this->make_view(0, this->size_, 0, cache);

  // Try to find a View with the required BYTESHIFT.
  File_read::View* vshifted;
  File_read::View* v = this->find_view(offset + start, size,
				       aligned ? byteshift : -1U,
				       &vshifted);
  if (v != NULL)
    {
      if (cache)
	v->set_cache();
      return v;
    }

  // If VSHIFTED is not NULL, then it has the data we need, but with
  // the wrong byteshift.
  v = vshifted;
  if (v != NULL)
    {
      gold_assert(aligned);

      unsigned char* pbytes;
      pbytes = static_cast<unsigned char*>(malloc(v->size() + byteshift));
      if (pbytes == NULL)
	gold_nomem();
      memset(pbytes, 0, byteshift);
      memcpy(pbytes + byteshift, v->data() + v->byteshift(), v->size());

      File_read::View* shifted_view =
          new File_read::View(v->start(), v->size(), pbytes, byteshift,
			      cache, View::DATA_ALLOCATED_ARRAY);

      this->add_view(shifted_view);
      return shifted_view;
    }

  // Make a new view.  If we don't need an aligned view, use a
  // byteshift of 0, so that we can use mmap.
  return this->make_view(offset + start, size,
			 aligned ? byteshift : 0,
			 cache);
}

// Get a view into the file.

const unsigned char*
File_read::get_view(off_t offset, off_t start, section_size_type size,
		    bool aligned, bool cache)
{
  File_read::View* pv = this->find_or_make_view(offset, start, size,
						aligned, cache);
  return pv->data() + (offset + start - pv->start() + pv->byteshift());
}

File_view*
File_read::get_lasting_view(off_t offset, off_t start, section_size_type size,
			    bool aligned, bool cache)
{
  File_read::View* pv = this->find_or_make_view(offset, start, size,
						aligned, cache);
  pv->lock();
  return new File_view(*this, pv,
		       (pv->data()
			+ (offset + start - pv->start() + pv->byteshift())));
}

// Use readv to read COUNT entries from RM starting at START.  BASE
// must be added to all file offsets in RM.

void
File_read::do_readv(off_t base, const Read_multiple& rm, size_t start,
		    size_t count)
{
  unsigned char discard[File_read::page_size];
  iovec iov[File_read::max_readv_entries * 2];
  size_t iov_index = 0;

  off_t first_offset = rm[start].file_offset;
  off_t last_offset = first_offset;
  ssize_t want = 0;
  for (size_t i = 0; i < count; ++i)
    {
      const Read_multiple_entry& i_entry(rm[start + i]);

      if (i_entry.file_offset > last_offset)
	{
	  size_t skip = i_entry.file_offset - last_offset;
	  gold_assert(skip <= sizeof discard);

	  iov[iov_index].iov_base = discard;
	  iov[iov_index].iov_len = skip;
	  ++iov_index;

	  want += skip;
	}

      iov[iov_index].iov_base = i_entry.buffer;
      iov[iov_index].iov_len = i_entry.size;
      ++iov_index;

      want += i_entry.size;

      last_offset = i_entry.file_offset + i_entry.size;
    }

  this->reopen_descriptor();

  gold_assert(iov_index < sizeof iov / sizeof iov[0]);

  if (::lseek(this->descriptor_, base + first_offset, SEEK_SET) < 0)
    gold_fatal(_("%s: lseek failed: %s"),
	       this->filename().c_str(), strerror(errno));

  ssize_t got = ::readv(this->descriptor_, iov, iov_index);

  if (got < 0)
    gold_fatal(_("%s: readv failed: %s"),
	       this->filename().c_str(), strerror(errno));
  if (got != want)
    gold_fatal(_("%s: file too short: read only %zd of %zd bytes at %lld"),
	       this->filename().c_str(),
	       got, want, static_cast<long long>(base + first_offset));
}

// Portable IOV_MAX.

#if !defined(HAVE_READV)
#define GOLD_IOV_MAX 1
#elif defined(IOV_MAX)
#define GOLD_IOV_MAX IOV_MAX
#else
#define GOLD_IOV_MAX (File_read::max_readv_entries * 2)
#endif

// Read several pieces of data from the file.

void
File_read::read_multiple(off_t base, const Read_multiple& rm)
{
  static size_t iov_max = GOLD_IOV_MAX;
  size_t count = rm.size();
  size_t i = 0;
  while (i < count)
    {
      // Find up to MAX_READV_ENTRIES consecutive entries which are
      // less than one page apart.
      const Read_multiple_entry& i_entry(rm[i]);
      off_t i_off = i_entry.file_offset;
      off_t end_off = i_off + i_entry.size;
      size_t j;
      for (j = i + 1; j < count; ++j)
	{
	  if (j - i >= File_read::max_readv_entries || j - i >= iov_max / 2)
	    break;
	  const Read_multiple_entry& j_entry(rm[j]);
	  off_t j_off = j_entry.file_offset;
	  gold_assert(j_off >= end_off);
	  off_t j_end_off = j_off + j_entry.size;
	  if (j_end_off - end_off >= File_read::page_size)
	    break;
	  end_off = j_end_off;
	}

      if (j == i + 1)
	this->read(base + i_off, i_entry.size, i_entry.buffer);
      else
	{
	  File_read::View* view = this->find_view(base + i_off,
						  end_off - i_off,
						  -1U, NULL);
	  if (view == NULL)
	    this->do_readv(base, rm, i, j - i);
	  else
	    {
	      const unsigned char* v = (view->data()
					+ (base + i_off - view->start()
					   + view->byteshift()));
	      for (size_t k = i; k < j; ++k)
		{
		  const Read_multiple_entry& k_entry(rm[k]);
		  gold_assert((convert_to_section_size_type(k_entry.file_offset
                                                           - i_off)
                               + k_entry.size)
			      <= convert_to_section_size_type(end_off
                                                              - i_off));
		  memcpy(k_entry.buffer,
			 v + (k_entry.file_offset - i_off),
			 k_entry.size);
		}
	    }
	}

      i = j;
    }
}

// Mark all views as no longer cached.

void
File_read::clear_view_cache_marks()
{
  // Just ignore this if there are multiple objects associated with
  // the file.  Otherwise we will wind up uncaching and freeing some
  // views for other objects.
  if (this->object_count_ > 1)
    return;

  for (Views::iterator p = this->views_.begin();
       p != this->views_.end();
       ++p)
    p->second->clear_cache();
  for (Saved_views::iterator p = this->saved_views_.begin();
       p != this->saved_views_.end();
       ++p)
    (*p)->clear_cache();
}

// Remove all the file views.  For a file which has multiple
// associated objects (i.e., an archive), we keep accessed views
// around until next time, in the hopes that they will be useful for
// the next object.

void
File_read::clear_views(Clear_views_mode mode)
{
  bool keep_files_mapped = (parameters->options_valid()
			    && parameters->options().keep_files_mapped());
  Views::iterator p = this->views_.begin();
  while (p != this->views_.end())
    {
      bool should_delete;
      if (p->second->is_locked() || p->second->is_permanent_view())
	should_delete = false;
      else if (mode == CLEAR_VIEWS_ALL)
	should_delete = true;
      else if ((p->second->should_cache()
		|| p->second == this->whole_file_view_)
	       && keep_files_mapped)
	should_delete = false;
      else if (this->object_count_ > 1
      	       && p->second->accessed()
      	       && mode != CLEAR_VIEWS_ARCHIVE)
	should_delete = false;
      else
	should_delete = true;

      if (should_delete)
	{
	  if (p->second == this->whole_file_view_)
	    this->whole_file_view_ = NULL;
	  delete p->second;

	  // map::erase invalidates only the iterator to the deleted
	  // element.
	  Views::iterator pe = p;
	  ++p;
	  this->views_.erase(pe);
	}
      else
	{
	  p->second->clear_accessed();
	  ++p;
	}
    }

  Saved_views::iterator q = this->saved_views_.begin();
  while (q != this->saved_views_.end())
    {
      if (!(*q)->is_locked())
	{
	  delete *q;
	  q = this->saved_views_.erase(q);
	}
      else
	{
	  gold_assert(mode != CLEAR_VIEWS_ALL);
	  ++q;
	}
    }
}

// Print statistical information to stderr.  This is used for --stats.

void
File_read::print_stats()
{
  fprintf(stderr, _("%s: total bytes mapped for read: %llu\n"),
	  program_name, File_read::total_mapped_bytes);
  fprintf(stderr, _("%s: maximum bytes mapped for read at one time: %llu\n"),
	  program_name, File_read::maximum_mapped_bytes);
}

// Class File_view.

File_view::~File_view()
{
  gold_assert(this->file_.is_locked());
  this->view_->unlock();
}

// Class Input_file.

// Create a file for testing.

Input_file::Input_file(const Task* task, const char* name,
		       const unsigned char* contents, off_t size)
  : file_()
{
  this->input_argument_ =
    new Input_file_argument(name, Input_file_argument::INPUT_FILE_TYPE_FILE,
                            "", false, Position_dependent_options());
  bool ok = this->file_.open(task, name, contents, size);
  gold_assert(ok);
}

// Return the position dependent options in force for this file.

const Position_dependent_options&
Input_file::options() const
{
  return this->input_argument_->options();
}

// Return the name given by the user.  For -lc this will return "c".

const char*
Input_file::name() const
{
  return this->input_argument_->name();
}

// Return whether this file is in a system directory.

bool
Input_file::is_in_system_directory() const
{
  if (this->is_in_sysroot())
    return true;
  return parameters->options().is_in_system_directory(this->filename());
}

// Return whether we are only reading symbols.

bool
Input_file::just_symbols() const
{
  return this->input_argument_->just_symbols();
}

// Return whether this is a file that we will search for in the list
// of directories.

bool
Input_file::will_search_for() const
{
  return (!IS_ABSOLUTE_PATH(this->input_argument_->name())
	  && (this->input_argument_->is_lib()
	      || this->input_argument_->is_searched_file()
	      || this->input_argument_->extra_search_path() != NULL));
}

// Return the file last modification time.  Calls gold_fatal if the stat
// system call failed.

Timespec
File_read::get_mtime()
{
  struct stat file_stat;
  this->reopen_descriptor();

  if (fstat(this->descriptor_, &file_stat) < 0)
    gold_fatal(_("%s: stat failed: %s"), this->name_.c_str(),
	       strerror(errno));
#ifdef HAVE_STAT_ST_MTIM
  return Timespec(file_stat.st_mtim.tv_sec, file_stat.st_mtim.tv_nsec);
#else
  return Timespec(file_stat.st_mtime, 0);
#endif
}

// Try to find a file in the extra search dirs.  Returns true on success.

bool
Input_file::try_extra_search_path(int* pindex,
				  const Input_file_argument* input_argument,
				  std::string filename, std::string* found_name,
				  std::string* namep)
{
  if (input_argument->extra_search_path() == NULL)
    return false;

  std::string name = input_argument->extra_search_path();
  if (!IS_DIR_SEPARATOR(name[name.length() - 1]))
    name += '/';
  name += filename;

  struct stat dummy_stat;
  if (*pindex > 0 || ::stat(name.c_str(), &dummy_stat) < 0)
    return false;

  *found_name = filename;
  *namep = name;
  return true;
}

// Find the actual file.
// If the filename is not absolute, we assume it is in the current
// directory *except* when:
//    A) input_argument_->is_lib() is true;
//    B) input_argument_->is_searched_file() is true; or
//    C) input_argument_->extra_search_path() is not empty.
// In each, we look in extra_search_path + library_path to find
// the file location, rather than the current directory.

bool
Input_file::find_file(const Dirsearch& dirpath, int* pindex,
		      const Input_file_argument* input_argument,
		      bool* is_in_sysroot,
		      std::string* found_name, std::string* namep)
{
  std::string name;

  // Case 1: name is an absolute file, just try to open it
  // Case 2: name is relative but is_lib is false, is_searched_file is false,
  //         and extra_search_path is empty
  if (IS_ABSOLUTE_PATH(input_argument->name())
      || (!input_argument->is_lib()
	  && !input_argument->is_searched_file()
	  && input_argument->extra_search_path() == NULL))
    {
      name = input_argument->name();
      *found_name = name;
      *namep = name;
      return true;
    }
  // Case 3: is_lib is true or is_searched_file is true
  else if (input_argument->is_lib()
	   || input_argument->is_searched_file())
    {
      std::vector<std::string> names;
      names.reserve(2);
      if (input_argument->is_lib())
	{
	  std::string prefix = "lib";
	  prefix += input_argument->name();
	  if (parameters->options().is_static()
	      || !input_argument->options().Bdynamic())
	    names.push_back(prefix + ".a");
	  else
	    {
	      names.push_back(prefix + ".so");
	      names.push_back(prefix + ".a");
	    }
	}
      else
	names.push_back(input_argument->name());

      for (std::vector<std::string>::const_iterator n = names.begin();
	   n != names.end();
	   ++n)
	if (Input_file::try_extra_search_path(pindex, input_argument, *n,
					      found_name, namep))
	  return true;

      // It is not in the extra_search_path.
      name = dirpath.find(names, is_in_sysroot, pindex, found_name);
      if (name.empty())
	{
	  gold_error(_("cannot find %s%s"),
		     input_argument->is_lib() ? "-l" : "",
		     input_argument->name());
	  return false;
	}
      *namep = name;
      return true;
    }
  // Case 4: extra_search_path is not empty
  else
    {
      gold_assert(input_argument->extra_search_path() != NULL);

      if (try_extra_search_path(pindex, input_argument, input_argument->name(),
				found_name, namep))
	return true;

      // extra_search_path failed, so check the normal search-path.
      int index = *pindex;
      if (index > 0)
	--index;
      name = dirpath.find(std::vector<std::string>(1, input_argument->name()),
			  is_in_sysroot, &index, found_name);
      if (name.empty())
	{
	  gold_error(_("cannot find %s"),
		     input_argument->name());
	  return false;
	}
      *namep = name;
      *pindex = index + 1;
      return true;
    }
}

// Open the file.

bool
Input_file::open(const Dirsearch& dirpath, const Task* task, int* pindex)
{
  std::string name;
  if (!Input_file::find_file(dirpath, pindex, this->input_argument_,
			     &this->is_in_sysroot_, &this->found_name_, &name))
    return false;

  // Now that we've figured out where the file lives, try to open it.

  General_options::Object_format format =
    this->input_argument_->options().format_enum();
  bool ok;
  if (format == General_options::OBJECT_FORMAT_ELF)
    {
      ok = this->file_.open(task, name);
      this->format_ = FORMAT_ELF;
    }
  else
    {
      gold_assert(format == General_options::OBJECT_FORMAT_BINARY);
      ok = this->open_binary(task, name);
      this->format_ = FORMAT_BINARY;
    }

  if (!ok)
    {
      gold_error(_("cannot open %s: %s"),
		 name.c_str(), strerror(errno));
      this->format_ = FORMAT_NONE;
      return false;
    }

  return true;
}

// Open a file for --format binary.

bool
Input_file::open_binary(const Task* task, const std::string& name)
{
  // In order to open a binary file, we need machine code, size, and
  // endianness.  We may not have a valid target at this point, in
  // which case we use the default target.
  parameters_force_valid_target();
  const Target& target(parameters->target());

  Binary_to_elf binary_to_elf(target.machine_code(),
			      target.get_size(),
			      target.is_big_endian(),
			      name);
  if (!binary_to_elf.convert(task))
    return false;
  return this->file_.open(task, name, binary_to_elf.converted_data_leak(),
			  binary_to_elf.converted_size());
}

} // End namespace gold.
