// output.h -- manage the output file for gold   -*- C++ -*-

// Copyright (C) 2006-2016 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.

#ifndef GOLD_OUTPUT_H
#define GOLD_OUTPUT_H

#include <algorithm>
#include <list>
#include <vector>

#include "elfcpp.h"
#include "mapfile.h"
#include "layout.h"
#include "reloc-types.h"

namespace gold
{

class General_options;
class Object;
class Symbol;
class Output_merge_base;
class Output_section;
class Relocatable_relocs;
class Target;
template<int size, bool big_endian>
class Sized_target;
template<int size, bool big_endian>
class Sized_relobj;
template<int size, bool big_endian>
class Sized_relobj_file;

// This class represents the output file.

class Output_file
{
 public:
  Output_file(const char* name);

  // Indicate that this is a temporary file which should not be
  // output.
  void
  set_is_temporary()
  { this->is_temporary_ = true; }

  // Try to open an existing file. Returns false if the file doesn't
  // exist, has a size of 0 or can't be mmaped.  This method is
  // thread-unsafe.  If BASE_NAME is not NULL, use the contents of
  // that file as the base for incremental linking.
  bool
  open_base_file(const char* base_name, bool writable);

  // Open the output file.  FILE_SIZE is the final size of the file.
  // If the file already exists, it is deleted/truncated.  This method
  // is thread-unsafe.
  void
  open(off_t file_size);

  // Resize the output file.  This method is thread-unsafe.
  void
  resize(off_t file_size);

  // Close the output file (flushing all buffered data) and make sure
  // there are no errors.  This method is thread-unsafe.
  void
  close();

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

  // Return the name of this file.
  const char*
  filename()
  { return this->name_; }

  // We currently always use mmap which makes the view handling quite
  // simple.  In the future we may support other approaches.

  // Write data to the output file.
  void
  write(off_t offset, const void* data, size_t len)
  { memcpy(this->base_ + offset, data, len); }

  // Get a buffer to use to write to the file, given the offset into
  // the file and the size.
  unsigned char*
  get_output_view(off_t start, size_t size)
  {
    gold_assert(start >= 0
		&& start + static_cast<off_t>(size) <= this->file_size_);
    return this->base_ + start;
  }

  // VIEW must have been returned by get_output_view.  Write the
  // buffer to the file, passing in the offset and the size.
  void
  write_output_view(off_t, size_t, unsigned char*)
  { }

  // Get a read/write buffer.  This is used when we want to write part
  // of the file, read it in, and write it again.
  unsigned char*
  get_input_output_view(off_t start, size_t size)
  { return this->get_output_view(start, size); }

  // Write a read/write buffer back to the file.
  void
  write_input_output_view(off_t, size_t, unsigned char*)
  { }

  // Get a read buffer.  This is used when we just want to read part
  // of the file back it in.
  const unsigned char*
  get_input_view(off_t start, size_t size)
  { return this->get_output_view(start, size); }

  // Release a read bfufer.
  void
  free_input_view(off_t, size_t, const unsigned char*)
  { }

 private:
  // Map the file into memory or, if that fails, allocate anonymous
  // memory.
  void
  map();

  // Allocate anonymous memory for the file.
  bool
  map_anonymous();

  // Map the file into memory.
  bool
  map_no_anonymous(bool);

  // Unmap the file from memory (and flush to disk buffers).
  void
  unmap();

  // File name.
  const char* name_;
  // File descriptor.
  int o_;
  // File size.
  off_t file_size_;
  // Base of file mapped into memory.
  unsigned char* base_;
  // True iff base_ points to a memory buffer rather than an output file.
  bool map_is_anonymous_;
  // True if base_ was allocated using new rather than mmap.
  bool map_is_allocated_;
  // True if this is a temporary file which should not be output.
  bool is_temporary_;
};

// An abtract class for data which has to go into the output file.

class Output_data
{
 public:
  explicit Output_data()
    : address_(0), data_size_(0), offset_(-1),
      is_address_valid_(false), is_data_size_valid_(false),
      is_offset_valid_(false), is_data_size_fixed_(false),
      has_dynamic_reloc_(false)
  { }

  virtual
  ~Output_data();

  // Return the address.  For allocated sections, this is only valid
  // after Layout::finalize is finished.
  uint64_t
  address() const
  {
    gold_assert(this->is_address_valid_);
    return this->address_;
  }

  // Return the size of the data.  For allocated sections, this must
  // be valid after Layout::finalize calls set_address, but need not
  // be valid before then.
  off_t
  data_size() const
  {
    gold_assert(this->is_data_size_valid_);
    return this->data_size_;
  }

  // Get the current data size.
  off_t
  current_data_size() const
  { return this->current_data_size_for_child(); }

  // Return true if data size is fixed.
  bool
  is_data_size_fixed() const
  { return this->is_data_size_fixed_; }

  // Return the file offset.  This is only valid after
  // Layout::finalize is finished.  For some non-allocated sections,
  // it may not be valid until near the end of the link.
  off_t
  offset() const
  {
    gold_assert(this->is_offset_valid_);
    return this->offset_;
  }

  // Reset the address, file offset and data size.  This essentially
  // disables the sanity testing about duplicate and unknown settings.
  void
  reset_address_and_file_offset()
  {
    this->is_address_valid_ = false;
    this->is_offset_valid_ = false;
    if (!this->is_data_size_fixed_)
      this->is_data_size_valid_ = false;
    this->do_reset_address_and_file_offset();
  }

  // As above, but just for data size.
  void
  reset_data_size()
  {
    if (!this->is_data_size_fixed_)
      this->is_data_size_valid_ = false;
  }

  // Return true if address and file offset already have reset values. In
  // other words, calling reset_address_and_file_offset will not change them.
  bool
  address_and_file_offset_have_reset_values() const
  { return this->do_address_and_file_offset_have_reset_values(); }

  // Return the required alignment.
  uint64_t
  addralign() const
  { return this->do_addralign(); }

  // Return whether this has a load address.
  bool
  has_load_address() const
  { return this->do_has_load_address(); }

  // Return the load address.
  uint64_t
  load_address() const
  { return this->do_load_address(); }

  // Return whether this is an Output_section.
  bool
  is_section() const
  { return this->do_is_section(); }

  // Return whether this is an Output_section of the specified type.
  bool
  is_section_type(elfcpp::Elf_Word stt) const
  { return this->do_is_section_type(stt); }

  // Return whether this is an Output_section with the specified flag
  // set.
  bool
  is_section_flag_set(elfcpp::Elf_Xword shf) const
  { return this->do_is_section_flag_set(shf); }

  // Return the output section that this goes in, if there is one.
  Output_section*
  output_section()
  { return this->do_output_section(); }

  const Output_section*
  output_section() const
  { return this->do_output_section(); }

  // Return the output section index, if there is an output section.
  unsigned int
  out_shndx() const
  { return this->do_out_shndx(); }

  // Set the output section index, if this is an output section.
  void
  set_out_shndx(unsigned int shndx)
  { this->do_set_out_shndx(shndx); }

  // Set the address and file offset of this data, and finalize the
  // size of the data.  This is called during Layout::finalize for
  // allocated sections.
  void
  set_address_and_file_offset(uint64_t addr, off_t off)
  {
    this->set_address(addr);
    this->set_file_offset(off);
    this->finalize_data_size();
  }

  // Set the address.
  void
  set_address(uint64_t addr)
  {
    gold_assert(!this->is_address_valid_);
    this->address_ = addr;
    this->is_address_valid_ = true;
  }

  // Set the file offset.
  void
  set_file_offset(off_t off)
  {
    gold_assert(!this->is_offset_valid_);
    this->offset_ = off;
    this->is_offset_valid_ = true;
  }

  // Update the data size without finalizing it.
  void
  pre_finalize_data_size()
  {
    if (!this->is_data_size_valid_)
      {
	// Tell the child class to update the data size.
	this->update_data_size();
      }
  }

  // Finalize the data size.
  void
  finalize_data_size()
  {
    if (!this->is_data_size_valid_)
      {
	// Tell the child class to set the data size.
	this->set_final_data_size();
	gold_assert(this->is_data_size_valid_);
      }
  }

  // Set the TLS offset.  Called only for SHT_TLS sections.
  void
  set_tls_offset(uint64_t tls_base)
  { this->do_set_tls_offset(tls_base); }

  // Return the TLS offset, relative to the base of the TLS segment.
  // Valid only for SHT_TLS sections.
  uint64_t
  tls_offset() const
  { return this->do_tls_offset(); }

  // Write the data to the output file.  This is called after
  // Layout::finalize is complete.
  void
  write(Output_file* file)
  { this->do_write(file); }

  // This is called by Layout::finalize to note that the sizes of
  // allocated sections must now be fixed.
  static void
  layout_complete()
  { Output_data::allocated_sizes_are_fixed = true; }

  // Used to check that layout has been done.
  static bool
  is_layout_complete()
  { return Output_data::allocated_sizes_are_fixed; }

  // Note that a dynamic reloc has been applied to this data.
  void
  add_dynamic_reloc()
  { this->has_dynamic_reloc_ = true; }

  // Return whether a dynamic reloc has been applied.
  bool
  has_dynamic_reloc() const
  { return this->has_dynamic_reloc_; }

  // Whether the address is valid.
  bool
  is_address_valid() const
  { return this->is_address_valid_; }

  // Whether the file offset is valid.
  bool
  is_offset_valid() const
  { return this->is_offset_valid_; }

  // Whether the data size is valid.
  bool
  is_data_size_valid() const
  { return this->is_data_size_valid_; }

  // Print information to the map file.
  void
  print_to_mapfile(Mapfile* mapfile) const
  { return this->do_print_to_mapfile(mapfile); }

 protected:
  // Functions that child classes may or in some cases must implement.

  // Write the data to the output file.
  virtual void
  do_write(Output_file*) = 0;

  // Return the required alignment.
  virtual uint64_t
  do_addralign() const = 0;

  // Return whether this has a load address.
  virtual bool
  do_has_load_address() const
  { return false; }

  // Return the load address.
  virtual uint64_t
  do_load_address() const
  { gold_unreachable(); }

  // Return whether this is an Output_section.
  virtual bool
  do_is_section() const
  { return false; }

  // Return whether this is an Output_section of the specified type.
  // This only needs to be implement by Output_section.
  virtual bool
  do_is_section_type(elfcpp::Elf_Word) const
  { return false; }

  // Return whether this is an Output_section with the specific flag
  // set.  This only needs to be implemented by Output_section.
  virtual bool
  do_is_section_flag_set(elfcpp::Elf_Xword) const
  { return false; }

  // Return the output section, if there is one.
  virtual Output_section*
  do_output_section()
  { return NULL; }

  virtual const Output_section*
  do_output_section() const
  { return NULL; }

  // Return the output section index, if there is an output section.
  virtual unsigned int
  do_out_shndx() const
  { gold_unreachable(); }

  // Set the output section index, if this is an output section.
  virtual void
  do_set_out_shndx(unsigned int)
  { gold_unreachable(); }

  // This is a hook for derived classes to set the preliminary data size.
  // This is called by pre_finalize_data_size, normally called during
  // Layout::finalize, before the section address is set, and is used
  // during an incremental update, when we need to know the size of a
  // section before allocating space in the output file.  For classes
  // where the current data size is up to date, this default version of
  // the method can be inherited.
  virtual void
  update_data_size()
  { }

  // This is a hook for derived classes to set the data size.  This is
  // called by finalize_data_size, normally called during
  // Layout::finalize, when the section address is set.
  virtual void
  set_final_data_size()
  { gold_unreachable(); }

  // A hook for resetting the address and file offset.
  virtual void
  do_reset_address_and_file_offset()
  { }

  // Return true if address and file offset already have reset values. In
  // other words, calling reset_address_and_file_offset will not change them.
  // A child class overriding do_reset_address_and_file_offset may need to
  // also override this.
  virtual bool
  do_address_and_file_offset_have_reset_values() const
  { return !this->is_address_valid_ && !this->is_offset_valid_; }

  // Set the TLS offset.  Called only for SHT_TLS sections.
  virtual void
  do_set_tls_offset(uint64_t)
  { gold_unreachable(); }

  // Return the TLS offset, relative to the base of the TLS segment.
  // Valid only for SHT_TLS sections.
  virtual uint64_t
  do_tls_offset() const
  { gold_unreachable(); }

  // Print to the map file.  This only needs to be implemented by
  // classes which may appear in a PT_LOAD segment.
  virtual void
  do_print_to_mapfile(Mapfile*) const
  { gold_unreachable(); }

  // Functions that child classes may call.

  // Reset the address.  The Output_section class needs this when an
  // SHF_ALLOC input section is added to an output section which was
  // formerly not SHF_ALLOC.
  void
  mark_address_invalid()
  { this->is_address_valid_ = false; }

  // Set the size of the data.
  void
  set_data_size(off_t data_size)
  {
    gold_assert(!this->is_data_size_valid_
		&& !this->is_data_size_fixed_);
    this->data_size_ = data_size;
    this->is_data_size_valid_ = true;
  }

  // Fix the data size.  Once it is fixed, it cannot be changed
  // and the data size remains always valid.
  void
  fix_data_size()
  {
    gold_assert(this->is_data_size_valid_);
    this->is_data_size_fixed_ = true;
  }

  // Get the current data size--this is for the convenience of
  // sections which build up their size over time.
  off_t
  current_data_size_for_child() const
  { return this->data_size_; }

  // Set the current data size--this is for the convenience of
  // sections which build up their size over time.
  void
  set_current_data_size_for_child(off_t data_size)
  {
    gold_assert(!this->is_data_size_valid_);
    this->data_size_ = data_size;
  }

  // Return default alignment for the target size.
  static uint64_t
  default_alignment();

  // Return default alignment for a specified size--32 or 64.
  static uint64_t
  default_alignment_for_size(int size);

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

  // This is used for verification, to make sure that we don't try to
  // change any sizes of allocated sections after we set the section
  // addresses.
  static bool allocated_sizes_are_fixed;

  // Memory address in output file.
  uint64_t address_;
  // Size of data in output file.
  off_t data_size_;
  // File offset of contents in output file.
  off_t offset_;
  // Whether address_ is valid.
  bool is_address_valid_ : 1;
  // Whether data_size_ is valid.
  bool is_data_size_valid_ : 1;
  // Whether offset_ is valid.
  bool is_offset_valid_ : 1;
  // Whether data size is fixed.
  bool is_data_size_fixed_ : 1;
  // Whether any dynamic relocs have been applied to this section.
  bool has_dynamic_reloc_ : 1;
};

// Output the section headers.

class Output_section_headers : public Output_data
{
 public:
  Output_section_headers(const Layout*,
			 const Layout::Segment_list*,
			 const Layout::Section_list*,
			 const Layout::Section_list*,
			 const Stringpool*,
			 const Output_section*);

 protected:
  // Write the data to the file.
  void
  do_write(Output_file*);

  // Return the required alignment.
  uint64_t
  do_addralign() const
  { return Output_data::default_alignment(); }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** section headers")); }

  // Update the data size.
  void
  update_data_size()
  { this->set_data_size(this->do_size()); }

  // Set final data size.
  void
  set_final_data_size()
  { this->set_data_size(this->do_size()); }

 private:
  // Write the data to the file with the right size and endianness.
  template<int size, bool big_endian>
  void
  do_sized_write(Output_file*);

  // Compute data size.
  off_t
  do_size() const;

  const Layout* layout_;
  const Layout::Segment_list* segment_list_;
  const Layout::Section_list* section_list_;
  const Layout::Section_list* unattached_section_list_;
  const Stringpool* secnamepool_;
  const Output_section* shstrtab_section_;
};

// Output the segment headers.

class Output_segment_headers : public Output_data
{
 public:
  Output_segment_headers(const Layout::Segment_list& segment_list);

 protected:
  // Write the data to the file.
  void
  do_write(Output_file*);

  // Return the required alignment.
  uint64_t
  do_addralign() const
  { return Output_data::default_alignment(); }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** segment headers")); }

  // Set final data size.
  void
  set_final_data_size()
  { this->set_data_size(this->do_size()); }

 private:
  // Write the data to the file with the right size and endianness.
  template<int size, bool big_endian>
  void
  do_sized_write(Output_file*);

  // Compute the current size.
  off_t
  do_size() const;

  const Layout::Segment_list& segment_list_;
};

// Output the ELF file header.

class Output_file_header : public Output_data
{
 public:
  Output_file_header(Target*,
		     const Symbol_table*,
		     const Output_segment_headers*);

  // Add information about the section headers.  We lay out the ELF
  // file header before we create the section headers.
  void set_section_info(const Output_section_headers*,
			const Output_section* shstrtab);

 protected:
  // Write the data to the file.
  void
  do_write(Output_file*);

  // Return the required alignment.
  uint64_t
  do_addralign() const
  { return Output_data::default_alignment(); }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** file header")); }

  // Set final data size.
  void
  set_final_data_size(void)
  { this->set_data_size(this->do_size()); }

 private:
  // Write the data to the file with the right size and endianness.
  template<int size, bool big_endian>
  void
  do_sized_write(Output_file*);

  // Return the value to use for the entry address.
  template<int size>
  typename elfcpp::Elf_types<size>::Elf_Addr
  entry();

  // Compute the current data size.
  off_t
  do_size() const;

  Target* target_;
  const Symbol_table* symtab_;
  const Output_segment_headers* segment_header_;
  const Output_section_headers* section_header_;
  const Output_section* shstrtab_;
};

// Output sections are mainly comprised of input sections.  However,
// there are cases where we have data to write out which is not in an
// input section.  Output_section_data is used in such cases.  This is
// an abstract base class.

class Output_section_data : public Output_data
{
 public:
  Output_section_data(off_t data_size, uint64_t addralign,
		      bool is_data_size_fixed)
    : Output_data(), output_section_(NULL), addralign_(addralign)
  {
    this->set_data_size(data_size);
    if (is_data_size_fixed)
      this->fix_data_size();
  }

  Output_section_data(uint64_t addralign)
    : Output_data(), output_section_(NULL), addralign_(addralign)
  { }

  // Return the output section.
  Output_section*
  output_section()
  { return this->output_section_; }

  const Output_section*
  output_section() const
  { return this->output_section_; }

  // Record the output section.
  void
  set_output_section(Output_section* os);

  // Add an input section, for SHF_MERGE sections.  This returns true
  // if the section was handled.
  bool
  add_input_section(Relobj* object, unsigned int shndx)
  { return this->do_add_input_section(object, shndx); }

  // Given an input OBJECT, an input section index SHNDX within that
  // object, and an OFFSET relative to the start of that input
  // section, return whether or not the corresponding offset within
  // the output section is known.  If this function returns true, it
  // sets *POUTPUT to the output offset.  The value -1 indicates that
  // this input offset is being discarded.
  bool
  output_offset(const Relobj* object, unsigned int shndx,
		section_offset_type offset,
		section_offset_type* poutput) const
  { return this->do_output_offset(object, shndx, offset, poutput); }

  // Write the contents to a buffer.  This is used for sections which
  // require postprocessing, such as compression.
  void
  write_to_buffer(unsigned char* buffer)
  { this->do_write_to_buffer(buffer); }

  // Print merge stats to stderr.  This should only be called for
  // SHF_MERGE sections.
  void
  print_merge_stats(const char* section_name)
  { this->do_print_merge_stats(section_name); }

 protected:
  // The child class must implement do_write.

  // The child class may implement specific adjustments to the output
  // section.
  virtual void
  do_adjust_output_section(Output_section*)
  { }

  // May be implemented by child class.  Return true if the section
  // was handled.
  virtual bool
  do_add_input_section(Relobj*, unsigned int)
  { gold_unreachable(); }

  // The child class may implement output_offset.
  virtual bool
  do_output_offset(const Relobj*, unsigned int, section_offset_type,
		   section_offset_type*) const
  { return false; }

  // The child class may implement write_to_buffer.  Most child
  // classes can not appear in a compressed section, and they do not
  // implement this.
  virtual void
  do_write_to_buffer(unsigned char*)
  { gold_unreachable(); }

  // Print merge statistics.
  virtual void
  do_print_merge_stats(const char*)
  { gold_unreachable(); }

  // Return the required alignment.
  uint64_t
  do_addralign() const
  { return this->addralign_; }

  // Return the output section.
  Output_section*
  do_output_section()
  { return this->output_section_; }

  const Output_section*
  do_output_section() const
  { return this->output_section_; }

  // Return the section index of the output section.
  unsigned int
  do_out_shndx() const;

  // Set the alignment.
  void
  set_addralign(uint64_t addralign);

 private:
  // The output section for this section.
  Output_section* output_section_;
  // The required alignment.
  uint64_t addralign_;
};

// Some Output_section_data classes build up their data step by step,
// rather than all at once.  This class provides an interface for
// them.

class Output_section_data_build : public Output_section_data
{
 public:
  Output_section_data_build(uint64_t addralign)
    : Output_section_data(addralign)
  { }

  Output_section_data_build(off_t data_size, uint64_t addralign)
    : Output_section_data(data_size, addralign, false)
  { }

  // Set the current data size.
  void
  set_current_data_size(off_t data_size)
  { this->set_current_data_size_for_child(data_size); }

 protected:
  // Set the final data size.
  virtual void
  set_final_data_size()
  { this->set_data_size(this->current_data_size_for_child()); }
};

// A simple case of Output_data in which we have constant data to
// output.

class Output_data_const : public Output_section_data
{
 public:
  Output_data_const(const std::string& data, uint64_t addralign)
    : Output_section_data(data.size(), addralign, true), data_(data)
  { }

  Output_data_const(const char* p, off_t len, uint64_t addralign)
    : Output_section_data(len, addralign, true), data_(p, len)
  { }

  Output_data_const(const unsigned char* p, off_t len, uint64_t addralign)
    : Output_section_data(len, addralign, true),
      data_(reinterpret_cast<const char*>(p), len)
  { }

 protected:
  // Write the data to the output file.
  void
  do_write(Output_file*);

  // Write the data to a buffer.
  void
  do_write_to_buffer(unsigned char* buffer)
  { memcpy(buffer, this->data_.data(), this->data_.size()); }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** fill")); }

 private:
  std::string data_;
};

// Another version of Output_data with constant data, in which the
// buffer is allocated by the caller.

class Output_data_const_buffer : public Output_section_data
{
 public:
  Output_data_const_buffer(const unsigned char* p, off_t len,
			   uint64_t addralign, const char* map_name)
    : Output_section_data(len, addralign, true),
      p_(p), map_name_(map_name)
  { }

 protected:
  // Write the data the output file.
  void
  do_write(Output_file*);

  // Write the data to a buffer.
  void
  do_write_to_buffer(unsigned char* buffer)
  { memcpy(buffer, this->p_, this->data_size()); }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _(this->map_name_)); }

 private:
  // The data to output.
  const unsigned char* p_;
  // Name to use in a map file.  Maps are a rarely used feature, but
  // the space usage is minor as aren't very many of these objects.
  const char* map_name_;
};

// A place holder for a fixed amount of data written out via some
// other mechanism.

class Output_data_fixed_space : public Output_section_data
{
 public:
  Output_data_fixed_space(off_t data_size, uint64_t addralign,
			  const char* map_name)
    : Output_section_data(data_size, addralign, true),
      map_name_(map_name)
  { }

 protected:
  // Write out the data--the actual data must be written out
  // elsewhere.
  void
  do_write(Output_file*)
  { }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _(this->map_name_)); }

 private:
  // Name to use in a map file.  Maps are a rarely used feature, but
  // the space usage is minor as aren't very many of these objects.
  const char* map_name_;
};

// A place holder for variable sized data written out via some other
// mechanism.

class Output_data_space : public Output_section_data_build
{
 public:
  explicit Output_data_space(uint64_t addralign, const char* map_name)
    : Output_section_data_build(addralign),
      map_name_(map_name)
  { }

  explicit Output_data_space(off_t data_size, uint64_t addralign,
			     const char* map_name)
    : Output_section_data_build(data_size, addralign),
      map_name_(map_name)
  { }

  // Set the alignment.
  void
  set_space_alignment(uint64_t align)
  { this->set_addralign(align); }

 protected:
  // Write out the data--the actual data must be written out
  // elsewhere.
  void
  do_write(Output_file*)
  { }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _(this->map_name_)); }

 private:
  // Name to use in a map file.  Maps are a rarely used feature, but
  // the space usage is minor as aren't very many of these objects.
  const char* map_name_;
};

// Fill fixed space with zeroes.  This is just like
// Output_data_fixed_space, except that the map name is known.

class Output_data_zero_fill : public Output_section_data
{
 public:
  Output_data_zero_fill(off_t data_size, uint64_t addralign)
    : Output_section_data(data_size, addralign, true)
  { }

 protected:
  // There is no data to write out.
  void
  do_write(Output_file*)
  { }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, "** zero fill"); }
};

// A string table which goes into an output section.

class Output_data_strtab : public Output_section_data
{
 public:
  Output_data_strtab(Stringpool* strtab)
    : Output_section_data(1), strtab_(strtab)
  { }

 protected:
  // This is called to update the section size prior to assigning
  // the address and file offset.
  void
  update_data_size()
  { this->set_final_data_size(); }

  // This is called to set the address and file offset.  Here we make
  // sure that the Stringpool is finalized.
  void
  set_final_data_size();

  // Write out the data.
  void
  do_write(Output_file*);

  // Write the data to a buffer.
  void
  do_write_to_buffer(unsigned char* buffer)
  { this->strtab_->write_to_buffer(buffer, this->data_size()); }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** string table")); }

 private:
  Stringpool* strtab_;
};

// This POD class is used to represent a single reloc in the output
// file.  This could be a private class within Output_data_reloc, but
// the templatization is complex enough that I broke it out into a
// separate class.  The class is templatized on either elfcpp::SHT_REL
// or elfcpp::SHT_RELA, and also on whether this is a dynamic
// relocation or an ordinary relocation.

// A relocation can be against a global symbol, a local symbol, a
// local section symbol, an output section, or the undefined symbol at
// index 0.  We represent the latter by using a NULL global symbol.

template<int sh_type, bool dynamic, int size, bool big_endian>
class Output_reloc;

template<bool dynamic, int size, bool big_endian>
class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;

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

  // An uninitialized entry.  We need this because we want to put
  // instances of this class into an STL container.
  Output_reloc()
    : local_sym_index_(INVALID_CODE)
  { }

  // We have a bunch of different constructors.  They come in pairs
  // depending on how the address of the relocation is specified.  It
  // can either be an offset in an Output_data or an offset in an
  // input section.

  // A reloc against a global symbol.

  Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
	       Address address, bool is_relative, bool is_symbolless,
	       bool use_plt_offset);

  Output_reloc(Symbol* gsym, unsigned int type,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address, bool is_relative,
	       bool is_symbolless, bool use_plt_offset);

  // A reloc against a local symbol or local section symbol.

  Output_reloc(Sized_relobj<size, big_endian>* relobj,
	       unsigned int local_sym_index, unsigned int type,
	       Output_data* od, Address address, bool is_relative,
	       bool is_symbolless, bool is_section_symbol,
	       bool use_plt_offset);

  Output_reloc(Sized_relobj<size, big_endian>* relobj,
	       unsigned int local_sym_index, unsigned int type,
	       unsigned int shndx, Address address, bool is_relative,
	       bool is_symbolless, bool is_section_symbol,
	       bool use_plt_offset);

  // A reloc against the STT_SECTION symbol of an output section.

  Output_reloc(Output_section* os, unsigned int type, Output_data* od,
	       Address address, bool is_relative);

  Output_reloc(Output_section* os, unsigned int type,
	       Sized_relobj<size, big_endian>* relobj, unsigned int shndx,
	       Address address, bool is_relative);

  // An absolute or relative relocation with no symbol.

  Output_reloc(unsigned int type, Output_data* od, Address address,
	       bool is_relative);

  Output_reloc(unsigned int type, Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address, bool is_relative);

  // A target specific relocation.  The target will be called to get
  // the symbol index, passing ARG.  The type and offset will be set
  // as for other relocation types.

  Output_reloc(unsigned int type, void* arg, Output_data* od,
	       Address address);

  Output_reloc(unsigned int type, void* arg,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address);

  // Return the reloc type.
  unsigned int
  type() const
  { return this->type_; }

  // Return whether this is a RELATIVE relocation.
  bool
  is_relative() const
  { return this->is_relative_; }

  // Return whether this is a relocation which should not use
  // a symbol, but which obtains its addend from a symbol.
  bool
  is_symbolless() const
  { return this->is_symbolless_; }

  // Return whether this is against a local section symbol.
  bool
  is_local_section_symbol() const
  {
    return (this->local_sym_index_ != GSYM_CODE
	    && this->local_sym_index_ != SECTION_CODE
	    && this->local_sym_index_ != INVALID_CODE
	    && this->local_sym_index_ != TARGET_CODE
	    && this->is_section_symbol_);
  }

  // Return whether this is a target specific relocation.
  bool
  is_target_specific() const
  { return this->local_sym_index_ == TARGET_CODE; }

  // Return the argument to pass to the target for a target specific
  // relocation.
  void*
  target_arg() const
  {
    gold_assert(this->local_sym_index_ == TARGET_CODE);
    return this->u1_.arg;
  }

  // For a local section symbol, return the offset of the input
  // section within the output section.  ADDEND is the addend being
  // applied to the input section.
  Address
  local_section_offset(Addend addend) const;

  // Get the value of the symbol referred to by a Rel relocation when
  // we are adding the given ADDEND.
  Address
  symbol_value(Addend addend) const;

  // If this relocation is against an input section, return the
  // relocatable object containing the input section.
  Sized_relobj<size, big_endian>*
  get_relobj() const
  {
    if (this->shndx_ == INVALID_CODE)
      return NULL;
    return this->u2_.relobj;
  }

  // Write the reloc entry to an output view.
  void
  write(unsigned char* pov) const;

  // Write the offset and info fields to Write_rel.
  template<typename Write_rel>
  void write_rel(Write_rel*) const;

  // This is used when sorting dynamic relocs.  Return -1 to sort this
  // reloc before R2, 0 to sort the same as R2, 1 to sort after R2.
  int
  compare(const Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>& r2)
    const;

  // Return whether this reloc should be sorted before the argument
  // when sorting dynamic relocs.
  bool
  sort_before(const Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>&
	      r2) const
  { return this->compare(r2) < 0; }

  // Return the symbol index.
  unsigned int
  get_symbol_index() const;

  // Return the output address.
  Address
  get_address() const;

 private:
  // Record that we need a dynamic symbol index.
  void
  set_needs_dynsym_index();

  // Codes for local_sym_index_.
  enum
  {
    // Global symbol.
    GSYM_CODE = -1U,
    // Output section.
    SECTION_CODE = -2U,
    // Target specific.
    TARGET_CODE = -3U,
    // Invalid uninitialized entry.
    INVALID_CODE = -4U
  };

  union
  {
    // For a local symbol or local section symbol
    // (this->local_sym_index_ >= 0), the object.  We will never
    // generate a relocation against a local symbol in a dynamic
    // object; that doesn't make sense.  And our callers will always
    // be templatized, so we use Sized_relobj here.
    Sized_relobj<size, big_endian>* relobj;
    // For a global symbol (this->local_sym_index_ == GSYM_CODE, the
    // symbol.  If this is NULL, it indicates a relocation against the
    // undefined 0 symbol.
    Symbol* gsym;
    // For a relocation against an output section
    // (this->local_sym_index_ == SECTION_CODE), the output section.
    Output_section* os;
    // For a target specific relocation, an argument to pass to the
    // target.
    void* arg;
  } u1_;
  union
  {
    // If this->shndx_ is not INVALID CODE, the object which holds the
    // input section being used to specify the reloc address.
    Sized_relobj<size, big_endian>* relobj;
    // If this->shndx_ is INVALID_CODE, the output data being used to
    // specify the reloc address.  This may be NULL if the reloc
    // address is absolute.
    Output_data* od;
  } u2_;
  // The address offset within the input section or the Output_data.
  Address address_;
  // This is GSYM_CODE for a global symbol, or SECTION_CODE for a
  // relocation against an output section, or TARGET_CODE for a target
  // specific relocation, or INVALID_CODE for an uninitialized value.
  // Otherwise, for a local symbol (this->is_section_symbol_ is
  // false), the local symbol index.  For a local section symbol
  // (this->is_section_symbol_ is true), the section index in the
  // input file.
  unsigned int local_sym_index_;
  // The reloc type--a processor specific code.
  unsigned int type_ : 28;
  // True if the relocation is a RELATIVE relocation.
  bool is_relative_ : 1;
  // True if the relocation is one which should not use
  // a symbol, but which obtains its addend from a symbol.
  bool is_symbolless_ : 1;
  // True if the relocation is against a section symbol.
  bool is_section_symbol_ : 1;
  // True if the addend should be the PLT offset.
  // (Used only for RELA, but stored here for space.)
  bool use_plt_offset_ : 1;
  // If the reloc address is an input section in an object, the
  // section index.  This is INVALID_CODE if the reloc address is
  // specified in some other way.
  unsigned int shndx_;
};

// The SHT_RELA version of Output_reloc<>.  This is just derived from
// the SHT_REL version of Output_reloc, but it adds an addend.

template<bool dynamic, int size, bool big_endian>
class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;

  // An uninitialized entry.
  Output_reloc()
    : rel_()
  { }

  // A reloc against a global symbol.

  Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
	       Address address, Addend addend, bool is_relative,
	       bool is_symbolless, bool use_plt_offset)
    : rel_(gsym, type, od, address, is_relative, is_symbolless,
	   use_plt_offset),
      addend_(addend)
  { }

  Output_reloc(Symbol* gsym, unsigned int type,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address, Addend addend,
	       bool is_relative, bool is_symbolless, bool use_plt_offset)
    : rel_(gsym, type, relobj, shndx, address, is_relative,
	   is_symbolless, use_plt_offset), addend_(addend)
  { }

  // A reloc against a local symbol.

  Output_reloc(Sized_relobj<size, big_endian>* relobj,
	       unsigned int local_sym_index, unsigned int type,
	       Output_data* od, Address address,
	       Addend addend, bool is_relative,
	       bool is_symbolless, bool is_section_symbol,
	       bool use_plt_offset)
    : rel_(relobj, local_sym_index, type, od, address, is_relative,
	   is_symbolless, is_section_symbol, use_plt_offset),
      addend_(addend)
  { }

  Output_reloc(Sized_relobj<size, big_endian>* relobj,
	       unsigned int local_sym_index, unsigned int type,
	       unsigned int shndx, Address address,
	       Addend addend, bool is_relative,
	       bool is_symbolless, bool is_section_symbol,
	       bool use_plt_offset)
    : rel_(relobj, local_sym_index, type, shndx, address, is_relative,
	   is_symbolless, is_section_symbol, use_plt_offset),
      addend_(addend)
  { }

  // A reloc against the STT_SECTION symbol of an output section.

  Output_reloc(Output_section* os, unsigned int type, Output_data* od,
	       Address address, Addend addend, bool is_relative)
    : rel_(os, type, od, address, is_relative), addend_(addend)
  { }

  Output_reloc(Output_section* os, unsigned int type,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address, Addend addend,
	       bool is_relative)
    : rel_(os, type, relobj, shndx, address, is_relative), addend_(addend)
  { }

  // An absolute or relative relocation with no symbol.

  Output_reloc(unsigned int type, Output_data* od, Address address,
	       Addend addend, bool is_relative)
    : rel_(type, od, address, is_relative), addend_(addend)
  { }

  Output_reloc(unsigned int type, Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address, Addend addend,
	       bool is_relative)
    : rel_(type, relobj, shndx, address, is_relative), addend_(addend)
  { }

  // A target specific relocation.  The target will be called to get
  // the symbol index and the addend, passing ARG.  The type and
  // offset will be set as for other relocation types.

  Output_reloc(unsigned int type, void* arg, Output_data* od,
	       Address address, Addend addend)
    : rel_(type, arg, od, address), addend_(addend)
  { }

  Output_reloc(unsigned int type, void* arg,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address, Addend addend)
    : rel_(type, arg, relobj, shndx, address), addend_(addend)
  { }

  // Return whether this is a RELATIVE relocation.
  bool
  is_relative() const
  { return this->rel_.is_relative(); }

  // Return whether this is a relocation which should not use
  // a symbol, but which obtains its addend from a symbol.
  bool
  is_symbolless() const
  { return this->rel_.is_symbolless(); }

  // If this relocation is against an input section, return the
  // relocatable object containing the input section.
  Sized_relobj<size, big_endian>*
  get_relobj() const
  { return this->rel_.get_relobj(); }

  // Write the reloc entry to an output view.
  void
  write(unsigned char* pov) const;

  // Return whether this reloc should be sorted before the argument
  // when sorting dynamic relocs.
  bool
  sort_before(const Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>&
	      r2) const
  {
    int i = this->rel_.compare(r2.rel_);
    if (i < 0)
      return true;
    else if (i > 0)
      return false;
    else
      return this->addend_ < r2.addend_;
  }

 private:
  // The basic reloc.
  Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> rel_;
  // The addend.
  Addend addend_;
};

// Output_data_reloc_generic is a non-template base class for
// Output_data_reloc_base.  This gives the generic code a way to hold
// a pointer to a reloc section.

class Output_data_reloc_generic : public Output_section_data_build
{
 public:
  Output_data_reloc_generic(int size, bool sort_relocs)
    : Output_section_data_build(Output_data::default_alignment_for_size(size)),
      relative_reloc_count_(0), sort_relocs_(sort_relocs)
  { }

  // Return the number of relative relocs in this section.
  size_t
  relative_reloc_count() const
  { return this->relative_reloc_count_; }

  // Whether we should sort the relocs.
  bool
  sort_relocs() const
  { return this->sort_relocs_; }

  // Add a reloc of type TYPE against the global symbol GSYM.  The
  // relocation applies to the data at offset ADDRESS within OD.
  virtual void
  add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
		     uint64_t address, uint64_t addend) = 0;

  // Add a reloc of type TYPE against the global symbol GSYM.  The
  // relocation applies to data at offset ADDRESS within section SHNDX
  // of object file RELOBJ.  OD is the associated output section.
  virtual void
  add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
		     Relobj* relobj, unsigned int shndx, uint64_t address,
		     uint64_t addend) = 0;

  // Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX
  // in RELOBJ.  The relocation applies to the data at offset ADDRESS
  // within OD.
  virtual void
  add_local_generic(Relobj* relobj, unsigned int local_sym_index,
		    unsigned int type, Output_data* od, uint64_t address,
		    uint64_t addend) = 0;

  // Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX
  // in RELOBJ.  The relocation applies to the data at offset ADDRESS
  // within section SHNDX of RELOBJ.  OD is the associated output
  // section.
  virtual void
  add_local_generic(Relobj* relobj, unsigned int local_sym_index,
		    unsigned int type, Output_data* od, unsigned int shndx,
		    uint64_t address, uint64_t addend) = 0;

  // Add a reloc of type TYPE against the STT_SECTION symbol of the
  // output section OS.  The relocation applies to the data at offset
  // ADDRESS within OD.
  virtual void
  add_output_section_generic(Output_section *os, unsigned int type,
			     Output_data* od, uint64_t address,
			     uint64_t addend) = 0;

  // Add a reloc of type TYPE against the STT_SECTION symbol of the
  // output section OS.  The relocation applies to the data at offset
  // ADDRESS within section SHNDX of RELOBJ.  OD is the associated
  // output section.
  virtual void
  add_output_section_generic(Output_section* os, unsigned int type,
			     Output_data* od, Relobj* relobj,
			     unsigned int shndx, uint64_t address,
			     uint64_t addend) = 0;

 protected:
  // Note that we've added another relative reloc.
  void
  bump_relative_reloc_count()
  { ++this->relative_reloc_count_; }

 private:
  // The number of relative relocs added to this section.  This is to
  // support DT_RELCOUNT.
  size_t relative_reloc_count_;
  // Whether to sort the relocations when writing them out, to make
  // the dynamic linker more efficient.
  bool sort_relocs_;
};

// Output_data_reloc is used to manage a section containing relocs.
// SH_TYPE is either elfcpp::SHT_REL or elfcpp::SHT_RELA.  DYNAMIC
// indicates whether this is a dynamic relocation or a normal
// relocation.  Output_data_reloc_base is a base class.
// Output_data_reloc is the real class, which we specialize based on
// the reloc type.

template<int sh_type, bool dynamic, int size, bool big_endian>
class Output_data_reloc_base : public Output_data_reloc_generic
{
 public:
  typedef Output_reloc<sh_type, dynamic, size, big_endian> Output_reloc_type;
  typedef typename Output_reloc_type::Address Address;
  static const int reloc_size =
    Reloc_types<sh_type, size, big_endian>::reloc_size;

  // Construct the section.
  Output_data_reloc_base(bool sort_relocs)
    : Output_data_reloc_generic(size, sort_relocs)
  { }

 protected:
  // Write out the data.
  void
  do_write(Output_file*);

  // Generic implementation of do_write, allowing a customized
  // class for writing the output relocation (e.g., for MIPS-64).
  template<class Output_reloc_writer>
  void
  do_write_generic(Output_file* of)
  {
    const off_t off = this->offset();
    const off_t oview_size = this->data_size();
    unsigned char* const oview = of->get_output_view(off, oview_size);

    if (this->sort_relocs())
      {
	gold_assert(dynamic);
	std::sort(this->relocs_.begin(), this->relocs_.end(),
		  Sort_relocs_comparison());
      }

    unsigned char* pov = oview;
    for (typename Relocs::const_iterator p = this->relocs_.begin();
	 p != this->relocs_.end();
	 ++p)
      {
	Output_reloc_writer::write(p, pov);
	pov += reloc_size;
      }

    gold_assert(pov - oview == oview_size);

    of->write_output_view(off, oview_size, oview);

    // We no longer need the relocation entries.
    this->relocs_.clear();
  }

  // Set the entry size and the link.
  void
  do_adjust_output_section(Output_section* os);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  {
    mapfile->print_output_data(this,
			       (dynamic
				? _("** dynamic relocs")
				: _("** relocs")));
  }

  // Add a relocation entry.
  void
  add(Output_data* od, const Output_reloc_type& reloc)
  {
    this->relocs_.push_back(reloc);
    this->set_current_data_size(this->relocs_.size() * reloc_size);
    if (dynamic)
      od->add_dynamic_reloc();
    if (reloc.is_relative())
      this->bump_relative_reloc_count();
    Sized_relobj<size, big_endian>* relobj = reloc.get_relobj();
    if (relobj != NULL)
      relobj->add_dyn_reloc(this->relocs_.size() - 1);
  }

 private:
  typedef std::vector<Output_reloc_type> Relocs;

  // The class used to sort the relocations.
  struct Sort_relocs_comparison
  {
    bool
    operator()(const Output_reloc_type& r1, const Output_reloc_type& r2) const
    { return r1.sort_before(r2); }
  };

  // The relocations in this section.
  Relocs relocs_;
};

// The class which callers actually create.

template<int sh_type, bool dynamic, int size, bool big_endian>
class Output_data_reloc;

// The SHT_REL version of Output_data_reloc.

template<bool dynamic, int size, bool big_endian>
class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
  : public Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian>
{
 private:
  typedef Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size,
				 big_endian> Base;

 public:
  typedef typename Base::Output_reloc_type Output_reloc_type;
  typedef typename Output_reloc_type::Address Address;

  Output_data_reloc(bool sr)
    : Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian>(sr)
  { }

  // Add a reloc against a global symbol.

  void
  add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address)
  {
    this->add(od, Output_reloc_type(gsym, type, od, address,
				    false, false, false));
  }

  void
  add_global(Symbol* gsym, unsigned int type, Output_data* od,
	     Sized_relobj<size, big_endian>* relobj,
	     unsigned int shndx, Address address)
  {
    this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
				    false, false, false));
  }

  void
  add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
		     uint64_t address, uint64_t addend)
  {
    gold_assert(addend == 0);
    this->add(od, Output_reloc_type(gsym, type, od,
				    convert_types<Address, uint64_t>(address),
				    false, false, false));
  }

  void
  add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
		     Relobj* relobj, unsigned int shndx, uint64_t address,
		     uint64_t addend)
  {
    gold_assert(addend == 0);
    Sized_relobj<size, big_endian>* sized_relobj =
      static_cast<Sized_relobj<size, big_endian>*>(relobj);
    this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx,
				    convert_types<Address, uint64_t>(address),
				    false, false, false));
  }

  // Add a RELATIVE reloc against a global symbol.  The final relocation
  // will not reference the symbol.

  void
  add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
		      Address address)
  {
    this->add(od, Output_reloc_type(gsym, type, od, address, true, true,
				    false));
  }

  void
  add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
		      Sized_relobj<size, big_endian>* relobj,
		      unsigned int shndx, Address address)
  {
    this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
				    true, true, false));
  }

  // Add a global relocation which does not use a symbol for the relocation,
  // but which gets its addend from a symbol.

  void
  add_symbolless_global_addend(Symbol* gsym, unsigned int type,
			       Output_data* od, Address address)
  {
    this->add(od, Output_reloc_type(gsym, type, od, address, false, true,
				    false));
  }

  void
  add_symbolless_global_addend(Symbol* gsym, unsigned int type,
			       Output_data* od,
			       Sized_relobj<size, big_endian>* relobj,
			       unsigned int shndx, Address address)
  {
    this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
				    false, true, false));
  }

  // Add a reloc against a local symbol.

  void
  add_local(Sized_relobj<size, big_endian>* relobj,
	    unsigned int local_sym_index, unsigned int type,
	    Output_data* od, Address address)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
				    address, false, false, false, false));
  }

  void
  add_local(Sized_relobj<size, big_endian>* relobj,
	    unsigned int local_sym_index, unsigned int type,
	    Output_data* od, unsigned int shndx, Address address)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
				    address, false, false, false, false));
  }

  void
  add_local_generic(Relobj* relobj, unsigned int local_sym_index,
		    unsigned int type, Output_data* od, uint64_t address,
		    uint64_t addend)
  {
    gold_assert(addend == 0);
    Sized_relobj<size, big_endian>* sized_relobj =
      static_cast<Sized_relobj<size, big_endian> *>(relobj);
    this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od,
				    convert_types<Address, uint64_t>(address),
				    false, false, false, false));
  }

  void
  add_local_generic(Relobj* relobj, unsigned int local_sym_index,
		    unsigned int type, Output_data* od, unsigned int shndx,
		    uint64_t address, uint64_t addend)
  {
    gold_assert(addend == 0);
    Sized_relobj<size, big_endian>* sized_relobj =
      static_cast<Sized_relobj<size, big_endian>*>(relobj);
    this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx,
				    convert_types<Address, uint64_t>(address),
				    false, false, false, false));
  }

  // Add a RELATIVE reloc against a local symbol.

  void
  add_local_relative(Sized_relobj<size, big_endian>* relobj,
		     unsigned int local_sym_index, unsigned int type,
		     Output_data* od, Address address)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
				    address, true, true, false, false));
  }

  void
  add_local_relative(Sized_relobj<size, big_endian>* relobj,
		     unsigned int local_sym_index, unsigned int type,
		     Output_data* od, unsigned int shndx, Address address)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
				    address, true, true, false, false));
  }

  void
  add_local_relative(Sized_relobj<size, big_endian>* relobj,
		     unsigned int local_sym_index, unsigned int type,
		     Output_data* od, unsigned int shndx, Address address,
		     bool use_plt_offset)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
				    address, true, true, false,
				    use_plt_offset));
  }

  // Add a local relocation which does not use a symbol for the relocation,
  // but which gets its addend from a symbol.

  void
  add_symbolless_local_addend(Sized_relobj<size, big_endian>* relobj,
			      unsigned int local_sym_index, unsigned int type,
			      Output_data* od, Address address)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, od,
				    address, false, true, false, false));
  }

  void
  add_symbolless_local_addend(Sized_relobj<size, big_endian>* relobj,
			      unsigned int local_sym_index, unsigned int type,
			      Output_data* od, unsigned int shndx,
			      Address address)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
				    address, false, true, false, false));
  }

  // Add a reloc against a local section symbol.  This will be
  // converted into a reloc against the STT_SECTION symbol of the
  // output section.

  void
  add_local_section(Sized_relobj<size, big_endian>* relobj,
		    unsigned int input_shndx, unsigned int type,
		    Output_data* od, Address address)
  {
    this->add(od, Output_reloc_type(relobj, input_shndx, type, od,
				    address, false, false, true, false));
  }

  void
  add_local_section(Sized_relobj<size, big_endian>* relobj,
		    unsigned int input_shndx, unsigned int type,
		    Output_data* od, unsigned int shndx, Address address)
  {
    this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx,
				    address, false, false, true, false));
  }

  // A reloc against the STT_SECTION symbol of an output section.
  // OS is the Output_section that the relocation refers to; OD is
  // the Output_data object being relocated.

  void
  add_output_section(Output_section* os, unsigned int type,
		     Output_data* od, Address address)
  { this->add(od, Output_reloc_type(os, type, od, address, false)); }

  void
  add_output_section(Output_section* os, unsigned int type, Output_data* od,
		     Sized_relobj<size, big_endian>* relobj,
		     unsigned int shndx, Address address)
  { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, false)); }

  void
  add_output_section_generic(Output_section* os, unsigned int type,
			     Output_data* od, uint64_t address,
			     uint64_t addend)
  {
    gold_assert(addend == 0);
    this->add(od, Output_reloc_type(os, type, od,
				    convert_types<Address, uint64_t>(address),
				    false));
  }

  void
  add_output_section_generic(Output_section* os, unsigned int type,
			     Output_data* od, Relobj* relobj,
			     unsigned int shndx, uint64_t address,
			     uint64_t addend)
  {
    gold_assert(addend == 0);
    Sized_relobj<size, big_endian>* sized_relobj =
      static_cast<Sized_relobj<size, big_endian>*>(relobj);
    this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
				    convert_types<Address, uint64_t>(address),
				    false));
  }

  // As above, but the reloc TYPE is relative

  void
  add_output_section_relative(Output_section* os, unsigned int type,
			      Output_data* od, Address address)
  { this->add(od, Output_reloc_type(os, type, od, address, true)); }

  void
  add_output_section_relative(Output_section* os, unsigned int type,
			      Output_data* od,
			      Sized_relobj<size, big_endian>* relobj,
			      unsigned int shndx, Address address)
  { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, true)); }

  // Add an absolute relocation.

  void
  add_absolute(unsigned int type, Output_data* od, Address address)
  { this->add(od, Output_reloc_type(type, od, address, false)); }

  void
  add_absolute(unsigned int type, Output_data* od,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address)
  { this->add(od, Output_reloc_type(type, relobj, shndx, address, false)); }

  // Add a relative relocation

  void
  add_relative(unsigned int type, Output_data* od, Address address)
  { this->add(od, Output_reloc_type(type, od, address, true)); }

  void
  add_relative(unsigned int type, Output_data* od,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address)
  { this->add(od, Output_reloc_type(type, relobj, shndx, address, true)); }

  // Add a target specific relocation.  A target which calls this must
  // define the reloc_symbol_index and reloc_addend virtual functions.

  void
  add_target_specific(unsigned int type, void* arg, Output_data* od,
		      Address address)
  { this->add(od, Output_reloc_type(type, arg, od, address)); }

  void
  add_target_specific(unsigned int type, void* arg, Output_data* od,
		      Sized_relobj<size, big_endian>* relobj,
		      unsigned int shndx, Address address)
  { this->add(od, Output_reloc_type(type, arg, relobj, shndx, address)); }
};

// The SHT_RELA version of Output_data_reloc.

template<bool dynamic, int size, bool big_endian>
class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
  : public Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian>
{
 private:
  typedef Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size,
				 big_endian> Base;

 public:
  typedef typename Base::Output_reloc_type Output_reloc_type;
  typedef typename Output_reloc_type::Address Address;
  typedef typename Output_reloc_type::Addend Addend;

  Output_data_reloc(bool sr)
    : Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian>(sr)
  { }

  // Add a reloc against a global symbol.

  void
  add_global(Symbol* gsym, unsigned int type, Output_data* od,
	     Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(gsym, type, od, address, addend,
				    false, false, false));
  }

  void
  add_global(Symbol* gsym, unsigned int type, Output_data* od,
	     Sized_relobj<size, big_endian>* relobj,
	     unsigned int shndx, Address address,
	     Addend addend)
  {
    this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
				    addend, false, false, false));
  }

  void
  add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
		     uint64_t address, uint64_t addend)
  {
    this->add(od, Output_reloc_type(gsym, type, od,
				    convert_types<Address, uint64_t>(address),
				    convert_types<Addend, uint64_t>(addend),
				    false, false, false));
  }

  void
  add_global_generic(Symbol* gsym, unsigned int type, Output_data* od,
		     Relobj* relobj, unsigned int shndx, uint64_t address,
		     uint64_t addend)
  {
    Sized_relobj<size, big_endian>* sized_relobj =
      static_cast<Sized_relobj<size, big_endian>*>(relobj);
    this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx,
				    convert_types<Address, uint64_t>(address),
				    convert_types<Addend, uint64_t>(addend),
				    false, false, false));
  }

  // Add a RELATIVE reloc against a global symbol.  The final output
  // relocation will not reference the symbol, but we must keep the symbol
  // information long enough to set the addend of the relocation correctly
  // when it is written.

  void
  add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
		      Address address, Addend addend, bool use_plt_offset)
  {
    this->add(od, Output_reloc_type(gsym, type, od, address, addend, true,
				    true, use_plt_offset));
  }

  void
  add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
		      Sized_relobj<size, big_endian>* relobj,
		      unsigned int shndx, Address address, Addend addend,
		      bool use_plt_offset)
  {
    this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
				    addend, true, true, use_plt_offset));
  }

  // Add a global relocation which does not use a symbol for the relocation,
  // but which gets its addend from a symbol.

  void
  add_symbolless_global_addend(Symbol* gsym, unsigned int type, Output_data* od,
			       Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(gsym, type, od, address, addend,
				    false, true, false));
  }

  void
  add_symbolless_global_addend(Symbol* gsym, unsigned int type,
			       Output_data* od,
			       Sized_relobj<size, big_endian>* relobj,
			       unsigned int shndx, Address address,
			       Addend addend)
  {
    this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
				    addend, false, true, false));
  }

  // Add a reloc against a local symbol.

  void
  add_local(Sized_relobj<size, big_endian>* relobj,
	    unsigned int local_sym_index, unsigned int type,
	    Output_data* od, Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
				    addend, false, false, false, false));
  }

  void
  add_local(Sized_relobj<size, big_endian>* relobj,
	    unsigned int local_sym_index, unsigned int type,
	    Output_data* od, unsigned int shndx, Address address,
	    Addend addend)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
				    address, addend, false, false, false,
				    false));
  }

  void
  add_local_generic(Relobj* relobj, unsigned int local_sym_index,
		    unsigned int type, Output_data* od, uint64_t address,
		    uint64_t addend)
  {
    Sized_relobj<size, big_endian>* sized_relobj =
      static_cast<Sized_relobj<size, big_endian> *>(relobj);
    this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od,
				    convert_types<Address, uint64_t>(address),
				    convert_types<Addend, uint64_t>(addend),
				    false, false, false, false));
  }

  void
  add_local_generic(Relobj* relobj, unsigned int local_sym_index,
		    unsigned int type, Output_data* od, unsigned int shndx,
		    uint64_t address, uint64_t addend)
  {
    Sized_relobj<size, big_endian>* sized_relobj =
      static_cast<Sized_relobj<size, big_endian>*>(relobj);
    this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx,
				    convert_types<Address, uint64_t>(address),
				    convert_types<Addend, uint64_t>(addend),
				    false, false, false, false));
  }

  // Add a RELATIVE reloc against a local symbol.

  void
  add_local_relative(Sized_relobj<size, big_endian>* relobj,
		     unsigned int local_sym_index, unsigned int type,
		     Output_data* od, Address address, Addend addend,
		     bool use_plt_offset)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
				    addend, true, true, false,
				    use_plt_offset));
  }

  void
  add_local_relative(Sized_relobj<size, big_endian>* relobj,
		     unsigned int local_sym_index, unsigned int type,
		     Output_data* od, unsigned int shndx, Address address,
		     Addend addend, bool use_plt_offset)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
				    address, addend, true, true, false,
				    use_plt_offset));
  }

  // Add a local relocation which does not use a symbol for the relocation,
  // but which gets it's addend from a symbol.

  void
  add_symbolless_local_addend(Sized_relobj<size, big_endian>* relobj,
			      unsigned int local_sym_index, unsigned int type,
			      Output_data* od, Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address,
				    addend, false, true, false, false));
  }

  void
  add_symbolless_local_addend(Sized_relobj<size, big_endian>* relobj,
			      unsigned int local_sym_index, unsigned int type,
			      Output_data* od, unsigned int shndx,
			      Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx,
				    address, addend, false, true, false,
				    false));
  }

  // Add a reloc against a local section symbol.  This will be
  // converted into a reloc against the STT_SECTION symbol of the
  // output section.

  void
  add_local_section(Sized_relobj<size, big_endian>* relobj,
		    unsigned int input_shndx, unsigned int type,
		    Output_data* od, Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(relobj, input_shndx, type, od, address,
				    addend, false, false, true, false));
  }

  void
  add_local_section(Sized_relobj<size, big_endian>* relobj,
		    unsigned int input_shndx, unsigned int type,
		    Output_data* od, unsigned int shndx, Address address,
		    Addend addend)
  {
    this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx,
				    address, addend, false, false, true,
				    false));
  }

  // A reloc against the STT_SECTION symbol of an output section.

  void
  add_output_section(Output_section* os, unsigned int type, Output_data* od,
		     Address address, Addend addend)
  { this->add(od, Output_reloc_type(os, type, od, address, addend, false)); }

  void
  add_output_section(Output_section* os, unsigned int type, Output_data* od,
		     Sized_relobj<size, big_endian>* relobj,
		     unsigned int shndx, Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(os, type, relobj, shndx, address,
				    addend, false));
  }

  void
  add_output_section_generic(Output_section* os, unsigned int type,
			     Output_data* od, uint64_t address,
			     uint64_t addend)
  {
    this->add(od, Output_reloc_type(os, type, od,
				    convert_types<Address, uint64_t>(address),
				    convert_types<Addend, uint64_t>(addend),
				    false));
  }

  void
  add_output_section_generic(Output_section* os, unsigned int type,
			     Output_data* od, Relobj* relobj,
			     unsigned int shndx, uint64_t address,
			     uint64_t addend)
  {
    Sized_relobj<size, big_endian>* sized_relobj =
      static_cast<Sized_relobj<size, big_endian>*>(relobj);
    this->add(od, Output_reloc_type(os, type, sized_relobj, shndx,
				    convert_types<Address, uint64_t>(address),
				    convert_types<Addend, uint64_t>(addend),
				    false));
  }

  // As above, but the reloc TYPE is relative

  void
  add_output_section_relative(Output_section* os, unsigned int type,
			      Output_data* od, Address address, Addend addend)
  { this->add(od, Output_reloc_type(os, type, od, address, addend, true)); }

  void
  add_output_section_relative(Output_section* os, unsigned int type,
			      Output_data* od,
			      Sized_relobj<size, big_endian>* relobj,
			      unsigned int shndx, Address address,
			      Addend addend)
  {
    this->add(od, Output_reloc_type(os, type, relobj, shndx,
				    address, addend, true));
  }

  // Add an absolute relocation.

  void
  add_absolute(unsigned int type, Output_data* od, Address address,
	       Addend addend)
  { this->add(od, Output_reloc_type(type, od, address, addend, false)); }

  void
  add_absolute(unsigned int type, Output_data* od,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(type, relobj, shndx, address, addend,
				    false));
  }

  // Add a relative relocation

  void
  add_relative(unsigned int type, Output_data* od, Address address,
	       Addend addend)
  { this->add(od, Output_reloc_type(type, od, address, addend, true)); }

  void
  add_relative(unsigned int type, Output_data* od,
	       Sized_relobj<size, big_endian>* relobj,
	       unsigned int shndx, Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(type, relobj, shndx, address, addend,
				    true));
  }

  // Add a target specific relocation.  A target which calls this must
  // define the reloc_symbol_index and reloc_addend virtual functions.

  void
  add_target_specific(unsigned int type, void* arg, Output_data* od,
		      Address address, Addend addend)
  { this->add(od, Output_reloc_type(type, arg, od, address, addend)); }

  void
  add_target_specific(unsigned int type, void* arg, Output_data* od,
		      Sized_relobj<size, big_endian>* relobj,
		      unsigned int shndx, Address address, Addend addend)
  {
    this->add(od, Output_reloc_type(type, arg, relobj, shndx, address,
				    addend));
  }
};

// Output_relocatable_relocs represents a relocation section in a
// relocatable link.  The actual data is written out in the target
// hook relocate_relocs.  This just saves space for it.

template<int sh_type, int size, bool big_endian>
class Output_relocatable_relocs : public Output_section_data
{
 public:
  Output_relocatable_relocs(Relocatable_relocs* rr)
    : Output_section_data(Output_data::default_alignment_for_size(size)),
      rr_(rr)
  { }

  void
  set_final_data_size();

  // Write out the data.  There is nothing to do here.
  void
  do_write(Output_file*)
  { }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** relocs")); }

 private:
  // The relocs associated with this input section.
  Relocatable_relocs* rr_;
};

// Handle a GROUP section.

template<int size, bool big_endian>
class Output_data_group : public Output_section_data
{
 public:
  // The constructor clears *INPUT_SHNDXES.
  Output_data_group(Sized_relobj_file<size, big_endian>* relobj,
		    section_size_type entry_count,
		    elfcpp::Elf_Word flags,
		    std::vector<unsigned int>* input_shndxes);

  void
  do_write(Output_file*);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** group")); }

  // Set final data size.
  void
  set_final_data_size()
  { this->set_data_size((this->input_shndxes_.size() + 1) * 4); }

 private:
  // The input object.
  Sized_relobj_file<size, big_endian>* relobj_;
  // The group flag word.
  elfcpp::Elf_Word flags_;
  // The section indexes of the input sections in this group.
  std::vector<unsigned int> input_shndxes_;
};

// Output_data_got is used to manage a GOT.  Each entry in the GOT is
// for one symbol--either a global symbol or a local symbol in an
// object.  The target specific code adds entries to the GOT as
// needed.  The GOT_SIZE template parameter is the size in bits of a
// GOT entry, typically 32 or 64.

class Output_data_got_base : public Output_section_data_build
{
 public:
  Output_data_got_base(uint64_t align)
    : Output_section_data_build(align)
  { }

  Output_data_got_base(off_t data_size, uint64_t align)
    : Output_section_data_build(data_size, align)
  { }

  // Reserve the slot at index I in the GOT.
  void
  reserve_slot(unsigned int i)
  { this->do_reserve_slot(i); }

 protected:
  // Reserve the slot at index I in the GOT.
  virtual void
  do_reserve_slot(unsigned int i) = 0;
};

template<int got_size, bool big_endian>
class Output_data_got : public Output_data_got_base
{
 public:
  typedef typename elfcpp::Elf_types<got_size>::Elf_Addr Valtype;

  Output_data_got()
    : Output_data_got_base(Output_data::default_alignment_for_size(got_size)),
      entries_(), free_list_()
  { }

  Output_data_got(off_t data_size)
    : Output_data_got_base(data_size,
			   Output_data::default_alignment_for_size(got_size)),
      entries_(), free_list_()
  {
    // For an incremental update, we have an existing GOT section.
    // Initialize the list of entries and the free list.
    this->entries_.resize(data_size / (got_size / 8));
    this->free_list_.init(data_size, false);
  }

  // Add an entry for a global symbol to the GOT.  Return true if this
  // is a new GOT entry, false if the symbol was already in the GOT.
  bool
  add_global(Symbol* gsym, unsigned int got_type);

  // Like add_global, but use the PLT offset of the global symbol if
  // it has one.
  bool
  add_global_plt(Symbol* gsym, unsigned int got_type);

  // Like add_global, but for a TLS symbol where the value will be
  // offset using Target::tls_offset_for_global.
  bool
  add_global_tls(Symbol* gsym, unsigned int got_type)
  { return add_global_plt(gsym, got_type); }

  // Add an entry for a global symbol to the GOT, and add a dynamic
  // relocation of type R_TYPE for the GOT entry.
  void
  add_global_with_rel(Symbol* gsym, unsigned int got_type,
		      Output_data_reloc_generic* rel_dyn, unsigned int r_type);

  // Add a pair of entries for a global symbol to the GOT, and add
  // dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
  void
  add_global_pair_with_rel(Symbol* gsym, unsigned int got_type,
			   Output_data_reloc_generic* rel_dyn,
			   unsigned int r_type_1, unsigned int r_type_2);

  // Add an entry for a local symbol to the GOT.  This returns true if
  // this is a new GOT entry, false if the symbol already has a GOT
  // entry.
  bool
  add_local(Relobj* object, unsigned int sym_index, unsigned int got_type);

  // Add an entry for a local symbol plus ADDEND to the GOT.  This returns
  // true if this is a new GOT entry, false if the symbol already has a GOT
  // entry.
  bool
  add_local(Relobj* object, unsigned int sym_index, unsigned int got_type,
	    uint64_t addend);

  // Like add_local, but use the PLT offset of the local symbol if it
  // has one.
  bool
  add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type);

  // Like add_local, but for a TLS symbol where the value will be
  // offset using Target::tls_offset_for_local.
  bool
  add_local_tls(Relobj* object, unsigned int sym_index, unsigned int got_type)
  { return add_local_plt(object, sym_index, got_type); }

  // Add an entry for a local symbol to the GOT, and add a dynamic
  // relocation of type R_TYPE for the GOT entry.
  void
  add_local_with_rel(Relobj* object, unsigned int sym_index,
		     unsigned int got_type, Output_data_reloc_generic* rel_dyn,
		     unsigned int r_type);

  // Add an entry for a local symbol plus ADDEND to the GOT, and add a dynamic
  // relocation of type R_TYPE for the GOT entry.
  void
  add_local_with_rel(Relobj* object, unsigned int sym_index,
		     unsigned int got_type, Output_data_reloc_generic* rel_dyn,
		     unsigned int r_type, uint64_t addend);

  // Add a pair of entries for a local symbol to the GOT, and add
  // a dynamic relocation of type R_TYPE using the section symbol of
  // the output section to which input section SHNDX maps, on the first.
  // The first got entry will have a value of zero, the second the
  // value of the local symbol.
  void
  add_local_pair_with_rel(Relobj* object, unsigned int sym_index,
			  unsigned int shndx, unsigned int got_type,
			  Output_data_reloc_generic* rel_dyn,
			  unsigned int r_type);

  // Add a pair of entries for a local symbol plus ADDEND to the GOT, and add
  // a dynamic relocation of type R_TYPE using the section symbol of
  // the output section to which input section SHNDX maps, on the first.
  // The first got entry will have a value of zero, the second the
  // value of the local symbol.
  void
  add_local_pair_with_rel(Relobj* object, unsigned int sym_index,
			  unsigned int shndx, unsigned int got_type,
			  Output_data_reloc_generic* rel_dyn,
			  unsigned int r_type, uint64_t addend);

  // Add a pair of entries for a local symbol to the GOT, and add
  // a dynamic relocation of type R_TYPE using STN_UNDEF on the first.
  // The first got entry will have a value of zero, the second the
  // value of the local symbol offset by Target::tls_offset_for_local.
  void
  add_local_tls_pair(Relobj* object, unsigned int sym_index,
		     unsigned int got_type,
		     Output_data_reloc_generic* rel_dyn,
		     unsigned int r_type);

  // Add a constant to the GOT.  This returns the offset of the new
  // entry from the start of the GOT.
  unsigned int
  add_constant(Valtype constant)
  { return this->add_got_entry(Got_entry(constant)); }

  // Add a pair of constants to the GOT.  This returns the offset of
  // the new entry from the start of the GOT.
  unsigned int
  add_constant_pair(Valtype c1, Valtype c2)
  { return this->add_got_entry_pair(Got_entry(c1), Got_entry(c2)); }

  // Replace GOT entry I with a new constant.
  void
  replace_constant(unsigned int i, Valtype constant)
  {
    this->replace_got_entry(i, Got_entry(constant));
  }

  // Reserve a slot in the GOT for a local symbol.
  void
  reserve_local(unsigned int i, Relobj* object, unsigned int sym_index,
		unsigned int got_type);

  // Reserve a slot in the GOT for a global symbol.
  void
  reserve_global(unsigned int i, Symbol* gsym, unsigned int got_type);

 protected:
  // Write out the GOT table.
  void
  do_write(Output_file*);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** GOT")); }

  // Reserve the slot at index I in the GOT.
  virtual void
  do_reserve_slot(unsigned int i)
  { this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); }

  // Return the number of words in the GOT.
  unsigned int
  num_entries () const
  { return this->entries_.size(); }

  // Return the offset into the GOT of GOT entry I.
  unsigned int
  got_offset(unsigned int i) const
  { return i * (got_size / 8); }

 private:
  // This POD class holds a single GOT entry.
  class Got_entry
  {
   public:
    // Create a zero entry.
    Got_entry()
      : local_sym_index_(RESERVED_CODE), use_plt_or_tls_offset_(false),
	addend_(0)
    { this->u_.constant = 0; }

    // Create a global symbol entry.
    Got_entry(Symbol* gsym, bool use_plt_or_tls_offset)
      : local_sym_index_(GSYM_CODE),
	use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(0)
    { this->u_.gsym = gsym; }

    // Create a local symbol entry.
    Got_entry(Relobj* object, unsigned int local_sym_index,
	      bool use_plt_or_tls_offset)
      : local_sym_index_(local_sym_index),
	use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(0)
    {
      gold_assert(local_sym_index != GSYM_CODE
		  && local_sym_index != CONSTANT_CODE
		  && local_sym_index != RESERVED_CODE
		  && local_sym_index == this->local_sym_index_);
      this->u_.object = object;
    }

    // Create a local symbol entry plus addend.
    Got_entry(Relobj* object, unsigned int local_sym_index,
	bool use_plt_or_tls_offset, uint64_t addend)
      : local_sym_index_(local_sym_index),
	use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(addend)
    {
      gold_assert(local_sym_index != GSYM_CODE
      && local_sym_index != CONSTANT_CODE
      && local_sym_index != RESERVED_CODE
      && local_sym_index == this->local_sym_index_);
      this->u_.object = object;
    }

    // Create a constant entry.  The constant is a host value--it will
    // be swapped, if necessary, when it is written out.
    explicit Got_entry(Valtype constant)
      : local_sym_index_(CONSTANT_CODE), use_plt_or_tls_offset_(false)
    { this->u_.constant = constant; }

    // Write the GOT entry to an output view.
    void
    write(unsigned int got_indx, unsigned char* pov) const;

   private:
    enum
    {
      GSYM_CODE = 0x7fffffff,
      CONSTANT_CODE = 0x7ffffffe,
      RESERVED_CODE = 0x7ffffffd
    };

    union
    {
      // For a local symbol, the object.
      Relobj* object;
      // For a global symbol, the symbol.
      Symbol* gsym;
      // For a constant, the constant.
      Valtype constant;
    } u_;
    // For a local symbol, the local symbol index.  This is GSYM_CODE
    // for a global symbol, or CONSTANT_CODE for a constant.
    unsigned int local_sym_index_ : 31;
    // Whether to use the PLT offset of the symbol if it has one.
    // For TLS symbols, whether to offset the symbol value.
    bool use_plt_or_tls_offset_ : 1;
    // The addend.
    uint64_t addend_;
  };

  typedef std::vector<Got_entry> Got_entries;

  // Create a new GOT entry and return its offset.
  unsigned int
  add_got_entry(Got_entry got_entry);

  // Create a pair of new GOT entries and return the offset of the first.
  unsigned int
  add_got_entry_pair(Got_entry got_entry_1, Got_entry got_entry_2);

  // Replace GOT entry I with a new value.
  void
  replace_got_entry(unsigned int i, Got_entry got_entry);

  // Return the offset into the GOT of the last entry added.
  unsigned int
  last_got_offset() const
  { return this->got_offset(this->num_entries() - 1); }

  // Set the size of the section.
  void
  set_got_size()
  { this->set_current_data_size(this->got_offset(this->num_entries())); }

  // The list of GOT entries.
  Got_entries entries_;

  // List of available regions within the section, for incremental
  // update links.
  Free_list free_list_;
};

// Output_data_dynamic is used to hold the data in SHT_DYNAMIC
// section.

class Output_data_dynamic : public Output_section_data
{
 public:
  Output_data_dynamic(Stringpool* pool)
    : Output_section_data(Output_data::default_alignment()),
      entries_(), pool_(pool)
  { }

  // Add a new dynamic entry with a fixed numeric value.
  void
  add_constant(elfcpp::DT tag, unsigned int val)
  { this->add_entry(Dynamic_entry(tag, val)); }

  // Add a new dynamic entry with the address of output data.
  void
  add_section_address(elfcpp::DT tag, const Output_data* od)
  { this->add_entry(Dynamic_entry(tag, od, false)); }

  // Add a new dynamic entry with the address of output data
  // plus a constant offset.
  void
  add_section_plus_offset(elfcpp::DT tag, const Output_data* od,
			  unsigned int offset)
  { this->add_entry(Dynamic_entry(tag, od, offset)); }

  // Add a new dynamic entry with the size of output data.
  void
  add_section_size(elfcpp::DT tag, const Output_data* od)
  { this->add_entry(Dynamic_entry(tag, od, true)); }

  // Add a new dynamic entry with the total size of two output datas.
  void
  add_section_size(elfcpp::DT tag, const Output_data* od,
		   const Output_data* od2)
  { this->add_entry(Dynamic_entry(tag, od, od2)); }

  // Add a new dynamic entry with the address of a symbol.
  void
  add_symbol(elfcpp::DT tag, const Symbol* sym)
  { this->add_entry(Dynamic_entry(tag, sym)); }

  // Add a new dynamic entry with a string.
  void
  add_string(elfcpp::DT tag, const char* str)
  { this->add_entry(Dynamic_entry(tag, this->pool_->add(str, true, NULL))); }

  void
  add_string(elfcpp::DT tag, const std::string& str)
  { this->add_string(tag, str.c_str()); }

  // Add a new dynamic entry with custom value.
  void
  add_custom(elfcpp::DT tag)
  { this->add_entry(Dynamic_entry(tag)); }

  // Get a dynamic entry offset.
  unsigned int
  get_entry_offset(elfcpp::DT tag) const;

 protected:
  // Adjust the output section to set the entry size.
  void
  do_adjust_output_section(Output_section*);

  // Set the final data size.
  void
  set_final_data_size();

  // Write out the dynamic entries.
  void
  do_write(Output_file*);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** dynamic")); }

 private:
  // This POD class holds a single dynamic entry.
  class Dynamic_entry
  {
   public:
    // Create an entry with a fixed numeric value.
    Dynamic_entry(elfcpp::DT tag, unsigned int val)
      : tag_(tag), offset_(DYNAMIC_NUMBER)
    { this->u_.val = val; }

    // Create an entry with the size or address of a section.
    Dynamic_entry(elfcpp::DT tag, const Output_data* od, bool section_size)
      : tag_(tag),
	offset_(section_size
		? DYNAMIC_SECTION_SIZE
		: DYNAMIC_SECTION_ADDRESS)
    {
      this->u_.od = od;
      this->od2 = NULL;
    }

    // Create an entry with the size of two sections.
    Dynamic_entry(elfcpp::DT tag, const Output_data* od, const Output_data* od2)
      : tag_(tag),
	offset_(DYNAMIC_SECTION_SIZE)
    {
      this->u_.od = od;
      this->od2 = od2;
    }

    // Create an entry with the address of a section plus a constant offset.
    Dynamic_entry(elfcpp::DT tag, const Output_data* od, unsigned int offset)
      : tag_(tag),
	offset_(offset)
    { this->u_.od = od; }

    // Create an entry with the address of a symbol.
    Dynamic_entry(elfcpp::DT tag, const Symbol* sym)
      : tag_(tag), offset_(DYNAMIC_SYMBOL)
    { this->u_.sym = sym; }

    // Create an entry with a string.
    Dynamic_entry(elfcpp::DT tag, const char* str)
      : tag_(tag), offset_(DYNAMIC_STRING)
    { this->u_.str = str; }

    // Create an entry with a custom value.
    Dynamic_entry(elfcpp::DT tag)
      : tag_(tag), offset_(DYNAMIC_CUSTOM)
    { }

    // Return the tag of this entry.
    elfcpp::DT
    tag() const
    { return this->tag_; }

    // Write the dynamic entry to an output view.
    template<int size, bool big_endian>
    void
    write(unsigned char* pov, const Stringpool*) const;

   private:
    // Classification is encoded in the OFFSET field.
    enum Classification
    {
      // Section address.
      DYNAMIC_SECTION_ADDRESS = 0,
      // Number.
      DYNAMIC_NUMBER = -1U,
      // Section size.
      DYNAMIC_SECTION_SIZE = -2U,
      // Symbol adress.
      DYNAMIC_SYMBOL = -3U,
      // String.
      DYNAMIC_STRING = -4U,
      // Custom value.
      DYNAMIC_CUSTOM = -5U
      // Any other value indicates a section address plus OFFSET.
    };

    union
    {
      // For DYNAMIC_NUMBER.
      unsigned int val;
      // For DYNAMIC_SECTION_SIZE and section address plus OFFSET.
      const Output_data* od;
      // For DYNAMIC_SYMBOL.
      const Symbol* sym;
      // For DYNAMIC_STRING.
      const char* str;
    } u_;
    // For DYNAMIC_SYMBOL with two sections.
    const Output_data* od2;
    // The dynamic tag.
    elfcpp::DT tag_;
    // The type of entry (Classification) or offset within a section.
    unsigned int offset_;
  };

  // Add an entry to the list.
  void
  add_entry(const Dynamic_entry& entry)
  { this->entries_.push_back(entry); }

  // Sized version of write function.
  template<int size, bool big_endian>
  void
  sized_write(Output_file* of);

  // The type of the list of entries.
  typedef std::vector<Dynamic_entry> Dynamic_entries;

  // The entries.
  Dynamic_entries entries_;
  // The pool used for strings.
  Stringpool* pool_;
};

// Output_symtab_xindex is used to handle SHT_SYMTAB_SHNDX sections,
// which may be required if the object file has more than
// SHN_LORESERVE sections.

class Output_symtab_xindex : public Output_section_data
{
 public:
  Output_symtab_xindex(size_t symcount)
    : Output_section_data(symcount * 4, 4, true),
      entries_()
  { }

  // Add an entry: symbol number SYMNDX has section SHNDX.
  void
  add(unsigned int symndx, unsigned int shndx)
  { this->entries_.push_back(std::make_pair(symndx, shndx)); }

 protected:
  void
  do_write(Output_file*);

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** symtab xindex")); }

 private:
  template<bool big_endian>
  void
  endian_do_write(unsigned char*);

  // It is likely that most symbols will not require entries.  Rather
  // than keep a vector for all symbols, we keep pairs of symbol index
  // and section index.
  typedef std::vector<std::pair<unsigned int, unsigned int> > Xindex_entries;

  // The entries we need.
  Xindex_entries entries_;
};

// A relaxed input section.
class Output_relaxed_input_section : public Output_section_data_build
{
 public:
  // We would like to call relobj->section_addralign(shndx) to get the
  // alignment but we do not want the constructor to fail.  So callers
  // are repsonsible for ensuring that.
  Output_relaxed_input_section(Relobj* relobj, unsigned int shndx,
			       uint64_t addralign)
    : Output_section_data_build(addralign), relobj_(relobj), shndx_(shndx)
  { }

  // Return the Relobj of this relaxed input section.
  Relobj*
  relobj() const
  { return this->relobj_; }

  // Return the section index of this relaxed input section.
  unsigned int
  shndx() const
  { return this->shndx_; }

 protected:
  void
  set_relobj(Relobj* relobj)
  { this->relobj_ = relobj; }

  void
  set_shndx(unsigned int shndx)
  { this->shndx_ = shndx; }

 private:
  Relobj* relobj_;
  unsigned int shndx_;
};

// This class describes properties of merge data sections.  It is used
// as a key type for maps.
class Merge_section_properties
{
 public:
  Merge_section_properties(bool is_string, uint64_t entsize,
			     uint64_t addralign)
    : is_string_(is_string), entsize_(entsize), addralign_(addralign)
  { }

  // Whether this equals to another Merge_section_properties MSP.
  bool
  eq(const Merge_section_properties& msp) const
  {
    return ((this->is_string_ == msp.is_string_)
	    && (this->entsize_ == msp.entsize_)
	    && (this->addralign_ == msp.addralign_));
  }

  // Compute a hash value for this using 64-bit FNV-1a hash.
  size_t
  hash_value() const
  {
    uint64_t h = 14695981039346656037ULL;	// FNV offset basis.
    uint64_t prime = 1099511628211ULL;
    h = (h ^ static_cast<uint64_t>(this->is_string_)) * prime;
    h = (h ^ static_cast<uint64_t>(this->entsize_)) * prime;
    h = (h ^ static_cast<uint64_t>(this->addralign_)) * prime;
    return h;
  }

  // Functors for associative containers.
  struct equal_to
  {
    bool
    operator()(const Merge_section_properties& msp1,
	       const Merge_section_properties& msp2) const
    { return msp1.eq(msp2); }
  };

  struct hash
  {
    size_t
    operator()(const Merge_section_properties& msp) const
    { return msp.hash_value(); }
  };

 private:
  // Whether this merge data section is for strings.
  bool is_string_;
  // Entsize of this merge data section.
  uint64_t entsize_;
  // Address alignment.
  uint64_t addralign_;
};

// This class is used to speed up look up of special input sections in an
// Output_section.

class Output_section_lookup_maps
{
 public:
  Output_section_lookup_maps()
    : is_valid_(true), merge_sections_by_properties_(),
      relaxed_input_sections_by_id_()
  { }

  // Whether the maps are valid.
  bool
  is_valid() const
  { return this->is_valid_; }

  // Invalidate the maps.
  void
  invalidate()
  { this->is_valid_ = false; }

  // Clear the maps.
  void
  clear()
  {
    this->merge_sections_by_properties_.clear();
    this->relaxed_input_sections_by_id_.clear();
    // A cleared map is valid.
    this->is_valid_ = true;
  }

  // Find a merge section by merge section properties.  Return NULL if none
  // is found.
  Output_merge_base*
  find_merge_section(const Merge_section_properties& msp) const
  {
    gold_assert(this->is_valid_);
    Merge_sections_by_properties::const_iterator p =
      this->merge_sections_by_properties_.find(msp);
    return p != this->merge_sections_by_properties_.end() ? p->second : NULL;
  }

  // Add a merge section pointed by POMB with properties MSP.
  void
  add_merge_section(const Merge_section_properties& msp,
		    Output_merge_base* pomb)
  {
    std::pair<Merge_section_properties, Output_merge_base*> value(msp, pomb);
    std::pair<Merge_sections_by_properties::iterator, bool> result =
      this->merge_sections_by_properties_.insert(value);
    gold_assert(result.second);
  }

  // Find a relaxed input section of OBJECT with index SHNDX.
  Output_relaxed_input_section*
  find_relaxed_input_section(const Relobj* object, unsigned int shndx) const
  {
    gold_assert(this->is_valid_);
    Relaxed_input_sections_by_id::const_iterator p =
      this->relaxed_input_sections_by_id_.find(Const_section_id(object, shndx));
    return p != this->relaxed_input_sections_by_id_.end() ? p->second : NULL;
  }

  // Add a relaxed input section pointed by POMB and whose original input
  // section is in OBJECT with index SHNDX.
  void
  add_relaxed_input_section(const Relobj* relobj, unsigned int shndx,
			    Output_relaxed_input_section* poris)
  {
    Const_section_id csid(relobj, shndx);
    std::pair<Const_section_id, Output_relaxed_input_section*>
      value(csid, poris);
    std::pair<Relaxed_input_sections_by_id::iterator, bool> result =
      this->relaxed_input_sections_by_id_.insert(value);
    gold_assert(result.second);
  }

 private:
  typedef Unordered_map<Merge_section_properties, Output_merge_base*,
			Merge_section_properties::hash,
			Merge_section_properties::equal_to>
    Merge_sections_by_properties;

  typedef Unordered_map<Const_section_id, Output_relaxed_input_section*,
			Const_section_id_hash>
    Relaxed_input_sections_by_id;

  // Whether this is valid
  bool is_valid_;
  // Merge sections by merge section properties.
  Merge_sections_by_properties merge_sections_by_properties_;
  // Relaxed sections by section IDs.
  Relaxed_input_sections_by_id relaxed_input_sections_by_id_;
};

// This abstract base class defines the interface for the
// types of methods used to fill free space left in an output
// section during an incremental link.  These methods are used
// to insert dummy compilation units into debug info so that
// debug info consumers can scan the debug info serially.

class Output_fill
{
 public:
  Output_fill()
    : is_big_endian_(parameters->target().is_big_endian())
  { }

  virtual
  ~Output_fill()
  { }

  // Return the smallest size chunk of free space that can be
  // filled with a dummy compilation unit.
  size_t
  minimum_hole_size() const
  { return this->do_minimum_hole_size(); }

  // Write a fill pattern of length LEN at offset OFF in the file.
  void
  write(Output_file* of, off_t off, size_t len) const
  { this->do_write(of, off, len); }

 protected:
  virtual size_t
  do_minimum_hole_size() const = 0;

  virtual void
  do_write(Output_file* of, off_t off, size_t len) const = 0;

  bool
  is_big_endian() const
  { return this->is_big_endian_; }

 private:
  bool is_big_endian_;
};

// Fill method that introduces a dummy compilation unit in
// a .debug_info or .debug_types section.

class Output_fill_debug_info : public Output_fill
{
 public:
  Output_fill_debug_info(bool is_debug_types)
    : is_debug_types_(is_debug_types)
  { }

 protected:
  virtual size_t
  do_minimum_hole_size() const;

  virtual void
  do_write(Output_file* of, off_t off, size_t len) const;

 private:
  // Version of the header.
  static const int version = 4;
  // True if this is a .debug_types section.
  bool is_debug_types_;
};

// Fill method that introduces a dummy compilation unit in
// a .debug_line section.

class Output_fill_debug_line : public Output_fill
{
 public:
  Output_fill_debug_line()
  { }

 protected:
  virtual size_t
  do_minimum_hole_size() const;

  virtual void
  do_write(Output_file* of, off_t off, size_t len) const;

 private:
  // Version of the header.  We write a DWARF-3 header because it's smaller
  // and many tools have not yet been updated to understand the DWARF-4 header.
  static const int version = 3;
  // Length of the portion of the header that follows the header_length
  // field.  This includes the following fields:
  // minimum_instruction_length, default_is_stmt, line_base, line_range,
  // opcode_base, standard_opcode_lengths[], include_directories, filenames.
  // The standard_opcode_lengths array is 12 bytes long, and the
  // include_directories and filenames fields each contain only a single
  // null byte.
  static const size_t header_length = 19;
};

// An output section.  We don't expect to have too many output
// sections, so we don't bother to do a template on the size.

class Output_section : public Output_data
{
 public:
  // Create an output section, giving the name, type, and flags.
  Output_section(const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword);
  virtual ~Output_section();

  // Add a new input section SHNDX, named NAME, with header SHDR, from
  // object OBJECT.  RELOC_SHNDX is the index of a relocation section
  // which applies to this section, or 0 if none, or -1 if more than
  // one.  HAVE_SECTIONS_SCRIPT is true if we have a SECTIONS clause
  // in a linker script; in that case we need to keep track of input
  // sections associated with an output section.  Return the offset
  // within the output section.
  template<int size, bool big_endian>
  off_t
  add_input_section(Layout* layout, Sized_relobj_file<size, big_endian>* object,
		    unsigned int shndx, const char* name,
		    const elfcpp::Shdr<size, big_endian>& shdr,
		    unsigned int reloc_shndx, bool have_sections_script);

  // Add generated data POSD to this output section.
  void
  add_output_section_data(Output_section_data* posd);

  // Add a relaxed input section PORIS called NAME to this output section
  // with LAYOUT.
  void
  add_relaxed_input_section(Layout* layout,
			    Output_relaxed_input_section* poris,
			    const std::string& name);

  // Return the section name.
  const char*
  name() const
  { return this->name_; }

  // Return the section type.
  elfcpp::Elf_Word
  type() const
  { return this->type_; }

  // Return the section flags.
  elfcpp::Elf_Xword
  flags() const
  { return this->flags_; }

  typedef std::map<Section_id, unsigned int> Section_layout_order;

  void
  update_section_layout(const Section_layout_order* order_map);

  // Update the output section flags based on input section flags.
  void
  update_flags_for_input_section(elfcpp::Elf_Xword flags);

  // Set the output section flags.
  void
  set_flags(elfcpp::Elf_Xword flags)
  { this->flags_ = flags; }

  // Return the entsize field.
  uint64_t
  entsize() const
  { return this->entsize_; }

  // Set the entsize field.
  void
  set_entsize(uint64_t v);

  // Set the load address.
  void
  set_load_address(uint64_t load_address)
  {
    this->load_address_ = load_address;
    this->has_load_address_ = true;
  }

  // Set the link field to the output section index of a section.
  void
  set_link_section(const Output_data* od)
  {
    gold_assert(this->link_ == 0
		&& !this->should_link_to_symtab_
		&& !this->should_link_to_dynsym_);
    this->link_section_ = od;
  }

  // Set the link field to a constant.
  void
  set_link(unsigned int v)
  {
    gold_assert(this->link_section_ == NULL
		&& !this->should_link_to_symtab_
		&& !this->should_link_to_dynsym_);
    this->link_ = v;
  }

  // Record that this section should link to the normal symbol table.
  void
  set_should_link_to_symtab()
  {
    gold_assert(this->link_section_ == NULL
		&& this->link_ == 0
		&& !this->should_link_to_dynsym_);
    this->should_link_to_symtab_ = true;
  }

  // Record that this section should link to the dynamic symbol table.
  void
  set_should_link_to_dynsym()
  {
    gold_assert(this->link_section_ == NULL
		&& this->link_ == 0
		&& !this->should_link_to_symtab_);
    this->should_link_to_dynsym_ = true;
  }

  // Return the info field.
  unsigned int
  info() const
  {
    gold_assert(this->info_section_ == NULL
		&& this->info_symndx_ == NULL);
    return this->info_;
  }

  // Set the info field to the output section index of a section.
  void
  set_info_section(const Output_section* os)
  {
    gold_assert((this->info_section_ == NULL
		 || (this->info_section_ == os
		     && this->info_uses_section_index_))
		&& this->info_symndx_ == NULL
		&& this->info_ == 0);
    this->info_section_ = os;
    this->info_uses_section_index_= true;
  }

  // Set the info field to the symbol table index of a symbol.
  void
  set_info_symndx(const Symbol* sym)
  {
    gold_assert(this->info_section_ == NULL
		&& (this->info_symndx_ == NULL
		    || this->info_symndx_ == sym)
		&& this->info_ == 0);
    this->info_symndx_ = sym;
  }

  // Set the info field to the symbol table index of a section symbol.
  void
  set_info_section_symndx(const Output_section* os)
  {
    gold_assert((this->info_section_ == NULL
		 || (this->info_section_ == os
		     && !this->info_uses_section_index_))
		&& this->info_symndx_ == NULL
		&& this->info_ == 0);
    this->info_section_ = os;
    this->info_uses_section_index_ = false;
  }

  // Set the info field to a constant.
  void
  set_info(unsigned int v)
  {
    gold_assert(this->info_section_ == NULL
		&& this->info_symndx_ == NULL
		&& (this->info_ == 0
		    || this->info_ == v));
    this->info_ = v;
  }

  // Set the addralign field.
  void
  set_addralign(uint64_t v)
  { this->addralign_ = v; }

  void
  checkpoint_set_addralign(uint64_t val)
  {
    if (this->checkpoint_ != NULL)
      this->checkpoint_->set_addralign(val);
  }

  // Whether the output section index has been set.
  bool
  has_out_shndx() const
  { return this->out_shndx_ != -1U; }

  // Indicate that we need a symtab index.
  void
  set_needs_symtab_index()
  { this->needs_symtab_index_ = true; }

  // Return whether we need a symtab index.
  bool
  needs_symtab_index() const
  { return this->needs_symtab_index_; }

  // Get the symtab index.
  unsigned int
  symtab_index() const
  {
    gold_assert(this->symtab_index_ != 0);
    return this->symtab_index_;
  }

  // Set the symtab index.
  void
  set_symtab_index(unsigned int index)
  {
    gold_assert(index != 0);
    this->symtab_index_ = index;
  }

  // Indicate that we need a dynsym index.
  void
  set_needs_dynsym_index()
  { this->needs_dynsym_index_ = true; }

  // Return whether we need a dynsym index.
  bool
  needs_dynsym_index() const
  { return this->needs_dynsym_index_; }

  // Get the dynsym index.
  unsigned int
  dynsym_index() const
  {
    gold_assert(this->dynsym_index_ != 0);
    return this->dynsym_index_;
  }

  // Set the dynsym index.
  void
  set_dynsym_index(unsigned int index)
  {
    gold_assert(index != 0);
    this->dynsym_index_ = index;
  }

  // Sort the attached input sections.
  void
  sort_attached_input_sections();

  // Return whether the input sections sections attachd to this output
  // section may require sorting.  This is used to handle constructor
  // priorities compatibly with GNU ld.
  bool
  may_sort_attached_input_sections() const
  { return this->may_sort_attached_input_sections_; }

  // Record that the input sections attached to this output section
  // may require sorting.
  void
  set_may_sort_attached_input_sections()
  { this->may_sort_attached_input_sections_ = true; }

   // Returns true if input sections must be sorted according to the
  // order in which their name appear in the --section-ordering-file.
  bool
  input_section_order_specified()
  { return this->input_section_order_specified_; }

  // Record that input sections must be sorted as some of their names
  // match the patterns specified through --section-ordering-file.
  void
  set_input_section_order_specified()
  { this->input_section_order_specified_ = true; }

  // Return whether the input sections attached to this output section
  // require sorting.  This is used to handle constructor priorities
  // compatibly with GNU ld.
  bool
  must_sort_attached_input_sections() const
  { return this->must_sort_attached_input_sections_; }

  // Record that the input sections attached to this output section
  // require sorting.
  void
  set_must_sort_attached_input_sections()
  { this->must_sort_attached_input_sections_ = true; }

  // Get the order in which this section appears in the PT_LOAD output
  // segment.
  Output_section_order
  order() const
  { return this->order_; }

  // Set the order for this section.
  void
  set_order(Output_section_order order)
  { this->order_ = order; }

  // Return whether this section holds relro data--data which has
  // dynamic relocations but which may be marked read-only after the
  // dynamic relocations have been completed.
  bool
  is_relro() const
  { return this->is_relro_; }

  // Record that this section holds relro data.
  void
  set_is_relro()
  { this->is_relro_ = true; }

  // Record that this section does not hold relro data.
  void
  clear_is_relro()
  { this->is_relro_ = false; }

  // True if this is a small section: a section which holds small
  // variables.
  bool
  is_small_section() const
  { return this->is_small_section_; }

  // Record that this is a small section.
  void
  set_is_small_section()
  { this->is_small_section_ = true; }

  // True if this is a large section: a section which holds large
  // variables.
  bool
  is_large_section() const
  { return this->is_large_section_; }

  // Record that this is a large section.
  void
  set_is_large_section()
  { this->is_large_section_ = true; }

  // True if this is a large data (not BSS) section.
  bool
  is_large_data_section()
  { return this->is_large_section_ && this->type_ != elfcpp::SHT_NOBITS; }

  // Return whether this section should be written after all the input
  // sections are complete.
  bool
  after_input_sections() const
  { return this->after_input_sections_; }

  // Record that this section should be written after all the input
  // sections are complete.
  void
  set_after_input_sections()
  { this->after_input_sections_ = true; }

  // Return whether this section requires postprocessing after all
  // relocations have been applied.
  bool
  requires_postprocessing() const
  { return this->requires_postprocessing_; }

  bool
  is_unique_segment() const
  { return this->is_unique_segment_; }

  void
  set_is_unique_segment()
  { this->is_unique_segment_ = true; }

  uint64_t extra_segment_flags() const
  { return this->extra_segment_flags_; }

  void
  set_extra_segment_flags(uint64_t flags)
  { this->extra_segment_flags_ = flags; }

  uint64_t segment_alignment() const
  { return this->segment_alignment_; }

  void
  set_segment_alignment(uint64_t align)
  { this->segment_alignment_ = align; }

  // If a section requires postprocessing, return the buffer to use.
  unsigned char*
  postprocessing_buffer() const
  {
    gold_assert(this->postprocessing_buffer_ != NULL);
    return this->postprocessing_buffer_;
  }

  // If a section requires postprocessing, create the buffer to use.
  void
  create_postprocessing_buffer();

  // If a section requires postprocessing, this is the size of the
  // buffer to which relocations should be applied.
  off_t
  postprocessing_buffer_size() const
  { return this->current_data_size_for_child(); }

  // Modify the section name.  This is only permitted for an
  // unallocated section, and only before the size has been finalized.
  // Otherwise the name will not get into Layout::namepool_.
  void
  set_name(const char* newname)
  {
    gold_assert((this->flags_ & elfcpp::SHF_ALLOC) == 0);
    gold_assert(!this->is_data_size_valid());
    this->name_ = newname;
  }

  // Return whether the offset OFFSET in the input section SHNDX in
  // object OBJECT is being included in the link.
  bool
  is_input_address_mapped(const Relobj* object, unsigned int shndx,
			  off_t offset) const;

  // Return the offset within the output section of OFFSET relative to
  // the start of input section SHNDX in object OBJECT.
  section_offset_type
  output_offset(const Relobj* object, unsigned int shndx,
		section_offset_type offset) const;

  // Return the output virtual address of OFFSET relative to the start
  // of input section SHNDX in object OBJECT.
  uint64_t
  output_address(const Relobj* object, unsigned int shndx,
		 off_t offset) const;

  // Look for the merged section for input section SHNDX in object
  // OBJECT.  If found, return true, and set *ADDR to the address of
  // the start of the merged section.  This is not necessary the
  // output offset corresponding to input offset 0 in the section,
  // since the section may be mapped arbitrarily.
  bool
  find_starting_output_address(const Relobj* object, unsigned int shndx,
			       uint64_t* addr) const;

  // Record that this output section was found in the SECTIONS clause
  // of a linker script.
  void
  set_found_in_sections_clause()
  { this->found_in_sections_clause_ = true; }

  // Return whether this output section was found in the SECTIONS
  // clause of a linker script.
  bool
  found_in_sections_clause() const
  { return this->found_in_sections_clause_; }

  // Write the section header into *OPHDR.
  template<int size, bool big_endian>
  void
  write_header(const Layout*, const Stringpool*,
	       elfcpp::Shdr_write<size, big_endian>*) const;

  // The next few calls are for linker script support.

  // In some cases we need to keep a list of the input sections
  // associated with this output section.  We only need the list if we
  // might have to change the offsets of the input section within the
  // output section after we add the input section.  The ordinary
  // input sections will be written out when we process the object
  // file, and as such we don't need to track them here.  We do need
  // to track Output_section_data objects here.  We store instances of
  // this structure in a std::vector, so it must be a POD.  There can
  // be many instances of this structure, so we use a union to save
  // some space.
  class Input_section
  {
   public:
    Input_section()
      : shndx_(0), p2align_(0)
    {
      this->u1_.data_size = 0;
      this->u2_.object = NULL;
    }

    // For an ordinary input section.
    Input_section(Relobj* object, unsigned int shndx, off_t data_size,
		  uint64_t addralign)
      : shndx_(shndx),
	p2align_(ffsll(static_cast<long long>(addralign))),
	section_order_index_(0)
    {
      gold_assert(shndx != OUTPUT_SECTION_CODE
		  && shndx != MERGE_DATA_SECTION_CODE
		  && shndx != MERGE_STRING_SECTION_CODE
		  && shndx != RELAXED_INPUT_SECTION_CODE);
      this->u1_.data_size = data_size;
      this->u2_.object = object;
    }

    // For a non-merge output section.
    Input_section(Output_section_data* posd)
      : shndx_(OUTPUT_SECTION_CODE), p2align_(0),
	section_order_index_(0)
    {
      this->u1_.data_size = 0;
      this->u2_.posd = posd;
    }

    // For a merge section.
    Input_section(Output_section_data* posd, bool is_string, uint64_t entsize)
      : shndx_(is_string
	       ? MERGE_STRING_SECTION_CODE
	       : MERGE_DATA_SECTION_CODE),
	p2align_(0),
	section_order_index_(0)
    {
      this->u1_.entsize = entsize;
      this->u2_.posd = posd;
    }

    // For a relaxed input section.
    Input_section(Output_relaxed_input_section* psection)
      : shndx_(RELAXED_INPUT_SECTION_CODE), p2align_(0),
	section_order_index_(0)
    {
      this->u1_.data_size = 0;
      this->u2_.poris = psection;
    }

    unsigned int
    section_order_index() const
    {
      return this->section_order_index_;
    }

    void
    set_section_order_index(unsigned int number)
    {
      this->section_order_index_ = number;
    }

    // The required alignment.
    uint64_t
    addralign() const
    {
      if (this->p2align_ != 0)
	return static_cast<uint64_t>(1) << (this->p2align_ - 1);
      else if (!this->is_input_section())
	return this->u2_.posd->addralign();
      else
	return 0;
    }

    // Set the required alignment, which must be either 0 or a power of 2.
    // For input sections that are sub-classes of Output_section_data, a
    // alignment of zero means asking the underlying object for alignment.
    void
    set_addralign(uint64_t addralign)
    {
      if (addralign == 0)
	this->p2align_ = 0;
      else
	{
	  gold_assert((addralign & (addralign - 1)) == 0);
	  this->p2align_ = ffsll(static_cast<long long>(addralign));
	}
    }

    // Return the current required size, without finalization.
    off_t
    current_data_size() const;

    // Return the required size.
    off_t
    data_size() const;

    // Whether this is an input section.
    bool
    is_input_section() const
    {
      return (this->shndx_ != OUTPUT_SECTION_CODE
	      && this->shndx_ != MERGE_DATA_SECTION_CODE
	      && this->shndx_ != MERGE_STRING_SECTION_CODE
	      && this->shndx_ != RELAXED_INPUT_SECTION_CODE);
    }

    // Return whether this is a merge section which matches the
    // parameters.
    bool
    is_merge_section(bool is_string, uint64_t entsize,
		     uint64_t addralign) const
    {
      return (this->shndx_ == (is_string
			       ? MERGE_STRING_SECTION_CODE
			       : MERGE_DATA_SECTION_CODE)
	      && this->u1_.entsize == entsize
	      && this->addralign() == addralign);
    }

    // Return whether this is a merge section for some input section.
    bool
    is_merge_section() const
    {
      return (this->shndx_ == MERGE_DATA_SECTION_CODE
	      || this->shndx_ == MERGE_STRING_SECTION_CODE);
    }

    // Return whether this is a relaxed input section.
    bool
    is_relaxed_input_section() const
    { return this->shndx_ == RELAXED_INPUT_SECTION_CODE; }

    // Return whether this is a generic Output_section_data.
    bool
    is_output_section_data() const
    {
      return this->shndx_ == OUTPUT_SECTION_CODE;
    }

    // Return the object for an input section.
    Relobj*
    relobj() const;

    // Return the input section index for an input section.
    unsigned int
    shndx() const;

    // For non-input-sections, return the associated Output_section_data
    // object.
    Output_section_data*
    output_section_data() const
    {
      gold_assert(!this->is_input_section());
      return this->u2_.posd;
    }

    // For a merge section, return the Output_merge_base pointer.
    Output_merge_base*
    output_merge_base() const
    {
      gold_assert(this->is_merge_section());
      return this->u2_.pomb;
    }

    // Return the Output_relaxed_input_section object.
    Output_relaxed_input_section*
    relaxed_input_section() const
    {
      gold_assert(this->is_relaxed_input_section());
      return this->u2_.poris;
    }

    // Set the output section.
    void
    set_output_section(Output_section* os)
    {
      gold_assert(!this->is_input_section());
      Output_section_data* posd =
	this->is_relaxed_input_section() ? this->u2_.poris : this->u2_.posd;
      posd->set_output_section(os);
    }

    // Set the address and file offset.  This is called during
    // Layout::finalize.  SECTION_FILE_OFFSET is the file offset of
    // the enclosing section.
    void
    set_address_and_file_offset(uint64_t address, off_t file_offset,
				off_t section_file_offset);

    // Reset the address and file offset.
    void
    reset_address_and_file_offset();

    // Finalize the data size.
    void
    finalize_data_size();

    // Add an input section, for SHF_MERGE sections.
    bool
    add_input_section(Relobj* object, unsigned int shndx)
    {
      gold_assert(this->shndx_ == MERGE_DATA_SECTION_CODE
		  || this->shndx_ == MERGE_STRING_SECTION_CODE);
      return this->u2_.posd->add_input_section(object, shndx);
    }

    // Given an input OBJECT, an input section index SHNDX within that
    // object, and an OFFSET relative to the start of that input
    // section, return whether or not the output offset is known.  If
    // this function returns true, it sets *POUTPUT to the offset in
    // the output section, relative to the start of the input section
    // in the output section.  *POUTPUT may be different from OFFSET
    // for a merged section.
    bool
    output_offset(const Relobj* object, unsigned int shndx,
		  section_offset_type offset,
		  section_offset_type* poutput) const;

    // Write out the data.  This does nothing for an input section.
    void
    write(Output_file*);

    // Write the data to a buffer.  This does nothing for an input
    // section.
    void
    write_to_buffer(unsigned char*);

    // Print to a map file.
    void
    print_to_mapfile(Mapfile*) const;

    // Print statistics about merge sections to stderr.
    void
    print_merge_stats(const char* section_name)
    {
      if (this->shndx_ == MERGE_DATA_SECTION_CODE
	  || this->shndx_ == MERGE_STRING_SECTION_CODE)
	this->u2_.posd->print_merge_stats(section_name);
    }

   private:
    // Code values which appear in shndx_.  If the value is not one of
    // these codes, it is the input section index in the object file.
    enum
    {
      // An Output_section_data.
      OUTPUT_SECTION_CODE = -1U,
      // An Output_section_data for an SHF_MERGE section with
      // SHF_STRINGS not set.
      MERGE_DATA_SECTION_CODE = -2U,
      // An Output_section_data for an SHF_MERGE section with
      // SHF_STRINGS set.
      MERGE_STRING_SECTION_CODE = -3U,
      // An Output_section_data for a relaxed input section.
      RELAXED_INPUT_SECTION_CODE = -4U
    };

    // For an ordinary input section, this is the section index in the
    // input file.  For an Output_section_data, this is
    // OUTPUT_SECTION_CODE or MERGE_DATA_SECTION_CODE or
    // MERGE_STRING_SECTION_CODE.
    unsigned int shndx_;
    // The required alignment, stored as a power of 2.
    unsigned int p2align_;
    union
    {
      // For an ordinary input section, the section size.
      off_t data_size;
      // For OUTPUT_SECTION_CODE or RELAXED_INPUT_SECTION_CODE, this is not
      // used.  For MERGE_DATA_SECTION_CODE or MERGE_STRING_SECTION_CODE, the
      // entity size.
      uint64_t entsize;
    } u1_;
    union
    {
      // For an ordinary input section, the object which holds the
      // input section.
      Relobj* object;
      // For OUTPUT_SECTION_CODE or MERGE_DATA_SECTION_CODE or
      // MERGE_STRING_SECTION_CODE, the data.
      Output_section_data* posd;
      Output_merge_base* pomb;
      // For RELAXED_INPUT_SECTION_CODE, the data.
      Output_relaxed_input_section* poris;
    } u2_;
    // The line number of the pattern it matches in the --section-ordering-file
    // file.  It is 0 if does not match any pattern.
    unsigned int section_order_index_;
  };

  // Store the list of input sections for this Output_section into the
  // list passed in.  This removes the input sections, leaving only
  // any Output_section_data elements.  This returns the size of those
  // Output_section_data elements.  ADDRESS is the address of this
  // output section.  FILL is the fill value to use, in case there are
  // any spaces between the remaining Output_section_data elements.
  uint64_t
  get_input_sections(uint64_t address, const std::string& fill,
		     std::list<Input_section>*);

  // Add a script input section.  A script input section can either be
  // a plain input section or a sub-class of Output_section_data.
  void
  add_script_input_section(const Input_section& input_section);

  // Set the current size of the output section.
  void
  set_current_data_size(off_t size)
  { this->set_current_data_size_for_child(size); }

  // End of linker script support.

  // Save states before doing section layout.
  // This is used for relaxation.
  void
  save_states();

  // Restore states prior to section layout.
  void
  restore_states();

  // Discard states.
  void
  discard_states();

  // Convert existing input sections to relaxed input sections.
  void
  convert_input_sections_to_relaxed_sections(
      const std::vector<Output_relaxed_input_section*>& sections);

  // Find a relaxed input section to an input section in OBJECT
  // with index SHNDX.  Return NULL if none is found.
  const Output_relaxed_input_section*
  find_relaxed_input_section(const Relobj* object, unsigned int shndx) const;

  // Whether section offsets need adjustment due to relaxation.
  bool
  section_offsets_need_adjustment() const
  { return this->section_offsets_need_adjustment_; }

  // Set section_offsets_need_adjustment to be true.
  void
  set_section_offsets_need_adjustment()
  { this->section_offsets_need_adjustment_ = true; }

  // Set section_offsets_need_adjustment to be false.
  void
  clear_section_offsets_need_adjustment()
  { this->section_offsets_need_adjustment_ = false; }

  // Adjust section offsets of input sections in this.  This is
  // requires if relaxation caused some input sections to change sizes.
  void
  adjust_section_offsets();

  // Whether this is a NOLOAD section.
  bool
  is_noload() const
  { return this->is_noload_; }

  // Set NOLOAD flag.
  void
  set_is_noload()
  { this->is_noload_ = true; }

  // Print merge statistics to stderr.
  void
  print_merge_stats();

  // Set a fixed layout for the section.  Used for incremental update links.
  void
  set_fixed_layout(uint64_t sh_addr, off_t sh_offset, off_t sh_size,
		   uint64_t sh_addralign);

  // Return TRUE if the section has a fixed layout.
  bool
  has_fixed_layout() const
  { return this->has_fixed_layout_; }

  // Set flag to allow patch space for this section.  Used for full
  // incremental links.
  void
  set_is_patch_space_allowed()
  { this->is_patch_space_allowed_ = true; }

  // Set a fill method to use for free space left in the output section
  // during incremental links.
  void
  set_free_space_fill(Output_fill* free_space_fill)
  {
    this->free_space_fill_ = free_space_fill;
    this->free_list_.set_min_hole_size(free_space_fill->minimum_hole_size());
  }

  // Reserve space within the fixed layout for the section.  Used for
  // incremental update links.
  void
  reserve(uint64_t sh_offset, uint64_t sh_size);

  // Allocate space from the free list for the section.  Used for
  // incremental update links.
  off_t
  allocate(off_t len, uint64_t addralign);

  typedef std::vector<Input_section> Input_section_list;

  // Allow access to the input sections.
  const Input_section_list&
  input_sections() const
  { return this->input_sections_; }

  Input_section_list&
  input_sections()
  { return this->input_sections_; }

 protected:
  // Return the output section--i.e., the object itself.
  Output_section*
  do_output_section()
  { return this; }

  const Output_section*
  do_output_section() const
  { return this; }

  // Return the section index in the output file.
  unsigned int
  do_out_shndx() const
  {
    gold_assert(this->out_shndx_ != -1U);
    return this->out_shndx_;
  }

  // Set the output section index.
  void
  do_set_out_shndx(unsigned int shndx)
  {
    gold_assert(this->out_shndx_ == -1U || this->out_shndx_ == shndx);
    this->out_shndx_ = shndx;
  }

  // Update the data size of the Output_section.  For a typical
  // Output_section, there is nothing to do, but if there are any
  // Output_section_data objects we need to do a trial layout
  // here.
  virtual void
  update_data_size();

  // Set the final data size of the Output_section.  For a typical
  // Output_section, there is nothing to do, but if there are any
  // Output_section_data objects we need to set their final addresses
  // here.
  virtual void
  set_final_data_size();

  // Reset the address and file offset.
  void
  do_reset_address_and_file_offset();

  // Return true if address and file offset already have reset values. In
  // other words, calling reset_address_and_file_offset will not change them.
  bool
  do_address_and_file_offset_have_reset_values() const;

  // Write the data to the file.  For a typical Output_section, this
  // does nothing: the data is written out by calling Object::Relocate
  // on each input object.  But if there are any Output_section_data
  // objects we do need to write them out here.
  virtual void
  do_write(Output_file*);

  // Return the address alignment--function required by parent class.
  uint64_t
  do_addralign() const
  { return this->addralign_; }

  // Return whether there is a load address.
  bool
  do_has_load_address() const
  { return this->has_load_address_; }

  // Return the load address.
  uint64_t
  do_load_address() const
  {
    gold_assert(this->has_load_address_);
    return this->load_address_;
  }

  // Return whether this is an Output_section.
  bool
  do_is_section() const
  { return true; }

  // Return whether this is a section of the specified type.
  bool
  do_is_section_type(elfcpp::Elf_Word type) const
  { return this->type_ == type; }

  // Return whether the specified section flag is set.
  bool
  do_is_section_flag_set(elfcpp::Elf_Xword flag) const
  { return (this->flags_ & flag) != 0; }

  // Set the TLS offset.  Called only for SHT_TLS sections.
  void
  do_set_tls_offset(uint64_t tls_base);

  // Return the TLS offset, relative to the base of the TLS segment.
  // Valid only for SHT_TLS sections.
  uint64_t
  do_tls_offset() const
  { return this->tls_offset_; }

  // This may be implemented by a child class.
  virtual void
  do_finalize_name(Layout*)
  { }

  // Print to the map file.
  virtual void
  do_print_to_mapfile(Mapfile*) const;

  // Record that this section requires postprocessing after all
  // relocations have been applied.  This is called by a child class.
  void
  set_requires_postprocessing()
  {
    this->requires_postprocessing_ = true;
    this->after_input_sections_ = true;
  }

  // Write all the data of an Output_section into the postprocessing
  // buffer.
  void
  write_to_postprocessing_buffer();

  // Whether this always keeps an input section list
  bool
  always_keeps_input_sections() const
  { return this->always_keeps_input_sections_; }

  // Always keep an input section list.
  void
  set_always_keeps_input_sections()
  {
    gold_assert(this->current_data_size_for_child() == 0);
    this->always_keeps_input_sections_ = true;
  }

 private:
  // We only save enough information to undo the effects of section layout.
  class Checkpoint_output_section
  {
   public:
    Checkpoint_output_section(uint64_t addralign, elfcpp::Elf_Xword flags,
			      const Input_section_list& input_sections,
			      off_t first_input_offset,
			      bool attached_input_sections_are_sorted)
      : addralign_(addralign), flags_(flags),
	input_sections_(input_sections),
	input_sections_size_(input_sections_.size()),
	input_sections_copy_(), first_input_offset_(first_input_offset),
	attached_input_sections_are_sorted_(attached_input_sections_are_sorted)
    { }

    virtual
    ~Checkpoint_output_section()
    { }

    // Return the address alignment.
    uint64_t
    addralign() const
    { return this->addralign_; }

    void
    set_addralign(uint64_t val)
    { this->addralign_ = val; }

    // Return the section flags.
    elfcpp::Elf_Xword
    flags() const
    { return this->flags_; }

    // Return a reference to the input section list copy.
    Input_section_list*
    input_sections()
    { return &this->input_sections_copy_; }

    // Return the size of input_sections at the time when checkpoint is
    // taken.
    size_t
    input_sections_size() const
    { return this->input_sections_size_; }

    // Whether input sections are copied.
    bool
    input_sections_saved() const
    { return this->input_sections_copy_.size() == this->input_sections_size_; }

    off_t
    first_input_offset() const
    { return this->first_input_offset_; }

    bool
    attached_input_sections_are_sorted() const
    { return this->attached_input_sections_are_sorted_; }

    // Save input sections.
    void
    save_input_sections()
    {
      this->input_sections_copy_.reserve(this->input_sections_size_);
      this->input_sections_copy_.clear();
      Input_section_list::const_iterator p = this->input_sections_.begin();
      gold_assert(this->input_sections_size_ >= this->input_sections_.size());
      for(size_t i = 0; i < this->input_sections_size_ ; i++, ++p)
	this->input_sections_copy_.push_back(*p);
    }

   private:
    // The section alignment.
    uint64_t addralign_;
    // The section flags.
    elfcpp::Elf_Xword flags_;
    // Reference to the input sections to be checkpointed.
    const Input_section_list& input_sections_;
    // Size of the checkpointed portion of input_sections_;
    size_t input_sections_size_;
    // Copy of input sections.
    Input_section_list input_sections_copy_;
    // The offset of the first entry in input_sections_.
    off_t first_input_offset_;
    // True if the input sections attached to this output section have
    // already been sorted.
    bool attached_input_sections_are_sorted_;
  };

  // This class is used to sort the input sections.
  class Input_section_sort_entry;

  // This is the sort comparison function for ctors and dtors.
  struct Input_section_sort_compare
  {
    bool
    operator()(const Input_section_sort_entry&,
	       const Input_section_sort_entry&) const;
  };

  // This is the sort comparison function for .init_array and .fini_array.
  struct Input_section_sort_init_fini_compare
  {
    bool
    operator()(const Input_section_sort_entry&,
	       const Input_section_sort_entry&) const;
  };

  // This is the sort comparison function when a section order is specified
  // from an input file.
  struct Input_section_sort_section_order_index_compare
  {
    bool
    operator()(const Input_section_sort_entry&,
	       const Input_section_sort_entry&) const;
  };

  // This is the sort comparison function for .text to sort sections with
  // prefixes .text.{unlikely,exit,startup,hot} before other sections.
  struct Input_section_sort_section_prefix_special_ordering_compare
  {
    bool
    operator()(const Input_section_sort_entry&,
	       const Input_section_sort_entry&) const;
  };

  // This is the sort comparison function for sorting sections by name.
  struct Input_section_sort_section_name_compare
  {
    bool
    operator()(const Input_section_sort_entry&,
	       const Input_section_sort_entry&) const;
  };

  // Fill data.  This is used to fill in data between input sections.
  // It is also used for data statements (BYTE, WORD, etc.) in linker
  // scripts.  When we have to keep track of the input sections, we
  // can use an Output_data_const, but we don't want to have to keep
  // track of input sections just to implement fills.
  class Fill
  {
   public:
    Fill(off_t section_offset, off_t length)
      : section_offset_(section_offset),
	length_(convert_to_section_size_type(length))
    { }

    // Return section offset.
    off_t
    section_offset() const
    { return this->section_offset_; }

    // Return fill length.
    section_size_type
    length() const
    { return this->length_; }

   private:
    // The offset within the output section.
    off_t section_offset_;
    // The length of the space to fill.
    section_size_type length_;
  };

  typedef std::vector<Fill> Fill_list;

  // Map used during relaxation of existing sections.  This map
  // a section id an input section list index.  We assume that
  // Input_section_list is a vector.
  typedef Unordered_map<Section_id, size_t, Section_id_hash> Relaxation_map;

  // Add a new output section by Input_section.
  void
  add_output_section_data(Input_section*);

  // Add an SHF_MERGE input section.  Returns true if the section was
  // handled.  If KEEPS_INPUT_SECTIONS is true, the output merge section
  // stores information about the merged input sections.
  bool
  add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags,
			  uint64_t entsize, uint64_t addralign,
			  bool keeps_input_sections);

  // Add an output SHF_MERGE section POSD to this output section.
  // IS_STRING indicates whether it is a SHF_STRINGS section, and
  // ENTSIZE is the entity size.  This returns the entry added to
  // input_sections_.
  void
  add_output_merge_section(Output_section_data* posd, bool is_string,
			   uint64_t entsize);

  // Find the merge section into which an input section with index SHNDX in
  // OBJECT has been added.  Return NULL if none found.
  const Output_section_data*
  find_merge_section(const Relobj* object, unsigned int shndx) const;

  // Build a relaxation map.
  void
  build_relaxation_map(
      const Input_section_list& input_sections,
      size_t limit,
      Relaxation_map* map) const;

  // Convert input sections in an input section list into relaxed sections.
  void
  convert_input_sections_in_list_to_relaxed_sections(
      const std::vector<Output_relaxed_input_section*>& relaxed_sections,
      const Relaxation_map& map,
      Input_section_list* input_sections);

  // Build the lookup maps for merge and relaxed input sections.
  void
  build_lookup_maps() const;

  // Most of these fields are only valid after layout.

  // The name of the section.  This will point into a Stringpool.
  const char* name_;
  // The section address is in the parent class.
  // The section alignment.
  uint64_t addralign_;
  // The section entry size.
  uint64_t entsize_;
  // The load address.  This is only used when using a linker script
  // with a SECTIONS clause.  The has_load_address_ field indicates
  // whether this field is valid.
  uint64_t load_address_;
  // The file offset is in the parent class.
  // Set the section link field to the index of this section.
  const Output_data* link_section_;
  // If link_section_ is NULL, this is the link field.
  unsigned int link_;
  // Set the section info field to the index of this section.
  const Output_section* info_section_;
  // If info_section_ is NULL, set the info field to the symbol table
  // index of this symbol.
  const Symbol* info_symndx_;
  // If info_section_ and info_symndx_ are NULL, this is the section
  // info field.
  unsigned int info_;
  // The section type.
  const elfcpp::Elf_Word type_;
  // The section flags.
  elfcpp::Elf_Xword flags_;
  // The order of this section in the output segment.
  Output_section_order order_;
  // The section index.
  unsigned int out_shndx_;
  // If there is a STT_SECTION for this output section in the normal
  // symbol table, this is the symbol index.  This starts out as zero.
  // It is initialized in Layout::finalize() to be the index, or -1U
  // if there isn't one.
  unsigned int symtab_index_;
  // If there is a STT_SECTION for this output section in the dynamic
  // symbol table, this is the symbol index.  This starts out as zero.
  // It is initialized in Layout::finalize() to be the index, or -1U
  // if there isn't one.
  unsigned int dynsym_index_;
  // The input sections.  This will be empty in cases where we don't
  // need to keep track of them.
  Input_section_list input_sections_;
  // The offset of the first entry in input_sections_.
  off_t first_input_offset_;
  // The fill data.  This is separate from input_sections_ because we
  // often will need fill sections without needing to keep track of
  // input sections.
  Fill_list fills_;
  // If the section requires postprocessing, this buffer holds the
  // section contents during relocation.
  unsigned char* postprocessing_buffer_;
  // Whether this output section needs a STT_SECTION symbol in the
  // normal symbol table.  This will be true if there is a relocation
  // which needs it.
  bool needs_symtab_index_ : 1;
  // Whether this output section needs a STT_SECTION symbol in the
  // dynamic symbol table.  This will be true if there is a dynamic
  // relocation which needs it.
  bool needs_dynsym_index_ : 1;
  // Whether the link field of this output section should point to the
  // normal symbol table.
  bool should_link_to_symtab_ : 1;
  // Whether the link field of this output section should point to the
  // dynamic symbol table.
  bool should_link_to_dynsym_ : 1;
  // Whether this section should be written after all the input
  // sections are complete.
  bool after_input_sections_ : 1;
  // Whether this section requires post processing after all
  // relocations have been applied.
  bool requires_postprocessing_ : 1;
  // Whether an input section was mapped to this output section
  // because of a SECTIONS clause in a linker script.
  bool found_in_sections_clause_ : 1;
  // Whether this section has an explicitly specified load address.
  bool has_load_address_ : 1;
  // True if the info_section_ field means the section index of the
  // section, false if it means the symbol index of the corresponding
  // section symbol.
  bool info_uses_section_index_ : 1;
  // True if input sections attached to this output section have to be
  // sorted according to a specified order.
  bool input_section_order_specified_ : 1;
  // True if the input sections attached to this output section may
  // need sorting.
  bool may_sort_attached_input_sections_ : 1;
  // True if the input sections attached to this output section must
  // be sorted.
  bool must_sort_attached_input_sections_ : 1;
  // True if the input sections attached to this output section have
  // already been sorted.
  bool attached_input_sections_are_sorted_ : 1;
  // True if this section holds relro data.
  bool is_relro_ : 1;
  // True if this is a small section.
  bool is_small_section_ : 1;
  // True if this is a large section.
  bool is_large_section_ : 1;
  // Whether code-fills are generated at write.
  bool generate_code_fills_at_write_ : 1;
  // Whether the entry size field should be zero.
  bool is_entsize_zero_ : 1;
  // Whether section offsets need adjustment due to relaxation.
  bool section_offsets_need_adjustment_ : 1;
  // Whether this is a NOLOAD section.
  bool is_noload_ : 1;
  // Whether this always keeps input section.
  bool always_keeps_input_sections_ : 1;
  // Whether this section has a fixed layout, for incremental update links.
  bool has_fixed_layout_ : 1;
  // True if we can add patch space to this section.
  bool is_patch_space_allowed_ : 1;
  // True if this output section goes into a unique segment.
  bool is_unique_segment_ : 1;
  // For SHT_TLS sections, the offset of this section relative to the base
  // of the TLS segment.
  uint64_t tls_offset_;
  // Additional segment flags, specified via linker plugin, when mapping some
  // input sections to unique segments.
  uint64_t extra_segment_flags_;
  // Segment alignment specified via linker plugin, when mapping some
  // input sections to unique segments.
  uint64_t segment_alignment_;
  // Saved checkpoint.
  Checkpoint_output_section* checkpoint_;
  // Fast lookup maps for merged and relaxed input sections.
  Output_section_lookup_maps* lookup_maps_;
  // List of available regions within the section, for incremental
  // update links.
  Free_list free_list_;
  // Method for filling chunks of free space.
  Output_fill* free_space_fill_;
  // Amount added as patch space for incremental linking.
  off_t patch_space_;
};

// An output segment.  PT_LOAD segments are built from collections of
// output sections.  Other segments typically point within PT_LOAD
// segments, and are built directly as needed.
//
// NOTE: We want to use the copy constructor for this class.  During
// relaxation, we may try built the segments multiple times.  We do
// that by copying the original segment list before lay-out, doing
// a trial lay-out and roll-back to the saved copied if we need to
// to the lay-out again.

class Output_segment
{
 public:
  // Create an output segment, specifying the type and flags.
  Output_segment(elfcpp::Elf_Word, elfcpp::Elf_Word);

  // Return the virtual address.
  uint64_t
  vaddr() const
  { return this->vaddr_; }

  // Return the physical address.
  uint64_t
  paddr() const
  { return this->paddr_; }

  // Return the segment type.
  elfcpp::Elf_Word
  type() const
  { return this->type_; }

  // Return the segment flags.
  elfcpp::Elf_Word
  flags() const
  { return this->flags_; }

  // Return the memory size.
  uint64_t
  memsz() const
  { return this->memsz_; }

  // Return the file size.
  off_t
  filesz() const
  { return this->filesz_; }

  // Return the file offset.
  off_t
  offset() const
  { return this->offset_; }

  // Whether this is a segment created to hold large data sections.
  bool
  is_large_data_segment() const
  { return this->is_large_data_segment_; }

  // Record that this is a segment created to hold large data
  // sections.
  void
  set_is_large_data_segment()
  { this->is_large_data_segment_ = true; }

  bool
  is_unique_segment() const
  { return this->is_unique_segment_; }

  // Mark segment as unique, happens when linker plugins request that
  // certain input sections be mapped to unique segments.
  void
  set_is_unique_segment()
  { this->is_unique_segment_ = true; }

  // Return the maximum alignment of the Output_data.
  uint64_t
  maximum_alignment();

  // Add the Output_section OS to this PT_LOAD segment.  SEG_FLAGS is
  // the segment flags to use.
  void
  add_output_section_to_load(Layout* layout, Output_section* os,
			     elfcpp::Elf_Word seg_flags);

  // Add the Output_section OS to this non-PT_LOAD segment.  SEG_FLAGS
  // is the segment flags to use.
  void
  add_output_section_to_nonload(Output_section* os,
				elfcpp::Elf_Word seg_flags);

  // Remove an Output_section from this segment.  It is an error if it
  // is not present.
  void
  remove_output_section(Output_section* os);

  // Add an Output_data (which need not be an Output_section) to the
  // start of this segment.
  void
  add_initial_output_data(Output_data*);

  // Return true if this segment has any sections which hold actual
  // data, rather than being a BSS section.
  bool
  has_any_data_sections() const;

  // Whether this segment has a dynamic relocs.
  bool
  has_dynamic_reloc() const;

  // Return the first section.
  Output_section*
  first_section() const;

  // Return the address of the first section.
  uint64_t
  first_section_load_address() const
  {
    const Output_section* os = this->first_section();
    return os->has_load_address() ? os->load_address() : os->address();
  }

  // Return whether the addresses have been set already.
  bool
  are_addresses_set() const
  { return this->are_addresses_set_; }

  // Set the addresses.
  void
  set_addresses(uint64_t vaddr, uint64_t paddr)
  {
    this->vaddr_ = vaddr;
    this->paddr_ = paddr;
    this->are_addresses_set_ = true;
  }

  // Update the flags for the flags of an output section added to this
  // segment.
  void
  update_flags_for_output_section(elfcpp::Elf_Xword flags)
  {
    // The ELF ABI specifies that a PT_TLS segment should always have
    // PF_R as the flags.
    if (this->type() != elfcpp::PT_TLS)
      this->flags_ |= flags;
  }

  // Set the segment flags.  This is only used if we have a PHDRS
  // clause which explicitly specifies the flags.
  void
  set_flags(elfcpp::Elf_Word flags)
  { this->flags_ = flags; }

  // Set the address of the segment to ADDR and the offset to *POFF
  // and set the addresses and offsets of all contained output
  // sections accordingly.  Set the section indexes of all contained
  // output sections starting with *PSHNDX.  If RESET is true, first
  // reset the addresses of the contained sections.  Return the
  // address of the immediately following segment.  Update *POFF and
  // *PSHNDX.  This should only be called for a PT_LOAD segment.
  uint64_t
  set_section_addresses(const Target*, Layout*, bool reset, uint64_t addr,
			unsigned int* increase_relro, bool* has_relro,
			off_t* poff, unsigned int* pshndx);

  // Set the minimum alignment of this segment.  This may be adjusted
  // upward based on the section alignments.
  void
  set_minimum_p_align(uint64_t align)
  {
    if (align > this->min_p_align_)
      this->min_p_align_ = align;
  }

  // Set the memory size of this segment.
  void
  set_size(uint64_t size)
  {
    this->memsz_ = size;
  }

  // Set the offset of this segment based on the section.  This should
  // only be called for a non-PT_LOAD segment.
  void
  set_offset(unsigned int increase);

  // Set the TLS offsets of the sections contained in the PT_TLS segment.
  void
  set_tls_offsets();

  // Return the number of output sections.
  unsigned int
  output_section_count() const;

  // Return the section attached to the list segment with the lowest
  // load address.  This is used when handling a PHDRS clause in a
  // linker script.
  Output_section*
  section_with_lowest_load_address() const;

  // Write the segment header into *OPHDR.
  template<int size, bool big_endian>
  void
  write_header(elfcpp::Phdr_write<size, big_endian>*);

  // Write the section headers of associated sections into V.
  template<int size, bool big_endian>
  unsigned char*
  write_section_headers(const Layout*, const Stringpool*, unsigned char* v,
			unsigned int* pshndx) const;

  // Print the output sections in the map file.
  void
  print_sections_to_mapfile(Mapfile*) const;

 private:
  typedef std::vector<Output_data*> Output_data_list;

  // Find the maximum alignment in an Output_data_list.
  static uint64_t
  maximum_alignment_list(const Output_data_list*);

  // Return whether the first data section is a relro section.
  bool
  is_first_section_relro() const;

  // Set the section addresses in an Output_data_list.
  uint64_t
  set_section_list_addresses(Layout*, bool reset, Output_data_list*,
			     uint64_t addr, off_t* poff, unsigned int* pshndx,
			     bool* in_tls);

  // Return the number of Output_sections in an Output_data_list.
  unsigned int
  output_section_count_list(const Output_data_list*) const;

  // Return whether an Output_data_list has a dynamic reloc.
  bool
  has_dynamic_reloc_list(const Output_data_list*) const;

  // Find the section with the lowest load address in an
  // Output_data_list.
  void
  lowest_load_address_in_list(const Output_data_list* pdl,
			      Output_section** found,
			      uint64_t* found_lma) const;

  // Find the first and last entries by address.
  void
  find_first_and_last_list(const Output_data_list* pdl,
			   const Output_data** pfirst,
			   const Output_data** plast) const;

  // Write the section headers in the list into V.
  template<int size, bool big_endian>
  unsigned char*
  write_section_headers_list(const Layout*, const Stringpool*,
			     const Output_data_list*, unsigned char* v,
			     unsigned int* pshdx) const;

  // Print a section list to the mapfile.
  void
  print_section_list_to_mapfile(Mapfile*, const Output_data_list*) const;

  // NOTE: We want to use the copy constructor.  Currently, shallow copy
  // works for us so we do not need to write our own copy constructor.

  // The list of output data attached to this segment.
  Output_data_list output_lists_[ORDER_MAX];
  // The segment virtual address.
  uint64_t vaddr_;
  // The segment physical address.
  uint64_t paddr_;
  // The size of the segment in memory.
  uint64_t memsz_;
  // The maximum section alignment.  The is_max_align_known_ field
  // indicates whether this has been finalized.
  uint64_t max_align_;
  // The required minimum value for the p_align field.  This is used
  // for PT_LOAD segments.  Note that this does not mean that
  // addresses should be aligned to this value; it means the p_paddr
  // and p_vaddr fields must be congruent modulo this value.  For
  // non-PT_LOAD segments, the dynamic linker works more efficiently
  // if the p_align field has the more conventional value, although it
  // can align as needed.
  uint64_t min_p_align_;
  // The offset of the segment data within the file.
  off_t offset_;
  // The size of the segment data in the file.
  off_t filesz_;
  // The segment type;
  elfcpp::Elf_Word type_;
  // The segment flags.
  elfcpp::Elf_Word flags_;
  // Whether we have finalized max_align_.
  bool is_max_align_known_ : 1;
  // Whether vaddr and paddr were set by a linker script.
  bool are_addresses_set_ : 1;
  // Whether this segment holds large data sections.
  bool is_large_data_segment_ : 1;
  // Whether this was marked as a unique segment via a linker plugin.
  bool is_unique_segment_ : 1;
};

} // End namespace gold.

#endif // !defined(GOLD_OUTPUT_H)
