// fileread.h -- read files for gold   -*- C++ -*-

// Copyright 2006, 2007, 2008 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.

// Classes used to read data from binary input files.

#ifndef GOLD_FILEREAD_H
#define GOLD_FILEREAD_H

#include <list>
#include <map>
#include <string>
#include <vector>

#include "token.h"

namespace gold
{

class Position_dependent_options;
class Input_file_argument;
class Dirsearch;
class File_view;

// File_read manages a file descriptor and mappings for a file we are
// reading.

class File_read
{
 public:
  File_read()
    : name_(), descriptor_(-1), is_descriptor_opened_(false), object_count_(0),
      size_(0), token_(false), views_(), saved_views_(), contents_(NULL),
      mapped_bytes_(0), released_(true)
  { }

  ~File_read();

  // Open a file.
  bool
  open(const Task*, const std::string& name);

  // Pretend to open the file, but provide the file contents.  No
  // actual file system activity will occur.  This is used for
  // testing.
  bool
  open(const Task*, const std::string& name, const unsigned char* contents,
       off_t size);

  // Return the file name.
  const std::string&
  filename() const
  { return this->name_; }

  // Add an object associated with a file.
  void
  add_object()
  { ++this->object_count_; }

  // Remove an object associated with a file.
  void
  remove_object()
  { --this->object_count_; }

  // Lock the file for exclusive access within a particular Task::run
  // execution.  This routine may only be called when the workqueue
  // lock is held.
  void
  lock(const Task* t);

  // Unlock the file.
  void
  unlock(const Task* t);

  // Test whether the object is locked.
  bool
  is_locked() const;

  // Return the token, so that the task can be queued.
  Task_token*
  token()
  { return &this->token_; }

  // Release the file.  This indicates that we aren't going to do
  // anything further with it until it is unlocked.  This is used
  // because a Task which locks the file never calls either lock or
  // unlock; it just locks the token.  The basic rule is that a Task
  // which locks a file via the Task::locks interface must explicitly
  // call release() when it is done.  This is not necessary for code
  // which calls unlock() on the file.
  void
  release();

  // Claim the file for a plugin.  This effectively releases the file without
  // closing it; the plugin will assume responsibility for closing it.
  void
  claim_for_plugin();

  // Return the size of the file.
  off_t
  filesize() const
  { return this->size_; }

  // Return a view into the file starting at file offset START for
  // SIZE bytes.  OFFSET is the offset into the input file for the
  // file we are reading; this is zero for a normal object file,
  // non-zero for an object file in an archive.  ALIGNED is true if
  // the data must be naturally aligned; this only matters when OFFSET
  // is not zero.  The pointer will remain valid until the File_read
  // is unlocked.  It is an error if we can not read enough data from
  // the file.  The CACHE parameter is a hint as to whether it will be
  // useful to cache this data for later accesses--i.e., later calls
  // to get_view, read, or get_lasting_view which retrieve the same
  // data.
  const unsigned char*
  get_view(off_t offset, off_t start, section_size_type size, bool aligned,
	   bool cache);

  // Read data from the file into the buffer P starting at file offset
  // START for SIZE bytes.
  void
  read(off_t start, section_size_type size, void* p);

  // Return a lasting view into the file starting at file offset START
  // for SIZE bytes.  This is allocated with new, and the caller is
  // responsible for deleting it when done.  The data associated with
  // this view will remain valid until the view is deleted.  It is an
  // error if we can not read enough data from the file.  The OFFSET,
  // ALIGNED and CACHE parameters are as in get_view.
  File_view*
  get_lasting_view(off_t offset, off_t start, section_size_type size,
		   bool aligned, bool cache);

  // Mark all views as no longer cached.
  void
  clear_view_cache_marks();

  // Discard all uncached views.  This is normally done by release(),
  // but not for objects in archives.  FIXME: This is a complicated
  // interface, and it would be nice to have something more automatic.
  void
  clear_uncached_views()
  { this->clear_views(false); }

  // A struct used to do a multiple read.
  struct Read_multiple_entry
  {
    // The file offset of the data to read.
    off_t file_offset;
    // The amount of data to read.
    section_size_type size;
    // The buffer where the data should be placed.
    unsigned char* buffer;

    Read_multiple_entry(off_t o, section_size_type s, unsigned char* b)
      : file_offset(o), size(s), buffer(b)
    { }
  };

  typedef std::vector<Read_multiple_entry> Read_multiple;

  // Read a bunch of data from the file into various different
  // locations.  The vector must be sorted by ascending file_offset.
  // BASE is a base offset to be added to all the offsets in the
  // vector.
  void
  read_multiple(off_t base, const Read_multiple&);

  // Dump statistical information to stderr.
  static void
  print_stats();

  // Return the open file descriptor (for plugins).
  int
  descriptor() const
  {
    gold_assert(this->descriptor_ >= 0);
    return this->descriptor_;
  }

 private:
  // This class may not be copied.
  File_read(const File_read&);
  File_read& operator=(const File_read&);

  // Total bytes mapped into memory during the link.  This variable
  // may not be accurate when running multi-threaded.
  static unsigned long long total_mapped_bytes;

  // Current number of bytes mapped into memory during the link.  This
  // variable may not be accurate when running multi-threaded.
  static unsigned long long current_mapped_bytes;

  // High water mark of bytes mapped into memory during the link.
  // This variable may not be accurate when running multi-threaded.
  static unsigned long long maximum_mapped_bytes;

  // A view into the file.
  class View
  {
   public:
    View(off_t start, section_size_type size, const unsigned char* data,
	 unsigned int byteshift, bool cache, bool mapped)
      : start_(start), size_(size), data_(data), lock_count_(0),
	byteshift_(byteshift), cache_(cache), mapped_(mapped), accessed_(true)
    { }

    ~View();

    off_t
    start() const
    { return this->start_; }

    section_size_type
    size() const
    { return this->size_; }

    const unsigned char*
    data() const
    { return this->data_; }

    void
    lock();

    void
    unlock();

    bool
    is_locked();

    unsigned int
    byteshift() const
    { return this->byteshift_; }

    void
    set_cache()
    { this->cache_ = true; }

    void
    clear_cache()
    { this->cache_ = false; }

    bool
    should_cache() const
    { return this->cache_; }

    void
    set_accessed()
    { this->accessed_ = true; }

    void
    clear_accessed()
    { this->accessed_= false; }

    bool
    accessed() const
    { return this->accessed_; }

   private:
    View(const View&);
    View& operator=(const View&);

    // The file offset of the start of the view.
    off_t start_;
    // The size of the view.
    section_size_type size_;
    // A pointer to the actual bytes.
    const unsigned char* data_;
    // The number of locks on this view.
    int lock_count_;
    // The number of bytes that the view is shifted relative to the
    // underlying file.  This is used to align data.  This is normally
    // zero, except possibly for an object in an archive.
    unsigned int byteshift_;
    // Whether the view is cached.
    bool cache_;
    // Whether the view is mapped into memory.  If not, data_ points
    // to memory allocated using new[].
    bool mapped_;
    // Whether the view has been accessed recently.
    bool accessed_;
  };

  friend class View;
  friend class File_view;

  // The type of a mapping from page start and byte shift to views.
  typedef std::map<std::pair<off_t, unsigned int>, View*> Views;

  // A simple list of Views.
  typedef std::list<View*> Saved_views;

  // Open the descriptor if necessary.
  void
  reopen_descriptor();

  // Find a view into the file.
  View*
  find_view(off_t start, section_size_type size, unsigned int byteshift,
	    View** vshifted) const;

  // Read data from the file into a buffer.
  void
  do_read(off_t start, section_size_type size, void* p);

  // Add a view.
  void
  add_view(View*);

  // Make a view into the file.
  View*
  make_view(off_t start, section_size_type size, unsigned int byteshift,
	    bool cache);

  // Find or make a view into the file.
  View*
  find_or_make_view(off_t offset, off_t start, section_size_type size,
		    bool aligned, bool cache);

  // Clear the file views.
  void
  clear_views(bool);

  // The size of a file page for buffering data.
  static const off_t page_size = 8192;

  // Given a file offset, return the page offset.
  static off_t
  page_offset(off_t file_offset)
  { return file_offset & ~ (page_size - 1); }

  // Given a file size, return the size to read integral pages.
  static off_t
  pages(off_t file_size)
  { return (file_size + (page_size - 1)) & ~ (page_size - 1); }

  // The maximum number of entries we will pass to ::readv.
  static const size_t max_readv_entries = 128;

  // Use readv to read data.
  void
  do_readv(off_t base, const Read_multiple&, size_t start, size_t count);

  // File name.
  std::string name_;
  // File descriptor.
  int descriptor_;
  // Whether we have regained the descriptor after releasing the file.
  bool is_descriptor_opened_;
  // The number of objects associated with this file.  This will be
  // more than 1 in the case of an archive.
  int object_count_;
  // File size.
  off_t size_;
  // A token used to lock the file.
  Task_token token_;
  // Buffered views into the file.
  Views views_;
  // List of views which were locked but had to be removed from views_
  // because they were not large enough.
  Saved_views saved_views_;
  // Specified file contents.  Used only for testing purposes.
  const unsigned char* contents_;
  // Total amount of space mapped into memory.  This is only changed
  // while the file is locked.  When we unlock the file, we transfer
  // the total to total_mapped_bytes, and reset this to zero.
  size_t mapped_bytes_;
  // Whether the file was released.
  bool released_;
};

// A view of file data that persists even when the file is unlocked.
// Callers should destroy these when no longer required.  These are
// obtained form File_read::get_lasting_view.  They may only be
// destroyed when the underlying File_read is locked.

class File_view
{
 public:
  // This may only be called when the underlying File_read is locked.
  ~File_view();

  // Return a pointer to the data associated with this view.
  const unsigned char*
  data() const
  { return this->data_; }

 private:
  File_view(const File_view&);
  File_view& operator=(const File_view&);

  friend class File_read;

  // Callers have to get these via File_read::get_lasting_view.
  File_view(File_read& file, File_read::View* view, const unsigned char* data)
    : file_(file), view_(view), data_(data)
  { }

  File_read& file_;
  File_read::View* view_;
  const unsigned char* data_;
};

// All the information we hold for a single input file.  This can be
// an object file, a shared library, or an archive.

class Input_file
{
 public:
  Input_file(const Input_file_argument* input_argument)
    : input_argument_(input_argument), found_name_(), file_(),
      is_in_sysroot_(false)
  { }

  // Create an input file with the contents already provided.  This is
  // only used for testing.  With this path, don't call the open
  // method.
  Input_file(const Task*, const char* name, const unsigned char* contents,
	     off_t size);

  // Open the file.  If the open fails, this will report an error and
  // return false.
  bool
  open(const General_options&, const Dirsearch&, const Task*);

  // Return the name given by the user.  For -lc this will return "c".
  const char*
  name() const;

  // Return the file name.  For -lc this will return something like
  // "/usr/lib/libc.so".
  const std::string&
  filename() const
  { return this->file_.filename(); }

  // Return the name under which we found the file, corresponding to
  // the command line.  For -lc this will return something like
  // "libc.so".
  const std::string&
  found_name() const
  { return this->found_name_; }

  // Return the position dependent options.
  const Position_dependent_options&
  options() const;

  // Return the file.
  File_read&
  file()
  { return this->file_; }

  const File_read&
  file() const
  { return this->file_; }

  // Whether we found the file in a directory in the system root.
  bool
  is_in_sysroot() const
  { return this->is_in_sysroot_; }

  // Return whether this file is to be read only for its symbols.
  bool
  just_symbols() const;

 private:
  Input_file(const Input_file&);
  Input_file& operator=(const Input_file&);

  // Open a binary file.
  bool
  open_binary(const General_options&, const Task* task,
	      const std::string& name);

  // The argument from the command line.
  const Input_file_argument* input_argument_;
  // The name under which we opened the file.  This is like the name
  // on the command line, but -lc turns into libc.so (or whatever).
  // It only includes the full path if the path was on the command
  // line.
  std::string found_name_;
  // The file after we open it.
  File_read file_;
  // Whether we found the file in a directory in the system root.
  bool is_in_sysroot_;
};

} // end namespace gold

#endif // !defined(GOLD_FILEREAD_H)
