// inremental.h -- incremental linking support for gold   -*- C++ -*-

// Copyright (C) 2009-2016 Free Software Foundation, Inc.
// Written by Mikolaj Zalewski <mikolajz@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.

#ifndef GOLD_INCREMENTAL_H
#define GOLD_INCREMENTAL_H

#include <map>
#include <vector>

#include "elfcpp_file.h"
#include "stringpool.h"
#include "workqueue.h"
#include "fileread.h"
#include "output.h"
#include "archive.h"

namespace gold
{

class Input_argument;
class Incremental_inputs_checker;
class Incremental_script_entry;
class Incremental_object_entry;
class Incremental_dynobj_entry;
class Incremental_archive_entry;
class Incremental_inputs;
class Incremental_binary;
class Incremental_library;
class Object;

// Incremental input type as stored in .gnu_incremental_inputs.

enum Incremental_input_type
{
  INCREMENTAL_INPUT_OBJECT = 1,
  INCREMENTAL_INPUT_ARCHIVE_MEMBER = 2,
  INCREMENTAL_INPUT_ARCHIVE = 3,
  INCREMENTAL_INPUT_SHARED_LIBRARY = 4,
  INCREMENTAL_INPUT_SCRIPT = 5
};

// Incremental input file flags.
// The input file type is stored in the lower eight bits.

enum Incremental_input_flags
{
  INCREMENTAL_INPUT_IN_SYSTEM_DIR = 0x8000,
  INCREMENTAL_INPUT_AS_NEEDED = 0x4000
};

// Symbol flags for the incremental symbol table.
// These flags are stored in the top two bits of
// the symbol index field.

enum Incremental_shlib_symbol_flags
{
  // Symbol is defined in this library.
  INCREMENTAL_SHLIB_SYM_DEF = 2,
  // Symbol is defined in this library, with a COPY relocation.
  INCREMENTAL_SHLIB_SYM_COPY = 3
};

static const int INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT = 30;

// Return TRUE if a section of type SH_TYPE can be updated in place
// during an incremental update.
bool
can_incremental_update(unsigned int sh_type);

// Create an Incremental_binary object for FILE. Returns NULL is this is not
// possible, e.g. FILE is not an ELF file or has an unsupported target.

Incremental_binary*
open_incremental_binary(Output_file* file);

// Base class for recording each input file.

class Incremental_input_entry
{
 public:
  Incremental_input_entry(Stringpool::Key filename_key, unsigned int arg_serial,
			  Timespec mtime)
    : filename_key_(filename_key), file_index_(0), offset_(0), info_offset_(0),
      arg_serial_(arg_serial), mtime_(mtime), is_in_system_directory_(false),
      as_needed_(false)
  { }

  virtual
  ~Incremental_input_entry()
  { }

  // Return the type of input file.
  Incremental_input_type
  type() const
  { return this->do_type(); }

  // Set the index and section offset of this input file entry.
  void
  set_offset(unsigned int file_index, unsigned int offset)
  {
    this->file_index_ = file_index;
    this->offset_ = offset;
  }

  // Set the section offset of the supplemental information for this entry.
  void
  set_info_offset(unsigned int info_offset)
  { this->info_offset_ = info_offset; }

  // Get the index of this input file entry.
  unsigned int
  get_file_index() const
  { return this->file_index_; }

  // Get the section offset of this input file entry.
  unsigned int
  get_offset() const
  { return this->offset_; }

  // Get the section offset of the supplemental information for this entry.
  unsigned int
  get_info_offset() const
  { return this->info_offset_; }

  // Get the stringpool key for the input filename.
  Stringpool::Key
  get_filename_key() const
  { return this->filename_key_; }

  // Get the serial number of the input file.
  unsigned int
  arg_serial() const
  { return this->arg_serial_; }

  // Get the modification time of the input file.
  const Timespec&
  get_mtime() const
  { return this->mtime_; }

  // Record that the file was found in a system directory.
  void
  set_is_in_system_directory()
  { this->is_in_system_directory_ = true; }

  // Return TRUE if the file was found in a system directory.
  bool
  is_in_system_directory() const
  { return this->is_in_system_directory_; }

  // Record that the file was linked with --as-needed.
  void
  set_as_needed()
  { this->as_needed_ = true; }

  // Return TRUE if the file was linked with --as-needed.
  bool
  as_needed() const
  { return this->as_needed_; }

  // Return a pointer to the derived Incremental_script_entry object.
  // Return NULL for input entries that are not script files.
  Incremental_script_entry*
  script_entry()
  { return this->do_script_entry(); }

  // Return a pointer to the derived Incremental_object_entry object.
  // Return NULL for input entries that are not object files.
  Incremental_object_entry*
  object_entry()
  { return this->do_object_entry(); }

  // Return a pointer to the derived Incremental_dynobj_entry object.
  // Return NULL for input entries that are not shared object files.
  Incremental_dynobj_entry*
  dynobj_entry()
  { return this->do_dynobj_entry(); }

  // Return a pointer to the derived Incremental_archive_entry object.
  // Return NULL for input entries that are not archive files.
  Incremental_archive_entry*
  archive_entry()
  { return this->do_archive_entry(); }

 protected:
  // Return the type of input file.
  virtual Incremental_input_type
  do_type() const = 0;

  // Return a pointer to the derived Incremental_script_entry object.
  // Return NULL for input entries that are not script files.
  virtual Incremental_script_entry*
  do_script_entry()
  { return NULL; }

  // Return a pointer to the derived Incremental_object_entry object.
  // Return NULL for input entries that are not object files.
  virtual Incremental_object_entry*
  do_object_entry()
  { return NULL; }

  // Return a pointer to the derived Incremental_dynobj_entry object.
  // Return NULL for input entries that are not shared object files.
  virtual Incremental_dynobj_entry*
  do_dynobj_entry()
  { return NULL; }

  // Return a pointer to the derived Incremental_archive_entry object.
  // Return NULL for input entries that are not archive files.
  virtual Incremental_archive_entry*
  do_archive_entry()
  { return NULL; }

 private:
  // Key of the filename string in the section stringtable.
  Stringpool::Key filename_key_;

  // Index of the entry in the output section.
  unsigned int file_index_;

  // Offset of the entry in the output section.
  unsigned int offset_;

  // Offset of the extra information in the output section.
  unsigned int info_offset_;

  // Serial number of the file in the argument list.
  unsigned int arg_serial_;

  // Last modification time of the file.
  Timespec mtime_;

  // TRUE if the file was found in a system directory.
  bool is_in_system_directory_;

  // TRUE if the file was linked with --as-needed.
  bool as_needed_;
};

// Information about a script input that will persist during the whole linker
// run.  Needed only during an incremental build to retrieve the input files
// added by this script.

class Script_info
{
 public:
  Script_info(const std::string& filename)
    : filename_(filename), input_file_index_(0),
      incremental_script_entry_(NULL)
  { }

  Script_info(const std::string& filename, unsigned int input_file_index)
    : filename_(filename), input_file_index_(input_file_index),
      incremental_script_entry_(NULL)
  { }

  // Store a pointer to the incremental information for this script.
  void
  set_incremental_info(Incremental_script_entry* entry)
  { this->incremental_script_entry_ = entry; }

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

  // Return the input file index.
  unsigned int
  input_file_index() const
  { return this->input_file_index_; }

  // Return the pointer to the incremental information for this script.
  Incremental_script_entry*
  incremental_info() const
  { return this->incremental_script_entry_; }

 private:
  const std::string filename_;
  unsigned int input_file_index_;
  Incremental_script_entry* incremental_script_entry_;
};

// Class for recording input scripts.

class Incremental_script_entry : public Incremental_input_entry
{
 public:
  Incremental_script_entry(Stringpool::Key filename_key,
			   unsigned int arg_serial, Script_info* /*script*/,
			   Timespec mtime)
    : Incremental_input_entry(filename_key, arg_serial, mtime),
      objects_()
  { }

  // Add a member object to the archive.
  void
  add_object(Incremental_input_entry* obj_entry)
  {
    this->objects_.push_back(obj_entry);
  }

  // Return the number of objects included by this script.
  unsigned int
  get_object_count()
  { return this->objects_.size(); }

  // Return the Nth object.
  Incremental_input_entry*
  get_object(unsigned int n)
  {
    gold_assert(n < this->objects_.size());
    return this->objects_[n];
  }

 protected:
  virtual Incremental_input_type
  do_type() const
  { return INCREMENTAL_INPUT_SCRIPT; }

  // Return a pointer to the derived Incremental_script_entry object.
  virtual Incremental_script_entry*
  do_script_entry()
  { return this; }

 private:
  // Objects that have been included by this script.
  std::vector<Incremental_input_entry*> objects_;
};

// Class for recording input object files.

class Incremental_object_entry : public Incremental_input_entry
{
 public:
  Incremental_object_entry(Stringpool::Key filename_key, Object* obj,
			   unsigned int arg_serial, Timespec mtime)
    : Incremental_input_entry(filename_key, arg_serial, mtime), obj_(obj),
      is_member_(false), sections_(), groups_()
  { this->sections_.reserve(obj->shnum()); }

  // Get the object.
  Object*
  object() const
  { return this->obj_; }

  // Record that this object is an archive member.
  void
  set_is_member()
  { this->is_member_ = true; }

  // Return true if this object is an archive member.
  bool
  is_member() const
  { return this->is_member_; }

  // Add an input section.
  void
  add_input_section(unsigned int shndx, Stringpool::Key name_key, off_t sh_size)
  { this->sections_.push_back(Input_section(shndx, name_key, sh_size)); }

  // Return the number of input sections in this object.
  unsigned int
  get_input_section_count() const
  { return this->sections_.size(); }

  // Return the input section index for the Nth input section.
  Stringpool::Key
  get_input_section_index(unsigned int n) const
  { return this->sections_[n].shndx_; }

  // Return the stringpool key of the Nth input section.
  Stringpool::Key
  get_input_section_name_key(unsigned int n) const
  { return this->sections_[n].name_key_; }

  // Return the size of the Nth input section.
  off_t
  get_input_section_size(unsigned int n) const
  { return this->sections_[n].sh_size_; }

  // Add a kept COMDAT group.
  void
  add_comdat_group(Stringpool::Key signature_key)
  { this->groups_.push_back(signature_key); }

  // Return the number of COMDAT groups.
  unsigned int
  get_comdat_group_count() const
  { return this->groups_.size(); }

  // Return the stringpool key for the signature of the Nth comdat group.
  Stringpool::Key
  get_comdat_signature_key(unsigned int n) const
  { return this->groups_[n]; }

 protected:
  virtual Incremental_input_type
  do_type() const
  {
    return (this->is_member_
	    ? INCREMENTAL_INPUT_ARCHIVE_MEMBER
	    : INCREMENTAL_INPUT_OBJECT);
  }

  // Return a pointer to the derived Incremental_object_entry object.
  virtual Incremental_object_entry*
  do_object_entry()
  { return this; }

 private:
  // The object file itself.
  Object* obj_;

  // Whether this object is an archive member.
  bool is_member_;

  // Input sections.
  struct Input_section
  {
    Input_section(unsigned int shndx, Stringpool::Key name_key, off_t sh_size)
      : shndx_(shndx), name_key_(name_key), sh_size_(sh_size)
    { }
    unsigned int shndx_;
    Stringpool::Key name_key_;
    off_t sh_size_;
  };
  std::vector<Input_section> sections_;

  // COMDAT groups.
  std::vector<Stringpool::Key> groups_;
};

// Class for recording shared library input files.

class Incremental_dynobj_entry : public Incremental_input_entry
{
 public:
  Incremental_dynobj_entry(Stringpool::Key filename_key,
  			   Stringpool::Key soname_key, Object* obj,
			   unsigned int arg_serial, Timespec mtime)
    : Incremental_input_entry(filename_key, arg_serial, mtime),
      soname_key_(soname_key), obj_(obj)
  { }

  // Get the object.
  Object*
  object() const
  { return this->obj_; }

  // Get the stringpool key for the soname.
  Stringpool::Key
  get_soname_key() const
  { return this->soname_key_; }

 protected:
  virtual Incremental_input_type
  do_type() const
  { return INCREMENTAL_INPUT_SHARED_LIBRARY; }

  // Return a pointer to the derived Incremental_dynobj_entry object.
  virtual Incremental_dynobj_entry*
  do_dynobj_entry()
  { return this; }

 private:
  // Key of the soname string in the section stringtable.
  Stringpool::Key soname_key_;

  // The object file itself.
  Object* obj_;
};

// Class for recording archive library input files.

class Incremental_archive_entry : public Incremental_input_entry
{
 public:
  Incremental_archive_entry(Stringpool::Key filename_key,
			    unsigned int arg_serial, Timespec mtime)
    : Incremental_input_entry(filename_key, arg_serial, mtime), members_(),
      unused_syms_()
  { }

  // Add a member object to the archive.
  void
  add_object(Incremental_object_entry* obj_entry)
  {
    this->members_.push_back(obj_entry);
    obj_entry->set_is_member();
  }

  // Add an unused global symbol to the archive.
  void
  add_unused_global_symbol(Stringpool::Key symbol_key)
  { this->unused_syms_.push_back(symbol_key); }

  // Return the number of member objects included in the link.
  unsigned int
  get_member_count()
  { return this->members_.size(); }

  // Return the Nth member object.
  Incremental_object_entry*
  get_member(unsigned int n)
  { return this->members_[n]; }

  // Return the number of unused global symbols in this archive.
  unsigned int
  get_unused_global_symbol_count()
  { return this->unused_syms_.size(); }

  // Return the Nth unused global symbol.
  Stringpool::Key
  get_unused_global_symbol(unsigned int n)
  { return this->unused_syms_[n]; }

 protected:
  virtual Incremental_input_type
  do_type() const
  { return INCREMENTAL_INPUT_ARCHIVE; }

  // Return a pointer to the derived Incremental_archive_entry object.
  virtual Incremental_archive_entry*
  do_archive_entry()
  { return this; }

 private:
  // Members of the archive that have been included in the link.
  std::vector<Incremental_object_entry*> members_;

  // Unused global symbols from this archive.
  std::vector<Stringpool::Key> unused_syms_;
};

// This class contains the information needed during an incremental
// build about the inputs necessary to build the .gnu_incremental_inputs.

class Incremental_inputs
{
 public:
  typedef std::vector<Incremental_input_entry*> Input_list;

  Incremental_inputs()
    : inputs_(), command_line_(), command_line_key_(0),
      strtab_(new Stringpool()), current_object_(NULL),
      current_object_entry_(NULL), inputs_section_(NULL),
      symtab_section_(NULL), relocs_section_(NULL),
      reloc_count_(0)
  { }

  ~Incremental_inputs() { delete this->strtab_; }

  // Record the command line.
  void
  report_command_line(int argc, const char* const* argv);

  // Record the initial info for archive file ARCHIVE.
  void
  report_archive_begin(Library_base* arch, unsigned int arg_serial,
		       Script_info* script_info);

  // Record the final info for archive file ARCHIVE.
  void
  report_archive_end(Library_base* arch);

  // Record the info for object file OBJ.  If ARCH is not NULL,
  // attach the object file to the archive.
  void
  report_object(Object* obj, unsigned int arg_serial, Library_base* arch,
		Script_info* script_info);

  // Record an input section belonging to object file OBJ.
  void
  report_input_section(Object* obj, unsigned int shndx, const char* name,
		       off_t sh_size);

  // Record a kept COMDAT group belonging to object file OBJ.
  void
  report_comdat_group(Object* obj, const char* name);

  // Record the info for input script SCRIPT.
  void
  report_script(Script_info* script, unsigned int arg_serial,
		Timespec mtime);

  // Return the running count of incremental relocations.
  unsigned int
  get_reloc_count() const
  { return this->reloc_count_; }

  // Update the running count of incremental relocations.
  void
  set_reloc_count(unsigned int count)
  { this->reloc_count_ = count; }

  // Prepare for layout.  Called from Layout::finalize.
  void
  finalize();

  // Create the .gnu_incremental_inputs and related sections.
  void
  create_data_sections(Symbol_table* symtab);

  // Return the .gnu_incremental_inputs section.
  Output_section_data*
  inputs_section() const
  { return this->inputs_section_; }

  // Return the .gnu_incremental_symtab section.
  Output_data_space*
  symtab_section() const
  { return this->symtab_section_; }

  // Return the .gnu_incremental_relocs section.
  Output_data_space*
  relocs_section() const
  { return this->relocs_section_; }

  // Return the .gnu_incremental_got_plt section.
  Output_data_space*
  got_plt_section() const
  { return this->got_plt_section_; }

  // Return the .gnu_incremental_strtab stringpool.
  Stringpool*
  get_stringpool() const
  { return this->strtab_; }

  // Return the canonical form of the command line, as will be stored in
  // .gnu_incremental_strtab.
  const std::string&
  command_line() const
  { return this->command_line_; }

  // Return the stringpool key of the command line.
  Stringpool::Key
  command_line_key() const
  { return this->command_line_key_; }

  // Return the number of input files.
  int
  input_file_count() const
  { return this->inputs_.size(); }

  // Return the input files.
  const Input_list&
  input_files() const
  { return this->inputs_; }

  // Return the sh_entsize value for the .gnu_incremental_relocs section.
  unsigned int
  relocs_entsize() const;

 private:
  // The list of input files.
  Input_list inputs_;

  // Canonical form of the command line, as will be stored in
  // .gnu_incremental_strtab.
  std::string command_line_;

  // The key of the command line string in the string pool.
  Stringpool::Key command_line_key_;

  // The .gnu_incremental_strtab string pool associated with the
  // .gnu_incremental_inputs.
  Stringpool* strtab_;

  // Keep track of the object currently being processed.
  Object* current_object_;
  Incremental_object_entry* current_object_entry_;

  // The .gnu_incremental_inputs section.
  Output_section_data* inputs_section_;

  // The .gnu_incremental_symtab section.
  Output_data_space* symtab_section_;

  // The .gnu_incremental_relocs section.
  Output_data_space* relocs_section_;

  // The .gnu_incremental_got_plt section.
  Output_data_space* got_plt_section_;

  // Total count of incremental relocations.  Updated during Scan_relocs
  // phase at the completion of each object file.
  unsigned int reloc_count_;
};

// Reader class for global symbol info from an object file entry in
// the .gnu_incremental_inputs section.

template<bool big_endian>
class Incremental_global_symbol_reader
{
 private:
  typedef elfcpp::Swap<32, big_endian> Swap32;

 public:
  Incremental_global_symbol_reader(const unsigned char* p)
    : p_(p)
  { }

  unsigned int
  output_symndx() const
  { return Swap32::readval(this->p_); }

  unsigned int
  shndx() const
  { return Swap32::readval(this->p_ + 4); }

  unsigned int
  next_offset() const
  { return Swap32::readval(this->p_ + 8); }

  unsigned int
  reloc_count() const
  { return Swap32::readval(this->p_ + 12); }

  unsigned int
  reloc_offset() const
  { return Swap32::readval(this->p_ + 16); }

 private:
  // Base address of the symbol entry.
  const unsigned char* p_;
};

// Reader class for .gnu_incremental_inputs section.

template<int size, bool big_endian>
class Incremental_inputs_reader
{
 private:
  typedef elfcpp::Swap<size, big_endian> Swap;
  typedef elfcpp::Swap<16, big_endian> Swap16;
  typedef elfcpp::Swap<32, big_endian> Swap32;
  typedef elfcpp::Swap<64, big_endian> Swap64;

 public:
  // Size of the .gnu_incremental_inputs header.
  // (3 x 4-byte fields, plus 4 bytes padding.)
  static const unsigned int header_size = 16;
  // Size of an input file entry.
  // (2 x 4-byte fields, 1 x 12-byte field, 2 x 2-byte fields.)
  static const unsigned int input_entry_size = 24;
  // Size of the first part of the supplemental info block for
  // relocatable objects and archive members.
  // (7 x 4-byte fields, plus 4 bytes padding.)
  static const unsigned int object_info_size = 32;
  // Size of an input section entry.
  // (2 x 4-byte fields, 2 x address-sized fields.)
  static const unsigned int input_section_entry_size = 8 + 2 * size / 8;
  // Size of a global symbol entry in the supplemental info block.
  // (5 x 4-byte fields.)
  static const unsigned int global_sym_entry_size = 20;

  Incremental_inputs_reader()
    : p_(NULL), strtab_(NULL, 0), input_file_count_(0)
  { }

  Incremental_inputs_reader(const unsigned char* p,
			    const elfcpp::Elf_strtab& strtab)
    : p_(p), strtab_(strtab)
  { this->input_file_count_ = Swap32::readval(this->p_ + 4); }

  // Return the version number.
  unsigned int
  version() const
  { return Swap32::readval(this->p_); }

  // Return the count of input file entries.
  unsigned int
  input_file_count() const
  { return this->input_file_count_; }

  // Return the command line.
  const char*
  command_line() const
  {
    unsigned int offset = Swap32::readval(this->p_ + 8);
    return this->get_string(offset);
  }

  // Reader class for an input file entry and its supplemental info.
  class Incremental_input_entry_reader
  {
   private:
    static const unsigned int object_info_size =
	Incremental_inputs_reader<size, big_endian>::object_info_size;
    static const unsigned int input_section_entry_size =
	Incremental_inputs_reader<size, big_endian>::input_section_entry_size;
    static const unsigned int global_sym_entry_size =
	Incremental_inputs_reader<size, big_endian>::global_sym_entry_size;

   public:
    Incremental_input_entry_reader(const Incremental_inputs_reader* inputs,
				   unsigned int offset)
      : inputs_(inputs), offset_(offset)
    {
      this->info_offset_ = Swap32::readval(inputs->p_ + offset + 4);
      this->flags_ = Swap16::readval(this->inputs_->p_ + offset + 20);
    }

    // Return the filename.
    const char*
    filename() const
    {
      unsigned int offset = Swap32::readval(this->inputs_->p_ + this->offset_);
      return this->inputs_->get_string(offset);
    }

    // Return the argument serial number.
    unsigned int
    arg_serial() const
    {
      return Swap16::readval(this->inputs_->p_ + this->offset_ + 22);
    }

    // Return the timestamp.
    Timespec
    get_mtime() const
    {
      Timespec t;
      const unsigned char* p = this->inputs_->p_ + this->offset_ + 8;
      t.seconds = Swap64::readval(p);
      t.nanoseconds = Swap32::readval(p+8);
      return t;
    }

    // Return the type of input file.
    Incremental_input_type
    type() const
    { return static_cast<Incremental_input_type>(this->flags_ & 0xff); }

    // Return TRUE if the file was found in a system directory.
    bool
    is_in_system_directory() const
    { return (this->flags_ & INCREMENTAL_INPUT_IN_SYSTEM_DIR) != 0; }

    // Return TRUE if the file was linked with --as-needed.
    bool
    as_needed() const
    { return (this->flags_ & INCREMENTAL_INPUT_AS_NEEDED) != 0; }

    // Return the input section count -- for objects only.
    unsigned int
    get_input_section_count() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
      return Swap32::readval(this->inputs_->p_ + this->info_offset_);
    }

    // Return the soname -- for shared libraries only.
    const char*
    get_soname() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
      unsigned int offset = Swap32::readval(this->inputs_->p_
					    + this->info_offset_);
      return this->inputs_->get_string(offset);
    }

    // Return the offset of the supplemental info for symbol SYMNDX --
    // for objects only.
    unsigned int
    get_symbol_offset(unsigned int symndx) const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);

      unsigned int section_count = this->get_input_section_count();
      return (this->info_offset_
	      + this->object_info_size
	      + section_count * this->input_section_entry_size
	      + symndx * this->global_sym_entry_size);
    }

    // Return the global symbol count -- for objects & shared libraries only.
    unsigned int
    get_global_symbol_count() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER
		  || this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 4);
    }

    // Return the offset of the first local symbol -- for objects only.
    unsigned int
    get_local_symbol_offset() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);

      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 8);
    }

    // Return the local symbol count -- for objects only.
    unsigned int
    get_local_symbol_count() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);

      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 12);
    }

    // Return the index of the first dynamic relocation -- for objects only.
    unsigned int
    get_first_dyn_reloc() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);

      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 16);
    }

    // Return the dynamic relocation count -- for objects only.
    unsigned int
    get_dyn_reloc_count() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);

      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 20);
    }

    // Return the COMDAT group count -- for objects only.
    unsigned int
    get_comdat_group_count() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);

      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 24);
    }

    // Return the object count -- for scripts only.
    unsigned int
    get_object_count() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_SCRIPT);
      return Swap32::readval(this->inputs_->p_ + this->info_offset_);
    }

    // Return the input file offset for object N -- for scripts only.
    unsigned int
    get_object_offset(unsigned int n) const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_SCRIPT);
      return Swap32::readval(this->inputs_->p_ + this->info_offset_
			     + 4 + n * 4);
    }

    // Return the member count -- for archives only.
    unsigned int
    get_member_count() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_ARCHIVE);
      return Swap32::readval(this->inputs_->p_ + this->info_offset_);
    }

    // Return the unused symbol count -- for archives only.
    unsigned int
    get_unused_symbol_count() const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_ARCHIVE);
      return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 4);
    }

    // Return the input file offset for archive member N -- for archives only.
    unsigned int
    get_member_offset(unsigned int n) const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_ARCHIVE);
      return Swap32::readval(this->inputs_->p_ + this->info_offset_
			     + 8 + n * 4);
    }

    // Return the Nth unused global symbol -- for archives only.
    const char*
    get_unused_symbol(unsigned int n) const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_ARCHIVE);
      unsigned int member_count = this->get_member_count();
      unsigned int offset = Swap32::readval(this->inputs_->p_
					    + this->info_offset_ + 8
					    + member_count * 4
					    + n * 4);
      return this->inputs_->get_string(offset);
    }

    // Information about an input section.
    struct Input_section_info
    {
      const char* name;
      unsigned int output_shndx;
      off_t sh_offset;
      off_t sh_size;
    };

    // Return info about the Nth input section -- for objects only.
    Input_section_info
    get_input_section(unsigned int n) const
    {
      Input_section_info info;
      const unsigned char* p = (this->inputs_->p_
				+ this->info_offset_
				+ this->object_info_size
				+ n * this->input_section_entry_size);
      unsigned int name_offset = Swap32::readval(p);
      info.name = this->inputs_->get_string(name_offset);
      info.output_shndx = Swap32::readval(p + 4);
      info.sh_offset = Swap::readval(p + 8);
      info.sh_size = Swap::readval(p + 8 + size / 8);
      return info;
    }

    // Return info about the Nth global symbol -- for objects only.
    Incremental_global_symbol_reader<big_endian>
    get_global_symbol_reader(unsigned int n) const
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
		  || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
      unsigned int section_count = this->get_input_section_count();
      const unsigned char* p = (this->inputs_->p_
				+ this->info_offset_
				+ this->object_info_size
				+ section_count * this->input_section_entry_size
				+ n * this->global_sym_entry_size);
      return Incremental_global_symbol_reader<big_endian>(p);
    }

    // Return the signature of the Nth comdat group -- for objects only.
    const char*
    get_comdat_group_signature(unsigned int n) const
    {
      unsigned int section_count = this->get_input_section_count();
      unsigned int symbol_count = this->get_global_symbol_count();
      const unsigned char* p = (this->inputs_->p_
				+ this->info_offset_
				+ this->object_info_size
				+ section_count * this->input_section_entry_size
				+ symbol_count * this->global_sym_entry_size
				+ n * 4);
      unsigned int name_offset = Swap32::readval(p);
      return this->inputs_->get_string(name_offset);
    }

    // Return the output symbol index for the Nth global symbol -- for shared
    // libraries only.  Sets *IS_DEF to TRUE if the symbol is defined in this
    // input file.  Sets *IS_COPY to TRUE if the symbol was copied from this
    // input file with a COPY relocation.
    unsigned int
    get_output_symbol_index(unsigned int n, bool* is_def, bool* is_copy)
    {
      gold_assert(this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
      const unsigned char* p = (this->inputs_->p_
				+ this->info_offset_ + 8
				+ n * 4);
      unsigned int output_symndx = Swap32::readval(p);
      unsigned int flags = output_symndx >> INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT;
      output_symndx &= ((1U << INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT) - 1);
      switch (flags)
	{
	  case INCREMENTAL_SHLIB_SYM_DEF:
	    *is_def = true;
	    *is_copy = false;
	    break;
	  case INCREMENTAL_SHLIB_SYM_COPY:
	    *is_def = true;
	    *is_copy = true;
	    break;
	  default:
	    *is_def = false;
	    *is_copy = false;
	}
      return output_symndx;
    }

   private:
    // The reader instance for the containing section.
    const Incremental_inputs_reader* inputs_;
    // The flags, including the type of input file.
    unsigned int flags_;
    // Section offset to the input file entry.
    unsigned int offset_;
    // Section offset to the supplemental info for the input file.
    unsigned int info_offset_;
  };

  // Return the offset of an input file entry given its index N.
  unsigned int
  input_file_offset(unsigned int n) const
  {
    gold_assert(n < this->input_file_count_);
    return this->header_size + n * this->input_entry_size;
  }

  // Return the index of an input file entry given its OFFSET.
  unsigned int
  input_file_index(unsigned int offset) const
  {
    int n = ((offset - this->header_size) / this->input_entry_size);
    gold_assert(input_file_offset(n) == offset);
    return n;
  }

  // Return a reader for the Nth input file entry.
  Incremental_input_entry_reader
  input_file(unsigned int n) const
  { return Incremental_input_entry_reader(this, this->input_file_offset(n)); }

  // Return a reader for the input file entry at OFFSET.
  Incremental_input_entry_reader
  input_file_at_offset(unsigned int offset) const
  {
    gold_assert(offset < (this->header_size
			  + this->input_file_count_ * this->input_entry_size));
    return Incremental_input_entry_reader(this, offset);
  }

  // Return a reader for the global symbol info at OFFSET.
  Incremental_global_symbol_reader<big_endian>
  global_symbol_reader_at_offset(unsigned int offset) const
  {
    const unsigned char* p = this->p_ + offset;
    return Incremental_global_symbol_reader<big_endian>(p);
  }

 private:
  // Lookup a string in the ELF string table.
  const char* get_string(unsigned int offset) const
  {
    const char* s;
    if (this->strtab_.get_c_string(offset, &s))
      return s;
    return NULL;
  }

  // Base address of the .gnu_incremental_inputs section.
  const unsigned char* p_;
  // The associated ELF string table.
  elfcpp::Elf_strtab strtab_;
  // The number of input file entries in this section.
  unsigned int input_file_count_;
};

// Reader class for the .gnu_incremental_symtab section.

template<bool big_endian>
class Incremental_symtab_reader
{
 public:
  Incremental_symtab_reader()
    : p_(NULL), len_(0)
  { }

  Incremental_symtab_reader(const unsigned char* p, off_t len)
    : p_(p), len_(len)
  { }

  // Return the count of symbols in this section.
  unsigned int
  symbol_count() const
  { return static_cast<unsigned int>(this->len_ / 4); }

  // Return the list head for symbol table entry N.
  unsigned int
  get_list_head(unsigned int n) const
  { return elfcpp::Swap<32, big_endian>::readval(this->p_ + 4 * n); }

 private:
  // Base address of the .gnu_incremental_relocs section.
  const unsigned char* p_;
  // Size of the section.
  off_t len_;
};

// Reader class for the .gnu_incremental_relocs section.

template<int size, bool big_endian>
class Incremental_relocs_reader
{
 private:
  // Size of each field.
  static const unsigned int field_size = size / 8;

 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename elfcpp::Elf_types<size>::Elf_Swxword Addend;

  // Size of each entry.
  static const unsigned int reloc_size = 8 + 2 * field_size;

  Incremental_relocs_reader()
    : p_(NULL), len_(0)
  { }

  Incremental_relocs_reader(const unsigned char* p, off_t len)
    : p_(p), len_(len)
  { }

  // Return the count of relocations in this section.
  unsigned int
  reloc_count() const
  { return static_cast<unsigned int>(this->len_ / reloc_size); }

  // Return the relocation type for relocation entry at offset OFF.
  unsigned int
  get_r_type(unsigned int off) const
  { return elfcpp::Swap<32, big_endian>::readval(this->p_ + off); }

  // Return the output section index for relocation entry at offset OFF.
  unsigned int
  get_r_shndx(unsigned int off) const
  { return elfcpp::Swap<32, big_endian>::readval(this->p_ + off + 4); }

  // Return the output section offset for relocation entry at offset OFF.
  Address
  get_r_offset(unsigned int off) const
  { return elfcpp::Swap<size, big_endian>::readval(this->p_ + off + 8); }

  // Return the addend for relocation entry at offset OFF.
  Addend
  get_r_addend(unsigned int off) const
  {
    return elfcpp::Swap<size, big_endian>::readval(this->p_ + off + 8
						   + this->field_size);
  }

  // Return a pointer to the relocation entry at offset OFF.
  const unsigned char*
  data(unsigned int off) const
  { return this->p_ + off; }

 private:
  // Base address of the .gnu_incremental_relocs section.
  const unsigned char* p_;
  // Size of the section.
  off_t len_;
};

// Reader class for the .gnu_incremental_got_plt section.

template<bool big_endian>
class Incremental_got_plt_reader
{
 public:
  Incremental_got_plt_reader()
    : p_(NULL), got_count_(0), got_desc_p_(NULL), plt_desc_p_(NULL)
  { }

  Incremental_got_plt_reader(const unsigned char* p) : p_(p)
  {
    this->got_count_ = elfcpp::Swap<32, big_endian>::readval(p);
    this->got_desc_p_ = p + 8 + ((this->got_count_ + 3) & ~3);
    this->plt_desc_p_ = this->got_desc_p_ + this->got_count_ * 8;
  }

  // Return the GOT entry count.
  unsigned int
  get_got_entry_count() const
  {
    return this->got_count_;
  }

  // Return the PLT entry count.
  unsigned int
  get_plt_entry_count() const
  {
    return elfcpp::Swap<32, big_endian>::readval(this->p_ + 4);
  }

  // Return the GOT type for GOT entry N.
  unsigned int
  get_got_type(unsigned int n)
  {
    return this->p_[8 + n];
  }

  // Return the symbol index for GOT entry N.
  unsigned int
  get_got_symndx(unsigned int n)
  {
    return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 8);
  }

  // Return the input file index for GOT entry N.
  unsigned int
  get_got_input_index(unsigned int n)
  {
    return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 8 + 4);
  }

  // Return the PLT descriptor for PLT entry N.
  unsigned int
  get_plt_desc(unsigned int n)
  {
    return elfcpp::Swap<32, big_endian>::readval(this->plt_desc_p_ + n * 4);
  }

 private:
  // Base address of the .gnu_incremental_got_plt section.
  const unsigned char* p_;
  // GOT entry count.
  unsigned int got_count_;
  // Base address of the GOT descriptor array.
  const unsigned char* got_desc_p_;
  // Base address of the PLT descriptor array.
  const unsigned char* plt_desc_p_;
};

// An object representing the ELF file we edit during an incremental build.
// Similar to Object or Dynobj, but operates on Output_file and contains
// methods to support incremental updating. This is the abstract parent class
// implemented in Sized_incremental_binary<size, big_endian> for a specific
// endianness and size.

class Incremental_binary
{
 public:
  Incremental_binary(Output_file* output, Target* /*target*/)
    : input_args_map_(), library_map_(), script_map_(),
      output_(output)
  { }

  virtual
  ~Incremental_binary()
  { }

  // Check the .gnu_incremental_inputs section to see whether an incremental
  // build is possible.
  bool
  check_inputs(const Command_line& cmdline,
	       Incremental_inputs* incremental_inputs)
  { return this->do_check_inputs(cmdline, incremental_inputs); }

  // Report an error.
  void
  error(const char* format, ...) const ATTRIBUTE_PRINTF_2;

  // Proxy class for a sized Incremental_input_entry_reader.

  class Input_reader
  {
   public:
    Input_reader()
    { }

    virtual
    ~Input_reader()
    { }

    const char*
    filename() const
    { return this->do_filename(); }

    Timespec
    get_mtime() const
    { return this->do_get_mtime(); }

    Incremental_input_type
    type() const
    { return this->do_type(); }

    unsigned int
    arg_serial() const
    { return this->do_arg_serial(); }

    unsigned int
    get_unused_symbol_count() const
    { return this->do_get_unused_symbol_count(); }

    const char*
    get_unused_symbol(unsigned int n) const
    { return this->do_get_unused_symbol(n); }

   protected:
    virtual const char*
    do_filename() const = 0;

    virtual Timespec
    do_get_mtime() const = 0;

    virtual Incremental_input_type
    do_type() const = 0;

    virtual unsigned int
    do_arg_serial() const = 0;

    virtual unsigned int
    do_get_unused_symbol_count() const = 0;

    virtual const char*
    do_get_unused_symbol(unsigned int n) const = 0;
  };

  // Return the number of input files.
  unsigned int
  input_file_count() const
  { return this->do_input_file_count(); }

  // Return an Input_reader for input file N.
  const Input_reader*
  get_input_reader(unsigned int n) const
  { return this->do_get_input_reader(n); }

  // Return TRUE if the input file N has changed since the last link.
  bool
  file_has_changed(unsigned int n) const
  { return this->do_file_has_changed(n); }

  // Return the Input_argument for input file N.  Returns NULL if
  // the Input_argument is not available.
  const Input_argument*
  get_input_argument(unsigned int n) const
  {
    const Input_reader* input_file = this->do_get_input_reader(n);
    unsigned int arg_serial = input_file->arg_serial();
    if (arg_serial == 0 || arg_serial > this->input_args_map_.size())
      return NULL;
    return this->input_args_map_[arg_serial - 1];
  }

  // Return an Incremental_library for the given input file.
  Incremental_library*
  get_library(unsigned int n) const
  { return this->library_map_[n]; }

  // Return a Script_info for the given input file.
  Script_info*
  get_script_info(unsigned int n) const
  { return this->script_map_[n]; }

  // Initialize the layout of the output file based on the existing
  // output file.
  void
  init_layout(Layout* layout)
  { this->do_init_layout(layout); }

  // Mark regions of the input file that must be kept unchanged.
  void
  reserve_layout(unsigned int input_file_index)
  { this->do_reserve_layout(input_file_index); }

  // Process the GOT and PLT entries from the existing output file.
  void
  process_got_plt(Symbol_table* symtab, Layout* layout)
  { this->do_process_got_plt(symtab, layout); }

  // Emit COPY relocations from the existing output file.
  void
  emit_copy_relocs(Symbol_table* symtab)
  { this->do_emit_copy_relocs(symtab); }

  // Apply incremental relocations for symbols whose values have changed.
  void
  apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
			   Output_file* of)
  { this->do_apply_incremental_relocs(symtab, layout, of); }

  // Functions and types for the elfcpp::Elf_file interface.  This
  // permit us to use Incremental_binary as the File template parameter for
  // elfcpp::Elf_file.

  // The View class is returned by view.  It must support a single
  // method, data().  This is trivial, because Output_file::get_output_view
  // does what we need.
  class View
  {
   public:
    View(const unsigned char* p)
      : p_(p)
    { }

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

   private:
    const unsigned char* p_;
  };

  // Return a View.
  View
  view(off_t file_offset, section_size_type data_size)
  { return View(this->output_->get_input_view(file_offset, data_size)); }

  // A location in the file.
  struct Location
  {
    off_t file_offset;
    off_t data_size;

    Location(off_t fo, section_size_type ds)
      : file_offset(fo), data_size(ds)
    { }

    Location()
      : file_offset(0), data_size(0)
    { }
  };

  // Get a View given a Location.
  View
  view(Location loc)
  { return View(this->view(loc.file_offset, loc.data_size)); }

  // Return the Output_file.
  Output_file*
  output_file()
  { return this->output_; }

 protected:
  // Check the .gnu_incremental_inputs section to see whether an incremental
  // build is possible.
  virtual bool
  do_check_inputs(const Command_line& cmdline,
		  Incremental_inputs* incremental_inputs) = 0;

  // Return TRUE if input file N has changed since the last incremental link.
  virtual bool
  do_file_has_changed(unsigned int n) const = 0;

  // Initialize the layout of the output file based on the existing
  // output file.
  virtual void
  do_init_layout(Layout* layout) = 0;

  // Mark regions of the input file that must be kept unchanged.
  virtual void
  do_reserve_layout(unsigned int input_file_index) = 0;

  // Process the GOT and PLT entries from the existing output file.
  virtual void
  do_process_got_plt(Symbol_table* symtab, Layout* layout) = 0;

  // Emit COPY relocations from the existing output file.
  virtual void
  do_emit_copy_relocs(Symbol_table* symtab) = 0;

  // Apply incremental relocations for symbols whose values have changed.
  virtual void
  do_apply_incremental_relocs(const Symbol_table*, Layout*, Output_file*) = 0;

  virtual unsigned int
  do_input_file_count() const = 0;

  virtual const Input_reader*
  do_get_input_reader(unsigned int) const = 0;

  // Map from input file index to Input_argument.
  std::vector<const Input_argument*> input_args_map_;
  // Map from an input file index to an Incremental_library.
  std::vector<Incremental_library*> library_map_;
  // Map from an input file index to a Script_info.
  std::vector<Script_info*> script_map_;

 private:
  // Edited output file object.
  Output_file* output_;
};

template<int size, bool big_endian>
class Sized_relobj_incr;

template<int size, bool big_endian>
class Sized_incremental_binary : public Incremental_binary
{
 public:
  Sized_incremental_binary(Output_file* output,
                           const elfcpp::Ehdr<size, big_endian>& ehdr,
                           Target* target)
    : Incremental_binary(output, target), elf_file_(this, ehdr),
      input_objects_(), section_map_(), symbol_map_(), copy_relocs_(),
      main_symtab_loc_(), main_strtab_loc_(), has_incremental_info_(false),
      inputs_reader_(), symtab_reader_(), relocs_reader_(), got_plt_reader_(),
      input_entry_readers_()
  { this->setup_readers(); }

  // Returns TRUE if the file contains incremental info.
  bool
  has_incremental_info() const
  { return this->has_incremental_info_; }

  // Record a pointer to the object for input file N.
  void
  set_input_object(unsigned int n,
		   Sized_relobj_incr<size, big_endian>* obj)
  { this->input_objects_[n] = obj; }

  // Return a pointer to the object for input file N.
  Sized_relobj_incr<size, big_endian>*
  input_object(unsigned int n) const
  {
    gold_assert(n < this->input_objects_.size());
    return this->input_objects_[n];
  }

  // Return the Output_section for section index SHNDX.
  Output_section*
  output_section(unsigned int shndx)
  { return this->section_map_[shndx]; }

  // Map a symbol table entry from the base file to the output symbol table.
  // SYMNDX is relative to the first forced-local or global symbol in the
  // input file symbol table.
  void
  add_global_symbol(unsigned int symndx, Symbol* gsym)
  { this->symbol_map_[symndx] = gsym; }

  // Map a symbol table entry from the base file to the output symbol table.
  // SYMNDX is relative to the first forced-local or global symbol in the
  // input file symbol table.
  Symbol*
  global_symbol(unsigned int symndx) const
  { return this->symbol_map_[symndx]; }

  // Add a COPY relocation for a global symbol.
  void
  add_copy_reloc(Symbol* gsym, Output_section* os, off_t offset)
  { this->copy_relocs_.push_back(Copy_reloc(gsym, os, offset)); }

  // Readers for the incremental info sections.

  const Incremental_inputs_reader<size, big_endian>&
  inputs_reader() const
  { return this->inputs_reader_; }

  const Incremental_symtab_reader<big_endian>&
  symtab_reader() const
  { return this->symtab_reader_; }

  const Incremental_relocs_reader<size, big_endian>&
  relocs_reader() const
  { return this->relocs_reader_; }

  const Incremental_got_plt_reader<big_endian>&
  got_plt_reader() const
  { return this->got_plt_reader_; }

  void
  get_symtab_view(View* symtab_view, unsigned int* sym_count,
		  elfcpp::Elf_strtab* strtab);

 protected:
  typedef Incremental_inputs_reader<size, big_endian> Inputs_reader;
  typedef typename Inputs_reader::Incremental_input_entry_reader
      Input_entry_reader;

  virtual bool
  do_check_inputs(const Command_line& cmdline,
		  Incremental_inputs* incremental_inputs);

  // Return TRUE if input file N has changed since the last incremental link.
  virtual bool
  do_file_has_changed(unsigned int n) const;

  // Initialize the layout of the output file based on the existing
  // output file.
  virtual void
  do_init_layout(Layout* layout);

  // Mark regions of the input file that must be kept unchanged.
  virtual void
  do_reserve_layout(unsigned int input_file_index);

  // Process the GOT and PLT entries from the existing output file.
  virtual void
  do_process_got_plt(Symbol_table* symtab, Layout* layout);

  // Emit COPY relocations from the existing output file.
  virtual void
  do_emit_copy_relocs(Symbol_table* symtab);

  // Apply incremental relocations for symbols whose values have changed.
  virtual void
  do_apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
			      Output_file* of);

  // Proxy class for a sized Incremental_input_entry_reader.

  class Sized_input_reader : public Input_reader
  {
   public:
    Sized_input_reader(Input_entry_reader r)
      : Input_reader(), reader_(r)
    { }

    virtual
    ~Sized_input_reader()
    { }

   private:
    const char*
    do_filename() const
    { return this->reader_.filename(); }

    Timespec
    do_get_mtime() const
    { return this->reader_.get_mtime(); }

    Incremental_input_type
    do_type() const
    { return this->reader_.type(); }

    unsigned int
    do_arg_serial() const
    { return this->reader_.arg_serial(); }

    unsigned int
    do_get_unused_symbol_count() const
    { return this->reader_.get_unused_symbol_count(); }

    const char*
    do_get_unused_symbol(unsigned int n) const
    { return this->reader_.get_unused_symbol(n); }

    Input_entry_reader reader_;
  };

  virtual unsigned int
  do_input_file_count() const
  { return this->inputs_reader_.input_file_count(); }

  virtual const Input_reader*
  do_get_input_reader(unsigned int n) const
  {
    gold_assert(n < this->input_entry_readers_.size());
    return &this->input_entry_readers_[n];
  }

 private:
  // List of symbols that need COPY relocations.
  struct Copy_reloc
  {
    Copy_reloc(Symbol* sym, Output_section* os, off_t off)
      : symbol(sym), output_section(os), offset(off)
    { }

    // The global symbol to copy.
    Symbol* symbol;
    // The output section into which the symbol was copied.
    Output_section* output_section;
    // The offset within that output section.
    off_t offset;
  };
  typedef std::vector<Copy_reloc> Copy_relocs;

  bool
  find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
				   unsigned int* p_symtab_shndx,
				   unsigned int* p_relocs_shndx,
				   unsigned int* p_got_plt_shndx,
				   unsigned int* p_strtab_shndx);

  void
  setup_readers();

  // Output as an ELF file.
  elfcpp::Elf_file<size, big_endian, Incremental_binary> elf_file_;

  // Vector of pointers to the input objects for the unchanged files.
  // For replaced files, the corresponding pointer is NULL.
  std::vector<Sized_relobj_incr<size, big_endian>*> input_objects_;

  // Map section index to an Output_section in the updated layout.
  std::vector<Output_section*> section_map_;

  // Map global symbols from the input file to the symbol table.
  std::vector<Symbol*> symbol_map_;

  // List of symbols that need COPY relocations.
  Copy_relocs copy_relocs_;

  // Locations of the main symbol table and symbol string table.
  Location main_symtab_loc_;
  Location main_strtab_loc_;

  // Readers for the incremental info sections.
  bool has_incremental_info_;
  Incremental_inputs_reader<size, big_endian> inputs_reader_;
  Incremental_symtab_reader<big_endian> symtab_reader_;
  Incremental_relocs_reader<size, big_endian> relocs_reader_;
  Incremental_got_plt_reader<big_endian> got_plt_reader_;
  std::vector<Sized_input_reader> input_entry_readers_;
};

// An incremental Relobj.  This class represents a relocatable object
// that has not changed since the last incremental link, and whose contents
// can be used directly from the base file.

template<int size, bool big_endian>
class Sized_relobj_incr : public Sized_relobj<size, big_endian>
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename Sized_relobj<size, big_endian>::Symbols Symbols;

  Sized_relobj_incr(const std::string& name,
		    Sized_incremental_binary<size, big_endian>* ibase,
		    unsigned int input_file_index);

 private:
  // For convenience.
  typedef Sized_relobj_incr<size, big_endian> This;
  static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;

  typedef typename Sized_relobj<size, big_endian>::Output_sections
      Output_sections;
  typedef Incremental_inputs_reader<size, big_endian> Inputs_reader;
  typedef typename Inputs_reader::Incremental_input_entry_reader
      Input_entry_reader;

  // A local symbol.
  struct Local_symbol
  {
    Local_symbol(const char* name_, Address value_, unsigned int size_,
		 unsigned int shndx_, unsigned int type_,
		 bool needs_dynsym_entry_)
      : st_value(value_), name(name_), st_size(size_), st_shndx(shndx_),
	st_type(type_), output_dynsym_index(0),
	needs_dynsym_entry(needs_dynsym_entry_)
    { }
    // The symbol value.
    Address st_value;
    // The symbol name.  This points to the stringpool entry.
    const char* name;
    // The symbol size.
    unsigned int st_size;
    // The output section index.
    unsigned int st_shndx : 28;
    // The symbol type.
    unsigned int st_type : 4;
    // The index of the symbol in the output dynamic symbol table.
    unsigned int output_dynsym_index : 31;
    // TRUE if the symbol needs to appear in the dynamic symbol table.
    unsigned int needs_dynsym_entry : 1;
  };

  // Return TRUE if this is an incremental (unchanged) input file.
  bool
  do_is_incremental() const
  { return true; }

  // Return the last modified time of the file.
  Timespec
  do_get_mtime()
  { return this->input_reader_.get_mtime(); }

  // Read the symbols.
  void
  do_read_symbols(Read_symbols_data*);

  // Lay out the input sections.
  void
  do_layout(Symbol_table*, Layout*, Read_symbols_data*);

  // Layout sections whose layout was deferred while waiting for
  // input files from a plugin.
  void
  do_layout_deferred_sections(Layout*);

  // Add the symbols to the symbol table.
  void
  do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);

  Archive::Should_include
  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
                           std::string* why);

  // Iterate over global symbols, calling a visitor class V for each.
  void
  do_for_all_global_symbols(Read_symbols_data* sd,
			    Library_base::Symbol_visitor_base* v);

  // Get the size of a section.
  uint64_t
  do_section_size(unsigned int shndx);

  // Get the name of a section.
  std::string
  do_section_name(unsigned int shndx) const;

  // Return a view of the contents of a section.
  const unsigned char*
  do_section_contents(unsigned int shndx, section_size_type* plen,
		      bool cache);

  // Return section flags.
  uint64_t
  do_section_flags(unsigned int shndx);

  // Return section entsize.
  uint64_t
  do_section_entsize(unsigned int shndx);

  // Return section address.
  uint64_t
  do_section_address(unsigned int shndx);

  // Return section type.
  unsigned int
  do_section_type(unsigned int shndx);

  // Return the section link field.
  unsigned int
  do_section_link(unsigned int shndx);

  // Return the section link field.
  unsigned int
  do_section_info(unsigned int shndx);

  // Return the section alignment.
  uint64_t
  do_section_addralign(unsigned int shndx);

  // Return the Xindex structure to use.
  Xindex*
  do_initialize_xindex();

  // Get symbol counts.
  void
  do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;

  // Get global symbols.
  const Symbols*
  do_get_global_symbols() const
  { return &this->symbols_; }

  // Return the value of a local symbol.
  uint64_t
  do_local_symbol_value(unsigned int, uint64_t) const
  { gold_unreachable(); }

  unsigned int
  do_local_plt_offset(unsigned int) const
  { gold_unreachable(); }

  bool
  do_local_is_tls(unsigned int) const
  { gold_unreachable(); }

  // Return the number of local symbols.
  unsigned int
  do_local_symbol_count() const
  { return this->local_symbol_count_; }

  // Return the number of local symbols in the output symbol table.
  unsigned int
  do_output_local_symbol_count() const
  { return this->local_symbol_count_; }

  // Return the file offset for local symbols in the output symbol table.
  off_t
  do_local_symbol_offset() const
  { return this->local_symbol_offset_; }

  // Read the relocs.
  void
  do_read_relocs(Read_relocs_data*);

  // Process the relocs to find list of referenced sections. Used only
  // during garbage collection.
  void
  do_gc_process_relocs(Symbol_table*, Layout*, Read_relocs_data*);

  // Scan the relocs and adjust the symbol table.
  void
  do_scan_relocs(Symbol_table*, Layout*, Read_relocs_data*);

  // Count the local symbols.
  void
  do_count_local_symbols(Stringpool_template<char>*,
			 Stringpool_template<char>*);

  // Finalize the local symbols.
  unsigned int
  do_finalize_local_symbols(unsigned int, off_t, Symbol_table*);

  // Set the offset where local dynamic symbol information will be stored.
  unsigned int
  do_set_local_dynsym_indexes(unsigned int);

  // Set the offset where local dynamic symbol information will be stored.
  unsigned int
  do_set_local_dynsym_offset(off_t);

  // Relocate the input sections and write out the local symbols.
  void
  do_relocate(const Symbol_table* symtab, const Layout*, Output_file* of);

  // Set the offset of a section.
  void
  do_set_section_offset(unsigned int shndx, uint64_t off);

  // The Incremental_binary base file.
  Sized_incremental_binary<size, big_endian>* ibase_;
  // The index of the object in the input file list.
  unsigned int input_file_index_;
  // The reader for the input file.
  Input_entry_reader input_reader_;
  // The number of local symbols.
  unsigned int local_symbol_count_;
  // The number of local symbols which go into the output file's dynamic
  // symbol table.
  unsigned int output_local_dynsym_count_;
  // This starting symbol index in the output symbol table.
  unsigned int local_symbol_index_;
  // The file offset for local symbols in the output symbol table.
  unsigned int local_symbol_offset_;
  // The file offset for local symbols in the output symbol table.
  unsigned int local_dynsym_offset_;
  // The entries in the symbol table for the external symbols.
  Symbols symbols_;
  // Number of symbols defined in object file itself.
  size_t defined_count_;
  // The offset of the first incremental relocation for this object.
  unsigned int incr_reloc_offset_;
  // The number of incremental relocations for this object.
  unsigned int incr_reloc_count_;
  // The index of the first incremental relocation for this object in the
  // updated output file.
  unsigned int incr_reloc_output_index_;
  // A copy of the incremental relocations from this object.
  unsigned char* incr_relocs_;
  // The local symbols.
  std::vector<Local_symbol> local_symbols_;
};

// An incremental Dynobj.  This class represents a shared object that has
// not changed since the last incremental link, and whose contents can be
// used directly from the base file.

template<int size, bool big_endian>
class Sized_incr_dynobj : public Dynobj
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;

  static const Address invalid_address = static_cast<Address>(0) - 1;

  Sized_incr_dynobj(const std::string& name,
		    Sized_incremental_binary<size, big_endian>* ibase,
		    unsigned int input_file_index);

 private:
  typedef Incremental_inputs_reader<size, big_endian> Inputs_reader;
  typedef typename Inputs_reader::Incremental_input_entry_reader
      Input_entry_reader;

  // Return TRUE if this is an incremental (unchanged) input file.
  bool
  do_is_incremental() const
  { return true; }

  // Return the last modified time of the file.
  Timespec
  do_get_mtime()
  { return this->input_reader_.get_mtime(); }

  // Read the symbols.
  void
  do_read_symbols(Read_symbols_data*);

  // Lay out the input sections.
  void
  do_layout(Symbol_table*, Layout*, Read_symbols_data*);

  // Add the symbols to the symbol table.
  void
  do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);

  Archive::Should_include
  do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
                           std::string* why);

  // Iterate over global symbols, calling a visitor class V for each.
  void
  do_for_all_global_symbols(Read_symbols_data* sd,
			    Library_base::Symbol_visitor_base* v);

  // Iterate over local symbols, calling a visitor class V for each GOT offset
  // associated with a local symbol.
  void
  do_for_all_local_got_entries(Got_offset_list::Visitor* v) const;

  // Get the size of a section.
  uint64_t
  do_section_size(unsigned int shndx);

  // Get the name of a section.
  std::string
  do_section_name(unsigned int shndx) const;

  // Return a view of the contents of a section.
  const unsigned char*
  do_section_contents(unsigned int shndx, section_size_type* plen,
		      bool cache);

  // Return section flags.
  uint64_t
  do_section_flags(unsigned int shndx);

  // Return section entsize.
  uint64_t
  do_section_entsize(unsigned int shndx);

  // Return section address.
  uint64_t
  do_section_address(unsigned int shndx);

  // Return section type.
  unsigned int
  do_section_type(unsigned int shndx);

  // Return the section link field.
  unsigned int
  do_section_link(unsigned int shndx);

  // Return the section link field.
  unsigned int
  do_section_info(unsigned int shndx);

  // Return the section alignment.
  uint64_t
  do_section_addralign(unsigned int shndx);

  // Return the Xindex structure to use.
  Xindex*
  do_initialize_xindex();

  // Get symbol counts.
  void
  do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;

  // Get global symbols.
  const Symbols*
  do_get_global_symbols() const
  { return &this->symbols_; }

  // The Incremental_binary base file.
  Sized_incremental_binary<size, big_endian>* ibase_;
  // The index of the object in the input file list.
  unsigned int input_file_index_;
  // The reader for the input file.
  Input_entry_reader input_reader_;
  // The entries in the symbol table for the external symbols.
  Symbols symbols_;
  // Number of symbols defined in object file itself.
  size_t defined_count_;
};

// Allocate an incremental object of the appropriate size and endianness.
extern Object*
make_sized_incremental_object(
    Incremental_binary* base,
    unsigned int input_file_index,
    Incremental_input_type input_type,
    const Incremental_binary::Input_reader* input_reader);

// This class represents an Archive library (or --start-lib/--end-lib group)
// that has not changed since the last incremental link.  Its contents come
// from the incremental inputs entry in the base file.

class Incremental_library : public Library_base
{
 public:
  Incremental_library(const char* filename, unsigned int input_file_index,
		      const Incremental_binary::Input_reader* input_reader)
    : Library_base(NULL), filename_(filename),
      input_file_index_(input_file_index), input_reader_(input_reader),
      unused_symbols_(), is_reported_(false)
  { }

  // Return the input file index.
  unsigned int
  input_file_index() const
  { return this->input_file_index_; }

  // Return the serial number of the input file.
  unsigned int
  arg_serial() const
  { return this->input_reader_->arg_serial(); }

  // Copy the unused symbols from the incremental input info.
  // We need to do this because we may be overwriting the incremental
  // input info in the base file before we write the new incremental
  // info.
  void
  copy_unused_symbols();

  // Return FALSE on the first call to indicate that the library needs
  // to be recorded; return TRUE subsequently.
  bool
  is_reported()
  {
    bool was_reported = this->is_reported_;
    is_reported_ = true;
    return was_reported;
  }

 private:
  typedef std::vector<std::string> Symbol_list;

  // The file name.
  const std::string&
  do_filename() const
  { return this->filename_; }

  // Return the modification time of the archive file.
  Timespec
  do_get_mtime()
  { return this->input_reader_->get_mtime(); }

  // Iterator for unused global symbols in the library.
  void
  do_for_all_unused_symbols(Symbol_visitor_base* v) const;

  // The name of the library.
  std::string filename_;
  // The input file index of this library.
  unsigned int input_file_index_;
  // A reader for the incremental input information.
  const Incremental_binary::Input_reader* input_reader_;
  // List of unused symbols defined in this library.
  Symbol_list unused_symbols_;
  // TRUE when this library has been reported to the new incremental info.
  bool is_reported_;
};

} // End namespace gold.

#endif // !defined(GOLD_INCREMENTAL_H)
