// layout.h -- lay out output file sections for gold  -*- C++ -*-

// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
// 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_LAYOUT_H
#define GOLD_LAYOUT_H

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

#include "script.h"
#include "workqueue.h"
#include "object.h"
#include "dynobj.h"
#include "stringpool.h"

namespace gold
{

class General_options;
class Incremental_inputs;
class Incremental_binary;
class Input_objects;
class Mapfile;
class Symbol_table;
class Output_section_data;
class Output_section;
class Output_section_headers;
class Output_segment_headers;
class Output_file_header;
class Output_segment;
class Output_data;
class Output_data_reloc_generic;
class Output_data_dynamic;
class Output_symtab_xindex;
class Output_reduced_debug_abbrev_section;
class Output_reduced_debug_info_section;
class Eh_frame;
class Gdb_index;
class Target;
struct Timespec;

// Return TRUE if SECNAME is the name of a compressed debug section.
extern bool
is_compressed_debug_section(const char* secname);

// Maintain a list of free space within a section, segment, or file.
// Used for incremental update links.

class Free_list
{
 public:
  struct Free_list_node
  {
    Free_list_node(off_t start, off_t end)
      : start_(start), end_(end)
    { }
    off_t start_;
    off_t end_;
  };
  typedef std::list<Free_list_node>::const_iterator Const_iterator;

  Free_list()
    : list_(), last_remove_(list_.begin()), extend_(false), length_(0),
      min_hole_(0)
  { }

  // Initialize the free list for a section of length LEN.
  // If EXTEND is true, free space may be allocated past the end.
  void
  init(off_t len, bool extend);

  // Set the minimum hole size that is allowed when allocating
  // from the free list.
  void
  set_min_hole_size(off_t min_hole)
  { this->min_hole_ = min_hole; }

  // Remove a chunk from the free list.
  void
  remove(off_t start, off_t end);

  // Allocate a chunk of space from the free list of length LEN,
  // with alignment ALIGN, and minimum offset MINOFF.
  off_t
  allocate(off_t len, uint64_t align, off_t minoff);

  // Return an iterator for the beginning of the free list.
  Const_iterator
  begin() const
  { return this->list_.begin(); }

  // Return an iterator for the end of the free list.
  Const_iterator
  end() const
  { return this->list_.end(); }

  // Dump the free list (for debugging).
  void
  dump();

  // Print usage statistics.
  static void
  print_stats();

 private:
  typedef std::list<Free_list_node>::iterator Iterator;

  // The free list.
  std::list<Free_list_node> list_;

  // The last node visited during a remove operation.
  Iterator last_remove_;

  // Whether we can extend past the original length.
  bool extend_;

  // The total length of the section, segment, or file.
  off_t length_;

  // The minimum hole size allowed.  When allocating from the free list,
  // we must not leave a hole smaller than this.
  off_t min_hole_;

  // Statistics:
  // The total number of free lists used.
  static unsigned int num_lists;
  // The total number of free list nodes used.
  static unsigned int num_nodes;
  // The total number of calls to Free_list::remove.
  static unsigned int num_removes;
  // The total number of nodes visited during calls to Free_list::remove.
  static unsigned int num_remove_visits;
  // The total number of calls to Free_list::allocate.
  static unsigned int num_allocates;
  // The total number of nodes visited during calls to Free_list::allocate.
  static unsigned int num_allocate_visits;
};

// This task function handles mapping the input sections to output
// sections and laying them out in memory.

class Layout_task_runner : public Task_function_runner
{
 public:
  // OPTIONS is the command line options, INPUT_OBJECTS is the list of
  // input objects, SYMTAB is the symbol table, LAYOUT is the layout
  // object.
  Layout_task_runner(const General_options& options,
		     const Input_objects* input_objects,
		     Symbol_table* symtab,
		     Target* target,
		     Layout* layout,
		     Mapfile* mapfile)
    : options_(options), input_objects_(input_objects), symtab_(symtab),
      target_(target), layout_(layout), mapfile_(mapfile)
  { }

  // Run the operation.
  void
  run(Workqueue*, const Task*);

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

  const General_options& options_;
  const Input_objects* input_objects_;
  Symbol_table* symtab_;
  Target* target_;
  Layout* layout_;
  Mapfile* mapfile_;
};

// This class holds information about the comdat group or
// .gnu.linkonce section that will be kept for a given signature.

class Kept_section
{
 private:
  // For a comdat group, we build a mapping from the name of each
  // section in the group to the section index and the size in object.
  // When we discard a group in some other object file, we use this
  // map to figure out which kept section the discarded section is
  // associated with.  We then use that mapping when processing relocs
  // against discarded sections.
  struct Comdat_section_info
  {
    // The section index.
    unsigned int shndx;
    // The section size.
    uint64_t size;

    Comdat_section_info(unsigned int a_shndx, uint64_t a_size)
      : shndx(a_shndx), size(a_size)
    { }
  };

  // Most comdat groups have only one or two sections, so we use a
  // std::map rather than an Unordered_map to optimize for that case
  // without paying too heavily for groups with more sections.
  typedef std::map<std::string, Comdat_section_info> Comdat_group;

 public:
  Kept_section()
    : object_(NULL), shndx_(0), is_comdat_(false), is_group_name_(false)
  { this->u_.linkonce_size = 0; }

  // We need to support copies for the signature map in the Layout
  // object, but we should never copy an object after it has been
  // marked as a comdat section.
  Kept_section(const Kept_section& k)
    : object_(k.object_), shndx_(k.shndx_), is_comdat_(false),
      is_group_name_(k.is_group_name_)
  {
    gold_assert(!k.is_comdat_);
    this->u_.linkonce_size = 0;
  }

  ~Kept_section()
  {
    if (this->is_comdat_)
      delete this->u_.group_sections;
  }

  // The object where this section lives.
  Relobj*
  object() const
  { return this->object_; }

  // Set the object.
  void
  set_object(Relobj* object)
  {
    gold_assert(this->object_ == NULL);
    this->object_ = object;
  }

  // The section index.
  unsigned int
  shndx() const
  { return this->shndx_; }

  // Set the section index.
  void
  set_shndx(unsigned int shndx)
  {
    gold_assert(this->shndx_ == 0);
    this->shndx_ = shndx;
  }

  // Whether this is a comdat group.
  bool
  is_comdat() const
  { return this->is_comdat_; }

  // Set that this is a comdat group.
  void
  set_is_comdat()
  {
    gold_assert(!this->is_comdat_);
    this->is_comdat_ = true;
    this->u_.group_sections = new Comdat_group();
  }

  // Whether this is associated with the name of a group or section
  // rather than the symbol name derived from a linkonce section.
  bool
  is_group_name() const
  { return this->is_group_name_; }

  // Note that this represents a comdat group rather than a single
  // linkonce section.
  void
  set_is_group_name()
  { this->is_group_name_ = true; }

  // Add a section to the group list.
  void
  add_comdat_section(const std::string& name, unsigned int shndx,
		     uint64_t size)
  {
    gold_assert(this->is_comdat_);
    Comdat_section_info sinfo(shndx, size);
    this->u_.group_sections->insert(std::make_pair(name, sinfo));
  }

  // Look for a section name in the group list, and return whether it
  // was found.  If found, returns the section index and size.
  bool
  find_comdat_section(const std::string& name, unsigned int* pshndx,
		      uint64_t* psize) const
  {
    gold_assert(this->is_comdat_);
    Comdat_group::const_iterator p = this->u_.group_sections->find(name);
    if (p == this->u_.group_sections->end())
      return false;
    *pshndx = p->second.shndx;
    *psize = p->second.size;
    return true;
  }

  // If there is only one section in the group list, return true, and
  // return the section index and size.
  bool
  find_single_comdat_section(unsigned int* pshndx, uint64_t* psize) const
  {
    gold_assert(this->is_comdat_);
    if (this->u_.group_sections->size() != 1)
      return false;
    Comdat_group::const_iterator p = this->u_.group_sections->begin();
    *pshndx = p->second.shndx;
    *psize = p->second.size;
    return true;
  }

  // Return the size of a linkonce section.
  uint64_t
  linkonce_size() const
  {
    gold_assert(!this->is_comdat_);
    return this->u_.linkonce_size;
  }

  // Set the size of a linkonce section.
  void
  set_linkonce_size(uint64_t size)
  {
    gold_assert(!this->is_comdat_);
    this->u_.linkonce_size = size;
  }

 private:
  // No assignment.
  Kept_section& operator=(const Kept_section&);

  // The object containing the comdat group or .gnu.linkonce section.
  Relobj* object_;
  // Index of the group section for comdats and the section itself for
  // .gnu.linkonce.
  unsigned int shndx_;
  // True if this is for a comdat group rather than a .gnu.linkonce
  // section.
  bool is_comdat_;
  // The Kept_sections are values of a mapping, that maps names to
  // them.  This field is true if this struct is associated with the
  // name of a comdat or .gnu.linkonce, false if it is associated with
  // the name of a symbol obtained from the .gnu.linkonce.* name
  // through some heuristics.
  bool is_group_name_;
  union
  {
    // If the is_comdat_ field is true, this holds a map from names of
    // the sections in the group to section indexes in object_ and to
    // section sizes.
    Comdat_group* group_sections;
    // If the is_comdat_ field is false, this holds the size of the
    // single section.
    uint64_t linkonce_size;
  } u_;
};

// The ordering for output sections.  This controls how output
// sections are ordered within a PT_LOAD output segment.

enum Output_section_order
{
  // Unspecified.  Used for non-load segments.  Also used for the file
  // and segment headers.
  ORDER_INVALID,

  // The PT_INTERP section should come first, so that the dynamic
  // linker can pick it up quickly.
  ORDER_INTERP,

  // Loadable read-only note sections come next so that the PT_NOTE
  // segment is on the first page of the executable.
  ORDER_RO_NOTE,

  // Put read-only sections used by the dynamic linker early in the
  // executable to minimize paging.
  ORDER_DYNAMIC_LINKER,

  // Put reloc sections used by the dynamic linker after other
  // sections used by the dynamic linker; otherwise, objcopy and strip
  // get confused.
  ORDER_DYNAMIC_RELOCS,

  // Put the PLT reloc section after the other dynamic relocs;
  // otherwise, prelink gets confused.
  ORDER_DYNAMIC_PLT_RELOCS,

  // The .init section.
  ORDER_INIT,

  // The PLT.
  ORDER_PLT,

  // The regular text sections.
  ORDER_TEXT,

  // The .fini section.
  ORDER_FINI,

  // The read-only sections.
  ORDER_READONLY,

  // The exception frame sections.
  ORDER_EHFRAME,

  // The TLS sections come first in the data section.
  ORDER_TLS_DATA,
  ORDER_TLS_BSS,

  // Local RELRO (read-only after relocation) sections come before
  // non-local RELRO sections.  This data will be fully resolved by
  // the prelinker.
  ORDER_RELRO_LOCAL,

  // Non-local RELRO sections are grouped together after local RELRO
  // sections.  All RELRO sections must be adjacent so that they can
  // all be put into a PT_GNU_RELRO segment.
  ORDER_RELRO,

  // We permit marking exactly one output section as the last RELRO
  // section.  We do this so that the read-only GOT can be adjacent to
  // the writable GOT.
  ORDER_RELRO_LAST,

  // Similarly, we permit marking exactly one output section as the
  // first non-RELRO section.
  ORDER_NON_RELRO_FIRST,

  // The regular data sections come after the RELRO sections.
  ORDER_DATA,

  // Large data sections normally go in large data segments.
  ORDER_LARGE_DATA,

  // Group writable notes so that we can have a single PT_NOTE
  // segment.
  ORDER_RW_NOTE,

  // The small data sections must be at the end of the data sections,
  // so that they can be adjacent to the small BSS sections.
  ORDER_SMALL_DATA,

  // The BSS sections start here.

  // The small BSS sections must be at the start of the BSS sections,
  // so that they can be adjacent to the small data sections.
  ORDER_SMALL_BSS,

  // The regular BSS sections.
  ORDER_BSS,

  // The large BSS sections come after the other BSS sections.
  ORDER_LARGE_BSS,

  // Maximum value.
  ORDER_MAX
};

// This class handles the details of laying out input sections.

class Layout
{
 public:
  Layout(int number_of_input_files, Script_options*);

  ~Layout()
  {
    delete this->relaxation_debug_check_;
    delete this->segment_states_;
  }

  // For incremental links, record the base file to be modified.
  void
  set_incremental_base(Incremental_binary* base);

  Incremental_binary*
  incremental_base()
  { return this->incremental_base_; }

  // For incremental links, record the initial fixed layout of a section
  // from the base file, and return a pointer to the Output_section.
  template<int size, bool big_endian>
  Output_section*
  init_fixed_output_section(const char*, elfcpp::Shdr<size, big_endian>&);

  // Given an input section SHNDX, named NAME, with data in SHDR, from
  // the object file OBJECT, return the output section where this
  // input section should go.  RELOC_SHNDX is the index of a
  // relocation section which applies to this section, or 0 if none,
  // or -1U if more than one.  RELOC_TYPE is the type of the
  // relocation section if there is one.  Set *OFFSET to the offset
  // within the output section.
  template<int size, bool big_endian>
  Output_section*
  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, unsigned int reloc_type, off_t* offset);

  std::map<Section_id, unsigned int>*
  get_section_order_map()
  { return &this->section_order_map_; }

  // Struct to store segment info when mapping some input sections to
  // unique segments using linker plugins.  Mapping an input section to
  // a unique segment is done by first placing such input sections in
  // unique output sections and then mapping the output section to a
  // unique segment.  NAME is the name of the output section.  FLAGS
  // and ALIGN are the extra flags and alignment of the segment.
  struct Unique_segment_info
  {
    // Identifier for the segment.  ELF segments dont have names.  This
    // is used as the name of the output section mapped to the segment.
    const char* name;
    // Additional segment flags.
    uint64_t flags;
    // Segment alignment.
    uint64_t align;
  };

  // Mapping from input section to segment.
  typedef std::map<Const_section_id, Unique_segment_info*>
  Section_segment_map;

  // Maps section SECN to SEGMENT s.
  void
  insert_section_segment_map(Const_section_id secn, Unique_segment_info *s);

  // Some input sections require special ordering, for compatibility
  // with GNU ld.  Given the name of an input section, return -1 if it
  // does not require special ordering.  Otherwise, return the index
  // by which it should be ordered compared to other input sections
  // that require special ordering.
  static int
  special_ordering_of_input_section(const char* name);

  bool
  is_section_ordering_specified()
  { return this->section_ordering_specified_; }

  void
  set_section_ordering_specified()
  { this->section_ordering_specified_ = true; }

  bool
  is_unique_segment_for_sections_specified() const
  { return this->unique_segment_for_sections_specified_; }

  void
  set_unique_segment_for_sections_specified()
  { this->unique_segment_for_sections_specified_ = true; }

  // For incremental updates, allocate a block of memory from the
  // free list.  Find a block starting at or after MINOFF.
  off_t
  allocate(off_t len, uint64_t align, off_t minoff)
  { return this->free_list_.allocate(len, align, minoff); }

  unsigned int
  find_section_order_index(const std::string&);

  // Read the sequence of input sections from the file specified with
  // linker option --section-ordering-file.
  void
  read_layout_from_file();

  // Layout an input reloc section when doing a relocatable link.  The
  // section is RELOC_SHNDX in OBJECT, with data in SHDR.
  // DATA_SECTION is the reloc section to which it refers.  RR is the
  // relocatable information.
  template<int size, bool big_endian>
  Output_section*
  layout_reloc(Sized_relobj_file<size, big_endian>* object,
	       unsigned int reloc_shndx,
	       const elfcpp::Shdr<size, big_endian>& shdr,
	       Output_section* data_section,
	       Relocatable_relocs* rr);

  // Layout a group section when doing a relocatable link.
  template<int size, bool big_endian>
  void
  layout_group(Symbol_table* symtab,
	       Sized_relobj_file<size, big_endian>* object,
	       unsigned int group_shndx,
	       const char* group_section_name,
	       const char* signature,
	       const elfcpp::Shdr<size, big_endian>& shdr,
	       elfcpp::Elf_Word flags,
	       std::vector<unsigned int>* shndxes);

  // Like layout, only for exception frame sections.  OBJECT is an
  // object file.  SYMBOLS is the contents of the symbol table
  // section, with size SYMBOLS_SIZE.  SYMBOL_NAMES is the contents of
  // the symbol name section, with size SYMBOL_NAMES_SIZE.  SHNDX is a
  // .eh_frame section in OBJECT.  SHDR is the section header.
  // RELOC_SHNDX is the index of a relocation section which applies to
  // this section, or 0 if none, or -1U if more than one.  RELOC_TYPE
  // is the type of the relocation section if there is one.  This
  // returns the output section, and sets *OFFSET to the offset.
  template<int size, bool big_endian>
  Output_section*
  layout_eh_frame(Sized_relobj_file<size, big_endian>* object,
		  const unsigned char* symbols,
		  off_t symbols_size,
		  const unsigned char* symbol_names,
		  off_t symbol_names_size,
		  unsigned int shndx,
		  const elfcpp::Shdr<size, big_endian>& shdr,
		  unsigned int reloc_shndx, unsigned int reloc_type,
		  off_t* offset);

  // Add .eh_frame information for a PLT.  The FDE must start with a
  // 4-byte PC-relative reference to the start of the PLT, followed by
  // a 4-byte size of PLT.
  void
  add_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data,
		       size_t cie_length, const unsigned char* fde_data,
		       size_t fde_length);

  // Scan a .debug_info or .debug_types section, and add summary
  // information to the .gdb_index section.
  template<int size, bool big_endian>
  void
  add_to_gdb_index(bool is_type_unit,
		   Sized_relobj<size, big_endian>* object,
		   const unsigned char* symbols,
		   off_t symbols_size,
		   unsigned int shndx,
		   unsigned int reloc_shndx,
		   unsigned int reloc_type);

  // Handle a GNU stack note.  This is called once per input object
  // file.  SEEN_GNU_STACK is true if the object file has a
  // .note.GNU-stack section.  GNU_STACK_FLAGS is the section flags
  // from that section if there was one.
  void
  layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags,
		   const Object*);

  // Add an Output_section_data to the layout.  This is used for
  // special sections like the GOT section.  ORDER is where the
  // section should wind up in the output segment.  IS_RELRO is true
  // for relro sections.
  Output_section*
  add_output_section_data(const char* name, elfcpp::Elf_Word type,
			  elfcpp::Elf_Xword flags,
			  Output_section_data*, Output_section_order order,
			  bool is_relro);

  // Increase the size of the relro segment by this much.
  void
  increase_relro(unsigned int s)
  { this->increase_relro_ += s; }

  // Create dynamic sections if necessary.
  void
  create_initial_dynamic_sections(Symbol_table*);

  // Define __start and __stop symbols for output sections.
  void
  define_section_symbols(Symbol_table*);

  // Create automatic note sections.
  void
  create_notes();

  // Create sections for linker scripts.
  void
  create_script_sections()
  { this->script_options_->create_script_sections(this); }

  // Define symbols from any linker script.
  void
  define_script_symbols(Symbol_table* symtab)
  { this->script_options_->add_symbols_to_table(symtab); }

  // Define symbols for group signatures.
  void
  define_group_signatures(Symbol_table*);

  // Return the Stringpool used for symbol names.
  const Stringpool*
  sympool() const
  { return &this->sympool_; }

  // Return the Stringpool used for dynamic symbol names and dynamic
  // tags.
  const Stringpool*
  dynpool() const
  { return &this->dynpool_; }

  // Return the .dynamic output section.  This is only valid after the
  // layout has been finalized.
  Output_section*
  dynamic_section() const
  { return this->dynamic_section_; }

  // Return the symtab_xindex section used to hold large section
  // indexes for the normal symbol table.
  Output_symtab_xindex*
  symtab_xindex() const
  { return this->symtab_xindex_; }

  // Return the dynsym_xindex section used to hold large section
  // indexes for the dynamic symbol table.
  Output_symtab_xindex*
  dynsym_xindex() const
  { return this->dynsym_xindex_; }

  // Return whether a section is a .gnu.linkonce section, given the
  // section name.
  static inline bool
  is_linkonce(const char* name)
  { return strncmp(name, ".gnu.linkonce", sizeof(".gnu.linkonce") - 1) == 0; }

  // Whether we have added an input section.
  bool
  have_added_input_section() const
  { return this->have_added_input_section_; }

  // Return true if a section is a debugging section.
  static inline bool
  is_debug_info_section(const char* name)
  {
    // Debugging sections can only be recognized by name.
    return (strncmp(name, ".debug", sizeof(".debug") - 1) == 0
	    || strncmp(name, ".zdebug", sizeof(".zdebug") - 1) == 0
	    || strncmp(name, ".gnu.linkonce.wi.",
		       sizeof(".gnu.linkonce.wi.") - 1) == 0
	    || strncmp(name, ".line", sizeof(".line") - 1) == 0
	    || strncmp(name, ".stab", sizeof(".stab") - 1) == 0);
  }

  // Return true if RELOBJ is an input file whose base name matches
  // FILE_NAME.  The base name must have an extension of ".o", and
  // must be exactly FILE_NAME.o or FILE_NAME, one character, ".o".
  static bool
  match_file_name(const Relobj* relobj, const char* file_name);

  // Return whether section SHNDX in RELOBJ is a .ctors/.dtors section
  // with more than one word being mapped to a .init_array/.fini_array
  // section.
  bool
  is_ctors_in_init_array(Relobj* relobj, unsigned int shndx) const;

  // Check if a comdat group or .gnu.linkonce section with the given
  // NAME is selected for the link.  If there is already a section,
  // *KEPT_SECTION is set to point to the signature and the function
  // returns false.  Otherwise, OBJECT, SHNDX,IS_COMDAT, and
  // IS_GROUP_NAME are recorded for this NAME in the layout object,
  // *KEPT_SECTION is set to the internal copy and the function return
  // false.
  bool
  find_or_add_kept_section(const std::string& name, Relobj* object,
			   unsigned int shndx, bool is_comdat,
			   bool is_group_name, Kept_section** kept_section);

  // Finalize the layout after all the input sections have been added.
  off_t
  finalize(const Input_objects*, Symbol_table*, Target*, const Task*);

  // Return whether any sections require postprocessing.
  bool
  any_postprocessing_sections() const
  { return this->any_postprocessing_sections_; }

  // Return the size of the output file.
  off_t
  output_file_size() const
  { return this->output_file_size_; }

  // Return the TLS segment.  This will return NULL if there isn't
  // one.
  Output_segment*
  tls_segment() const
  { return this->tls_segment_; }

  // Return the normal symbol table.
  Output_section*
  symtab_section() const
  {
    gold_assert(this->symtab_section_ != NULL);
    return this->symtab_section_;
  }

  // Return the file offset of the normal symbol table.
  off_t
  symtab_section_offset() const;

  // Return the section index of the normal symbol tabl.e
  unsigned int
  symtab_section_shndx() const;

  // Return the dynamic symbol table.
  Output_section*
  dynsym_section() const
  {
    gold_assert(this->dynsym_section_ != NULL);
    return this->dynsym_section_;
  }

  // Return the dynamic tags.
  Output_data_dynamic*
  dynamic_data() const
  { return this->dynamic_data_; }

  // Write out the output sections.
  void
  write_output_sections(Output_file* of) const;

  // Write out data not associated with an input file or the symbol
  // table.
  void
  write_data(const Symbol_table*, Output_file*) const;

  // Write out output sections which can not be written until all the
  // input sections are complete.
  void
  write_sections_after_input_sections(Output_file* of);

  // Return an output section named NAME, or NULL if there is none.
  Output_section*
  find_output_section(const char* name) const;

  // Return an output segment of type TYPE, with segment flags SET set
  // and segment flags CLEAR clear.  Return NULL if there is none.
  Output_segment*
  find_output_segment(elfcpp::PT type, elfcpp::Elf_Word set,
		      elfcpp::Elf_Word clear) const;

  // Return the number of segments we expect to produce.
  size_t
  expected_segment_count() const;

  // Set a flag to indicate that an object file uses the static TLS model.
  void
  set_has_static_tls()
  { this->has_static_tls_ = true; }

  // Return true if any object file uses the static TLS model.
  bool
  has_static_tls() const
  { return this->has_static_tls_; }

  // Return the options which may be set by a linker script.
  Script_options*
  script_options()
  { return this->script_options_; }

  const Script_options*
  script_options() const
  { return this->script_options_; }

  // Return the object managing inputs in incremental build. NULL in
  // non-incremental builds.
  Incremental_inputs*
  incremental_inputs() const
  { return this->incremental_inputs_; }

  // For the target-specific code to add dynamic tags which are common
  // to most targets.
  void
  add_target_dynamic_tags(bool use_rel, const Output_data* plt_got,
			  const Output_data* plt_rel,
			  const Output_data_reloc_generic* dyn_rel,
			  bool add_debug, bool dynrel_includes_plt);

  // If a treehash is necessary to compute the build ID, then queue
  // the necessary tasks and return a blocker that will unblock when
  // they finish.  Otherwise return BUILD_ID_BLOCKER.
  Task_token*
  queue_build_id_tasks(Workqueue* workqueue, Task_token* build_id_blocker,
                       Output_file* of);

  // Compute and write out the build ID if needed.
  void
  write_build_id(Output_file*) const;

  // Rewrite output file in binary format.
  void
  write_binary(Output_file* in) const;

  // Print output sections to the map file.
  void
  print_to_mapfile(Mapfile*) const;

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

  // A list of segments.

  typedef std::vector<Output_segment*> Segment_list;

  // A list of sections.

  typedef std::vector<Output_section*> Section_list;

  // The list of information to write out which is not attached to
  // either a section or a segment.
  typedef std::vector<Output_data*> Data_list;

  // Store the allocated sections into the section list.  This is used
  // by the linker script code.
  void
  get_allocated_sections(Section_list*) const;

  // Store the executable sections into the section list.
  void
  get_executable_sections(Section_list*) const;

  // Make a section for a linker script to hold data.
  Output_section*
  make_output_section_for_script(const char* name,
				 Script_sections::Section_type section_type);

  // Make a segment.  This is used by the linker script code.
  Output_segment*
  make_output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags);

  // Return the number of segments.
  size_t
  segment_count() const
  { return this->segment_list_.size(); }

  // Map from section flags to segment flags.
  static elfcpp::Elf_Word
  section_flags_to_segment(elfcpp::Elf_Xword flags);

  // Attach sections to segments.
  void
  attach_sections_to_segments(const Target*);

  // For relaxation clean up, we need to know output section data created
  // from a linker script.
  void
  new_output_section_data_from_script(Output_section_data* posd)
  {
    if (this->record_output_section_data_from_script_)
      this->script_output_section_data_list_.push_back(posd);
  }

  // Return section list.
  const Section_list&
  section_list() const
  { return this->section_list_; }

  // Returns TRUE iff NAME (an input section from RELOBJ) will
  // be mapped to an output section that should be KEPT.
  bool
  keep_input_section(const Relobj*, const char*);
  
 private:
  Layout(const Layout&);
  Layout& operator=(const Layout&);

  // Mapping from input section names to output section names.
  struct Section_name_mapping
  {
    const char* from;
    int fromlen;
    const char* to;
    int tolen;
  };
  static const Section_name_mapping section_name_mapping[];
  static const int section_name_mapping_count;

  // During a relocatable link, a list of group sections and
  // signatures.
  struct Group_signature
  {
    // The group section.
    Output_section* section;
    // The signature.
    const char* signature;

    Group_signature()
      : section(NULL), signature(NULL)
    { }

    Group_signature(Output_section* sectiona, const char* signaturea)
      : section(sectiona), signature(signaturea)
    { }
  };
  typedef std::vector<Group_signature> Group_signatures;

  // Create a note section, filling in the header.
  Output_section*
  create_note(const char* name, int note_type, const char* section_name,
	      size_t descsz, bool allocate, size_t* trailing_padding);

  // Create a note section for gold version.
  void
  create_gold_note();

  // Record whether the stack must be executable.
  void
  create_executable_stack_info();

  // Create a build ID note if needed.
  void
  create_build_id();

  // Link .stab and .stabstr sections.
  void
  link_stabs_sections();

  // Create .gnu_incremental_inputs and .gnu_incremental_strtab sections needed
  // for the next run of incremental linking to check what has changed.
  void
  create_incremental_info_sections(Symbol_table*);

  // Find the first read-only PT_LOAD segment, creating one if
  // necessary.
  Output_segment*
  find_first_load_seg(const Target*);

  // Count the local symbols in the regular symbol table and the dynamic
  // symbol table, and build the respective string pools.
  void
  count_local_symbols(const Task*, const Input_objects*);

  // Create the output sections for the symbol table.
  void
  create_symtab_sections(const Input_objects*, Symbol_table*,
			 unsigned int, off_t*);

  // Create the .shstrtab section.
  Output_section*
  create_shstrtab();

  // Create the section header table.
  void
  create_shdrs(const Output_section* shstrtab_section, off_t*);

  // Create the dynamic symbol table.
  void
  create_dynamic_symtab(const Input_objects*, Symbol_table*,
			Output_section** pdynstr,
			unsigned int* plocal_dynamic_count,
			std::vector<Symbol*>* pdynamic_symbols,
			Versions* versions);

  // Assign offsets to each local portion of the dynamic symbol table.
  void
  assign_local_dynsym_offsets(const Input_objects*);

  // Finish the .dynamic section and PT_DYNAMIC segment.
  void
  finish_dynamic_section(const Input_objects*, const Symbol_table*);

  // Set the size of the _DYNAMIC symbol.
  void
  set_dynamic_symbol_size(const Symbol_table*);

  // Create the .interp section and PT_INTERP segment.
  void
  create_interp(const Target* target);

  // Create the version sections.
  void
  create_version_sections(const Versions*,
			  const Symbol_table*,
			  unsigned int local_symcount,
			  const std::vector<Symbol*>& dynamic_symbols,
			  const Output_section* dynstr);

  template<int size, bool big_endian>
  void
  sized_create_version_sections(const Versions* versions,
				const Symbol_table*,
				unsigned int local_symcount,
				const std::vector<Symbol*>& dynamic_symbols,
				const Output_section* dynstr);

  // Return whether to include this section in the link.
  template<int size, bool big_endian>
  bool
  include_section(Sized_relobj_file<size, big_endian>* object, const char* name,
		  const elfcpp::Shdr<size, big_endian>&);

  // Return the output section name to use given an input section
  // name.  Set *PLEN to the length of the name.  *PLEN must be
  // initialized to the length of NAME.
  static const char*
  output_section_name(const Relobj*, const char* name, size_t* plen);

  // Return the number of allocated output sections.
  size_t
  allocated_output_section_count() const;

  // Return the output section for NAME, TYPE and FLAGS.
  Output_section*
  get_output_section(const char* name, Stringpool::Key name_key,
		     elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
		     Output_section_order order, bool is_relro);

  // Clear the input section flags that should not be copied to the
  // output section.
  elfcpp::Elf_Xword
  get_output_section_flags (elfcpp::Elf_Xword input_section_flags);

  // Choose the output section for NAME in RELOBJ.
  Output_section*
  choose_output_section(const Relobj* relobj, const char* name,
			elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
			bool is_input_section, Output_section_order order,
			bool is_relro);

  // Create a new Output_section.
  Output_section*
  make_output_section(const char* name, elfcpp::Elf_Word type,
		      elfcpp::Elf_Xword flags, Output_section_order order,
		      bool is_relro);

  // Attach a section to a segment.
  void
  attach_section_to_segment(const Target*, Output_section*);

  // Get section order.
  Output_section_order
  default_section_order(Output_section*, bool is_relro_local);

  // Attach an allocated section to a segment.
  void
  attach_allocated_section_to_segment(const Target*, Output_section*);

  // Make the .eh_frame section.
  Output_section*
  make_eh_frame_section(const Relobj*);

  // Set the final file offsets of all the segments.
  off_t
  set_segment_offsets(const Target*, Output_segment*, unsigned int* pshndx);

  // Set the file offsets of the sections when doing a relocatable
  // link.
  off_t
  set_relocatable_section_offsets(Output_data*, unsigned int* pshndx);

  // Set the final file offsets of all the sections not associated
  // with a segment.  We set section offsets in three passes: the
  // first handles all allocated sections, the second sections that
  // require postprocessing, and the last the late-bound STRTAB
  // sections (probably only shstrtab, which is the one we care about
  // because it holds section names).
  enum Section_offset_pass
  {
    BEFORE_INPUT_SECTIONS_PASS,
    POSTPROCESSING_SECTIONS_PASS,
    STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS
  };
  off_t
  set_section_offsets(off_t, Section_offset_pass pass);

  // Set the final section indexes of all the sections not associated
  // with a segment.  Returns the next unused index.
  unsigned int
  set_section_indexes(unsigned int pshndx);

  // Set the section addresses when using a script.
  Output_segment*
  set_section_addresses_from_script(Symbol_table*);

  // Find appropriate places or orphan sections in a script.
  void
  place_orphan_sections_in_script();

  // Return whether SEG1 comes before SEG2 in the output file.
  bool
  segment_precedes(const Output_segment* seg1, const Output_segment* seg2);

  // Use to save and restore segments during relaxation.
  typedef Unordered_map<const Output_segment*, const Output_segment*>
    Segment_states;

  // Save states of current output segments.
  void
  save_segments(Segment_states*);

  // Restore output segment states.
  void
  restore_segments(const Segment_states*);

  // Clean up after relaxation so that it is possible to lay out the
  // sections and segments again.
  void
  clean_up_after_relaxation();

  // Doing preparation work for relaxation.  This is factored out to make
  // Layout::finalized a bit smaller and easier to read.
  void
  prepare_for_relaxation();

  // Main body of the relaxation loop, which lays out the section.
  off_t
  relaxation_loop_body(int, Target*, Symbol_table*, Output_segment**,
		       Output_segment*, Output_segment_headers*,
		       Output_file_header*, unsigned int*);

  // A mapping used for kept comdats/.gnu.linkonce group signatures.
  typedef Unordered_map<std::string, Kept_section> Signatures;

  // Mapping from input section name/type/flags to output section.  We
  // use canonicalized strings here.

  typedef std::pair<Stringpool::Key,
		    std::pair<elfcpp::Elf_Word, elfcpp::Elf_Xword> > Key;

  struct Hash_key
  {
    size_t
    operator()(const Key& k) const;
  };

  typedef Unordered_map<Key, Output_section*, Hash_key> Section_name_map;

  // A comparison class for segments.

  class Compare_segments
  {
   public:
    Compare_segments(Layout* layout)
      : layout_(layout)
    { }

    bool
    operator()(const Output_segment* seg1, const Output_segment* seg2)
    { return this->layout_->segment_precedes(seg1, seg2); }

   private:
    Layout* layout_;
  };

  typedef std::vector<Output_section_data*> Output_section_data_list;

  // Debug checker class.
  class Relaxation_debug_check
  {
   public:
    Relaxation_debug_check()
      : section_infos_()
    { }

    // Check that sections and special data are in reset states.
    void
    check_output_data_for_reset_values(const Layout::Section_list&,
				       const Layout::Data_list&);

    // Record information of a section list.
    void
    read_sections(const Layout::Section_list&);

    // Verify a section list with recorded information.
    void
    verify_sections(const Layout::Section_list&);

   private:
    // Information we care about a section.
    struct Section_info
    {
      // Output section described by this.
      Output_section* output_section;
      // Load address.
      uint64_t address;
      // Data size.
      off_t data_size;
      // File offset.
      off_t offset;
    };

    // Section information.
    std::vector<Section_info> section_infos_;
  };

  // The number of input files, for sizing tables.
  int number_of_input_files_;
  // Information set by scripts or by command line options.
  Script_options* script_options_;
  // The output section names.
  Stringpool namepool_;
  // The output symbol names.
  Stringpool sympool_;
  // The dynamic strings, if needed.
  Stringpool dynpool_;
  // The list of group sections and linkonce sections which we have seen.
  Signatures signatures_;
  // The mapping from input section name/type/flags to output sections.
  Section_name_map section_name_map_;
  // The list of output segments.
  Segment_list segment_list_;
  // The list of output sections.
  Section_list section_list_;
  // The list of output sections which are not attached to any output
  // segment.
  Section_list unattached_section_list_;
  // The list of unattached Output_data objects which require special
  // handling because they are not Output_sections.
  Data_list special_output_list_;
  // The section headers.
  Output_section_headers* section_headers_;
  // A pointer to the PT_TLS segment if there is one.
  Output_segment* tls_segment_;
  // A pointer to the PT_GNU_RELRO segment if there is one.
  Output_segment* relro_segment_;
  // A pointer to the PT_INTERP segment if there is one.
  Output_segment* interp_segment_;
  // A backend may increase the size of the PT_GNU_RELRO segment if
  // there is one.  This is the amount to increase it by.
  unsigned int increase_relro_;
  // The SHT_SYMTAB output section.
  Output_section* symtab_section_;
  // The SHT_SYMTAB_SHNDX for the regular symbol table if there is one.
  Output_symtab_xindex* symtab_xindex_;
  // The SHT_DYNSYM output section if there is one.
  Output_section* dynsym_section_;
  // The SHT_SYMTAB_SHNDX for the dynamic symbol table if there is one.
  Output_symtab_xindex* dynsym_xindex_;
  // The SHT_DYNAMIC output section if there is one.
  Output_section* dynamic_section_;
  // The _DYNAMIC symbol if there is one.
  Symbol* dynamic_symbol_;
  // The dynamic data which goes into dynamic_section_.
  Output_data_dynamic* dynamic_data_;
  // The exception frame output section if there is one.
  Output_section* eh_frame_section_;
  // The exception frame data for eh_frame_section_.
  Eh_frame* eh_frame_data_;
  // Whether we have added eh_frame_data_ to the .eh_frame section.
  bool added_eh_frame_data_;
  // The exception frame header output section if there is one.
  Output_section* eh_frame_hdr_section_;
  // The data for the .gdb_index section.
  Gdb_index* gdb_index_data_;
  // The space for the build ID checksum if there is one.
  Output_section_data* build_id_note_;
  // Temporary storage for tree hash of build ID.
  unsigned char* array_of_hashes_;
  // Size of array_of_hashes_ (in bytes).
  size_t size_of_array_of_hashes_;
  // Input view for computing tree hash of build ID.  Freed in write_build_id().
  const unsigned char* input_view_;
  // The output section containing dwarf abbreviations
  Output_reduced_debug_abbrev_section* debug_abbrev_;
  // The output section containing the dwarf debug info tree
  Output_reduced_debug_info_section* debug_info_;
  // A list of group sections and their signatures.
  Group_signatures group_signatures_;
  // The size of the output file.
  off_t output_file_size_;
  // Whether we have added an input section to an output section.
  bool have_added_input_section_;
  // Whether we have attached the sections to the segments.
  bool sections_are_attached_;
  // Whether we have seen an object file marked to require an
  // executable stack.
  bool input_requires_executable_stack_;
  // Whether we have seen at least one object file with an executable
  // stack marker.
  bool input_with_gnu_stack_note_;
  // Whether we have seen at least one object file without an
  // executable stack marker.
  bool input_without_gnu_stack_note_;
  // Whether we have seen an object file that uses the static TLS model.
  bool has_static_tls_;
  // Whether any sections require postprocessing.
  bool any_postprocessing_sections_;
  // Whether we have resized the signatures_ hash table.
  bool resized_signatures_;
  // Whether we have created a .stab*str output section.
  bool have_stabstr_section_;
  // True if the input sections in the output sections should be sorted
  // as specified in a section ordering file.
  bool section_ordering_specified_;
  // True if some input sections need to be mapped to a unique segment,
  // after being mapped to a unique Output_section.
  bool unique_segment_for_sections_specified_;
  // In incremental build, holds information check the inputs and build the
  // .gnu_incremental_inputs section.
  Incremental_inputs* incremental_inputs_;
  // Whether we record output section data created in script
  bool record_output_section_data_from_script_;
  // List of output data that needs to be removed at relaxation clean up.
  Output_section_data_list script_output_section_data_list_;
  // Structure to save segment states before entering the relaxation loop.
  Segment_states* segment_states_;
  // A relaxation debug checker.  We only create one when in debugging mode.
  Relaxation_debug_check* relaxation_debug_check_;
  // Plugins specify section_ordering using this map.  This is set in
  // update_section_order in plugin.cc
  std::map<Section_id, unsigned int> section_order_map_;
  // This maps an input section to a unique segment. This is done by first
  // placing such input sections in unique output sections and then mapping
  // the output section to a unique segment.  Unique_segment_info stores
  // any additional flags and alignment of the new segment.
  Section_segment_map section_segment_map_;
  // Hash a pattern to its position in the section ordering file.
  Unordered_map<std::string, unsigned int> input_section_position_;
  // Vector of glob only patterns in the section_ordering file.
  std::vector<std::string> input_section_glob_;
  // For incremental links, the base file to be modified.
  Incremental_binary* incremental_base_;
  // For incremental links, a list of free space within the file.
  Free_list free_list_;
};

// This task handles writing out data in output sections which is not
// part of an input section, or which requires special handling.  When
// this is done, it unblocks both output_sections_blocker and
// final_blocker.

class Write_sections_task : public Task
{
 public:
  Write_sections_task(const Layout* layout, Output_file* of,
		      Task_token* output_sections_blocker,
		      Task_token* final_blocker)
    : layout_(layout), of_(of),
      output_sections_blocker_(output_sections_blocker),
      final_blocker_(final_blocker)
  { }

  // The standard Task methods.

  Task_token*
  is_runnable();

  void
  locks(Task_locker*);

  void
  run(Workqueue*);

  std::string
  get_name() const
  { return "Write_sections_task"; }

 private:
  class Write_sections_locker;

  const Layout* layout_;
  Output_file* of_;
  Task_token* output_sections_blocker_;
  Task_token* final_blocker_;
};

// This task handles writing out data which is not part of a section
// or segment.

class Write_data_task : public Task
{
 public:
  Write_data_task(const Layout* layout, const Symbol_table* symtab,
		  Output_file* of, Task_token* final_blocker)
    : layout_(layout), symtab_(symtab), of_(of), final_blocker_(final_blocker)
  { }

  // The standard Task methods.

  Task_token*
  is_runnable();

  void
  locks(Task_locker*);

  void
  run(Workqueue*);

  std::string
  get_name() const
  { return "Write_data_task"; }

 private:
  const Layout* layout_;
  const Symbol_table* symtab_;
  Output_file* of_;
  Task_token* final_blocker_;
};

// This task handles writing out the global symbols.

class Write_symbols_task : public Task
{
 public:
  Write_symbols_task(const Layout* layout, const Symbol_table* symtab,
		     const Input_objects* input_objects,
		     const Stringpool* sympool, const Stringpool* dynpool,
		     Output_file* of, Task_token* final_blocker)
    : layout_(layout), symtab_(symtab), input_objects_(input_objects),
      sympool_(sympool), dynpool_(dynpool), of_(of),
      final_blocker_(final_blocker)
  { }

  // The standard Task methods.

  Task_token*
  is_runnable();

  void
  locks(Task_locker*);

  void
  run(Workqueue*);

  std::string
  get_name() const
  { return "Write_symbols_task"; }

 private:
  const Layout* layout_;
  const Symbol_table* symtab_;
  const Input_objects* input_objects_;
  const Stringpool* sympool_;
  const Stringpool* dynpool_;
  Output_file* of_;
  Task_token* final_blocker_;
};

// This task handles writing out data in output sections which can't
// be written out until all the input sections have been handled.
// This is for sections whose contents is based on the contents of
// other output sections.

class Write_after_input_sections_task : public Task
{
 public:
  Write_after_input_sections_task(Layout* layout, Output_file* of,
				  Task_token* input_sections_blocker,
				  Task_token* final_blocker)
    : layout_(layout), of_(of),
      input_sections_blocker_(input_sections_blocker),
      final_blocker_(final_blocker)
  { }

  // The standard Task methods.

  Task_token*
  is_runnable();

  void
  locks(Task_locker*);

  void
  run(Workqueue*);

  std::string
  get_name() const
  { return "Write_after_input_sections_task"; }

 private:
  Layout* layout_;
  Output_file* of_;
  Task_token* input_sections_blocker_;
  Task_token* final_blocker_;
};

// This task function handles closing the file.

class Close_task_runner : public Task_function_runner
{
 public:
  Close_task_runner(const General_options* options, const Layout* layout,
		    Output_file* of)
    : options_(options), layout_(layout), of_(of)
  { }

  // Run the operation.
  void
  run(Workqueue*, const Task*);

 private:
  const General_options* options_;
  const Layout* layout_;
  Output_file* of_;
};

// A small helper function to align an address.

inline uint64_t
align_address(uint64_t address, uint64_t addralign)
{
  if (addralign != 0)
    address = (address + addralign - 1) &~ (addralign - 1);
  return address;
}

} // End namespace gold.

#endif // !defined(GOLD_LAYOUT_H)
