// layout.cc -- lay out output file sections for gold

// Copyright (C) 2006-2014 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// This file is part of gold.

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

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

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

#include "gold.h"

#include <cerrno>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <utility>
#include <fcntl.h>
#include <fnmatch.h>
#include <unistd.h>
#include "libiberty.h"
#include "md5.h"
#include "sha1.h"

#include "parameters.h"
#include "options.h"
#include "mapfile.h"
#include "script.h"
#include "script-sections.h"
#include "output.h"
#include "symtab.h"
#include "dynobj.h"
#include "ehframe.h"
#include "gdb-index.h"
#include "compressed_output.h"
#include "reduced_debug_output.h"
#include "object.h"
#include "reloc.h"
#include "descriptors.h"
#include "plugin.h"
#include "incremental.h"
#include "layout.h"

namespace gold
{

// Class Free_list.

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

// Initialize the free list.  Creates a single free list node that
// describes the entire region of length LEN.  If EXTEND is true,
// allocate() is allowed to extend the region beyond its initial
// length.

void
Free_list::init(off_t len, bool extend)
{
  this->list_.push_front(Free_list_node(0, len));
  this->last_remove_ = this->list_.begin();
  this->extend_ = extend;
  this->length_ = len;
  ++Free_list::num_lists;
  ++Free_list::num_nodes;
}

// Remove a chunk from the free list.  Because we start with a single
// node that covers the entire section, and remove chunks from it one
// at a time, we do not need to coalesce chunks or handle cases that
// span more than one free node.  We expect to remove chunks from the
// free list in order, and we expect to have only a few chunks of free
// space left (corresponding to files that have changed since the last
// incremental link), so a simple linear list should provide sufficient
// performance.

void
Free_list::remove(off_t start, off_t end)
{
  if (start == end)
    return;
  gold_assert(start < end);

  ++Free_list::num_removes;

  Iterator p = this->last_remove_;
  if (p->start_ > start)
    p = this->list_.begin();

  for (; p != this->list_.end(); ++p)
    {
      ++Free_list::num_remove_visits;
      // Find a node that wholly contains the indicated region.
      if (p->start_ <= start && p->end_ >= end)
	{
	  // Case 1: the indicated region spans the whole node.
	  // Add some fuzz to avoid creating tiny free chunks.
	  if (p->start_ + 3 >= start && p->end_ <= end + 3)
	    p = this->list_.erase(p);
	  // Case 2: remove a chunk from the start of the node.
	  else if (p->start_ + 3 >= start)
	    p->start_ = end;
	  // Case 3: remove a chunk from the end of the node.
	  else if (p->end_ <= end + 3)
	    p->end_ = start;
	  // Case 4: remove a chunk from the middle, and split
	  // the node into two.
	  else
	    {
	      Free_list_node newnode(p->start_, start);
	      p->start_ = end;
	      this->list_.insert(p, newnode);
	      ++Free_list::num_nodes;
	    }
	  this->last_remove_ = p;
	  return;
	}
    }

  // Did not find a node containing the given chunk.  This could happen
  // because a small chunk was already removed due to the fuzz.
  gold_debug(DEBUG_INCREMENTAL,
	     "Free_list::remove(%d,%d) not found",
	     static_cast<int>(start), static_cast<int>(end));
}

// Allocate a chunk of size LEN from the free list.  Returns -1ULL
// if a sufficiently large chunk of free space is not found.
// We use a simple first-fit algorithm.

off_t
Free_list::allocate(off_t len, uint64_t align, off_t minoff)
{
  gold_debug(DEBUG_INCREMENTAL,
	     "Free_list::allocate(%08lx, %d, %08lx)",
	     static_cast<long>(len), static_cast<int>(align),
	     static_cast<long>(minoff));
  if (len == 0)
    return align_address(minoff, align);

  ++Free_list::num_allocates;

  // We usually want to drop free chunks smaller than 4 bytes.
  // If we need to guarantee a minimum hole size, though, we need
  // to keep track of all free chunks.
  const int fuzz = this->min_hole_ > 0 ? 0 : 3;

  for (Iterator p = this->list_.begin(); p != this->list_.end(); ++p)
    {
      ++Free_list::num_allocate_visits;
      off_t start = p->start_ > minoff ? p->start_ : minoff;
      start = align_address(start, align);
      off_t end = start + len;
      if (end > p->end_ && p->end_ == this->length_ && this->extend_)
	{
	  this->length_ = end;
	  p->end_ = end;
	}
      if (end == p->end_ || (end <= p->end_ - this->min_hole_))
	{
	  if (p->start_ + fuzz >= start && p->end_ <= end + fuzz)
	    this->list_.erase(p);
	  else if (p->start_ + fuzz >= start)
	    p->start_ = end;
	  else if (p->end_ <= end + fuzz)
	    p->end_ = start;
	  else
	    {
	      Free_list_node newnode(p->start_, start);
	      p->start_ = end;
	      this->list_.insert(p, newnode);
	      ++Free_list::num_nodes;
	    }
	  return start;
	}
    }
  if (this->extend_)
    {
      off_t start = align_address(this->length_, align);
      this->length_ = start + len;
      return start;
    }
  return -1;
}

// Dump the free list (for debugging).
void
Free_list::dump()
{
  gold_info("Free list:\n     start      end   length\n");
  for (Iterator p = this->list_.begin(); p != this->list_.end(); ++p)
    gold_info("  %08lx %08lx %08lx", static_cast<long>(p->start_),
	      static_cast<long>(p->end_),
	      static_cast<long>(p->end_ - p->start_));
}

// Print the statistics for the free lists.
void
Free_list::print_stats()
{
  fprintf(stderr, _("%s: total free lists: %u\n"),
	  program_name, Free_list::num_lists);
  fprintf(stderr, _("%s: total free list nodes: %u\n"),
	  program_name, Free_list::num_nodes);
  fprintf(stderr, _("%s: calls to Free_list::remove: %u\n"),
	  program_name, Free_list::num_removes);
  fprintf(stderr, _("%s: nodes visited: %u\n"),
	  program_name, Free_list::num_remove_visits);
  fprintf(stderr, _("%s: calls to Free_list::allocate: %u\n"),
	  program_name, Free_list::num_allocates);
  fprintf(stderr, _("%s: nodes visited: %u\n"),
	  program_name, Free_list::num_allocate_visits);
}

// A Hash_task computes the MD5 checksum of an array of char.
// It has a blocker on either side (i.e., the task cannot run until
// the first is unblocked, and it unblocks the second after running).

class Hash_task : public Task
{
 public:
  Hash_task(const unsigned char* src,
	    size_t size,
	    unsigned char* dst,
	    Task_token* build_id_blocker,
	    Task_token* final_blocker)
    : src_(src), size_(size), dst_(dst), build_id_blocker_(build_id_blocker),
      final_blocker_(final_blocker)
  { }

  void
  run(Workqueue*)
  { md5_buffer(reinterpret_cast<const char*>(src_), size_, dst_); }

  Task_token*
  is_runnable();

  // Unblock FINAL_BLOCKER_ when done.
  void
  locks(Task_locker* tl)
  { tl->add(this, this->final_blocker_); }

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

 private:
  const unsigned char* const src_;
  const size_t size_;
  unsigned char* const dst_;
  Task_token* const build_id_blocker_;
  Task_token* const final_blocker_;
};

Task_token*
Hash_task::is_runnable()
{
  if (this->build_id_blocker_->is_blocked())
    return this->build_id_blocker_;
  return NULL;
}

// Layout::Relaxation_debug_check methods.

// Check that sections and special data are in reset states.
// We do not save states for Output_sections and special Output_data.
// So we check that they have not assigned any addresses or offsets.
// clean_up_after_relaxation simply resets their addresses and offsets.
void
Layout::Relaxation_debug_check::check_output_data_for_reset_values(
    const Layout::Section_list& sections,
    const Layout::Data_list& special_outputs,
    const Layout::Data_list& relax_outputs)
{
  for(Layout::Section_list::const_iterator p = sections.begin();
      p != sections.end();
      ++p)
    gold_assert((*p)->address_and_file_offset_have_reset_values());

  for(Layout::Data_list::const_iterator p = special_outputs.begin();
      p != special_outputs.end();
      ++p)
    gold_assert((*p)->address_and_file_offset_have_reset_values());

  gold_assert(relax_outputs.empty());
}

// Save information of SECTIONS for checking later.

void
Layout::Relaxation_debug_check::read_sections(
    const Layout::Section_list& sections)
{
  for(Layout::Section_list::const_iterator p = sections.begin();
      p != sections.end();
      ++p)
    {
      Output_section* os = *p;
      Section_info info;
      info.output_section = os;
      info.address = os->is_address_valid() ? os->address() : 0;
      info.data_size = os->is_data_size_valid() ? os->data_size() : -1;
      info.offset = os->is_offset_valid()? os->offset() : -1 ;
      this->section_infos_.push_back(info);
    }
}

// Verify SECTIONS using previously recorded information.

void
Layout::Relaxation_debug_check::verify_sections(
    const Layout::Section_list& sections)
{
  size_t i = 0;
  for(Layout::Section_list::const_iterator p = sections.begin();
      p != sections.end();
      ++p, ++i)
    {
      Output_section* os = *p;
      uint64_t address = os->is_address_valid() ? os->address() : 0;
      off_t data_size = os->is_data_size_valid() ? os->data_size() : -1;
      off_t offset = os->is_offset_valid()? os->offset() : -1 ;

      if (i >= this->section_infos_.size())
	{
	  gold_fatal("Section_info of %s missing.\n", os->name());
	}
      const Section_info& info = this->section_infos_[i];
      if (os != info.output_section)
	gold_fatal("Section order changed.  Expecting %s but see %s\n",
		   info.output_section->name(), os->name());
      if (address != info.address
	  || data_size != info.data_size
	  || offset != info.offset)
	gold_fatal("Section %s changed.\n", os->name());
    }
}

// Layout_task_runner methods.

// Lay out the sections.  This is called after all the input objects
// have been read.

void
Layout_task_runner::run(Workqueue* workqueue, const Task* task)
{
  // See if any of the input definitions violate the One Definition Rule.
  // TODO: if this is too slow, do this as a task, rather than inline.
  this->symtab_->detect_odr_violations(task, this->options_.output_file_name());

  Layout* layout = this->layout_;
  off_t file_size = layout->finalize(this->input_objects_,
				     this->symtab_,
				     this->target_,
				     task);

  // Now we know the final size of the output file and we know where
  // each piece of information goes.

  if (this->mapfile_ != NULL)
    {
      this->mapfile_->print_discarded_sections(this->input_objects_);
      layout->print_to_mapfile(this->mapfile_);
    }

  Output_file* of;
  if (layout->incremental_base() == NULL)
    {
      of = new Output_file(parameters->options().output_file_name());
      if (this->options_.oformat_enum() != General_options::OBJECT_FORMAT_ELF)
	of->set_is_temporary();
      of->open(file_size);
    }
  else
    {
      of = layout->incremental_base()->output_file();

      // Apply the incremental relocations for symbols whose values
      // have changed.  We do this before we resize the file and start
      // writing anything else to it, so that we can read the old
      // incremental information from the file before (possibly)
      // overwriting it.
      if (parameters->incremental_update())
	layout->incremental_base()->apply_incremental_relocs(this->symtab_,
							     this->layout_,
							     of);

      of->resize(file_size);
    }

  // Queue up the final set of tasks.
  gold::queue_final_tasks(this->options_, this->input_objects_,
			  this->symtab_, layout, workqueue, of);
}

// Layout methods.

Layout::Layout(int number_of_input_files, Script_options* script_options)
  : number_of_input_files_(number_of_input_files),
    script_options_(script_options),
    namepool_(),
    sympool_(),
    dynpool_(),
    signatures_(),
    section_name_map_(),
    segment_list_(),
    section_list_(),
    unattached_section_list_(),
    special_output_list_(),
    relax_output_list_(),
    section_headers_(NULL),
    tls_segment_(NULL),
    relro_segment_(NULL),
    interp_segment_(NULL),
    increase_relro_(0),
    symtab_section_(NULL),
    symtab_xindex_(NULL),
    dynsym_section_(NULL),
    dynsym_xindex_(NULL),
    dynamic_section_(NULL),
    dynamic_symbol_(NULL),
    dynamic_data_(NULL),
    eh_frame_section_(NULL),
    eh_frame_data_(NULL),
    added_eh_frame_data_(false),
    eh_frame_hdr_section_(NULL),
    gdb_index_data_(NULL),
    build_id_note_(NULL),
    array_of_hashes_(NULL),
    size_of_array_of_hashes_(0),
    input_view_(NULL),
    debug_abbrev_(NULL),
    debug_info_(NULL),
    group_signatures_(),
    output_file_size_(-1),
    have_added_input_section_(false),
    sections_are_attached_(false),
    input_requires_executable_stack_(false),
    input_with_gnu_stack_note_(false),
    input_without_gnu_stack_note_(false),
    has_static_tls_(false),
    any_postprocessing_sections_(false),
    resized_signatures_(false),
    have_stabstr_section_(false),
    section_ordering_specified_(false),
    unique_segment_for_sections_specified_(false),
    incremental_inputs_(NULL),
    record_output_section_data_from_script_(false),
    script_output_section_data_list_(),
    segment_states_(NULL),
    relaxation_debug_check_(NULL),
    section_order_map_(),
    section_segment_map_(),
    input_section_position_(),
    input_section_glob_(),
    incremental_base_(NULL),
    free_list_()
{
  // Make space for more than enough segments for a typical file.
  // This is just for efficiency--it's OK if we wind up needing more.
  this->segment_list_.reserve(12);

  // We expect two unattached Output_data objects: the file header and
  // the segment headers.
  this->special_output_list_.reserve(2);

  // Initialize structure needed for an incremental build.
  if (parameters->incremental())
    this->incremental_inputs_ = new Incremental_inputs;

  // The section name pool is worth optimizing in all cases, because
  // it is small, but there are often overlaps due to .rel sections.
  this->namepool_.set_optimize();
}

// For incremental links, record the base file to be modified.

void
Layout::set_incremental_base(Incremental_binary* base)
{
  this->incremental_base_ = base;
  this->free_list_.init(base->output_file()->filesize(), true);
}

// Hash a key we use to look up an output section mapping.

size_t
Layout::Hash_key::operator()(const Layout::Key& k) const
{
 return k.first + k.second.first + k.second.second;
}

// These are the debug sections that are actually used by gdb.
// Currently, we've checked versions of gdb up to and including 7.4.
// We only check the part of the name that follows ".debug_" or
// ".zdebug_".

static const char* gdb_sections[] =
{
  "abbrev",
  "addr",         // Fission extension
  // "aranges",   // not used by gdb as of 7.4
  "frame",
  "info",
  "types",
  "line",
  "loc",
  "macinfo",
  "macro",
  // "pubnames",  // not used by gdb as of 7.4
  // "pubtypes",  // not used by gdb as of 7.4
  "ranges",
  "str",
};

// This is the minimum set of sections needed for line numbers.

static const char* lines_only_debug_sections[] =
{
  "abbrev",
  // "addr",      // Fission extension
  // "aranges",   // not used by gdb as of 7.4
  // "frame",
  "info",
  // "types",
  "line",
  // "loc",
  // "macinfo",
  // "macro",
  // "pubnames",  // not used by gdb as of 7.4
  // "pubtypes",  // not used by gdb as of 7.4
  // "ranges",
  "str",
};

// These sections are the DWARF fast-lookup tables, and are not needed
// when building a .gdb_index section.

static const char* gdb_fast_lookup_sections[] =
{
  "aranges",
  "pubnames",
  "gnu_pubnames",
  "pubtypes",
  "gnu_pubtypes",
};

// Returns whether the given debug section is in the list of
// debug-sections-used-by-some-version-of-gdb.  SUFFIX is the
// portion of the name following ".debug_" or ".zdebug_".

static inline bool
is_gdb_debug_section(const char* suffix)
{
  // We can do this faster: binary search or a hashtable.  But why bother?
  for (size_t i = 0; i < sizeof(gdb_sections)/sizeof(*gdb_sections); ++i)
    if (strcmp(suffix, gdb_sections[i]) == 0)
      return true;
  return false;
}

// Returns whether the given section is needed for lines-only debugging.

static inline bool
is_lines_only_debug_section(const char* suffix)
{
  // We can do this faster: binary search or a hashtable.  But why bother?
  for (size_t i = 0;
       i < sizeof(lines_only_debug_sections)/sizeof(*lines_only_debug_sections);
       ++i)
    if (strcmp(suffix, lines_only_debug_sections[i]) == 0)
      return true;
  return false;
}

// Returns whether the given section is a fast-lookup section that
// will not be needed when building a .gdb_index section.

static inline bool
is_gdb_fast_lookup_section(const char* suffix)
{
  // We can do this faster: binary search or a hashtable.  But why bother?
  for (size_t i = 0;
       i < sizeof(gdb_fast_lookup_sections)/sizeof(*gdb_fast_lookup_sections);
       ++i)
    if (strcmp(suffix, gdb_fast_lookup_sections[i]) == 0)
      return true;
  return false;
}

// Sometimes we compress sections.  This is typically done for
// sections that are not part of normal program execution (such as
// .debug_* sections), and where the readers of these sections know
// how to deal with compressed sections.  This routine doesn't say for
// certain whether we'll compress -- it depends on commandline options
// as well -- just whether this section is a candidate for compression.
// (The Output_compressed_section class decides whether to compress
// a given section, and picks the name of the compressed section.)

static bool
is_compressible_debug_section(const char* secname)
{
  return (is_prefix_of(".debug", secname));
}

// We may see compressed debug sections in input files.  Return TRUE
// if this is the name of a compressed debug section.

bool
is_compressed_debug_section(const char* secname)
{
  return (is_prefix_of(".zdebug", secname));
}

// Whether to include this section in the link.

template<int size, bool big_endian>
bool
Layout::include_section(Sized_relobj_file<size, big_endian>*, const char* name,
			const elfcpp::Shdr<size, big_endian>& shdr)
{
  if (!parameters->options().relocatable()
      && (shdr.get_sh_flags() & elfcpp::SHF_EXCLUDE))
    return false;

  elfcpp::Elf_Word sh_type = shdr.get_sh_type();

  if ((sh_type >= elfcpp::SHT_LOOS && sh_type <= elfcpp::SHT_HIOS)
      || (sh_type >= elfcpp::SHT_LOPROC && sh_type <= elfcpp::SHT_HIPROC))
    return parameters->target().should_include_section(sh_type);

  switch (sh_type)
    {
    case elfcpp::SHT_NULL:
    case elfcpp::SHT_SYMTAB:
    case elfcpp::SHT_DYNSYM:
    case elfcpp::SHT_HASH:
    case elfcpp::SHT_DYNAMIC:
    case elfcpp::SHT_SYMTAB_SHNDX:
      return false;

    case elfcpp::SHT_STRTAB:
      // Discard the sections which have special meanings in the ELF
      // ABI.  Keep others (e.g., .stabstr).  We could also do this by
      // checking the sh_link fields of the appropriate sections.
      return (strcmp(name, ".dynstr") != 0
	      && strcmp(name, ".strtab") != 0
	      && strcmp(name, ".shstrtab") != 0);

    case elfcpp::SHT_RELA:
    case elfcpp::SHT_REL:
    case elfcpp::SHT_GROUP:
      // If we are emitting relocations these should be handled
      // elsewhere.
      gold_assert(!parameters->options().relocatable());
      return false;

    case elfcpp::SHT_PROGBITS:
      if (parameters->options().strip_debug()
	  && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
	{
	  if (is_debug_info_section(name))
	    return false;
	}
      if (parameters->options().strip_debug_non_line()
	  && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
	{
	  // Debugging sections can only be recognized by name.
	  if (is_prefix_of(".debug_", name)
	      && !is_lines_only_debug_section(name + 7))
	    return false;
	  if (is_prefix_of(".zdebug_", name)
	      && !is_lines_only_debug_section(name + 8))
	    return false;
	}
      if (parameters->options().strip_debug_gdb()
	  && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
	{
	  // Debugging sections can only be recognized by name.
	  if (is_prefix_of(".debug_", name)
	      && !is_gdb_debug_section(name + 7))
	    return false;
	  if (is_prefix_of(".zdebug_", name)
	      && !is_gdb_debug_section(name + 8))
	    return false;
	}
      if (parameters->options().gdb_index()
	  && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
	{
	  // When building .gdb_index, we can strip .debug_pubnames,
	  // .debug_pubtypes, and .debug_aranges sections.
	  if (is_prefix_of(".debug_", name)
	      && is_gdb_fast_lookup_section(name + 7))
	    return false;
	  if (is_prefix_of(".zdebug_", name)
	      && is_gdb_fast_lookup_section(name + 8))
	    return false;
	}
      if (parameters->options().strip_lto_sections()
	  && !parameters->options().relocatable()
	  && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
	{
	  // Ignore LTO sections containing intermediate code.
	  if (is_prefix_of(".gnu.lto_", name))
	    return false;
	}
      // The GNU linker strips .gnu_debuglink sections, so we do too.
      // This is a feature used to keep debugging information in
      // separate files.
      if (strcmp(name, ".gnu_debuglink") == 0)
	return false;
      return true;

    default:
      return true;
    }
}

// Return an output section named NAME, or NULL if there is none.

Output_section*
Layout::find_output_section(const char* name) const
{
  for (Section_list::const_iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    if (strcmp((*p)->name(), name) == 0)
      return *p;
  return NULL;
}

// 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*
Layout::find_output_segment(elfcpp::PT type, elfcpp::Elf_Word set,
			    elfcpp::Elf_Word clear) const
{
  for (Segment_list::const_iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    if (static_cast<elfcpp::PT>((*p)->type()) == type
	&& ((*p)->flags() & set) == set
	&& ((*p)->flags() & clear) == 0)
      return *p;
  return NULL;
}

// When we put a .ctors or .dtors section with more than one word into
// a .init_array or .fini_array section, we need to reverse the words
// in the .ctors/.dtors section.  This is because .init_array executes
// constructors front to back, where .ctors executes them back to
// front, and vice-versa for .fini_array/.dtors.  Although we do want
// to remap .ctors/.dtors into .init_array/.fini_array because it can
// be more efficient, we don't want to change the order in which
// constructors/destructors are run.  This set just keeps track of
// these sections which need to be reversed.  It is only changed by
// Layout::layout.  It should be a private member of Layout, but that
// would require layout.h to #include object.h to get the definition
// of Section_id.
static Unordered_set<Section_id, Section_id_hash> ctors_sections_in_init_array;

// Return whether OBJECT/SHNDX is a .ctors/.dtors section mapped to a
// .init_array/.fini_array section.

bool
Layout::is_ctors_in_init_array(Relobj* relobj, unsigned int shndx) const
{
  return (ctors_sections_in_init_array.find(Section_id(relobj, shndx))
	  != ctors_sections_in_init_array.end());
}

// Return the output section to use for section NAME with type TYPE
// and section flags FLAGS.  NAME must be canonicalized in the string
// pool, and NAME_KEY is the key.  ORDER is where this should appear
// in the output sections.  IS_RELRO is true for a relro section.

Output_section*
Layout::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)
{
  elfcpp::Elf_Word lookup_type = type;

  // For lookup purposes, treat INIT_ARRAY, FINI_ARRAY, and
  // PREINIT_ARRAY like PROGBITS.  This ensures that we combine
  // .init_array, .fini_array, and .preinit_array sections by name
  // whatever their type in the input file.  We do this because the
  // types are not always right in the input files.
  if (lookup_type == elfcpp::SHT_INIT_ARRAY
      || lookup_type == elfcpp::SHT_FINI_ARRAY
      || lookup_type == elfcpp::SHT_PREINIT_ARRAY)
    lookup_type = elfcpp::SHT_PROGBITS;

  elfcpp::Elf_Xword lookup_flags = flags;

  // Ignoring SHF_WRITE and SHF_EXECINSTR here means that we combine
  // read-write with read-only sections.  Some other ELF linkers do
  // not do this.  FIXME: Perhaps there should be an option
  // controlling this.
  lookup_flags &= ~(elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR);

  const Key key(name_key, std::make_pair(lookup_type, lookup_flags));
  const std::pair<Key, Output_section*> v(key, NULL);
  std::pair<Section_name_map::iterator, bool> ins(
    this->section_name_map_.insert(v));

  if (!ins.second)
    return ins.first->second;
  else
    {
      // This is the first time we've seen this name/type/flags
      // combination.  For compatibility with the GNU linker, we
      // combine sections with contents and zero flags with sections
      // with non-zero flags.  This is a workaround for cases where
      // assembler code forgets to set section flags.  FIXME: Perhaps
      // there should be an option to control this.
      Output_section* os = NULL;

      if (lookup_type == elfcpp::SHT_PROGBITS)
	{
	  if (flags == 0)
	    {
	      Output_section* same_name = this->find_output_section(name);
	      if (same_name != NULL
		  && (same_name->type() == elfcpp::SHT_PROGBITS
		      || same_name->type() == elfcpp::SHT_INIT_ARRAY
		      || same_name->type() == elfcpp::SHT_FINI_ARRAY
		      || same_name->type() == elfcpp::SHT_PREINIT_ARRAY)
		  && (same_name->flags() & elfcpp::SHF_TLS) == 0)
		os = same_name;
	    }
	  else if ((flags & elfcpp::SHF_TLS) == 0)
	    {
	      elfcpp::Elf_Xword zero_flags = 0;
	      const Key zero_key(name_key, std::make_pair(lookup_type,
							  zero_flags));
	      Section_name_map::iterator p =
		  this->section_name_map_.find(zero_key);
	      if (p != this->section_name_map_.end())
		os = p->second;
	    }
	}

      if (os == NULL)
	os = this->make_output_section(name, type, flags, order, is_relro);

      ins.first->second = os;
      return os;
    }
}

// Returns TRUE iff NAME (an input section from RELOBJ) will
// be mapped to an output section that should be KEPT.

bool
Layout::keep_input_section(const Relobj* relobj, const char* name)
{
  if (! this->script_options_->saw_sections_clause())
    return false;

  Script_sections* ss = this->script_options_->script_sections();
  const char* file_name = relobj == NULL ? NULL : relobj->name().c_str();
  Output_section** output_section_slot;
  Script_sections::Section_type script_section_type;
  bool keep;

  name = ss->output_section_name(file_name, name, &output_section_slot,
				 &script_section_type, &keep);
  return name != NULL && keep;
}

// Clear the input section flags that should not be copied to the
// output section.

elfcpp::Elf_Xword
Layout::get_output_section_flags(elfcpp::Elf_Xword input_section_flags)
{
  // Some flags in the input section should not be automatically
  // copied to the output section.
  input_section_flags &= ~ (elfcpp::SHF_INFO_LINK
			    | elfcpp::SHF_GROUP
			    | elfcpp::SHF_MERGE
			    | elfcpp::SHF_STRINGS);

  // We only clear the SHF_LINK_ORDER flag in for
  // a non-relocatable link.
  if (!parameters->options().relocatable())
    input_section_flags &= ~elfcpp::SHF_LINK_ORDER;

  return input_section_flags;
}

// Pick the output section to use for section NAME, in input file
// RELOBJ, with type TYPE and flags FLAGS.  RELOBJ may be NULL for a
// linker created section.  IS_INPUT_SECTION is true if we are
// choosing an output section for an input section found in a input
// file.  ORDER is where this section should appear in the output
// sections.  IS_RELRO is true for a relro section.  This will return
// NULL if the input section should be discarded.

Output_section*
Layout::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)
{
  // We should not see any input sections after we have attached
  // sections to segments.
  gold_assert(!is_input_section || !this->sections_are_attached_);

  flags = this->get_output_section_flags(flags);

  if (this->script_options_->saw_sections_clause())
    {
      // We are using a SECTIONS clause, so the output section is
      // chosen based only on the name.

      Script_sections* ss = this->script_options_->script_sections();
      const char* file_name = relobj == NULL ? NULL : relobj->name().c_str();
      Output_section** output_section_slot;
      Script_sections::Section_type script_section_type;
      const char* orig_name = name;
      bool keep;
      name = ss->output_section_name(file_name, name, &output_section_slot,
				     &script_section_type, &keep);

      if (name == NULL)
	{
	  gold_debug(DEBUG_SCRIPT, _("Unable to create output section '%s' "
				     "because it is not allowed by the "
				     "SECTIONS clause of the linker script"),
		     orig_name);
	  // The SECTIONS clause says to discard this input section.
	  return NULL;
	}

      // We can only handle script section types ST_NONE and ST_NOLOAD.
      switch (script_section_type)
	{
	case Script_sections::ST_NONE:
	  break;
	case Script_sections::ST_NOLOAD:
	  flags &= elfcpp::SHF_ALLOC;
	  break;
	default:
	  gold_unreachable();
	}

      // If this is an orphan section--one not mentioned in the linker
      // script--then OUTPUT_SECTION_SLOT will be NULL, and we do the
      // default processing below.

      if (output_section_slot != NULL)
	{
	  if (*output_section_slot != NULL)
	    {
	      (*output_section_slot)->update_flags_for_input_section(flags);
	      return *output_section_slot;
	    }

	  // We don't put sections found in the linker script into
	  // SECTION_NAME_MAP_.  That keeps us from getting confused
	  // if an orphan section is mapped to a section with the same
	  // name as one in the linker script.

	  name = this->namepool_.add(name, false, NULL);

	  Output_section* os = this->make_output_section(name, type, flags,
							 order, is_relro);

	  os->set_found_in_sections_clause();

	  // Special handling for NOLOAD sections.
	  if (script_section_type == Script_sections::ST_NOLOAD)
	    {
	      os->set_is_noload();

	      // The constructor of Output_section sets addresses of non-ALLOC
	      // sections to 0 by default.  We don't want that for NOLOAD
	      // sections even if they have no SHF_ALLOC flag.
	      if ((os->flags() & elfcpp::SHF_ALLOC) == 0
		  && os->is_address_valid())
		{
		  gold_assert(os->address() == 0
			      && !os->is_offset_valid()
			      && !os->is_data_size_valid());
		  os->reset_address_and_file_offset();
		}
	    }

	  *output_section_slot = os;
	  return os;
	}
    }

  // FIXME: Handle SHF_OS_NONCONFORMING somewhere.

  size_t len = strlen(name);
  char* uncompressed_name = NULL;

  // Compressed debug sections should be mapped to the corresponding
  // uncompressed section.
  if (is_compressed_debug_section(name))
    {
      uncompressed_name = new char[len];
      uncompressed_name[0] = '.';
      gold_assert(name[0] == '.' && name[1] == 'z');
      strncpy(&uncompressed_name[1], &name[2], len - 2);
      uncompressed_name[len - 1] = '\0';
      len -= 1;
      name = uncompressed_name;
    }

  // Turn NAME from the name of the input section into the name of the
  // output section.
  if (is_input_section
      && !this->script_options_->saw_sections_clause()
      && !parameters->options().relocatable())
    {
      const char *orig_name = name;
      name = parameters->target().output_section_name(relobj, name, &len);
      if (name == NULL)
	name = Layout::output_section_name(relobj, orig_name, &len);
    }

  Stringpool::Key name_key;
  name = this->namepool_.add_with_length(name, len, true, &name_key);

  if (uncompressed_name != NULL)
    delete[] uncompressed_name;

  // Find or make the output section.  The output section is selected
  // based on the section name, type, and flags.
  return this->get_output_section(name, name_key, type, flags, order, is_relro);
}

// 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*
Layout::init_fixed_output_section(const char* name,
				  elfcpp::Shdr<size, big_endian>& shdr)
{
  unsigned int sh_type = shdr.get_sh_type();

  // We preserve the layout of PROGBITS, NOBITS, INIT_ARRAY, FINI_ARRAY,
  // PRE_INIT_ARRAY, and NOTE sections.
  // All others will be created from scratch and reallocated.
  if (!can_incremental_update(sh_type))
    return NULL;

  // If we're generating a .gdb_index section, we need to regenerate
  // it from scratch.
  if (parameters->options().gdb_index()
      && sh_type == elfcpp::SHT_PROGBITS
      && strcmp(name, ".gdb_index") == 0)
    return NULL;

  typename elfcpp::Elf_types<size>::Elf_Addr sh_addr = shdr.get_sh_addr();
  typename elfcpp::Elf_types<size>::Elf_Off sh_offset = shdr.get_sh_offset();
  typename elfcpp::Elf_types<size>::Elf_WXword sh_size = shdr.get_sh_size();
  typename elfcpp::Elf_types<size>::Elf_WXword sh_flags = shdr.get_sh_flags();
  typename elfcpp::Elf_types<size>::Elf_WXword sh_addralign =
      shdr.get_sh_addralign();

  // Make the output section.
  Stringpool::Key name_key;
  name = this->namepool_.add(name, true, &name_key);
  Output_section* os = this->get_output_section(name, name_key, sh_type,
						sh_flags, ORDER_INVALID, false);
  os->set_fixed_layout(sh_addr, sh_offset, sh_size, sh_addralign);
  if (sh_type != elfcpp::SHT_NOBITS)
    this->free_list_.remove(sh_offset, sh_offset + sh_size);
  return os;
}

// Return the index by which an input section should be ordered.  This
// is used to sort some .text sections, for compatibility with GNU ld.

int
Layout::special_ordering_of_input_section(const char* name)
{
  // The GNU linker has some special handling for some sections that
  // wind up in the .text section.  Sections that start with these
  // prefixes must appear first, and must appear in the order listed
  // here.
  static const char* const text_section_sort[] =
  {
    ".text.unlikely",
    ".text.exit",
    ".text.startup",
    ".text.hot"
  };

  for (size_t i = 0;
       i < sizeof(text_section_sort) / sizeof(text_section_sort[0]);
       i++)
    if (is_prefix_of(text_section_sort[i], name))
      return i;

  return -1;
}

// Return the output section to use for input section SHNDX, with name
// NAME, with header HEADER, from object OBJECT.  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 *OFF to the offset of this
// input section without the output section.  Return NULL if the
// section should be discarded.  Set *OFF to -1 if the section
// contents should not be written directly to the output file, but
// will instead receive special handling.

template<int size, bool big_endian>
Output_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, unsigned int, off_t* off)
{
  *off = 0;

  if (!this->include_section(object, name, shdr))
    return NULL;

  elfcpp::Elf_Word sh_type = shdr.get_sh_type();

  // In a relocatable link a grouped section must not be combined with
  // any other sections.
  Output_section* os;
  if (parameters->options().relocatable()
      && (shdr.get_sh_flags() & elfcpp::SHF_GROUP) != 0)
    {
      name = this->namepool_.add(name, true, NULL);
      os = this->make_output_section(name, sh_type, shdr.get_sh_flags(),
				     ORDER_INVALID, false);
    }
  else
    {
      // Plugins can choose to place one or more subsets of sections in
      // unique segments and this is done by mapping these section subsets
      // to unique output sections.  Check if this section needs to be
      // remapped to a unique output section.
      Section_segment_map::iterator it
	  = this->section_segment_map_.find(Const_section_id(object, shndx));
      if (it == this->section_segment_map_.end())
	{
	  os = this->choose_output_section(object, name, sh_type,
					   shdr.get_sh_flags(), true,
					   ORDER_INVALID, false);
	}
      else
	{
	  // We know the name of the output section, directly call
	  // get_output_section here by-passing choose_output_section.
	  elfcpp::Elf_Xword flags
	    = this->get_output_section_flags(shdr.get_sh_flags());

	  const char* os_name = it->second->name;
	  Stringpool::Key name_key;
	  os_name = this->namepool_.add(os_name, true, &name_key);
	  os = this->get_output_section(os_name, name_key, sh_type, flags,
					ORDER_INVALID, false);
	  if (!os->is_unique_segment())
	    {
	      os->set_is_unique_segment();
	      os->set_extra_segment_flags(it->second->flags);
	      os->set_segment_alignment(it->second->align);
	    }
	}
      if (os == NULL)
	return NULL;
    }

  // By default the GNU linker sorts input sections whose names match
  // .ctors.*, .dtors.*, .init_array.*, or .fini_array.*.  The
  // sections are sorted by name.  This is used to implement
  // constructor priority ordering.  We are compatible.  When we put
  // .ctor sections in .init_array and .dtor sections in .fini_array,
  // we must also sort plain .ctor and .dtor sections.
  if (!this->script_options_->saw_sections_clause()
      && !parameters->options().relocatable()
      && (is_prefix_of(".ctors.", name)
	  || is_prefix_of(".dtors.", name)
	  || is_prefix_of(".init_array.", name)
	  || is_prefix_of(".fini_array.", name)
	  || (parameters->options().ctors_in_init_array()
	      && (strcmp(name, ".ctors") == 0
		  || strcmp(name, ".dtors") == 0))))
    os->set_must_sort_attached_input_sections();

  // By default the GNU linker sorts some special text sections ahead
  // of others.  We are compatible.
  if (parameters->options().text_reorder()
      && !this->script_options_->saw_sections_clause()
      && !this->is_section_ordering_specified()
      && !parameters->options().relocatable()
      && Layout::special_ordering_of_input_section(name) >= 0)
    os->set_must_sort_attached_input_sections();

  // If this is a .ctors or .ctors.* section being mapped to a
  // .init_array section, or a .dtors or .dtors.* section being mapped
  // to a .fini_array section, we will need to reverse the words if
  // there is more than one.  Record this section for later.  See
  // ctors_sections_in_init_array above.
  if (!this->script_options_->saw_sections_clause()
      && !parameters->options().relocatable()
      && shdr.get_sh_size() > size / 8
      && (((strcmp(name, ".ctors") == 0
	    || is_prefix_of(".ctors.", name))
	   && strcmp(os->name(), ".init_array") == 0)
	  || ((strcmp(name, ".dtors") == 0
	       || is_prefix_of(".dtors.", name))
	      && strcmp(os->name(), ".fini_array") == 0)))
    ctors_sections_in_init_array.insert(Section_id(object, shndx));

  // FIXME: Handle SHF_LINK_ORDER somewhere.

  elfcpp::Elf_Xword orig_flags = os->flags();

  *off = os->add_input_section(this, object, shndx, name, shdr, reloc_shndx,
			       this->script_options_->saw_sections_clause());

  // If the flags changed, we may have to change the order.
  if ((orig_flags & elfcpp::SHF_ALLOC) != 0)
    {
      orig_flags &= (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR);
      elfcpp::Elf_Xword new_flags =
	os->flags() & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR);
      if (orig_flags != new_flags)
	os->set_order(this->default_section_order(os, false));
    }

  this->have_added_input_section_ = true;

  return os;
}

// Maps section SECN to SEGMENT s.
void
Layout::insert_section_segment_map(Const_section_id secn,
				   Unique_segment_info *s)
{
  gold_assert(this->unique_segment_for_sections_specified_);
  this->section_segment_map_[secn] = s;
}

// Handle a relocation section when doing a relocatable link.

template<int size, bool big_endian>
Output_section*
Layout::layout_reloc(Sized_relobj_file<size, big_endian>* object,
		     unsigned int,
		     const elfcpp::Shdr<size, big_endian>& shdr,
		     Output_section* data_section,
		     Relocatable_relocs* rr)
{
  gold_assert(parameters->options().relocatable()
	      || parameters->options().emit_relocs());

  int sh_type = shdr.get_sh_type();

  std::string name;
  if (sh_type == elfcpp::SHT_REL)
    name = ".rel";
  else if (sh_type == elfcpp::SHT_RELA)
    name = ".rela";
  else
    gold_unreachable();
  name += data_section->name();

  // In a relocatable link relocs for a grouped section must not be
  // combined with other reloc sections.
  Output_section* os;
  if (!parameters->options().relocatable()
      || (data_section->flags() & elfcpp::SHF_GROUP) == 0)
    os = this->choose_output_section(object, name.c_str(), sh_type,
				     shdr.get_sh_flags(), false,
				     ORDER_INVALID, false);
  else
    {
      const char* n = this->namepool_.add(name.c_str(), true, NULL);
      os = this->make_output_section(n, sh_type, shdr.get_sh_flags(),
				     ORDER_INVALID, false);
    }

  os->set_should_link_to_symtab();
  os->set_info_section(data_section);

  Output_section_data* posd;
  if (sh_type == elfcpp::SHT_REL)
    {
      os->set_entsize(elfcpp::Elf_sizes<size>::rel_size);
      posd = new Output_relocatable_relocs<elfcpp::SHT_REL,
					   size,
					   big_endian>(rr);
    }
  else if (sh_type == elfcpp::SHT_RELA)
    {
      os->set_entsize(elfcpp::Elf_sizes<size>::rela_size);
      posd = new Output_relocatable_relocs<elfcpp::SHT_RELA,
					   size,
					   big_endian>(rr);
    }
  else
    gold_unreachable();

  os->add_output_section_data(posd);
  rr->set_output_data(posd);

  return os;
}

// Handle a group section when doing a relocatable link.

template<int size, bool big_endian>
void
Layout::layout_group(Symbol_table* symtab,
		     Sized_relobj_file<size, big_endian>* object,
		     unsigned int,
		     const char* group_section_name,
		     const char* signature,
		     const elfcpp::Shdr<size, big_endian>& shdr,
		     elfcpp::Elf_Word flags,
		     std::vector<unsigned int>* shndxes)
{
  gold_assert(parameters->options().relocatable());
  gold_assert(shdr.get_sh_type() == elfcpp::SHT_GROUP);
  group_section_name = this->namepool_.add(group_section_name, true, NULL);
  Output_section* os = this->make_output_section(group_section_name,
						 elfcpp::SHT_GROUP,
						 shdr.get_sh_flags(),
						 ORDER_INVALID, false);

  // We need to find a symbol with the signature in the symbol table.
  // If we don't find one now, we need to look again later.
  Symbol* sym = symtab->lookup(signature, NULL);
  if (sym != NULL)
    os->set_info_symndx(sym);
  else
    {
      // Reserve some space to minimize reallocations.
      if (this->group_signatures_.empty())
	this->group_signatures_.reserve(this->number_of_input_files_ * 16);

      // We will wind up using a symbol whose name is the signature.
      // So just put the signature in the symbol name pool to save it.
      signature = symtab->canonicalize_name(signature);
      this->group_signatures_.push_back(Group_signature(os, signature));
    }

  os->set_should_link_to_symtab();
  os->set_entsize(4);

  section_size_type entry_count =
    convert_to_section_size_type(shdr.get_sh_size() / 4);
  Output_section_data* posd =
    new Output_data_group<size, big_endian>(object, entry_count, flags,
					    shndxes);
  os->add_output_section_data(posd);
}

// Special GNU handling of sections name .eh_frame.  They will
// normally hold exception frame data as defined by the C++ ABI
// (http://codesourcery.com/cxx-abi/).

template<int size, bool big_endian>
Output_section*
Layout::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* off)
{
  gold_assert(shdr.get_sh_type() == elfcpp::SHT_PROGBITS
	      || shdr.get_sh_type() == elfcpp::SHT_X86_64_UNWIND);
  gold_assert((shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0);

  Output_section* os = this->make_eh_frame_section(object);
  if (os == NULL)
    return NULL;

  gold_assert(this->eh_frame_section_ == os);

  elfcpp::Elf_Xword orig_flags = os->flags();

  Eh_frame::Eh_frame_section_disposition disp =
      Eh_frame::EH_UNRECOGNIZED_SECTION;
  if (!parameters->incremental())
    {
      disp = this->eh_frame_data_->add_ehframe_input_section(object,
							     symbols,
							     symbols_size,
							     symbol_names,
							     symbol_names_size,
							     shndx,
							     reloc_shndx,
							     reloc_type);
    }

  if (disp == Eh_frame::EH_OPTIMIZABLE_SECTION)
    {
      os->update_flags_for_input_section(shdr.get_sh_flags());

      // A writable .eh_frame section is a RELRO section.
      if ((orig_flags & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR))
	  != (os->flags() & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR)))
	{
	  os->set_is_relro();
	  os->set_order(ORDER_RELRO);
	}

      *off = -1;
      return os;
    }

  if (disp == Eh_frame::EH_END_MARKER_SECTION && !this->added_eh_frame_data_)
    {
      // We found the end marker section, so now we can add the set of
      // optimized sections to the output section.  We need to postpone
      // adding this until we've found a section we can optimize so that
      // the .eh_frame section in crtbeginT.o winds up at the start of
      // the output section.
      os->add_output_section_data(this->eh_frame_data_);
      this->added_eh_frame_data_ = true;
     }

  // We couldn't handle this .eh_frame section for some reason.
  // Add it as a normal section.
  bool saw_sections_clause = this->script_options_->saw_sections_clause();
  *off = os->add_input_section(this, object, shndx, ".eh_frame", shdr,
			       reloc_shndx, saw_sections_clause);
  this->have_added_input_section_ = true;

  if ((orig_flags & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR))
      != (os->flags() & (elfcpp::SHF_WRITE | elfcpp::SHF_EXECINSTR)))
    os->set_order(this->default_section_order(os, false));

  return os;
}

void
Layout::finalize_eh_frame_section()
{
  // If we never found an end marker section, we need to add the
  // optimized eh sections to the output section now.
  if (!parameters->incremental()
      && this->eh_frame_section_ != NULL
      && !this->added_eh_frame_data_)
    {
      this->eh_frame_section_->add_output_section_data(this->eh_frame_data_);
      this->added_eh_frame_data_ = true;
    }
}

// Create and return the magic .eh_frame section.  Create
// .eh_frame_hdr also if appropriate.  OBJECT is the object with the
// input .eh_frame section; it may be NULL.

Output_section*
Layout::make_eh_frame_section(const Relobj* object)
{
  // FIXME: On x86_64, this could use SHT_X86_64_UNWIND rather than
  // SHT_PROGBITS.
  Output_section* os = this->choose_output_section(object, ".eh_frame",
						   elfcpp::SHT_PROGBITS,
						   elfcpp::SHF_ALLOC, false,
						   ORDER_EHFRAME, false);
  if (os == NULL)
    return NULL;

  if (this->eh_frame_section_ == NULL)
    {
      this->eh_frame_section_ = os;
      this->eh_frame_data_ = new Eh_frame();

      // For incremental linking, we do not optimize .eh_frame sections
      // or create a .eh_frame_hdr section.
      if (parameters->options().eh_frame_hdr() && !parameters->incremental())
	{
	  Output_section* hdr_os =
	    this->choose_output_section(NULL, ".eh_frame_hdr",
					elfcpp::SHT_PROGBITS,
					elfcpp::SHF_ALLOC, false,
					ORDER_EHFRAME, false);

	  if (hdr_os != NULL)
	    {
	      Eh_frame_hdr* hdr_posd = new Eh_frame_hdr(os,
							this->eh_frame_data_);
	      hdr_os->add_output_section_data(hdr_posd);

	      hdr_os->set_after_input_sections();

	      if (!this->script_options_->saw_phdrs_clause())
		{
		  Output_segment* hdr_oseg;
		  hdr_oseg = this->make_output_segment(elfcpp::PT_GNU_EH_FRAME,
						       elfcpp::PF_R);
		  hdr_oseg->add_output_section_to_nonload(hdr_os,
							  elfcpp::PF_R);
		}

	      this->eh_frame_data_->set_eh_frame_hdr(hdr_posd);
	    }
	}
    }

  return os;
}

// Add an exception frame for a PLT.  This is called from target code.

void
Layout::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)
{
  if (parameters->incremental())
    {
      // FIXME: Maybe this could work some day....
      return;
    }
  Output_section* os = this->make_eh_frame_section(NULL);
  if (os == NULL)
    return;
  this->eh_frame_data_->add_ehframe_for_plt(plt, cie_data, cie_length,
					    fde_data, fde_length);
  if (!this->added_eh_frame_data_)
    {
      os->add_output_section_data(this->eh_frame_data_);
      this->added_eh_frame_data_ = true;
    }
}

// Scan a .debug_info or .debug_types section, and add summary
// information to the .gdb_index section.

template<int size, bool big_endian>
void
Layout::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)
{
  if (this->gdb_index_data_ == NULL)
    {
      Output_section* os = this->choose_output_section(NULL, ".gdb_index",
						       elfcpp::SHT_PROGBITS, 0,
						       false, ORDER_INVALID,
						       false);
      if (os == NULL)
	return;

      this->gdb_index_data_ = new Gdb_index(os);
      os->add_output_section_data(this->gdb_index_data_);
      os->set_after_input_sections();
    }

  this->gdb_index_data_->scan_debug_info(is_type_unit, object, symbols,
					 symbols_size, shndx, reloc_shndx,
					 reloc_type);
}

// Add POSD to an output section using NAME, TYPE, and FLAGS.  Return
// the output section.

Output_section*
Layout::add_output_section_data(const char* name, elfcpp::Elf_Word type,
				elfcpp::Elf_Xword flags,
				Output_section_data* posd,
				Output_section_order order, bool is_relro)
{
  Output_section* os = this->choose_output_section(NULL, name, type, flags,
						   false, order, is_relro);
  if (os != NULL)
    os->add_output_section_data(posd);
  return os;
}

// Map section flags to segment flags.

elfcpp::Elf_Word
Layout::section_flags_to_segment(elfcpp::Elf_Xword flags)
{
  elfcpp::Elf_Word ret = elfcpp::PF_R;
  if ((flags & elfcpp::SHF_WRITE) != 0)
    ret |= elfcpp::PF_W;
  if ((flags & elfcpp::SHF_EXECINSTR) != 0)
    ret |= elfcpp::PF_X;
  return ret;
}

// Make a new Output_section, and attach it to segments as
// appropriate.  ORDER is the order in which this section should
// appear in the output segment.  IS_RELRO is true if this is a relro
// (read-only after relocations) section.

Output_section*
Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
			    elfcpp::Elf_Xword flags,
			    Output_section_order order, bool is_relro)
{
  Output_section* os;
  if ((flags & elfcpp::SHF_ALLOC) == 0
      && strcmp(parameters->options().compress_debug_sections(), "none") != 0
      && is_compressible_debug_section(name))
    os = new Output_compressed_section(&parameters->options(), name, type,
				       flags);
  else if ((flags & elfcpp::SHF_ALLOC) == 0
	   && parameters->options().strip_debug_non_line()
	   && strcmp(".debug_abbrev", name) == 0)
    {
      os = this->debug_abbrev_ = new Output_reduced_debug_abbrev_section(
	  name, type, flags);
      if (this->debug_info_)
	this->debug_info_->set_abbreviations(this->debug_abbrev_);
    }
  else if ((flags & elfcpp::SHF_ALLOC) == 0
	   && parameters->options().strip_debug_non_line()
	   && strcmp(".debug_info", name) == 0)
    {
      os = this->debug_info_ = new Output_reduced_debug_info_section(
	  name, type, flags);
      if (this->debug_abbrev_)
	this->debug_info_->set_abbreviations(this->debug_abbrev_);
    }
  else
    {
      // Sometimes .init_array*, .preinit_array* and .fini_array* do
      // not have correct section types.  Force them here.
      if (type == elfcpp::SHT_PROGBITS)
	{
	  if (is_prefix_of(".init_array", name))
	    type = elfcpp::SHT_INIT_ARRAY;
	  else if (is_prefix_of(".preinit_array", name))
	    type = elfcpp::SHT_PREINIT_ARRAY;
	  else if (is_prefix_of(".fini_array", name))
	    type = elfcpp::SHT_FINI_ARRAY;
	}

      // FIXME: const_cast is ugly.
      Target* target = const_cast<Target*>(&parameters->target());
      os = target->make_output_section(name, type, flags);
    }

  // With -z relro, we have to recognize the special sections by name.
  // There is no other way.
  bool is_relro_local = false;
  if (!this->script_options_->saw_sections_clause()
      && parameters->options().relro()
      && (flags & elfcpp::SHF_ALLOC) != 0
      && (flags & elfcpp::SHF_WRITE) != 0)
    {
      if (type == elfcpp::SHT_PROGBITS)
	{
	  if ((flags & elfcpp::SHF_TLS) != 0)
	    is_relro = true;
	  else if (strcmp(name, ".data.rel.ro") == 0)
	    is_relro = true;
	  else if (strcmp(name, ".data.rel.ro.local") == 0)
	    {
	      is_relro = true;
	      is_relro_local = true;
	    }
	  else if (strcmp(name, ".ctors") == 0
		   || strcmp(name, ".dtors") == 0
		   || strcmp(name, ".jcr") == 0)
	    is_relro = true;
	}
      else if (type == elfcpp::SHT_INIT_ARRAY
	       || type == elfcpp::SHT_FINI_ARRAY
	       || type == elfcpp::SHT_PREINIT_ARRAY)
	is_relro = true;
    }

  if (is_relro)
    os->set_is_relro();

  if (order == ORDER_INVALID && (flags & elfcpp::SHF_ALLOC) != 0)
    order = this->default_section_order(os, is_relro_local);

  os->set_order(order);

  parameters->target().new_output_section(os);

  this->section_list_.push_back(os);

  // The GNU linker by default sorts some sections by priority, so we
  // do the same.  We need to know that this might happen before we
  // attach any input sections.
  if (!this->script_options_->saw_sections_clause()
      && !parameters->options().relocatable()
      && (strcmp(name, ".init_array") == 0
	  || strcmp(name, ".fini_array") == 0
	  || (!parameters->options().ctors_in_init_array()
	      && (strcmp(name, ".ctors") == 0
		  || strcmp(name, ".dtors") == 0))))
    os->set_may_sort_attached_input_sections();

  // The GNU linker by default sorts .text.{unlikely,exit,startup,hot}
  // sections before other .text sections.  We are compatible.  We
  // need to know that this might happen before we attach any input
  // sections.
  if (parameters->options().text_reorder()
      && !this->script_options_->saw_sections_clause()
      && !this->is_section_ordering_specified()
      && !parameters->options().relocatable()
      && strcmp(name, ".text") == 0)
    os->set_may_sort_attached_input_sections();

  // GNU linker sorts section by name with --sort-section=name.
  if (strcmp(parameters->options().sort_section(), "name") == 0)
      os->set_must_sort_attached_input_sections();

  // Check for .stab*str sections, as .stab* sections need to link to
  // them.
  if (type == elfcpp::SHT_STRTAB
      && !this->have_stabstr_section_
      && strncmp(name, ".stab", 5) == 0
      && strcmp(name + strlen(name) - 3, "str") == 0)
    this->have_stabstr_section_ = true;

  // During a full incremental link, we add patch space to most
  // PROGBITS and NOBITS sections.  Flag those that may be
  // arbitrarily padded.
  if ((type == elfcpp::SHT_PROGBITS || type == elfcpp::SHT_NOBITS)
      && order != ORDER_INTERP
      && order != ORDER_INIT
      && order != ORDER_PLT
      && order != ORDER_FINI
      && order != ORDER_RELRO_LAST
      && order != ORDER_NON_RELRO_FIRST
      && strcmp(name, ".eh_frame") != 0
      && strcmp(name, ".ctors") != 0
      && strcmp(name, ".dtors") != 0
      && strcmp(name, ".jcr") != 0)
    {
      os->set_is_patch_space_allowed();

      // Certain sections require "holes" to be filled with
      // specific fill patterns.  These fill patterns may have
      // a minimum size, so we must prevent allocations from the
      // free list that leave a hole smaller than the minimum.
      if (strcmp(name, ".debug_info") == 0)
	os->set_free_space_fill(new Output_fill_debug_info(false));
      else if (strcmp(name, ".debug_types") == 0)
	os->set_free_space_fill(new Output_fill_debug_info(true));
      else if (strcmp(name, ".debug_line") == 0)
	os->set_free_space_fill(new Output_fill_debug_line());
    }

  // If we have already attached the sections to segments, then we
  // need to attach this one now.  This happens for sections created
  // directly by the linker.
  if (this->sections_are_attached_)
    this->attach_section_to_segment(&parameters->target(), os);

  return os;
}

// Return the default order in which a section should be placed in an
// output segment.  This function captures a lot of the ideas in
// ld/scripttempl/elf.sc in the GNU linker.  Note that the order of a
// linker created section is normally set when the section is created;
// this function is used for input sections.

Output_section_order
Layout::default_section_order(Output_section* os, bool is_relro_local)
{
  gold_assert((os->flags() & elfcpp::SHF_ALLOC) != 0);
  bool is_write = (os->flags() & elfcpp::SHF_WRITE) != 0;
  bool is_execinstr = (os->flags() & elfcpp::SHF_EXECINSTR) != 0;
  bool is_bss = false;

  switch (os->type())
    {
    default:
    case elfcpp::SHT_PROGBITS:
      break;
    case elfcpp::SHT_NOBITS:
      is_bss = true;
      break;
    case elfcpp::SHT_RELA:
    case elfcpp::SHT_REL:
      if (!is_write)
	return ORDER_DYNAMIC_RELOCS;
      break;
    case elfcpp::SHT_HASH:
    case elfcpp::SHT_DYNAMIC:
    case elfcpp::SHT_SHLIB:
    case elfcpp::SHT_DYNSYM:
    case elfcpp::SHT_GNU_HASH:
    case elfcpp::SHT_GNU_verdef:
    case elfcpp::SHT_GNU_verneed:
    case elfcpp::SHT_GNU_versym:
      if (!is_write)
	return ORDER_DYNAMIC_LINKER;
      break;
    case elfcpp::SHT_NOTE:
      return is_write ? ORDER_RW_NOTE : ORDER_RO_NOTE;
    }

  if ((os->flags() & elfcpp::SHF_TLS) != 0)
    return is_bss ? ORDER_TLS_BSS : ORDER_TLS_DATA;

  if (!is_bss && !is_write)
    {
      if (is_execinstr)
	{
	  if (strcmp(os->name(), ".init") == 0)
	    return ORDER_INIT;
	  else if (strcmp(os->name(), ".fini") == 0)
	    return ORDER_FINI;
	}
      return is_execinstr ? ORDER_TEXT : ORDER_READONLY;
    }

  if (os->is_relro())
    return is_relro_local ? ORDER_RELRO_LOCAL : ORDER_RELRO;

  if (os->is_small_section())
    return is_bss ? ORDER_SMALL_BSS : ORDER_SMALL_DATA;
  if (os->is_large_section())
    return is_bss ? ORDER_LARGE_BSS : ORDER_LARGE_DATA;

  return is_bss ? ORDER_BSS : ORDER_DATA;
}

// Attach output sections to segments.  This is called after we have
// seen all the input sections.

void
Layout::attach_sections_to_segments(const Target* target)
{
  for (Section_list::iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    this->attach_section_to_segment(target, *p);

  this->sections_are_attached_ = true;
}

// Attach an output section to a segment.

void
Layout::attach_section_to_segment(const Target* target, Output_section* os)
{
  if ((os->flags() & elfcpp::SHF_ALLOC) == 0)
    this->unattached_section_list_.push_back(os);
  else
    this->attach_allocated_section_to_segment(target, os);
}

// Attach an allocated output section to a segment.

void
Layout::attach_allocated_section_to_segment(const Target* target,
					    Output_section* os)
{
  elfcpp::Elf_Xword flags = os->flags();
  gold_assert((flags & elfcpp::SHF_ALLOC) != 0);

  if (parameters->options().relocatable())
    return;

  // If we have a SECTIONS clause, we can't handle the attachment to
  // segments until after we've seen all the sections.
  if (this->script_options_->saw_sections_clause())
    return;

  gold_assert(!this->script_options_->saw_phdrs_clause());

  // This output section goes into a PT_LOAD segment.

  elfcpp::Elf_Word seg_flags = Layout::section_flags_to_segment(flags);

  // If this output section's segment has extra flags that need to be set,
  // coming from a linker plugin, do that.
  seg_flags |= os->extra_segment_flags();

  // Check for --section-start.
  uint64_t addr;
  bool is_address_set = parameters->options().section_start(os->name(), &addr);

  // In general the only thing we really care about for PT_LOAD
  // segments is whether or not they are writable or executable,
  // so that is how we search for them.
  // Large data sections also go into their own PT_LOAD segment.
  // People who need segments sorted on some other basis will
  // have to use a linker script.

  Segment_list::const_iterator p;
  if (!os->is_unique_segment())
    {
      for (p = this->segment_list_.begin();
	   p != this->segment_list_.end();
	   ++p)
	{
	  if ((*p)->type() != elfcpp::PT_LOAD)
	    continue;
	  if ((*p)->is_unique_segment())
	    continue;
	  if (!parameters->options().omagic()
	      && ((*p)->flags() & elfcpp::PF_W) != (seg_flags & elfcpp::PF_W))
	    continue;
	  if ((target->isolate_execinstr() || parameters->options().rosegment())
	      && ((*p)->flags() & elfcpp::PF_X) != (seg_flags & elfcpp::PF_X))
	    continue;
	  // If -Tbss was specified, we need to separate the data and BSS
	  // segments.
	  if (parameters->options().user_set_Tbss())
	    {
	      if ((os->type() == elfcpp::SHT_NOBITS)
		  == (*p)->has_any_data_sections())
		continue;
	    }
	  if (os->is_large_data_section() && !(*p)->is_large_data_segment())
	    continue;

	  if (is_address_set)
	    {
	      if ((*p)->are_addresses_set())
		continue;

	      (*p)->add_initial_output_data(os);
	      (*p)->update_flags_for_output_section(seg_flags);
	      (*p)->set_addresses(addr, addr);
	      break;
	    }

	  (*p)->add_output_section_to_load(this, os, seg_flags);
	  break;
	}
    }

  if (p == this->segment_list_.end()
      || os->is_unique_segment())
    {
      Output_segment* oseg = this->make_output_segment(elfcpp::PT_LOAD,
						       seg_flags);
      if (os->is_large_data_section())
	oseg->set_is_large_data_segment();
      oseg->add_output_section_to_load(this, os, seg_flags);
      if (is_address_set)
	oseg->set_addresses(addr, addr);
      // Check if segment should be marked unique.  For segments marked
      // unique by linker plugins, set the new alignment if specified.
      if (os->is_unique_segment())
	{
	  oseg->set_is_unique_segment();
	  if (os->segment_alignment() != 0)
	    oseg->set_minimum_p_align(os->segment_alignment());
	}
    }

  // If we see a loadable SHT_NOTE section, we create a PT_NOTE
  // segment.
  if (os->type() == elfcpp::SHT_NOTE)
    {
      // See if we already have an equivalent PT_NOTE segment.
      for (p = this->segment_list_.begin();
	   p != segment_list_.end();
	   ++p)
	{
	  if ((*p)->type() == elfcpp::PT_NOTE
	      && (((*p)->flags() & elfcpp::PF_W)
		  == (seg_flags & elfcpp::PF_W)))
	    {
	      (*p)->add_output_section_to_nonload(os, seg_flags);
	      break;
	    }
	}

      if (p == this->segment_list_.end())
	{
	  Output_segment* oseg = this->make_output_segment(elfcpp::PT_NOTE,
							   seg_flags);
	  oseg->add_output_section_to_nonload(os, seg_flags);
	}
    }

  // If we see a loadable SHF_TLS section, we create a PT_TLS
  // segment.  There can only be one such segment.
  if ((flags & elfcpp::SHF_TLS) != 0)
    {
      if (this->tls_segment_ == NULL)
	this->make_output_segment(elfcpp::PT_TLS, seg_flags);
      this->tls_segment_->add_output_section_to_nonload(os, seg_flags);
    }

  // If -z relro is in effect, and we see a relro section, we create a
  // PT_GNU_RELRO segment.  There can only be one such segment.
  if (os->is_relro() && parameters->options().relro())
    {
      gold_assert(seg_flags == (elfcpp::PF_R | elfcpp::PF_W));
      if (this->relro_segment_ == NULL)
	this->make_output_segment(elfcpp::PT_GNU_RELRO, seg_flags);
      this->relro_segment_->add_output_section_to_nonload(os, seg_flags);
    }

  // If we see a section named .interp, put it into a PT_INTERP
  // segment.  This seems broken to me, but this is what GNU ld does,
  // and glibc expects it.
  if (strcmp(os->name(), ".interp") == 0
      && !this->script_options_->saw_phdrs_clause())
    {
      if (this->interp_segment_ == NULL)
	this->make_output_segment(elfcpp::PT_INTERP, seg_flags);
      else
	gold_warning(_("multiple '.interp' sections in input files "
		       "may cause confusing PT_INTERP segment"));
      this->interp_segment_->add_output_section_to_nonload(os, seg_flags);
    }
}

// Make an output section for a script.

Output_section*
Layout::make_output_section_for_script(
    const char* name,
    Script_sections::Section_type section_type)
{
  name = this->namepool_.add(name, false, NULL);
  elfcpp::Elf_Xword sh_flags = elfcpp::SHF_ALLOC;
  if (section_type == Script_sections::ST_NOLOAD)
    sh_flags = 0;
  Output_section* os = this->make_output_section(name, elfcpp::SHT_PROGBITS,
						 sh_flags, ORDER_INVALID,
						 false);
  os->set_found_in_sections_clause();
  if (section_type == Script_sections::ST_NOLOAD)
    os->set_is_noload();
  return os;
}

// Return the number of segments we expect to see.

size_t
Layout::expected_segment_count() const
{
  size_t ret = this->segment_list_.size();

  // If we didn't see a SECTIONS clause in a linker script, we should
  // already have the complete list of segments.  Otherwise we ask the
  // SECTIONS clause how many segments it expects, and add in the ones
  // we already have (PT_GNU_STACK, PT_GNU_EH_FRAME, etc.)

  if (!this->script_options_->saw_sections_clause())
    return ret;
  else
    {
      const Script_sections* ss = this->script_options_->script_sections();
      return ret + ss->expected_segment_count(this);
    }
}

// Handle the .note.GNU-stack section at layout time.  SEEN_GNU_STACK
// is whether we saw a .note.GNU-stack section in the object file.
// GNU_STACK_FLAGS is the section flags.  The flags give the
// protection required for stack memory.  We record this in an
// executable as a PT_GNU_STACK segment.  If an object file does not
// have a .note.GNU-stack segment, we must assume that it is an old
// object.  On some targets that will force an executable stack.

void
Layout::layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags,
			 const Object* obj)
{
  if (!seen_gnu_stack)
    {
      this->input_without_gnu_stack_note_ = true;
      if (parameters->options().warn_execstack()
	  && parameters->target().is_default_stack_executable())
	gold_warning(_("%s: missing .note.GNU-stack section"
		       " implies executable stack"),
		     obj->name().c_str());
    }
  else
    {
      this->input_with_gnu_stack_note_ = true;
      if ((gnu_stack_flags & elfcpp::SHF_EXECINSTR) != 0)
	{
	  this->input_requires_executable_stack_ = true;
	  if (parameters->options().warn_execstack()
	      || parameters->options().is_stack_executable())
	    gold_warning(_("%s: requires executable stack"),
			 obj->name().c_str());
	}
    }
}

// Create automatic note sections.

void
Layout::create_notes()
{
  this->create_gold_note();
  this->create_executable_stack_info();
  this->create_build_id();
}

// Create the dynamic sections which are needed before we read the
// relocs.

void
Layout::create_initial_dynamic_sections(Symbol_table* symtab)
{
  if (parameters->doing_static_link())
    return;

  this->dynamic_section_ = this->choose_output_section(NULL, ".dynamic",
						       elfcpp::SHT_DYNAMIC,
						       (elfcpp::SHF_ALLOC
							| elfcpp::SHF_WRITE),
						       false, ORDER_RELRO,
						       true);

  // A linker script may discard .dynamic, so check for NULL.
  if (this->dynamic_section_ != NULL)
    {
      this->dynamic_symbol_ =
	symtab->define_in_output_data("_DYNAMIC", NULL,
				      Symbol_table::PREDEFINED,
				      this->dynamic_section_, 0, 0,
				      elfcpp::STT_OBJECT, elfcpp::STB_LOCAL,
				      elfcpp::STV_HIDDEN, 0, false, false);

      this->dynamic_data_ =  new Output_data_dynamic(&this->dynpool_);

      this->dynamic_section_->add_output_section_data(this->dynamic_data_);
    }
}

// For each output section whose name can be represented as C symbol,
// define __start and __stop symbols for the section.  This is a GNU
// extension.

void
Layout::define_section_symbols(Symbol_table* symtab)
{
  for (Section_list::const_iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      const char* const name = (*p)->name();
      if (is_cident(name))
	{
	  const std::string name_string(name);
	  const std::string start_name(cident_section_start_prefix
				       + name_string);
	  const std::string stop_name(cident_section_stop_prefix
				      + name_string);

	  symtab->define_in_output_data(start_name.c_str(),
					NULL, // version
					Symbol_table::PREDEFINED,
					*p,
					0, // value
					0, // symsize
					elfcpp::STT_NOTYPE,
					elfcpp::STB_GLOBAL,
					elfcpp::STV_DEFAULT,
					0, // nonvis
					false, // offset_is_from_end
					true); // only_if_ref

	  symtab->define_in_output_data(stop_name.c_str(),
					NULL, // version
					Symbol_table::PREDEFINED,
					*p,
					0, // value
					0, // symsize
					elfcpp::STT_NOTYPE,
					elfcpp::STB_GLOBAL,
					elfcpp::STV_DEFAULT,
					0, // nonvis
					true, // offset_is_from_end
					true); // only_if_ref
	}
    }
}

// Define symbols for group signatures.

void
Layout::define_group_signatures(Symbol_table* symtab)
{
  for (Group_signatures::iterator p = this->group_signatures_.begin();
       p != this->group_signatures_.end();
       ++p)
    {
      Symbol* sym = symtab->lookup(p->signature, NULL);
      if (sym != NULL)
	p->section->set_info_symndx(sym);
      else
	{
	  // Force the name of the group section to the group
	  // signature, and use the group's section symbol as the
	  // signature symbol.
	  if (strcmp(p->section->name(), p->signature) != 0)
	    {
	      const char* name = this->namepool_.add(p->signature,
						     true, NULL);
	      p->section->set_name(name);
	    }
	  p->section->set_needs_symtab_index();
	  p->section->set_info_section_symndx(p->section);
	}
    }

  this->group_signatures_.clear();
}

// Find the first read-only PT_LOAD segment, creating one if
// necessary.

Output_segment*
Layout::find_first_load_seg(const Target* target)
{
  Output_segment* best = NULL;
  for (Segment_list::const_iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    {
      if ((*p)->type() == elfcpp::PT_LOAD
	  && ((*p)->flags() & elfcpp::PF_R) != 0
	  && (parameters->options().omagic()
	      || ((*p)->flags() & elfcpp::PF_W) == 0)
	  && (!target->isolate_execinstr()
	      || ((*p)->flags() & elfcpp::PF_X) == 0))
	{
	  if (best == NULL || this->segment_precedes(*p, best))
	    best = *p;
	}
    }
  if (best != NULL)
    return best;

  gold_assert(!this->script_options_->saw_phdrs_clause());

  Output_segment* load_seg = this->make_output_segment(elfcpp::PT_LOAD,
						       elfcpp::PF_R);
  return load_seg;
}

// Save states of all current output segments.  Store saved states
// in SEGMENT_STATES.

void
Layout::save_segments(Segment_states* segment_states)
{
  for (Segment_list::const_iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    {
      Output_segment* segment = *p;
      // Shallow copy.
      Output_segment* copy = new Output_segment(*segment);
      (*segment_states)[segment] = copy;
    }
}

// Restore states of output segments and delete any segment not found in
// SEGMENT_STATES.

void
Layout::restore_segments(const Segment_states* segment_states)
{
  // Go through the segment list and remove any segment added in the
  // relaxation loop.
  this->tls_segment_ = NULL;
  this->relro_segment_ = NULL;
  Segment_list::iterator list_iter = this->segment_list_.begin();
  while (list_iter != this->segment_list_.end())
    {
      Output_segment* segment = *list_iter;
      Segment_states::const_iterator states_iter =
	  segment_states->find(segment);
      if (states_iter != segment_states->end())
	{
	  const Output_segment* copy = states_iter->second;
	  // Shallow copy to restore states.
	  *segment = *copy;

	  // Also fix up TLS and RELRO segment pointers as appropriate.
	  if (segment->type() == elfcpp::PT_TLS)
	    this->tls_segment_ = segment;
	  else if (segment->type() == elfcpp::PT_GNU_RELRO)
	    this->relro_segment_ = segment;

	  ++list_iter;
	}
      else
	{
	  list_iter = this->segment_list_.erase(list_iter);
	  // This is a segment created during section layout.  It should be
	  // safe to remove it since we should have removed all pointers to it.
	  delete segment;
	}
    }
}

// Clean up after relaxation so that sections can be laid out again.

void
Layout::clean_up_after_relaxation()
{
  // Restore the segments to point state just prior to the relaxation loop.
  Script_sections* script_section = this->script_options_->script_sections();
  script_section->release_segments();
  this->restore_segments(this->segment_states_);

  // Reset section addresses and file offsets
  for (Section_list::iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      (*p)->restore_states();

      // If an input section changes size because of relaxation,
      // we need to adjust the section offsets of all input sections.
      // after such a section.
      if ((*p)->section_offsets_need_adjustment())
	(*p)->adjust_section_offsets();

      (*p)->reset_address_and_file_offset();
    }

  // Reset special output object address and file offsets.
  for (Data_list::iterator p = this->special_output_list_.begin();
       p != this->special_output_list_.end();
       ++p)
    (*p)->reset_address_and_file_offset();

  // A linker script may have created some output section data objects.
  // They are useless now.
  for (Output_section_data_list::const_iterator p =
	 this->script_output_section_data_list_.begin();
       p != this->script_output_section_data_list_.end();
       ++p)
    delete *p;
  this->script_output_section_data_list_.clear();

  // Special-case fill output objects are recreated each time through
  // the relaxation loop.
  this->reset_relax_output();
}

void
Layout::reset_relax_output()
{
  for (Data_list::const_iterator p = this->relax_output_list_.begin();
       p != this->relax_output_list_.end();
       ++p)
    delete *p;
  this->relax_output_list_.clear();
}

// Prepare for relaxation.

void
Layout::prepare_for_relaxation()
{
  // Create an relaxation debug check if in debugging mode.
  if (is_debugging_enabled(DEBUG_RELAXATION))
    this->relaxation_debug_check_ = new Relaxation_debug_check();

  // Save segment states.
  this->segment_states_ = new Segment_states();
  this->save_segments(this->segment_states_);

  for(Section_list::const_iterator p = this->section_list_.begin();
      p != this->section_list_.end();
      ++p)
    (*p)->save_states();

  if (is_debugging_enabled(DEBUG_RELAXATION))
    this->relaxation_debug_check_->check_output_data_for_reset_values(
	this->section_list_, this->special_output_list_,
	this->relax_output_list_);

  // Also enable recording of output section data from scripts.
  this->record_output_section_data_from_script_ = true;
}

// If the user set the address of the text segment, that may not be
// compatible with putting the segment headers and file headers into
// that segment.  For isolate_execinstr() targets, it's the rodata
// segment rather than text where we might put the headers.
static inline bool
load_seg_unusable_for_headers(const Target* target)
{
  const General_options& options = parameters->options();
  if (target->isolate_execinstr())
    return (options.user_set_Trodata_segment()
	    && options.Trodata_segment() % target->abi_pagesize() != 0);
  else
    return (options.user_set_Ttext()
	    && options.Ttext() % target->abi_pagesize() != 0);
}

// Relaxation loop body:  If target has no relaxation, this runs only once
// Otherwise, the target relaxation hook is called at the end of
// each iteration.  If the hook returns true, it means re-layout of
// section is required.
//
// The number of segments created by a linking script without a PHDRS
// clause may be affected by section sizes and alignments.  There is
// a remote chance that relaxation causes different number of PT_LOAD
// segments are created and sections are attached to different segments.
// Therefore, we always throw away all segments created during section
// layout.  In order to be able to restart the section layout, we keep
// a copy of the segment list right before the relaxation loop and use
// that to restore the segments.
//
// PASS is the current relaxation pass number.
// SYMTAB is a symbol table.
// PLOAD_SEG is the address of a pointer for the load segment.
// PHDR_SEG is a pointer to the PHDR segment.
// SEGMENT_HEADERS points to the output segment header.
// FILE_HEADER points to the output file header.
// PSHNDX is the address to store the output section index.

off_t inline
Layout::relaxation_loop_body(
    int pass,
    Target* target,
    Symbol_table* symtab,
    Output_segment** pload_seg,
    Output_segment* phdr_seg,
    Output_segment_headers* segment_headers,
    Output_file_header* file_header,
    unsigned int* pshndx)
{
  // If this is not the first iteration, we need to clean up after
  // relaxation so that we can lay out the sections again.
  if (pass != 0)
    this->clean_up_after_relaxation();

  // If there is a SECTIONS clause, put all the input sections into
  // the required order.
  Output_segment* load_seg;
  if (this->script_options_->saw_sections_clause())
    load_seg = this->set_section_addresses_from_script(symtab);
  else if (parameters->options().relocatable())
    load_seg = NULL;
  else
    load_seg = this->find_first_load_seg(target);

  if (parameters->options().oformat_enum()
      != General_options::OBJECT_FORMAT_ELF)
    load_seg = NULL;

  if (load_seg_unusable_for_headers(target))
    {
      load_seg = NULL;
      phdr_seg = NULL;
    }

  gold_assert(phdr_seg == NULL
	      || load_seg != NULL
	      || this->script_options_->saw_sections_clause());

  // If the address of the load segment we found has been set by
  // --section-start rather than by a script, then adjust the VMA and
  // LMA downward if possible to include the file and section headers.
  uint64_t header_gap = 0;
  if (load_seg != NULL
      && load_seg->are_addresses_set()
      && !this->script_options_->saw_sections_clause()
      && !parameters->options().relocatable())
    {
      file_header->finalize_data_size();
      segment_headers->finalize_data_size();
      size_t sizeof_headers = (file_header->data_size()
			       + segment_headers->data_size());
      const uint64_t abi_pagesize = target->abi_pagesize();
      uint64_t hdr_paddr = load_seg->paddr() - sizeof_headers;
      hdr_paddr &= ~(abi_pagesize - 1);
      uint64_t subtract = load_seg->paddr() - hdr_paddr;
      if (load_seg->paddr() < subtract || load_seg->vaddr() < subtract)
	load_seg = NULL;
      else
	{
	  load_seg->set_addresses(load_seg->vaddr() - subtract,
				  load_seg->paddr() - subtract);
	  header_gap = subtract - sizeof_headers;
	}
    }

  // Lay out the segment headers.
  if (!parameters->options().relocatable())
    {
      gold_assert(segment_headers != NULL);
      if (header_gap != 0 && load_seg != NULL)
	{
	  Output_data_zero_fill* z = new Output_data_zero_fill(header_gap, 1);
	  load_seg->add_initial_output_data(z);
	}
      if (load_seg != NULL)
	load_seg->add_initial_output_data(segment_headers);
      if (phdr_seg != NULL)
	phdr_seg->add_initial_output_data(segment_headers);
    }

  // Lay out the file header.
  if (load_seg != NULL)
    load_seg->add_initial_output_data(file_header);

  if (this->script_options_->saw_phdrs_clause()
      && !parameters->options().relocatable())
    {
      // Support use of FILEHDRS and PHDRS attachments in a PHDRS
      // clause in a linker script.
      Script_sections* ss = this->script_options_->script_sections();
      ss->put_headers_in_phdrs(file_header, segment_headers);
    }

  // We set the output section indexes in set_segment_offsets and
  // set_section_indexes.
  *pshndx = 1;

  // Set the file offsets of all the segments, and all the sections
  // they contain.
  off_t off;
  if (!parameters->options().relocatable())
    off = this->set_segment_offsets(target, load_seg, pshndx);
  else
    off = this->set_relocatable_section_offsets(file_header, pshndx);

   // Verify that the dummy relaxation does not change anything.
  if (is_debugging_enabled(DEBUG_RELAXATION))
    {
      if (pass == 0)
	this->relaxation_debug_check_->read_sections(this->section_list_);
      else
	this->relaxation_debug_check_->verify_sections(this->section_list_);
    }

  *pload_seg = load_seg;
  return off;
}

// Search the list of patterns and find the postion of the given section
// name in the output section.  If the section name matches a glob
// pattern and a non-glob name, then the non-glob position takes
// precedence.  Return 0 if no match is found.

unsigned int
Layout::find_section_order_index(const std::string& section_name)
{
  Unordered_map<std::string, unsigned int>::iterator map_it;
  map_it = this->input_section_position_.find(section_name);
  if (map_it != this->input_section_position_.end())
    return map_it->second;

  // Absolute match failed.  Linear search the glob patterns.
  std::vector<std::string>::iterator it;
  for (it = this->input_section_glob_.begin();
       it != this->input_section_glob_.end();
       ++it)
    {
       if (fnmatch((*it).c_str(), section_name.c_str(), FNM_NOESCAPE) == 0)
	 {
	   map_it = this->input_section_position_.find(*it);
	   gold_assert(map_it != this->input_section_position_.end());
	   return map_it->second;
	 }
    }
  return 0;
}

// Read the sequence of input sections from the file specified with
// option --section-ordering-file.

void
Layout::read_layout_from_file()
{
  const char* filename = parameters->options().section_ordering_file();
  std::ifstream in;
  std::string line;

  in.open(filename);
  if (!in)
    gold_fatal(_("unable to open --section-ordering-file file %s: %s"),
	       filename, strerror(errno));

  std::getline(in, line);   // this chops off the trailing \n, if any
  unsigned int position = 1;
  this->set_section_ordering_specified();

  while (in)
    {
      if (!line.empty() && line[line.length() - 1] == '\r')   // Windows
	line.resize(line.length() - 1);
      // Ignore comments, beginning with '#'
      if (line[0] == '#')
	{
	  std::getline(in, line);
	  continue;
	}
      this->input_section_position_[line] = position;
      // Store all glob patterns in a vector.
      if (is_wildcard_string(line.c_str()))
	this->input_section_glob_.push_back(line);
      position++;
      std::getline(in, line);
    }
}

// Finalize the layout.  When this is called, we have created all the
// output sections and all the output segments which are based on
// input sections.  We have several things to do, and we have to do
// them in the right order, so that we get the right results correctly
// and efficiently.

// 1) Finalize the list of output segments and create the segment
// table header.

// 2) Finalize the dynamic symbol table and associated sections.

// 3) Determine the final file offset of all the output segments.

// 4) Determine the final file offset of all the SHF_ALLOC output
// sections.

// 5) Create the symbol table sections and the section name table
// section.

// 6) Finalize the symbol table: set symbol values to their final
// value and make a final determination of which symbols are going
// into the output symbol table.

// 7) Create the section table header.

// 8) Determine the final file offset of all the output sections which
// are not SHF_ALLOC, including the section table header.

// 9) Finalize the ELF file header.

// This function returns the size of the output file.

off_t
Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
		 Target* target, const Task* task)
{
  target->finalize_sections(this, input_objects, symtab);

  this->count_local_symbols(task, input_objects);

  this->link_stabs_sections();

  Output_segment* phdr_seg = NULL;
  if (!parameters->options().relocatable() && !parameters->doing_static_link())
    {
      // There was a dynamic object in the link.  We need to create
      // some information for the dynamic linker.

      // Create the PT_PHDR segment which will hold the program
      // headers.
      if (!this->script_options_->saw_phdrs_clause())
	phdr_seg = this->make_output_segment(elfcpp::PT_PHDR, elfcpp::PF_R);

      // Create the dynamic symbol table, including the hash table.
      Output_section* dynstr;
      std::vector<Symbol*> dynamic_symbols;
      unsigned int local_dynamic_count;
      Versions versions(*this->script_options()->version_script_info(),
			&this->dynpool_);
      this->create_dynamic_symtab(input_objects, symtab, &dynstr,
				  &local_dynamic_count, &dynamic_symbols,
				  &versions);

      // Create the .interp section to hold the name of the
      // interpreter, and put it in a PT_INTERP segment.  Don't do it
      // if we saw a .interp section in an input file.
      if ((!parameters->options().shared()
	   || parameters->options().dynamic_linker() != NULL)
	  && this->interp_segment_ == NULL)
	this->create_interp(target);

      // Finish the .dynamic section to hold the dynamic data, and put
      // it in a PT_DYNAMIC segment.
      this->finish_dynamic_section(input_objects, symtab);

      // We should have added everything we need to the dynamic string
      // table.
      this->dynpool_.set_string_offsets();

      // Create the version sections.  We can't do this until the
      // dynamic string table is complete.
      this->create_version_sections(&versions, symtab, local_dynamic_count,
				    dynamic_symbols, dynstr);

      // Set the size of the _DYNAMIC symbol.  We can't do this until
      // after we call create_version_sections.
      this->set_dynamic_symbol_size(symtab);
    }

  // Create segment headers.
  Output_segment_headers* segment_headers =
    (parameters->options().relocatable()
     ? NULL
     : new Output_segment_headers(this->segment_list_));

  // Lay out the file header.
  Output_file_header* file_header = new Output_file_header(target, symtab,
							   segment_headers);

  this->special_output_list_.push_back(file_header);
  if (segment_headers != NULL)
    this->special_output_list_.push_back(segment_headers);

  // Find approriate places for orphan output sections if we are using
  // a linker script.
  if (this->script_options_->saw_sections_clause())
    this->place_orphan_sections_in_script();

  Output_segment* load_seg;
  off_t off;
  unsigned int shndx;
  int pass = 0;

  // Take a snapshot of the section layout as needed.
  if (target->may_relax())
    this->prepare_for_relaxation();

  // Run the relaxation loop to lay out sections.
  do
    {
      off = this->relaxation_loop_body(pass, target, symtab, &load_seg,
				       phdr_seg, segment_headers, file_header,
				       &shndx);
      pass++;
    }
  while (target->may_relax()
	 && target->relax(pass, input_objects, symtab, this, task));

  // Check if data segment size is less than the safe value with PIE links.
  // Warn about bug http://b/20165734 for unsafe sizes.
  if (parameters->options().pie() && target->max_pie_data_segment_size())
    {
      Segment_list::const_iterator p;
      uint64_t re_vaddr = 0, re_memsz = 0, rw_vaddr = 0, rw_memsz = 0;
      uint64_t data_seg_size = 0;
      for (p = this->segment_list_.begin();
	   p != this->segment_list_.end();
	   ++p)
	{
	  // With -Wl,--rosegment, note the end addr of "R E" segment.
	  if (parameters->options().rosegment()
	      && (*p)->type() == elfcpp::PT_LOAD
	      && ((*p)->flags() & elfcpp::PF_X) != 0
	      && ((*p)->flags() & elfcpp::PF_R) != 0)
	    {
	      re_vaddr = (*p)->vaddr();
	      re_memsz = (*p)->memsz();
	      continue;
	    }
	  if ((*p)->type() == elfcpp::PT_LOAD
	      && ((*p)->flags() & elfcpp::PF_W) != 0
	      && ((*p)->flags() & elfcpp::PF_R) != 0)
	    {
	      rw_vaddr = (*p)->vaddr();
	      rw_memsz = (*p)->memsz();
	      break;
	    }
	}

      // With -Wl,--rosegment, report data segment size as delta of end of
      // "RW" segment and end of "R E" segment.  Otherwise, data segment
      // size is just the memsz of "RW" segment.
      if (parameters->options().rosegment())
        data_seg_size = (rw_vaddr + rw_memsz) - (re_vaddr + re_memsz);
      else
        data_seg_size = rw_memsz;

      if (data_seg_size >= target->max_pie_data_segment_size())
	gold_warning(_("Unsafe PIE data segment size (%ld > %ld). See "
		       "go/unsafe-pie."),
		       data_seg_size, target->max_pie_data_segment_size());
    }

  // If there is a load segment that contains the file and program headers,
  // provide a symbol __ehdr_start pointing there.
  // A program can use this to examine itself robustly.
  Symbol *ehdr_start = symtab->lookup("__ehdr_start");
  if (ehdr_start != NULL && ehdr_start->is_predefined())
    {
      if (load_seg != NULL)
	ehdr_start->set_output_segment(load_seg, Symbol::SEGMENT_START);
      else
        ehdr_start->set_undefined();
    }

  // Set the file offsets of all the non-data sections we've seen so
  // far which don't have to wait for the input sections.  We need
  // this in order to finalize local symbols in non-allocated
  // sections.
  off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS);

  // Set the section indexes of all unallocated sections seen so far,
  // in case any of them are somehow referenced by a symbol.
  shndx = this->set_section_indexes(shndx);

  // Create the symbol table sections.
  this->create_symtab_sections(input_objects, symtab, shndx, &off);
  if (!parameters->doing_static_link())
    this->assign_local_dynsym_offsets(input_objects);

  // Process any symbol assignments from a linker script.  This must
  // be called after the symbol table has been finalized.
  this->script_options_->finalize_symbols(symtab, this);

  // Create the incremental inputs sections.
  if (this->incremental_inputs_)
    {
      this->incremental_inputs_->finalize();
      this->create_incremental_info_sections(symtab);
    }

  // Create the .shstrtab section.
  Output_section* shstrtab_section = this->create_shstrtab();

  // Set the file offsets of the rest of the non-data sections which
  // don't have to wait for the input sections.
  off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS);

  // Now that all sections have been created, set the section indexes
  // for any sections which haven't been done yet.
  shndx = this->set_section_indexes(shndx);

  // Create the section table header.
  this->create_shdrs(shstrtab_section, &off);

  // If there are no sections which require postprocessing, we can
  // handle the section names now, and avoid a resize later.
  if (!this->any_postprocessing_sections_)
    {
      off = this->set_section_offsets(off,
				      POSTPROCESSING_SECTIONS_PASS);
      off =
	  this->set_section_offsets(off,
				    STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS);
    }

  file_header->set_section_info(this->section_headers_, shstrtab_section);

  // Now we know exactly where everything goes in the output file
  // (except for non-allocated sections which require postprocessing).
  Output_data::layout_complete();

  this->output_file_size_ = off;

  return off;
}

// Create a note header following the format defined in the ELF ABI.
// NAME is the name, NOTE_TYPE is the type, SECTION_NAME is the name
// of the section to create, DESCSZ is the size of the descriptor.
// ALLOCATE is true if the section should be allocated in memory.
// This returns the new note section.  It sets *TRAILING_PADDING to
// the number of trailing zero bytes required.

Output_section*
Layout::create_note(const char* name, int note_type,
		    const char* section_name, size_t descsz,
		    bool allocate, size_t* trailing_padding)
{
  // Authorities all agree that the values in a .note field should
  // be aligned on 4-byte boundaries for 32-bit binaries.  However,
  // they differ on what the alignment is for 64-bit binaries.
  // The GABI says unambiguously they take 8-byte alignment:
  //    http://sco.com/developers/gabi/latest/ch5.pheader.html#note_section
  // Other documentation says alignment should always be 4 bytes:
  //    http://www.netbsd.org/docs/kernel/elf-notes.html#note-format
  // GNU ld and GNU readelf both support the latter (at least as of
  // version 2.16.91), and glibc always generates the latter for
  // .note.ABI-tag (as of version 1.6), so that's the one we go with
  // here.
#ifdef GABI_FORMAT_FOR_DOTNOTE_SECTION   // This is not defined by default.
  const int size = parameters->target().get_size();
#else
  const int size = 32;
#endif

  // The contents of the .note section.
  size_t namesz = strlen(name) + 1;
  size_t aligned_namesz = align_address(namesz, size / 8);
  size_t aligned_descsz = align_address(descsz, size / 8);

  size_t notehdrsz = 3 * (size / 8) + aligned_namesz;

  unsigned char* buffer = new unsigned char[notehdrsz];
  memset(buffer, 0, notehdrsz);

  bool is_big_endian = parameters->target().is_big_endian();

  if (size == 32)
    {
      if (!is_big_endian)
	{
	  elfcpp::Swap<32, false>::writeval(buffer, namesz);
	  elfcpp::Swap<32, false>::writeval(buffer + 4, descsz);
	  elfcpp::Swap<32, false>::writeval(buffer + 8, note_type);
	}
      else
	{
	  elfcpp::Swap<32, true>::writeval(buffer, namesz);
	  elfcpp::Swap<32, true>::writeval(buffer + 4, descsz);
	  elfcpp::Swap<32, true>::writeval(buffer + 8, note_type);
	}
    }
  else if (size == 64)
    {
      if (!is_big_endian)
	{
	  elfcpp::Swap<64, false>::writeval(buffer, namesz);
	  elfcpp::Swap<64, false>::writeval(buffer + 8, descsz);
	  elfcpp::Swap<64, false>::writeval(buffer + 16, note_type);
	}
      else
	{
	  elfcpp::Swap<64, true>::writeval(buffer, namesz);
	  elfcpp::Swap<64, true>::writeval(buffer + 8, descsz);
	  elfcpp::Swap<64, true>::writeval(buffer + 16, note_type);
	}
    }
  else
    gold_unreachable();

  memcpy(buffer + 3 * (size / 8), name, namesz);

  elfcpp::Elf_Xword flags = 0;
  Output_section_order order = ORDER_INVALID;
  if (allocate)
    {
      flags = elfcpp::SHF_ALLOC;
      order = ORDER_RO_NOTE;
    }
  Output_section* os = this->choose_output_section(NULL, section_name,
						   elfcpp::SHT_NOTE,
						   flags, false, order, false);
  if (os == NULL)
    return NULL;

  Output_section_data* posd = new Output_data_const_buffer(buffer, notehdrsz,
							   size / 8,
							   "** note header");
  os->add_output_section_data(posd);

  *trailing_padding = aligned_descsz - descsz;

  return os;
}

// For an executable or shared library, create a note to record the
// version of gold used to create the binary.

void
Layout::create_gold_note()
{
  if (parameters->options().relocatable()
      || parameters->incremental_update())
    return;

  std::string desc = std::string("gold ") + gold::get_version_string();

  size_t trailing_padding;
  Output_section* os = this->create_note("GNU", elfcpp::NT_GNU_GOLD_VERSION,
					 ".note.gnu.gold-version", desc.size(),
					 false, &trailing_padding);
  if (os == NULL)
    return;

  Output_section_data* posd = new Output_data_const(desc, 4);
  os->add_output_section_data(posd);

  if (trailing_padding > 0)
    {
      posd = new Output_data_zero_fill(trailing_padding, 0);
      os->add_output_section_data(posd);
    }
}

// Record whether the stack should be executable.  This can be set
// from the command line using the -z execstack or -z noexecstack
// options.  Otherwise, if any input file has a .note.GNU-stack
// section with the SHF_EXECINSTR flag set, the stack should be
// executable.  Otherwise, if at least one input file a
// .note.GNU-stack section, and some input file has no .note.GNU-stack
// section, we use the target default for whether the stack should be
// executable.  Otherwise, we don't generate a stack note.  When
// generating a object file, we create a .note.GNU-stack section with
// the appropriate marking.  When generating an executable or shared
// library, we create a PT_GNU_STACK segment.

void
Layout::create_executable_stack_info()
{
  bool is_stack_executable;
  if (parameters->options().is_execstack_set())
    is_stack_executable = parameters->options().is_stack_executable();
  else if (!this->input_with_gnu_stack_note_)
    return;
  else
    {
      if (this->input_requires_executable_stack_)
	is_stack_executable = true;
      else if (this->input_without_gnu_stack_note_)
	is_stack_executable =
	  parameters->target().is_default_stack_executable();
      else
	is_stack_executable = false;
    }

  if (parameters->options().relocatable())
    {
      const char* name = this->namepool_.add(".note.GNU-stack", false, NULL);
      elfcpp::Elf_Xword flags = 0;
      if (is_stack_executable)
	flags |= elfcpp::SHF_EXECINSTR;
      this->make_output_section(name, elfcpp::SHT_PROGBITS, flags,
				ORDER_INVALID, false);
    }
  else
    {
      if (this->script_options_->saw_phdrs_clause())
	return;
      int flags = elfcpp::PF_R | elfcpp::PF_W;
      if (is_stack_executable)
	flags |= elfcpp::PF_X;
      this->make_output_segment(elfcpp::PT_GNU_STACK, flags);
    }
}

// If --build-id was used, set up the build ID note.

void
Layout::create_build_id()
{
  if (!parameters->options().user_set_build_id())
    return;

  const char* style = parameters->options().build_id();
  if (strcmp(style, "none") == 0)
    return;

  // Set DESCSZ to the size of the note descriptor.  When possible,
  // set DESC to the note descriptor contents.
  size_t descsz;
  std::string desc;
  if (strcmp(style, "md5") == 0)
    descsz = 128 / 8;
  else if ((strcmp(style, "sha1") == 0) || (strcmp(style, "tree") == 0))
    descsz = 160 / 8;
  else if (strcmp(style, "uuid") == 0)
    {
      const size_t uuidsz = 128 / 8;

      char buffer[uuidsz];
      memset(buffer, 0, uuidsz);

      int descriptor = open_descriptor(-1, "/dev/urandom", O_RDONLY);
      if (descriptor < 0)
	gold_error(_("--build-id=uuid failed: could not open /dev/urandom: %s"),
		   strerror(errno));
      else
	{
	  ssize_t got = ::read(descriptor, buffer, uuidsz);
	  release_descriptor(descriptor, true);
	  if (got < 0)
	    gold_error(_("/dev/urandom: read failed: %s"), strerror(errno));
	  else if (static_cast<size_t>(got) != uuidsz)
	    gold_error(_("/dev/urandom: expected %zu bytes, got %zd bytes"),
		       uuidsz, got);
	}

      desc.assign(buffer, uuidsz);
      descsz = uuidsz;
    }
  else if (strncmp(style, "0x", 2) == 0)
    {
      hex_init();
      const char* p = style + 2;
      while (*p != '\0')
	{
	  if (hex_p(p[0]) && hex_p(p[1]))
	    {
	      char c = (hex_value(p[0]) << 4) | hex_value(p[1]);
	      desc += c;
	      p += 2;
	    }
	  else if (*p == '-' || *p == ':')
	    ++p;
	  else
	    gold_fatal(_("--build-id argument '%s' not a valid hex number"),
		       style);
	}
      descsz = desc.size();
    }
  else
    gold_fatal(_("unrecognized --build-id argument '%s'"), style);

  // Create the note.
  size_t trailing_padding;
  Output_section* os = this->create_note("GNU", elfcpp::NT_GNU_BUILD_ID,
					 ".note.gnu.build-id", descsz, true,
					 &trailing_padding);
  if (os == NULL)
    return;

  if (!desc.empty())
    {
      // We know the value already, so we fill it in now.
      gold_assert(desc.size() == descsz);

      Output_section_data* posd = new Output_data_const(desc, 4);
      os->add_output_section_data(posd);

      if (trailing_padding != 0)
	{
	  posd = new Output_data_zero_fill(trailing_padding, 0);
	  os->add_output_section_data(posd);
	}
    }
  else
    {
      // We need to compute a checksum after we have completed the
      // link.
      gold_assert(trailing_padding == 0);
      this->build_id_note_ = new Output_data_zero_fill(descsz, 4);
      os->add_output_section_data(this->build_id_note_);
    }
}

// If we have both .stabXX and .stabXXstr sections, then the sh_link
// field of the former should point to the latter.  I'm not sure who
// started this, but the GNU linker does it, and some tools depend
// upon it.

void
Layout::link_stabs_sections()
{
  if (!this->have_stabstr_section_)
    return;

  for (Section_list::iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      if ((*p)->type() != elfcpp::SHT_STRTAB)
	continue;

      const char* name = (*p)->name();
      if (strncmp(name, ".stab", 5) != 0)
	continue;

      size_t len = strlen(name);
      if (strcmp(name + len - 3, "str") != 0)
	continue;

      std::string stab_name(name, len - 3);
      Output_section* stab_sec;
      stab_sec = this->find_output_section(stab_name.c_str());
      if (stab_sec != NULL)
	stab_sec->set_link_section(*p);
    }
}

// Create .gnu_incremental_inputs and related sections needed
// for the next run of incremental linking to check what has changed.

void
Layout::create_incremental_info_sections(Symbol_table* symtab)
{
  Incremental_inputs* incr = this->incremental_inputs_;

  gold_assert(incr != NULL);

  // Create the .gnu_incremental_inputs, _symtab, and _relocs input sections.
  incr->create_data_sections(symtab);

  // Add the .gnu_incremental_inputs section.
  const char* incremental_inputs_name =
    this->namepool_.add(".gnu_incremental_inputs", false, NULL);
  Output_section* incremental_inputs_os =
    this->make_output_section(incremental_inputs_name,
			      elfcpp::SHT_GNU_INCREMENTAL_INPUTS, 0,
			      ORDER_INVALID, false);
  incremental_inputs_os->add_output_section_data(incr->inputs_section());

  // Add the .gnu_incremental_symtab section.
  const char* incremental_symtab_name =
    this->namepool_.add(".gnu_incremental_symtab", false, NULL);
  Output_section* incremental_symtab_os =
    this->make_output_section(incremental_symtab_name,
			      elfcpp::SHT_GNU_INCREMENTAL_SYMTAB, 0,
			      ORDER_INVALID, false);
  incremental_symtab_os->add_output_section_data(incr->symtab_section());
  incremental_symtab_os->set_entsize(4);

  // Add the .gnu_incremental_relocs section.
  const char* incremental_relocs_name =
    this->namepool_.add(".gnu_incremental_relocs", false, NULL);
  Output_section* incremental_relocs_os =
    this->make_output_section(incremental_relocs_name,
			      elfcpp::SHT_GNU_INCREMENTAL_RELOCS, 0,
			      ORDER_INVALID, false);
  incremental_relocs_os->add_output_section_data(incr->relocs_section());
  incremental_relocs_os->set_entsize(incr->relocs_entsize());

  // Add the .gnu_incremental_got_plt section.
  const char* incremental_got_plt_name =
    this->namepool_.add(".gnu_incremental_got_plt", false, NULL);
  Output_section* incremental_got_plt_os =
    this->make_output_section(incremental_got_plt_name,
			      elfcpp::SHT_GNU_INCREMENTAL_GOT_PLT, 0,
			      ORDER_INVALID, false);
  incremental_got_plt_os->add_output_section_data(incr->got_plt_section());

  // Add the .gnu_incremental_strtab section.
  const char* incremental_strtab_name =
    this->namepool_.add(".gnu_incremental_strtab", false, NULL);
  Output_section* incremental_strtab_os = this->make_output_section(incremental_strtab_name,
							elfcpp::SHT_STRTAB, 0,
							ORDER_INVALID, false);
  Output_data_strtab* strtab_data =
      new Output_data_strtab(incr->get_stringpool());
  incremental_strtab_os->add_output_section_data(strtab_data);

  incremental_inputs_os->set_after_input_sections();
  incremental_symtab_os->set_after_input_sections();
  incremental_relocs_os->set_after_input_sections();
  incremental_got_plt_os->set_after_input_sections();

  incremental_inputs_os->set_link_section(incremental_strtab_os);
  incremental_symtab_os->set_link_section(incremental_inputs_os);
  incremental_relocs_os->set_link_section(incremental_inputs_os);
  incremental_got_plt_os->set_link_section(incremental_inputs_os);
}

// Return whether SEG1 should be before SEG2 in the output file.  This
// is based entirely on the segment type and flags.  When this is
// called the segment addresses have normally not yet been set.

bool
Layout::segment_precedes(const Output_segment* seg1,
			 const Output_segment* seg2)
{
  elfcpp::Elf_Word type1 = seg1->type();
  elfcpp::Elf_Word type2 = seg2->type();

  // The single PT_PHDR segment is required to precede any loadable
  // segment.  We simply make it always first.
  if (type1 == elfcpp::PT_PHDR)
    {
      gold_assert(type2 != elfcpp::PT_PHDR);
      return true;
    }
  if (type2 == elfcpp::PT_PHDR)
    return false;

  // The single PT_INTERP segment is required to precede any loadable
  // segment.  We simply make it always second.
  if (type1 == elfcpp::PT_INTERP)
    {
      gold_assert(type2 != elfcpp::PT_INTERP);
      return true;
    }
  if (type2 == elfcpp::PT_INTERP)
    return false;

  // We then put PT_LOAD segments before any other segments.
  if (type1 == elfcpp::PT_LOAD && type2 != elfcpp::PT_LOAD)
    return true;
  if (type2 == elfcpp::PT_LOAD && type1 != elfcpp::PT_LOAD)
    return false;

  // We put the PT_TLS segment last except for the PT_GNU_RELRO
  // segment, because that is where the dynamic linker expects to find
  // it (this is just for efficiency; other positions would also work
  // correctly).
  if (type1 == elfcpp::PT_TLS
      && type2 != elfcpp::PT_TLS
      && type2 != elfcpp::PT_GNU_RELRO)
    return false;
  if (type2 == elfcpp::PT_TLS
      && type1 != elfcpp::PT_TLS
      && type1 != elfcpp::PT_GNU_RELRO)
    return true;

  // We put the PT_GNU_RELRO segment last, because that is where the
  // dynamic linker expects to find it (as with PT_TLS, this is just
  // for efficiency).
  if (type1 == elfcpp::PT_GNU_RELRO && type2 != elfcpp::PT_GNU_RELRO)
    return false;
  if (type2 == elfcpp::PT_GNU_RELRO && type1 != elfcpp::PT_GNU_RELRO)
    return true;

  const elfcpp::Elf_Word flags1 = seg1->flags();
  const elfcpp::Elf_Word flags2 = seg2->flags();

  // The order of non-PT_LOAD segments is unimportant.  We simply sort
  // by the numeric segment type and flags values.  There should not
  // be more than one segment with the same type and flags, except
  // when a linker script specifies such.
  if (type1 != elfcpp::PT_LOAD)
    {
      if (type1 != type2)
	return type1 < type2;
      gold_assert(flags1 != flags2
		  || this->script_options_->saw_phdrs_clause());
      return flags1 < flags2;
    }

  // If the addresses are set already, sort by load address.
  if (seg1->are_addresses_set())
    {
      if (!seg2->are_addresses_set())
	return true;

      unsigned int section_count1 = seg1->output_section_count();
      unsigned int section_count2 = seg2->output_section_count();
      if (section_count1 == 0 && section_count2 > 0)
	return true;
      if (section_count1 > 0 && section_count2 == 0)
	return false;

      uint64_t paddr1 =	(seg1->are_addresses_set()
			 ? seg1->paddr()
			 : seg1->first_section_load_address());
      uint64_t paddr2 =	(seg2->are_addresses_set()
			 ? seg2->paddr()
			 : seg2->first_section_load_address());

      if (paddr1 != paddr2)
	return paddr1 < paddr2;
    }
  else if (seg2->are_addresses_set())
    return false;

  // A segment which holds large data comes after a segment which does
  // not hold large data.
  if (seg1->is_large_data_segment())
    {
      if (!seg2->is_large_data_segment())
	return false;
    }
  else if (seg2->is_large_data_segment())
    return true;

  // Otherwise, we sort PT_LOAD segments based on the flags.  Readonly
  // segments come before writable segments.  Then writable segments
  // with data come before writable segments without data.  Then
  // executable segments come before non-executable segments.  Then
  // the unlikely case of a non-readable segment comes before the
  // normal case of a readable segment.  If there are multiple
  // segments with the same type and flags, we require that the
  // address be set, and we sort by virtual address and then physical
  // address.
  if ((flags1 & elfcpp::PF_W) != (flags2 & elfcpp::PF_W))
    return (flags1 & elfcpp::PF_W) == 0;
  if ((flags1 & elfcpp::PF_W) != 0
      && seg1->has_any_data_sections() != seg2->has_any_data_sections())
    return seg1->has_any_data_sections();
  if ((flags1 & elfcpp::PF_X) != (flags2 & elfcpp::PF_X))
    return (flags1 & elfcpp::PF_X) != 0;
  if ((flags1 & elfcpp::PF_R) != (flags2 & elfcpp::PF_R))
    return (flags1 & elfcpp::PF_R) == 0;

  // We shouldn't get here--we shouldn't create segments which we
  // can't distinguish.  Unless of course we are using a weird linker
  // script or overlapping --section-start options.  We could also get
  // here if plugins want unique segments for subsets of sections.
  gold_assert(this->script_options_->saw_phdrs_clause()
	      || parameters->options().any_section_start()
	      || this->is_unique_segment_for_sections_specified());
  return false;
}

// Increase OFF so that it is congruent to ADDR modulo ABI_PAGESIZE.

static off_t
align_file_offset(off_t off, uint64_t addr, uint64_t abi_pagesize)
{
  uint64_t unsigned_off = off;
  uint64_t aligned_off = ((unsigned_off & ~(abi_pagesize - 1))
			  | (addr & (abi_pagesize - 1)));
  if (aligned_off < unsigned_off)
    aligned_off += abi_pagesize;
  return aligned_off;
}

// On targets where the text segment contains only executable code,
// a non-executable segment is never the text segment.

static inline bool
is_text_segment(const Target* target, const Output_segment* seg)
{
  elfcpp::Elf_Xword flags = seg->flags();
  if ((flags & elfcpp::PF_W) != 0)
    return false;
  if ((flags & elfcpp::PF_X) == 0)
    return !target->isolate_execinstr();
  return true;
}

// Set the file offsets of all the segments, and all the sections they
// contain.  They have all been created.  LOAD_SEG must be be laid out
// first.  Return the offset of the data to follow.

off_t
Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
			    unsigned int* pshndx)
{
  // Sort them into the final order.  We use a stable sort so that we
  // don't randomize the order of indistinguishable segments created
  // by linker scripts.
  std::stable_sort(this->segment_list_.begin(), this->segment_list_.end(),
		   Layout::Compare_segments(this));

  // Find the PT_LOAD segments, and set their addresses and offsets
  // and their section's addresses and offsets.
  uint64_t start_addr;
  if (parameters->options().user_set_Ttext())
    start_addr = parameters->options().Ttext();
  else if (parameters->options().output_is_position_independent())
    start_addr = 0;
  else
    start_addr = target->default_text_segment_address();

  uint64_t addr = start_addr;
  off_t off = 0;

  // If LOAD_SEG is NULL, then the file header and segment headers
  // will not be loadable.  But they still need to be at offset 0 in
  // the file.  Set their offsets now.
  if (load_seg == NULL)
    {
      for (Data_list::iterator p = this->special_output_list_.begin();
	   p != this->special_output_list_.end();
	   ++p)
	{
	  off = align_address(off, (*p)->addralign());
	  (*p)->set_address_and_file_offset(0, off);
	  off += (*p)->data_size();
	}
    }

  unsigned int increase_relro = this->increase_relro_;
  if (this->script_options_->saw_sections_clause())
    increase_relro = 0;

  const bool check_sections = parameters->options().check_sections();
  Output_segment* last_load_segment = NULL;

  unsigned int shndx_begin = *pshndx;
  unsigned int shndx_load_seg = *pshndx;

  for (Segment_list::iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    {
      if ((*p)->type() == elfcpp::PT_LOAD)
	{
	  if (target->isolate_execinstr())
	    {
	      // When we hit the segment that should contain the
	      // file headers, reset the file offset so we place
	      // it and subsequent segments appropriately.
	      // We'll fix up the preceding segments below.
	      if (load_seg == *p)
		{
		  if (off == 0)
		    load_seg = NULL;
		  else
		    {
		      off = 0;
		      shndx_load_seg = *pshndx;
		    }
		}
	    }
	  else
	    {
	      // Verify that the file headers fall into the first segment.
	      if (load_seg != NULL && load_seg != *p)
		gold_unreachable();
	      load_seg = NULL;
	    }

	  bool are_addresses_set = (*p)->are_addresses_set();
	  if (are_addresses_set)
	    {
	      // When it comes to setting file offsets, we care about
	      // the physical address.
	      addr = (*p)->paddr();
	    }
	  else if (parameters->options().user_set_Ttext()
		   && (parameters->options().omagic()
		       || is_text_segment(target, *p)))
	    {
	      are_addresses_set = true;
	    }
	  else if (parameters->options().user_set_Trodata_segment()
		   && ((*p)->flags() & (elfcpp::PF_W | elfcpp::PF_X)) == 0)
	    {
	      addr = parameters->options().Trodata_segment();
	      are_addresses_set = true;
	    }
	  else if (parameters->options().user_set_Tdata()
		   && ((*p)->flags() & elfcpp::PF_W) != 0
		   && (!parameters->options().user_set_Tbss()
		       || (*p)->has_any_data_sections()))
	    {
	      addr = parameters->options().Tdata();
	      are_addresses_set = true;
	    }
	  else if (parameters->options().user_set_Tbss()
		   && ((*p)->flags() & elfcpp::PF_W) != 0
		   && !(*p)->has_any_data_sections())
	    {
	      addr = parameters->options().Tbss();
	      are_addresses_set = true;
	    }

	  uint64_t orig_addr = addr;
	  uint64_t orig_off = off;

	  uint64_t aligned_addr = 0;
	  uint64_t abi_pagesize = target->abi_pagesize();
	  uint64_t common_pagesize = target->common_pagesize();

	  if (!parameters->options().nmagic()
	      && !parameters->options().omagic())
	    (*p)->set_minimum_p_align(abi_pagesize);

	  if (!are_addresses_set)
	    {
	      // Skip the address forward one page, maintaining the same
	      // position within the page.  This lets us store both segments
	      // overlapping on a single page in the file, but the loader will
	      // put them on different pages in memory. We will revisit this
	      // decision once we know the size of the segment.

	      addr = align_address(addr, (*p)->maximum_alignment());
	      aligned_addr = addr;

	      if (load_seg == *p)
		{
		  // This is the segment that will contain the file
		  // headers, so its offset will have to be exactly zero.
		  gold_assert(orig_off == 0);

		  // If the target wants a fixed minimum distance from the
		  // text segment to the read-only segment, move up now.
		  uint64_t min_addr =
		    start_addr + (parameters->options().user_set_rosegment_gap()
				  ? parameters->options().rosegment_gap()
				  : target->rosegment_gap());
		  if (addr < min_addr)
		    addr = min_addr;

		  // But this is not the first segment!  To make its
		  // address congruent with its offset, that address better
		  // be aligned to the ABI-mandated page size.
		  addr = align_address(addr, abi_pagesize);
		  aligned_addr = addr;
		}
	      else
		{
		  if ((addr & (abi_pagesize - 1)) != 0)
		    addr = addr + abi_pagesize;

		  off = orig_off + ((addr - orig_addr) & (abi_pagesize - 1));
		}
	    }

	  if (!parameters->options().nmagic()
	      && !parameters->options().omagic())
	    {
	      // Here we are also taking care of the case when
	      // the maximum segment alignment is larger than the page size.
	      off = align_file_offset(off, addr,
				      std::max(abi_pagesize,
					       (*p)->maximum_alignment()));
	    }
	  else
	    {
	      // This is -N or -n with a section script which prevents
	      // us from using a load segment.  We need to ensure that
	      // the file offset is aligned to the alignment of the
	      // segment.  This is because the linker script
	      // implicitly assumed a zero offset.  If we don't align
	      // here, then the alignment of the sections in the
	      // linker script may not match the alignment of the
	      // sections in the set_section_addresses call below,
	      // causing an error about dot moving backward.
	      off = align_address(off, (*p)->maximum_alignment());
	    }

	  unsigned int shndx_hold = *pshndx;
	  bool has_relro = false;
	  uint64_t new_addr = (*p)->set_section_addresses(target, this,
							  false, addr,
							  &increase_relro,
							  &has_relro,
							  &off, pshndx);

	  // Now that we know the size of this segment, we may be able
	  // to save a page in memory, at the cost of wasting some
	  // file space, by instead aligning to the start of a new
	  // page.  Here we use the real machine page size rather than
	  // the ABI mandated page size.  If the segment has been
	  // aligned so that the relro data ends at a page boundary,
	  // we do not try to realign it.

	  if (!are_addresses_set
	      && !has_relro
	      && aligned_addr != addr
	      && !parameters->incremental())
	    {
	      uint64_t first_off = (common_pagesize
				    - (aligned_addr
				       & (common_pagesize - 1)));
	      uint64_t last_off = new_addr & (common_pagesize - 1);
	      if (first_off > 0
		  && last_off > 0
		  && ((aligned_addr & ~ (common_pagesize - 1))
		      != (new_addr & ~ (common_pagesize - 1)))
		  && first_off + last_off <= common_pagesize)
		{
		  *pshndx = shndx_hold;
		  addr = align_address(aligned_addr, common_pagesize);
		  addr = align_address(addr, (*p)->maximum_alignment());
		  if ((addr & (abi_pagesize - 1)) != 0)
		    addr = addr + abi_pagesize;
		  off = orig_off + ((addr - orig_addr) & (abi_pagesize - 1));
		  off = align_file_offset(off, addr, abi_pagesize);

		  increase_relro = this->increase_relro_;
		  if (this->script_options_->saw_sections_clause())
		    increase_relro = 0;
		  has_relro = false;

		  new_addr = (*p)->set_section_addresses(target, this,
							 true, addr,
							 &increase_relro,
							 &has_relro,
							 &off, pshndx);
		}
	    }

	  addr = new_addr;

	  // Implement --check-sections.  We know that the segments
	  // are sorted by LMA.
	  if (check_sections && last_load_segment != NULL)
	    {
	      gold_assert(last_load_segment->paddr() <= (*p)->paddr());
	      if (last_load_segment->paddr() + last_load_segment->memsz()
		  > (*p)->paddr())
		{
		  unsigned long long lb1 = last_load_segment->paddr();
		  unsigned long long le1 = lb1 + last_load_segment->memsz();
		  unsigned long long lb2 = (*p)->paddr();
		  unsigned long long le2 = lb2 + (*p)->memsz();
		  gold_error(_("load segment overlap [0x%llx -> 0x%llx] and "
			       "[0x%llx -> 0x%llx]"),
			     lb1, le1, lb2, le2);
		}
	    }
	  last_load_segment = *p;
	}
    }

  if (load_seg != NULL && target->isolate_execinstr())
    {
      // Process the early segments again, setting their file offsets
      // so they land after the segments starting at LOAD_SEG.
      off = align_file_offset(off, 0, target->abi_pagesize());

      this->reset_relax_output();

      for (Segment_list::iterator p = this->segment_list_.begin();
	   *p != load_seg;
	   ++p)
	{
	  if ((*p)->type() == elfcpp::PT_LOAD)
	    {
	      // We repeat the whole job of assigning addresses and
	      // offsets, but we really only want to change the offsets and
	      // must ensure that the addresses all come out the same as
	      // they did the first time through.
	      bool has_relro = false;
	      const uint64_t old_addr = (*p)->vaddr();
	      const uint64_t old_end = old_addr + (*p)->memsz();
	      uint64_t new_addr = (*p)->set_section_addresses(target, this,
							      true, old_addr,
							      &increase_relro,
							      &has_relro,
							      &off,
							      &shndx_begin);
	      gold_assert(new_addr == old_end);
	    }
	}

      gold_assert(shndx_begin == shndx_load_seg);
    }

  // Handle the non-PT_LOAD segments, setting their offsets from their
  // section's offsets.
  for (Segment_list::iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    {
      if ((*p)->type() != elfcpp::PT_LOAD)
	(*p)->set_offset((*p)->type() == elfcpp::PT_GNU_RELRO
			 ? increase_relro
			 : 0);
    }

  // Set the TLS offsets for each section in the PT_TLS segment.
  if (this->tls_segment_ != NULL)
    this->tls_segment_->set_tls_offsets();

  return off;
}

// Set the offsets of all the allocated sections when doing a
// relocatable link.  This does the same jobs as set_segment_offsets,
// only for a relocatable link.

off_t
Layout::set_relocatable_section_offsets(Output_data* file_header,
					unsigned int* pshndx)
{
  off_t off = 0;

  file_header->set_address_and_file_offset(0, 0);
  off += file_header->data_size();

  for (Section_list::iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      // We skip unallocated sections here, except that group sections
      // have to come first.
      if (((*p)->flags() & elfcpp::SHF_ALLOC) == 0
	  && (*p)->type() != elfcpp::SHT_GROUP)
	continue;

      off = align_address(off, (*p)->addralign());

      // The linker script might have set the address.
      if (!(*p)->is_address_valid())
	(*p)->set_address(0);
      (*p)->set_file_offset(off);
      (*p)->finalize_data_size();
      if ((*p)->type() != elfcpp::SHT_NOBITS)
	off += (*p)->data_size();

      (*p)->set_out_shndx(*pshndx);
      ++*pshndx;
    }

  return off;
}

// Set the file offset of all the sections not associated with a
// segment.

off_t
Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass)
{
  off_t startoff = off;
  off_t maxoff = off;

  for (Section_list::iterator p = this->unattached_section_list_.begin();
       p != this->unattached_section_list_.end();
       ++p)
    {
      // The symtab section is handled in create_symtab_sections.
      if (*p == this->symtab_section_)
	continue;

      // If we've already set the data size, don't set it again.
      if ((*p)->is_offset_valid() && (*p)->is_data_size_valid())
	continue;

      if (pass == BEFORE_INPUT_SECTIONS_PASS
	  && (*p)->requires_postprocessing())
	{
	  (*p)->create_postprocessing_buffer();
	  this->any_postprocessing_sections_ = true;
	}

      if (pass == BEFORE_INPUT_SECTIONS_PASS
	  && (*p)->after_input_sections())
	continue;
      else if (pass == POSTPROCESSING_SECTIONS_PASS
	       && (!(*p)->after_input_sections()
		   || (*p)->type() == elfcpp::SHT_STRTAB))
	continue;
      else if (pass == STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS
	       && (!(*p)->after_input_sections()
		   || (*p)->type() != elfcpp::SHT_STRTAB))
	continue;

      if (!parameters->incremental_update())
	{
	  off = align_address(off, (*p)->addralign());
	  (*p)->set_file_offset(off);
	  (*p)->finalize_data_size();
	}
      else
	{
	  // Incremental update: allocate file space from free list.
	  (*p)->pre_finalize_data_size();
	  off_t current_size = (*p)->current_data_size();
	  off = this->allocate(current_size, (*p)->addralign(), startoff);
	  if (off == -1)
	    {
	      if (is_debugging_enabled(DEBUG_INCREMENTAL))
		this->free_list_.dump();
	      gold_assert((*p)->output_section() != NULL);
	      gold_fallback(_("out of patch space for section %s; "
			      "relink with --incremental-full"),
			    (*p)->output_section()->name());
	    }
	  (*p)->set_file_offset(off);
	  (*p)->finalize_data_size();
	  if ((*p)->data_size() > current_size)
	    {
	      gold_assert((*p)->output_section() != NULL);
	      gold_fallback(_("%s: section changed size; "
			      "relink with --incremental-full"),
			    (*p)->output_section()->name());
	    }
	  gold_debug(DEBUG_INCREMENTAL,
		     "set_section_offsets: %08lx %08lx %s",
		     static_cast<long>(off),
		     static_cast<long>((*p)->data_size()),
		     ((*p)->output_section() != NULL
		      ? (*p)->output_section()->name() : "(special)"));
	}

      off += (*p)->data_size();
      if (off > maxoff)
	maxoff = off;

      // At this point the name must be set.
      if (pass != STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS)
	this->namepool_.add((*p)->name(), false, NULL);
    }
  return maxoff;
}

// Set the section indexes of all the sections not associated with a
// segment.

unsigned int
Layout::set_section_indexes(unsigned int shndx)
{
  for (Section_list::iterator p = this->unattached_section_list_.begin();
       p != this->unattached_section_list_.end();
       ++p)
    {
      if (!(*p)->has_out_shndx())
	{
	  (*p)->set_out_shndx(shndx);
	  ++shndx;
	}
    }
  return shndx;
}

// Set the section addresses according to the linker script.  This is
// only called when we see a SECTIONS clause.  This returns the
// program segment which should hold the file header and segment
// headers, if any.  It will return NULL if they should not be in a
// segment.

Output_segment*
Layout::set_section_addresses_from_script(Symbol_table* symtab)
{
  Script_sections* ss = this->script_options_->script_sections();
  gold_assert(ss->saw_sections_clause());
  return this->script_options_->set_section_addresses(symtab, this);
}

// Place the orphan sections in the linker script.

void
Layout::place_orphan_sections_in_script()
{
  Script_sections* ss = this->script_options_->script_sections();
  gold_assert(ss->saw_sections_clause());

  // Place each orphaned output section in the script.
  for (Section_list::iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      if (!(*p)->found_in_sections_clause())
	ss->place_orphan(*p);
    }
}

// Count the local symbols in the regular symbol table and the dynamic
// symbol table, and build the respective string pools.

void
Layout::count_local_symbols(const Task* task,
			    const Input_objects* input_objects)
{
  // First, figure out an upper bound on the number of symbols we'll
  // be inserting into each pool.  This helps us create the pools with
  // the right size, to avoid unnecessary hashtable resizing.
  unsigned int symbol_count = 0;
  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    symbol_count += (*p)->local_symbol_count();

  // Go from "upper bound" to "estimate."  We overcount for two
  // reasons: we double-count symbols that occur in more than one
  // object file, and we count symbols that are dropped from the
  // output.  Add it all together and assume we overcount by 100%.
  symbol_count /= 2;

  // We assume all symbols will go into both the sympool and dynpool.
  this->sympool_.reserve(symbol_count);
  this->dynpool_.reserve(symbol_count);

  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      Task_lock_obj<Object> tlo(task, *p);
      (*p)->count_local_symbols(&this->sympool_, &this->dynpool_);
    }
}

// Create the symbol table sections.  Here we also set the final
// values of the symbols.  At this point all the loadable sections are
// fully laid out.  SHNUM is the number of sections so far.

void
Layout::create_symtab_sections(const Input_objects* input_objects,
			       Symbol_table* symtab,
			       unsigned int shnum,
			       off_t* poff)
{
  int symsize;
  unsigned int align;
  if (parameters->target().get_size() == 32)
    {
      symsize = elfcpp::Elf_sizes<32>::sym_size;
      align = 4;
    }
  else if (parameters->target().get_size() == 64)
    {
      symsize = elfcpp::Elf_sizes<64>::sym_size;
      align = 8;
    }
  else
    gold_unreachable();

  // Compute file offsets relative to the start of the symtab section.
  off_t off = 0;

  // Save space for the dummy symbol at the start of the section.  We
  // never bother to write this out--it will just be left as zero.
  off += symsize;
  unsigned int local_symbol_index = 1;

  // Add STT_SECTION symbols for each Output section which needs one.
  for (Section_list::iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      if (!(*p)->needs_symtab_index())
	(*p)->set_symtab_index(-1U);
      else
	{
	  (*p)->set_symtab_index(local_symbol_index);
	  ++local_symbol_index;
	  off += symsize;
	}
    }

  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      unsigned int index = (*p)->finalize_local_symbols(local_symbol_index,
							off, symtab);
      off += (index - local_symbol_index) * symsize;
      local_symbol_index = index;
    }

  unsigned int local_symcount = local_symbol_index;
  gold_assert(static_cast<off_t>(local_symcount * symsize) == off);

  off_t dynoff;
  size_t dyn_global_index;
  size_t dyncount;
  if (this->dynsym_section_ == NULL)
    {
      dynoff = 0;
      dyn_global_index = 0;
      dyncount = 0;
    }
  else
    {
      dyn_global_index = this->dynsym_section_->info();
      off_t locsize = dyn_global_index * this->dynsym_section_->entsize();
      dynoff = this->dynsym_section_->offset() + locsize;
      dyncount = (this->dynsym_section_->data_size() - locsize) / symsize;
      gold_assert(static_cast<off_t>(dyncount * symsize)
		  == this->dynsym_section_->data_size() - locsize);
    }

  off_t global_off = off;
  off = symtab->finalize(off, dynoff, dyn_global_index, dyncount,
			 &this->sympool_, &local_symcount);

  if (!parameters->options().strip_all())
    {
      this->sympool_.set_string_offsets();

      const char* symtab_name = this->namepool_.add(".symtab", false, NULL);
      Output_section* osymtab = this->make_output_section(symtab_name,
							  elfcpp::SHT_SYMTAB,
							  0, ORDER_INVALID,
							  false);
      this->symtab_section_ = osymtab;

      Output_section_data* pos = new Output_data_fixed_space(off, align,
							     "** symtab");
      osymtab->add_output_section_data(pos);

      // We generate a .symtab_shndx section if we have more than
      // SHN_LORESERVE sections.  Technically it is possible that we
      // don't need one, because it is possible that there are no
      // symbols in any of sections with indexes larger than
      // SHN_LORESERVE.  That is probably unusual, though, and it is
      // easier to always create one than to compute section indexes
      // twice (once here, once when writing out the symbols).
      if (shnum >= elfcpp::SHN_LORESERVE)
	{
	  const char* symtab_xindex_name = this->namepool_.add(".symtab_shndx",
							       false, NULL);
	  Output_section* osymtab_xindex =
	    this->make_output_section(symtab_xindex_name,
				      elfcpp::SHT_SYMTAB_SHNDX, 0,
				      ORDER_INVALID, false);

	  size_t symcount = off / symsize;
	  this->symtab_xindex_ = new Output_symtab_xindex(symcount);

	  osymtab_xindex->add_output_section_data(this->symtab_xindex_);

	  osymtab_xindex->set_link_section(osymtab);
	  osymtab_xindex->set_addralign(4);
	  osymtab_xindex->set_entsize(4);

	  osymtab_xindex->set_after_input_sections();

	  // This tells the driver code to wait until the symbol table
	  // has written out before writing out the postprocessing
	  // sections, including the .symtab_shndx section.
	  this->any_postprocessing_sections_ = true;
	}

      const char* strtab_name = this->namepool_.add(".strtab", false, NULL);
      Output_section* ostrtab = this->make_output_section(strtab_name,
							  elfcpp::SHT_STRTAB,
							  0, ORDER_INVALID,
							  false);

      Output_section_data* pstr = new Output_data_strtab(&this->sympool_);
      ostrtab->add_output_section_data(pstr);

      off_t symtab_off;
      if (!parameters->incremental_update())
	symtab_off = align_address(*poff, align);
      else
	{
	  symtab_off = this->allocate(off, align, *poff);
	  if (off == -1)
	    gold_fallback(_("out of patch space for symbol table; "
			    "relink with --incremental-full"));
	  gold_debug(DEBUG_INCREMENTAL,
		     "create_symtab_sections: %08lx %08lx .symtab",
		     static_cast<long>(symtab_off),
		     static_cast<long>(off));
	}

      symtab->set_file_offset(symtab_off + global_off);
      osymtab->set_file_offset(symtab_off);
      osymtab->finalize_data_size();
      osymtab->set_link_section(ostrtab);
      osymtab->set_info(local_symcount);
      osymtab->set_entsize(symsize);

      if (symtab_off + off > *poff)
	*poff = symtab_off + off;
    }
}

// Create the .shstrtab section, which holds the names of the
// sections.  At the time this is called, we have created all the
// output sections except .shstrtab itself.

Output_section*
Layout::create_shstrtab()
{
  // FIXME: We don't need to create a .shstrtab section if we are
  // stripping everything.

  const char* name = this->namepool_.add(".shstrtab", false, NULL);

  Output_section* os = this->make_output_section(name, elfcpp::SHT_STRTAB, 0,
						 ORDER_INVALID, false);

  if (strcmp(parameters->options().compress_debug_sections(), "none") != 0)
    {
      // We can't write out this section until we've set all the
      // section names, and we don't set the names of compressed
      // output sections until relocations are complete.  FIXME: With
      // the current names we use, this is unnecessary.
      os->set_after_input_sections();
    }

  Output_section_data* posd = new Output_data_strtab(&this->namepool_);
  os->add_output_section_data(posd);

  return os;
}

// Create the section headers.  SIZE is 32 or 64.  OFF is the file
// offset.

void
Layout::create_shdrs(const Output_section* shstrtab_section, off_t* poff)
{
  Output_section_headers* oshdrs;
  oshdrs = new Output_section_headers(this,
				      &this->segment_list_,
				      &this->section_list_,
				      &this->unattached_section_list_,
				      &this->namepool_,
				      shstrtab_section);
  off_t off;
  if (!parameters->incremental_update())
    off = align_address(*poff, oshdrs->addralign());
  else
    {
      oshdrs->pre_finalize_data_size();
      off = this->allocate(oshdrs->data_size(), oshdrs->addralign(), *poff);
      if (off == -1)
	  gold_fallback(_("out of patch space for section header table; "
			  "relink with --incremental-full"));
      gold_debug(DEBUG_INCREMENTAL,
		 "create_shdrs: %08lx %08lx (section header table)",
		 static_cast<long>(off),
		 static_cast<long>(off + oshdrs->data_size()));
    }
  oshdrs->set_address_and_file_offset(0, off);
  off += oshdrs->data_size();
  if (off > *poff)
    *poff = off;
  this->section_headers_ = oshdrs;
}

// Count the allocated sections.

size_t
Layout::allocated_output_section_count() const
{
  size_t section_count = 0;
  for (Segment_list::const_iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    section_count += (*p)->output_section_count();
  return section_count;
}

// Create the dynamic symbol table.

void
Layout::create_dynamic_symtab(const Input_objects* input_objects,
			      Symbol_table* symtab,
			      Output_section** pdynstr,
			      unsigned int* plocal_dynamic_count,
			      std::vector<Symbol*>* pdynamic_symbols,
			      Versions* pversions)
{
  // Count all the symbols in the dynamic symbol table, and set the
  // dynamic symbol indexes.

  // Skip symbol 0, which is always all zeroes.
  unsigned int index = 1;

  // Add STT_SECTION symbols for each Output section which needs one.
  for (Section_list::iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      if (!(*p)->needs_dynsym_index())
	(*p)->set_dynsym_index(-1U);
      else
	{
	  (*p)->set_dynsym_index(index);
	  ++index;
	}
    }

  // Count the local symbols that need to go in the dynamic symbol table,
  // and set the dynamic symbol indexes.
  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      unsigned int new_index = (*p)->set_local_dynsym_indexes(index);
      index = new_index;
    }

  unsigned int local_symcount = index;
  *plocal_dynamic_count = local_symcount;

  index = symtab->set_dynsym_indexes(index, pdynamic_symbols,
				     &this->dynpool_, pversions);

  int symsize;
  unsigned int align;
  const int size = parameters->target().get_size();
  if (size == 32)
    {
      symsize = elfcpp::Elf_sizes<32>::sym_size;
      align = 4;
    }
  else if (size == 64)
    {
      symsize = elfcpp::Elf_sizes<64>::sym_size;
      align = 8;
    }
  else
    gold_unreachable();

  // Create the dynamic symbol table section.

  Output_section* dynsym = this->choose_output_section(NULL, ".dynsym",
						       elfcpp::SHT_DYNSYM,
						       elfcpp::SHF_ALLOC,
						       false,
						       ORDER_DYNAMIC_LINKER,
						       false);

  // Check for NULL as a linker script may discard .dynsym.
  if (dynsym != NULL)
    {
      Output_section_data* odata = new Output_data_fixed_space(index * symsize,
							       align,
							       "** dynsym");
      dynsym->add_output_section_data(odata);

      dynsym->set_info(local_symcount);
      dynsym->set_entsize(symsize);
      dynsym->set_addralign(align);

      this->dynsym_section_ = dynsym;
    }

  Output_data_dynamic* const odyn = this->dynamic_data_;
  if (odyn != NULL)
    {
      odyn->add_section_address(elfcpp::DT_SYMTAB, dynsym);
      odyn->add_constant(elfcpp::DT_SYMENT, symsize);
    }

  // If there are more than SHN_LORESERVE allocated sections, we
  // create a .dynsym_shndx section.  It is possible that we don't
  // need one, because it is possible that there are no dynamic
  // symbols in any of the sections with indexes larger than
  // SHN_LORESERVE.  This is probably unusual, though, and at this
  // time we don't know the actual section indexes so it is
  // inconvenient to check.
  if (this->allocated_output_section_count() >= elfcpp::SHN_LORESERVE)
    {
      Output_section* dynsym_xindex =
	this->choose_output_section(NULL, ".dynsym_shndx",
				    elfcpp::SHT_SYMTAB_SHNDX,
				    elfcpp::SHF_ALLOC,
				    false, ORDER_DYNAMIC_LINKER, false);

      if (dynsym_xindex != NULL)
	{
	  this->dynsym_xindex_ = new Output_symtab_xindex(index);

	  dynsym_xindex->add_output_section_data(this->dynsym_xindex_);

	  dynsym_xindex->set_link_section(dynsym);
	  dynsym_xindex->set_addralign(4);
	  dynsym_xindex->set_entsize(4);

	  dynsym_xindex->set_after_input_sections();

	  // This tells the driver code to wait until the symbol table
	  // has written out before writing out the postprocessing
	  // sections, including the .dynsym_shndx section.
	  this->any_postprocessing_sections_ = true;
	}
    }

  // Create the dynamic string table section.

  Output_section* dynstr = this->choose_output_section(NULL, ".dynstr",
						       elfcpp::SHT_STRTAB,
						       elfcpp::SHF_ALLOC,
						       false,
						       ORDER_DYNAMIC_LINKER,
						       false);
  *pdynstr = dynstr;
  if (dynstr != NULL)
    {
      Output_section_data* strdata = new Output_data_strtab(&this->dynpool_);
      dynstr->add_output_section_data(strdata);

      if (dynsym != NULL)
	dynsym->set_link_section(dynstr);
      if (this->dynamic_section_ != NULL)
	this->dynamic_section_->set_link_section(dynstr);

      if (odyn != NULL)
	{
	  odyn->add_section_address(elfcpp::DT_STRTAB, dynstr);
	  odyn->add_section_size(elfcpp::DT_STRSZ, dynstr);
	}
    }

  // Create the hash tables.  The Gnu-style hash table must be
  // built first, because it changes the order of the symbols
  // in the dynamic symbol table.

  if (strcmp(parameters->options().hash_style(), "gnu") == 0
      || strcmp(parameters->options().hash_style(), "both") == 0)
    {
      unsigned char* phash;
      unsigned int hashlen;
      Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
				    &phash, &hashlen);

      Output_section* hashsec =
	this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
				    elfcpp::SHF_ALLOC, false,
				    ORDER_DYNAMIC_LINKER, false);

      Output_section_data* hashdata = new Output_data_const_buffer(phash,
								   hashlen,
								   align,
								   "** hash");
      if (hashsec != NULL && hashdata != NULL)
	hashsec->add_output_section_data(hashdata);

      if (hashsec != NULL)
	{
	  if (dynsym != NULL)
	    hashsec->set_link_section(dynsym);

	  // For a 64-bit target, the entries in .gnu.hash do not have
	  // a uniform size, so we only set the entry size for a
	  // 32-bit target.
	  if (parameters->target().get_size() == 32)
	    hashsec->set_entsize(4);

	  if (odyn != NULL)
	    odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
	}
    }

  if (strcmp(parameters->options().hash_style(), "sysv") == 0
      || strcmp(parameters->options().hash_style(), "both") == 0)
    {
      unsigned char* phash;
      unsigned int hashlen;
      Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
				    &phash, &hashlen);

      Output_section* hashsec =
	this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
				    elfcpp::SHF_ALLOC, false,
				    ORDER_DYNAMIC_LINKER, false);

      Output_section_data* hashdata = new Output_data_const_buffer(phash,
								   hashlen,
								   align,
								   "** hash");
      if (hashsec != NULL && hashdata != NULL)
	hashsec->add_output_section_data(hashdata);

      if (hashsec != NULL)
	{
	  if (dynsym != NULL)
	    hashsec->set_link_section(dynsym);
	  hashsec->set_entsize(4);
	}

      if (odyn != NULL)
	odyn->add_section_address(elfcpp::DT_HASH, hashsec);
    }
}

// Assign offsets to each local portion of the dynamic symbol table.

void
Layout::assign_local_dynsym_offsets(const Input_objects* input_objects)
{
  Output_section* dynsym = this->dynsym_section_;
  if (dynsym == NULL)
    return;

  off_t off = dynsym->offset();

  // Skip the dummy symbol at the start of the section.
  off += dynsym->entsize();

  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      unsigned int count = (*p)->set_local_dynsym_offset(off);
      off += count * dynsym->entsize();
    }
}

// Create the version sections.

void
Layout::create_version_sections(const Versions* versions,
				const Symbol_table* symtab,
				unsigned int local_symcount,
				const std::vector<Symbol*>& dynamic_symbols,
				const Output_section* dynstr)
{
  if (!versions->any_defs() && !versions->any_needs())
    return;

  switch (parameters->size_and_endianness())
    {
#ifdef HAVE_TARGET_32_LITTLE
    case Parameters::TARGET_32_LITTLE:
      this->sized_create_version_sections<32, false>(versions, symtab,
						     local_symcount,
						     dynamic_symbols, dynstr);
      break;
#endif
#ifdef HAVE_TARGET_32_BIG
    case Parameters::TARGET_32_BIG:
      this->sized_create_version_sections<32, true>(versions, symtab,
						    local_symcount,
						    dynamic_symbols, dynstr);
      break;
#endif
#ifdef HAVE_TARGET_64_LITTLE
    case Parameters::TARGET_64_LITTLE:
      this->sized_create_version_sections<64, false>(versions, symtab,
						     local_symcount,
						     dynamic_symbols, dynstr);
      break;
#endif
#ifdef HAVE_TARGET_64_BIG
    case Parameters::TARGET_64_BIG:
      this->sized_create_version_sections<64, true>(versions, symtab,
						    local_symcount,
						    dynamic_symbols, dynstr);
      break;
#endif
    default:
      gold_unreachable();
    }
}

// Create the version sections, sized version.

template<int size, bool big_endian>
void
Layout::sized_create_version_sections(
    const Versions* versions,
    const Symbol_table* symtab,
    unsigned int local_symcount,
    const std::vector<Symbol*>& dynamic_symbols,
    const Output_section* dynstr)
{
  Output_section* vsec = this->choose_output_section(NULL, ".gnu.version",
						     elfcpp::SHT_GNU_versym,
						     elfcpp::SHF_ALLOC,
						     false,
						     ORDER_DYNAMIC_LINKER,
						     false);

  // Check for NULL since a linker script may discard this section.
  if (vsec != NULL)
    {
      unsigned char* vbuf;
      unsigned int vsize;
      versions->symbol_section_contents<size, big_endian>(symtab,
							  &this->dynpool_,
							  local_symcount,
							  dynamic_symbols,
							  &vbuf, &vsize);

      Output_section_data* vdata = new Output_data_const_buffer(vbuf, vsize, 2,
								"** versions");

      vsec->add_output_section_data(vdata);
      vsec->set_entsize(2);
      vsec->set_link_section(this->dynsym_section_);
    }

  Output_data_dynamic* const odyn = this->dynamic_data_;
  if (odyn != NULL && vsec != NULL)
    odyn->add_section_address(elfcpp::DT_VERSYM, vsec);

  if (versions->any_defs())
    {
      Output_section* vdsec;
      vdsec = this->choose_output_section(NULL, ".gnu.version_d",
					  elfcpp::SHT_GNU_verdef,
					  elfcpp::SHF_ALLOC,
					  false, ORDER_DYNAMIC_LINKER, false);

      if (vdsec != NULL)
	{
	  unsigned char* vdbuf;
	  unsigned int vdsize;
	  unsigned int vdentries;
	  versions->def_section_contents<size, big_endian>(&this->dynpool_,
							   &vdbuf, &vdsize,
							   &vdentries);

	  Output_section_data* vddata =
	    new Output_data_const_buffer(vdbuf, vdsize, 4, "** version defs");

	  vdsec->add_output_section_data(vddata);
	  vdsec->set_link_section(dynstr);
	  vdsec->set_info(vdentries);

	  if (odyn != NULL)
	    {
	      odyn->add_section_address(elfcpp::DT_VERDEF, vdsec);
	      odyn->add_constant(elfcpp::DT_VERDEFNUM, vdentries);
	    }
	}
    }

  if (versions->any_needs())
    {
      Output_section* vnsec;
      vnsec = this->choose_output_section(NULL, ".gnu.version_r",
					  elfcpp::SHT_GNU_verneed,
					  elfcpp::SHF_ALLOC,
					  false, ORDER_DYNAMIC_LINKER, false);

      if (vnsec != NULL)
	{
	  unsigned char* vnbuf;
	  unsigned int vnsize;
	  unsigned int vnentries;
	  versions->need_section_contents<size, big_endian>(&this->dynpool_,
							    &vnbuf, &vnsize,
							    &vnentries);

	  Output_section_data* vndata =
	    new Output_data_const_buffer(vnbuf, vnsize, 4, "** version refs");

	  vnsec->add_output_section_data(vndata);
	  vnsec->set_link_section(dynstr);
	  vnsec->set_info(vnentries);

	  if (odyn != NULL)
	    {
	      odyn->add_section_address(elfcpp::DT_VERNEED, vnsec);
	      odyn->add_constant(elfcpp::DT_VERNEEDNUM, vnentries);
	    }
	}
    }
}

// Create the .interp section and PT_INTERP segment.

void
Layout::create_interp(const Target* target)
{
  gold_assert(this->interp_segment_ == NULL);

  const char* interp = parameters->options().dynamic_linker();
  if (interp == NULL)
    {
      interp = target->dynamic_linker();
      gold_assert(interp != NULL);
    }

  size_t len = strlen(interp) + 1;

  Output_section_data* odata = new Output_data_const(interp, len, 1);

  Output_section* osec = this->choose_output_section(NULL, ".interp",
						     elfcpp::SHT_PROGBITS,
						     elfcpp::SHF_ALLOC,
						     false, ORDER_INTERP,
						     false);
  if (osec != NULL)
    osec->add_output_section_data(odata);
}

// Add dynamic tags for the PLT and the dynamic relocs.  This is
// called by the target-specific code.  This does nothing if not doing
// a dynamic link.

// USE_REL is true for REL relocs rather than RELA relocs.

// If PLT_GOT is not NULL, then DT_PLTGOT points to it.

// If PLT_REL is not NULL, it is used for DT_PLTRELSZ, and DT_JMPREL,
// and we also set DT_PLTREL.  We use PLT_REL's output section, since
// some targets have multiple reloc sections in PLT_REL.

// If DYN_REL is not NULL, it is used for DT_REL/DT_RELA,
// DT_RELSZ/DT_RELASZ, DT_RELENT/DT_RELAENT.  Again we use the output
// section.

// If ADD_DEBUG is true, we add a DT_DEBUG entry when generating an
// executable.

void
Layout::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)
{
  Output_data_dynamic* odyn = this->dynamic_data_;
  if (odyn == NULL)
    return;

  if (plt_got != NULL && plt_got->output_section() != NULL)
    odyn->add_section_address(elfcpp::DT_PLTGOT, plt_got);

  if (plt_rel != NULL && plt_rel->output_section() != NULL)
    {
      odyn->add_section_size(elfcpp::DT_PLTRELSZ, plt_rel->output_section());
      odyn->add_section_address(elfcpp::DT_JMPREL, plt_rel->output_section());
      odyn->add_constant(elfcpp::DT_PLTREL,
			 use_rel ? elfcpp::DT_REL : elfcpp::DT_RELA);
    }

  if ((dyn_rel != NULL && dyn_rel->output_section() != NULL)
      || (dynrel_includes_plt
	  && plt_rel != NULL
	  && plt_rel->output_section() != NULL))
    {
      bool have_dyn_rel = dyn_rel != NULL && dyn_rel->output_section() != NULL;
      bool have_plt_rel = plt_rel != NULL && plt_rel->output_section() != NULL;
      odyn->add_section_address(use_rel ? elfcpp::DT_REL : elfcpp::DT_RELA,
				(have_dyn_rel
				 ? dyn_rel->output_section()
				 : plt_rel->output_section()));
      elfcpp::DT size_tag = use_rel ? elfcpp::DT_RELSZ : elfcpp::DT_RELASZ;
      if (have_dyn_rel && have_plt_rel && dynrel_includes_plt)
	odyn->add_section_size(size_tag,
			       dyn_rel->output_section(),
			       plt_rel->output_section());
      else if (have_dyn_rel)
	odyn->add_section_size(size_tag, dyn_rel->output_section());
      else
	odyn->add_section_size(size_tag, plt_rel->output_section());
      const int size = parameters->target().get_size();
      elfcpp::DT rel_tag;
      int rel_size;
      if (use_rel)
	{
	  rel_tag = elfcpp::DT_RELENT;
	  if (size == 32)
	    rel_size = Reloc_types<elfcpp::SHT_REL, 32, false>::reloc_size;
	  else if (size == 64)
	    rel_size = Reloc_types<elfcpp::SHT_REL, 64, false>::reloc_size;
	  else
	    gold_unreachable();
	}
      else
	{
	  rel_tag = elfcpp::DT_RELAENT;
	  if (size == 32)
	    rel_size = Reloc_types<elfcpp::SHT_RELA, 32, false>::reloc_size;
	  else if (size == 64)
	    rel_size = Reloc_types<elfcpp::SHT_RELA, 64, false>::reloc_size;
	  else
	    gold_unreachable();
	}
      odyn->add_constant(rel_tag, rel_size);

      if (parameters->options().combreloc() && have_dyn_rel)
	{
	  size_t c = dyn_rel->relative_reloc_count();
	  if (c > 0)
	    odyn->add_constant((use_rel
				? elfcpp::DT_RELCOUNT
				: elfcpp::DT_RELACOUNT),
			       c);
	}
    }

  if (add_debug && !parameters->options().shared())
    {
      // The value of the DT_DEBUG tag is filled in by the dynamic
      // linker at run time, and used by the debugger.
      odyn->add_constant(elfcpp::DT_DEBUG, 0);
    }
}

// Finish the .dynamic section and PT_DYNAMIC segment.

void
Layout::finish_dynamic_section(const Input_objects* input_objects,
			       const Symbol_table* symtab)
{
  if (!this->script_options_->saw_phdrs_clause()
      && this->dynamic_section_ != NULL)
    {
      Output_segment* oseg = this->make_output_segment(elfcpp::PT_DYNAMIC,
						       (elfcpp::PF_R
							| elfcpp::PF_W));
      oseg->add_output_section_to_nonload(this->dynamic_section_,
					  elfcpp::PF_R | elfcpp::PF_W);
    }

  Output_data_dynamic* const odyn = this->dynamic_data_;
  if (odyn == NULL)
    return;

  for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
       p != input_objects->dynobj_end();
       ++p)
    {
      if (!(*p)->is_needed() && (*p)->as_needed())
	{
	  // This dynamic object was linked with --as-needed, but it
	  // is not needed.
	  continue;
	}

      odyn->add_string(elfcpp::DT_NEEDED, (*p)->soname());
    }

  if (parameters->options().shared())
    {
      const char* soname = parameters->options().soname();
      if (soname != NULL)
	odyn->add_string(elfcpp::DT_SONAME, soname);
    }

  Symbol* sym = symtab->lookup(parameters->options().init());
  if (sym != NULL && sym->is_defined() && !sym->is_from_dynobj())
    odyn->add_symbol(elfcpp::DT_INIT, sym);

  sym = symtab->lookup(parameters->options().fini());
  if (sym != NULL && sym->is_defined() && !sym->is_from_dynobj())
    odyn->add_symbol(elfcpp::DT_FINI, sym);

  // Look for .init_array, .preinit_array and .fini_array by checking
  // section types.
  for(Layout::Section_list::const_iterator p = this->section_list_.begin();
      p != this->section_list_.end();
      ++p)
    switch((*p)->type())
      {
      case elfcpp::SHT_FINI_ARRAY:
	odyn->add_section_address(elfcpp::DT_FINI_ARRAY, *p);
	odyn->add_section_size(elfcpp::DT_FINI_ARRAYSZ, *p);
	break;
      case elfcpp::SHT_INIT_ARRAY:
	odyn->add_section_address(elfcpp::DT_INIT_ARRAY, *p);
	odyn->add_section_size(elfcpp::DT_INIT_ARRAYSZ, *p);
	break;
      case elfcpp::SHT_PREINIT_ARRAY:
	odyn->add_section_address(elfcpp::DT_PREINIT_ARRAY, *p);
	odyn->add_section_size(elfcpp::DT_PREINIT_ARRAYSZ, *p);
	break;
      default:
	break;
      }

  // Add a DT_RPATH entry if needed.
  const General_options::Dir_list& rpath(parameters->options().rpath());
  if (!rpath.empty())
    {
      std::string rpath_val;
      for (General_options::Dir_list::const_iterator p = rpath.begin();
	   p != rpath.end();
	   ++p)
	{
	  if (rpath_val.empty())
	    rpath_val = p->name();
	  else
	    {
	      // Eliminate duplicates.
	      General_options::Dir_list::const_iterator q;
	      for (q = rpath.begin(); q != p; ++q)
		if (q->name() == p->name())
		  break;
	      if (q == p)
		{
		  rpath_val += ':';
		  rpath_val += p->name();
		}
	    }
	}

      if (!parameters->options().enable_new_dtags())
	odyn->add_string(elfcpp::DT_RPATH, rpath_val);
      else
	odyn->add_string(elfcpp::DT_RUNPATH, rpath_val);
    }

  // Look for text segments that have dynamic relocations.
  bool have_textrel = false;
  if (!this->script_options_->saw_sections_clause())
    {
      for (Segment_list::const_iterator p = this->segment_list_.begin();
	   p != this->segment_list_.end();
	   ++p)
	{
	  if ((*p)->type() == elfcpp::PT_LOAD
	      && ((*p)->flags() & elfcpp::PF_W) == 0
	      && (*p)->has_dynamic_reloc())
	    {
	      have_textrel = true;
	      break;
	    }
	}
    }
  else
    {
      // We don't know the section -> segment mapping, so we are
      // conservative and just look for readonly sections with
      // relocations.  If those sections wind up in writable segments,
      // then we have created an unnecessary DT_TEXTREL entry.
      for (Section_list::const_iterator p = this->section_list_.begin();
	   p != this->section_list_.end();
	   ++p)
	{
	  if (((*p)->flags() & elfcpp::SHF_ALLOC) != 0
	      && ((*p)->flags() & elfcpp::SHF_WRITE) == 0
	      && (*p)->has_dynamic_reloc())
	    {
	      have_textrel = true;
	      break;
	    }
	}
    }

  if (parameters->options().filter() != NULL)
    odyn->add_string(elfcpp::DT_FILTER, parameters->options().filter());
  if (parameters->options().any_auxiliary())
    {
      for (options::String_set::const_iterator p =
	     parameters->options().auxiliary_begin();
	   p != parameters->options().auxiliary_end();
	   ++p)
	odyn->add_string(elfcpp::DT_AUXILIARY, *p);
    }

  // Add a DT_FLAGS entry if necessary.
  unsigned int flags = 0;
  if (have_textrel)
    {
      // Add a DT_TEXTREL for compatibility with older loaders.
      odyn->add_constant(elfcpp::DT_TEXTREL, 0);
      flags |= elfcpp::DF_TEXTREL;

      if (parameters->options().text())
	gold_error(_("read-only segment has dynamic relocations"));
      else if (parameters->options().warn_shared_textrel()
	       && parameters->options().shared())
	gold_warning(_("shared library text segment is not shareable"));
    }
  if (parameters->options().shared() && this->has_static_tls())
    flags |= elfcpp::DF_STATIC_TLS;
  if (parameters->options().origin())
    flags |= elfcpp::DF_ORIGIN;
  if (parameters->options().Bsymbolic()
      && !parameters->options().have_dynamic_list())
    {
      flags |= elfcpp::DF_SYMBOLIC;
      // Add DT_SYMBOLIC for compatibility with older loaders.
      odyn->add_constant(elfcpp::DT_SYMBOLIC, 0);
    }
  if (parameters->options().now())
    flags |= elfcpp::DF_BIND_NOW;
  if (flags != 0)
    odyn->add_constant(elfcpp::DT_FLAGS, flags);

  flags = 0;
  if (parameters->options().initfirst())
    flags |= elfcpp::DF_1_INITFIRST;
  if (parameters->options().interpose())
    flags |= elfcpp::DF_1_INTERPOSE;
  if (parameters->options().loadfltr())
    flags |= elfcpp::DF_1_LOADFLTR;
  if (parameters->options().nodefaultlib())
    flags |= elfcpp::DF_1_NODEFLIB;
  if (parameters->options().nodelete())
    flags |= elfcpp::DF_1_NODELETE;
  if (parameters->options().nodlopen())
    flags |= elfcpp::DF_1_NOOPEN;
  if (parameters->options().nodump())
    flags |= elfcpp::DF_1_NODUMP;
  if (!parameters->options().shared())
    flags &= ~(elfcpp::DF_1_INITFIRST
	       | elfcpp::DF_1_NODELETE
	       | elfcpp::DF_1_NOOPEN);
  if (parameters->options().origin())
    flags |= elfcpp::DF_1_ORIGIN;
  if (parameters->options().now())
    flags |= elfcpp::DF_1_NOW;
  if (parameters->options().Bgroup())
    flags |= elfcpp::DF_1_GROUP;
  if (flags != 0)
    odyn->add_constant(elfcpp::DT_FLAGS_1, flags);
}

// Set the size of the _DYNAMIC symbol table to be the size of the
// dynamic data.

void
Layout::set_dynamic_symbol_size(const Symbol_table* symtab)
{
  Output_data_dynamic* const odyn = this->dynamic_data_;
  if (odyn == NULL)
    return;
  odyn->finalize_data_size();
  if (this->dynamic_symbol_ == NULL)
    return;
  off_t data_size = odyn->data_size();
  const int size = parameters->target().get_size();
  if (size == 32)
    symtab->get_sized_symbol<32>(this->dynamic_symbol_)->set_symsize(data_size);
  else if (size == 64)
    symtab->get_sized_symbol<64>(this->dynamic_symbol_)->set_symsize(data_size);
  else
    gold_unreachable();
}

// The mapping of input section name prefixes to output section names.
// In some cases one prefix is itself a prefix of another prefix; in
// such a case the longer prefix must come first.  These prefixes are
// based on the GNU linker default ELF linker script.

#define MAPPING_INIT(f, t) { f, sizeof(f) - 1, t, sizeof(t) - 1 }
#define MAPPING_INIT_EXACT(f, t) { f, 0, t, sizeof(t) - 1 }
const Layout::Section_name_mapping Layout::section_name_mapping[] =
{
  MAPPING_INIT(".text.", ".text"),
  MAPPING_INIT(".rodata.", ".rodata"),
  MAPPING_INIT(".data.rel.ro.local.", ".data.rel.ro.local"),
  MAPPING_INIT_EXACT(".data.rel.ro.local", ".data.rel.ro.local"),
  MAPPING_INIT(".data.rel.ro.", ".data.rel.ro"),
  MAPPING_INIT_EXACT(".data.rel.ro", ".data.rel.ro"),
  MAPPING_INIT(".data.", ".data"),
  MAPPING_INIT(".bss.", ".bss"),
  MAPPING_INIT(".tdata.", ".tdata"),
  MAPPING_INIT(".tbss.", ".tbss"),
  MAPPING_INIT(".init_array.", ".init_array"),
  MAPPING_INIT(".fini_array.", ".fini_array"),
  MAPPING_INIT(".sdata.", ".sdata"),
  MAPPING_INIT(".sbss.", ".sbss"),
  // FIXME: In the GNU linker, .sbss2 and .sdata2 are handled
  // differently depending on whether it is creating a shared library.
  MAPPING_INIT(".sdata2.", ".sdata"),
  MAPPING_INIT(".sbss2.", ".sbss"),
  MAPPING_INIT(".lrodata.", ".lrodata"),
  MAPPING_INIT(".ldata.", ".ldata"),
  MAPPING_INIT(".lbss.", ".lbss"),
  MAPPING_INIT(".gcc_except_table.", ".gcc_except_table"),
  MAPPING_INIT(".gnu.linkonce.d.rel.ro.local.", ".data.rel.ro.local"),
  MAPPING_INIT(".gnu.linkonce.d.rel.ro.", ".data.rel.ro"),
  MAPPING_INIT(".gnu.linkonce.t.", ".text"),
  MAPPING_INIT(".gnu.linkonce.r.", ".rodata"),
  MAPPING_INIT(".gnu.linkonce.d.", ".data"),
  MAPPING_INIT(".gnu.linkonce.b.", ".bss"),
  MAPPING_INIT(".gnu.linkonce.s.", ".sdata"),
  MAPPING_INIT(".gnu.linkonce.sb.", ".sbss"),
  MAPPING_INIT(".gnu.linkonce.s2.", ".sdata"),
  MAPPING_INIT(".gnu.linkonce.sb2.", ".sbss"),
  MAPPING_INIT(".gnu.linkonce.wi.", ".debug_info"),
  MAPPING_INIT(".gnu.linkonce.td.", ".tdata"),
  MAPPING_INIT(".gnu.linkonce.tb.", ".tbss"),
  MAPPING_INIT(".gnu.linkonce.lr.", ".lrodata"),
  MAPPING_INIT(".gnu.linkonce.l.", ".ldata"),
  MAPPING_INIT(".gnu.linkonce.lb.", ".lbss"),
  MAPPING_INIT(".ARM.extab", ".ARM.extab"),
  MAPPING_INIT(".gnu.linkonce.armextab.", ".ARM.extab"),
  MAPPING_INIT(".ARM.exidx", ".ARM.exidx"),
  MAPPING_INIT(".gnu.linkonce.armexidx.", ".ARM.exidx"),
  MAPPING_INIT("_function_patch_prologue.", "_function_patch_prologue"),
  MAPPING_INIT("_function_patch_epilogue.", "_function_patch_epilogue"),
};
#undef MAPPING_INIT
#undef MAPPING_INIT_EXACT

const int Layout::section_name_mapping_count =
  (sizeof(Layout::section_name_mapping)
   / sizeof(Layout::section_name_mapping[0]));

// Choose the output section name to use given an input section name.
// Set *PLEN to the length of the name.  *PLEN is initialized to the
// length of NAME.

const char*
Layout::output_section_name(const Relobj* relobj, const char* name,
			    size_t* plen)
{
  // gcc 4.3 generates the following sorts of section names when it
  // needs a section name specific to a function:
  //   .text.FN
  //   .rodata.FN
  //   .sdata2.FN
  //   .data.FN
  //   .data.rel.FN
  //   .data.rel.local.FN
  //   .data.rel.ro.FN
  //   .data.rel.ro.local.FN
  //   .sdata.FN
  //   .bss.FN
  //   .sbss.FN
  //   .tdata.FN
  //   .tbss.FN

  // The GNU linker maps all of those to the part before the .FN,
  // except that .data.rel.local.FN is mapped to .data, and
  // .data.rel.ro.local.FN is mapped to .data.rel.ro.  The sections
  // beginning with .data.rel.ro.local are grouped together.

  // For an anonymous namespace, the string FN can contain a '.'.

  // Also of interest: .rodata.strN.N, .rodata.cstN, both of which the
  // GNU linker maps to .rodata.

  // The .data.rel.ro sections are used with -z relro.  The sections
  // are recognized by name.  We use the same names that the GNU
  // linker does for these sections.

  // It is hard to handle this in a principled way, so we don't even
  // try.  We use a table of mappings.  If the input section name is
  // not found in the table, we simply use it as the output section
  // name.

  const Section_name_mapping* psnm = section_name_mapping;
  for (int i = 0; i < section_name_mapping_count; ++i, ++psnm)
    {
      if (psnm->fromlen > 0)
	{
	  if (strncmp(name, psnm->from, psnm->fromlen) == 0)
	    {
	      *plen = psnm->tolen;
	      return psnm->to;
	    }
	}
      else
	{
	  if (strcmp(name, psnm->from) == 0)
	    {
	      *plen = psnm->tolen;
	      return psnm->to;
	    }
	}
    }

  // As an additional complication, .ctors sections are output in
  // either .ctors or .init_array sections, and .dtors sections are
  // output in either .dtors or .fini_array sections.
  if (is_prefix_of(".ctors.", name) || is_prefix_of(".dtors.", name))
    {
      if (parameters->options().ctors_in_init_array())
	{
	  *plen = 11;
	  return name[1] == 'c' ? ".init_array" : ".fini_array";
	}
      else
	{
	  *plen = 6;
	  return name[1] == 'c' ? ".ctors" : ".dtors";
	}
    }
  if (parameters->options().ctors_in_init_array()
      && (strcmp(name, ".ctors") == 0 || strcmp(name, ".dtors") == 0))
    {
      // To make .init_array/.fini_array work with gcc we must exclude
      // .ctors and .dtors sections from the crtbegin and crtend
      // files.
      if (relobj == NULL
	  || (!Layout::match_file_name(relobj, "crtbegin")
	      && !Layout::match_file_name(relobj, "crtend")))
	{
	  *plen = 11;
	  return name[1] == 'c' ? ".init_array" : ".fini_array";
	}
    }

  return name;
}

// 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".  This is
// to match crtbegin.o as well as crtbeginS.o without getting confused
// by other possibilities.  Overall matching the file name this way is
// a dreadful hack, but the GNU linker does it in order to better
// support gcc, and we need to be compatible.

bool
Layout::match_file_name(const Relobj* relobj, const char* match)
{
  const std::string& file_name(relobj->name());
  const char* base_name = lbasename(file_name.c_str());
  size_t match_len = strlen(match);
  if (strncmp(base_name, match, match_len) != 0)
    return false;
  size_t base_len = strlen(base_name);
  if (base_len != match_len + 2 && base_len != match_len + 3)
    return false;
  return memcmp(base_name + base_len - 2, ".o", 2) == 0;
}

// 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 existing section 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 returns
// true.

bool
Layout::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)
{
  // It's normal to see a couple of entries here, for the x86 thunk
  // sections.  If we see more than a few, we're linking a C++
  // program, and we resize to get more space to minimize rehashing.
  if (this->signatures_.size() > 4
      && !this->resized_signatures_)
    {
      reserve_unordered_map(&this->signatures_,
			    this->number_of_input_files_ * 64);
      this->resized_signatures_ = true;
    }

  Kept_section candidate;
  std::pair<Signatures::iterator, bool> ins =
    this->signatures_.insert(std::make_pair(name, candidate));

  if (kept_section != NULL)
    *kept_section = &ins.first->second;
  if (ins.second)
    {
      // This is the first time we've seen this signature.
      ins.first->second.set_object(object);
      ins.first->second.set_shndx(shndx);
      if (is_comdat)
	ins.first->second.set_is_comdat();
      if (is_group_name)
	ins.first->second.set_is_group_name();
      return true;
    }

  // We have already seen this signature.

  if (ins.first->second.is_group_name())
    {
      // We've already seen a real section group with this signature.
      // If the kept group is from a plugin object, and we're in the
      // replacement phase, accept the new one as a replacement.
      if (ins.first->second.object() == NULL
	  && parameters->options().plugins()->in_replacement_phase())
	{
	  ins.first->second.set_object(object);
	  ins.first->second.set_shndx(shndx);
	  return true;
	}
      return false;
    }
  else if (is_group_name)
    {
      // This is a real section group, and we've already seen a
      // linkonce section with this signature.  Record that we've seen
      // a section group, and don't include this section group.
      ins.first->second.set_is_group_name();
      return false;
    }
  else
    {
      // We've already seen a linkonce section and this is a linkonce
      // section.  These don't block each other--this may be the same
      // symbol name with different section types.
      return true;
    }
}

// Store the allocated sections into the section list.

void
Layout::get_allocated_sections(Section_list* section_list) const
{
  for (Section_list::const_iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    if (((*p)->flags() & elfcpp::SHF_ALLOC) != 0)
      section_list->push_back(*p);
}

// Store the executable sections into the section list.

void
Layout::get_executable_sections(Section_list* section_list) const
{
  for (Section_list::const_iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    if (((*p)->flags() & (elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR))
	== (elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR))
      section_list->push_back(*p);
}

// Create an output segment.

Output_segment*
Layout::make_output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
{
  gold_assert(!parameters->options().relocatable());
  Output_segment* oseg = new Output_segment(type, flags);
  this->segment_list_.push_back(oseg);

  if (type == elfcpp::PT_TLS)
    this->tls_segment_ = oseg;
  else if (type == elfcpp::PT_GNU_RELRO)
    this->relro_segment_ = oseg;
  else if (type == elfcpp::PT_INTERP)
    this->interp_segment_ = oseg;

  return oseg;
}

// Return the file offset of the normal symbol table.

off_t
Layout::symtab_section_offset() const
{
  if (this->symtab_section_ != NULL)
    return this->symtab_section_->offset();
  return 0;
}

// Return the section index of the normal symbol table.  It may have
// been stripped by the -s/--strip-all option.

unsigned int
Layout::symtab_section_shndx() const
{
  if (this->symtab_section_ != NULL)
    return this->symtab_section_->out_shndx();
  return 0;
}

// Write out the Output_sections.  Most won't have anything to write,
// since most of the data will come from input sections which are
// handled elsewhere.  But some Output_sections do have Output_data.

void
Layout::write_output_sections(Output_file* of) const
{
  for (Section_list::const_iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      if (!(*p)->after_input_sections())
	(*p)->write(of);
    }
}

// Write out data not associated with a section or the symbol table.

void
Layout::write_data(const Symbol_table* symtab, Output_file* of) const
{
  if (!parameters->options().strip_all())
    {
      const Output_section* symtab_section = this->symtab_section_;
      for (Section_list::const_iterator p = this->section_list_.begin();
	   p != this->section_list_.end();
	   ++p)
	{
	  if ((*p)->needs_symtab_index())
	    {
	      gold_assert(symtab_section != NULL);
	      unsigned int index = (*p)->symtab_index();
	      gold_assert(index > 0 && index != -1U);
	      off_t off = (symtab_section->offset()
			   + index * symtab_section->entsize());
	      symtab->write_section_symbol(*p, this->symtab_xindex_, of, off);
	    }
	}
    }

  const Output_section* dynsym_section = this->dynsym_section_;
  for (Section_list::const_iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      if ((*p)->needs_dynsym_index())
	{
	  gold_assert(dynsym_section != NULL);
	  unsigned int index = (*p)->dynsym_index();
	  gold_assert(index > 0 && index != -1U);
	  off_t off = (dynsym_section->offset()
		       + index * dynsym_section->entsize());
	  symtab->write_section_symbol(*p, this->dynsym_xindex_, of, off);
	}
    }

  // Write out the Output_data which are not in an Output_section.
  for (Data_list::const_iterator p = this->special_output_list_.begin();
       p != this->special_output_list_.end();
       ++p)
    (*p)->write(of);

  // Write out the Output_data which are not in an Output_section
  // and are regenerated in each iteration of relaxation.
  for (Data_list::const_iterator p = this->relax_output_list_.begin();
       p != this->relax_output_list_.end();
       ++p)
    (*p)->write(of);
}

// Write out the Output_sections which can only be written after the
// input sections are complete.

void
Layout::write_sections_after_input_sections(Output_file* of)
{
  // Determine the final section offsets, and thus the final output
  // file size.  Note we finalize the .shstrab last, to allow the
  // after_input_section sections to modify their section-names before
  // writing.
  if (this->any_postprocessing_sections_)
    {
      off_t off = this->output_file_size_;
      off = this->set_section_offsets(off, POSTPROCESSING_SECTIONS_PASS);

      // Now that we've finalized the names, we can finalize the shstrab.
      off =
	this->set_section_offsets(off,
				  STRTAB_AFTER_POSTPROCESSING_SECTIONS_PASS);

      if (off > this->output_file_size_)
	{
	  of->resize(off);
	  this->output_file_size_ = off;
	}
    }

  for (Section_list::const_iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    {
      if ((*p)->after_input_sections())
	(*p)->write(of);
    }

  this->section_headers_->write(of);
}

// Build IDs can be computed as a "flat" sha1 or md5 of a string of bytes,
// or as a "tree" where each chunk of the string is hashed and then those
// hashes are put into a (much smaller) string which is hashed with sha1.
// We compute a checksum over the entire file because that is simplest.

Task_token*
Layout::queue_build_id_tasks(Workqueue* workqueue, Task_token* build_id_blocker,
			     Output_file* of)
{
  const size_t filesize = (this->output_file_size() <= 0 ? 0
			   : static_cast<size_t>(this->output_file_size()));
  if (this->build_id_note_ != NULL
      && strcmp(parameters->options().build_id(), "tree") == 0
      && parameters->options().build_id_chunk_size_for_treehash() > 0
      && filesize > 0
      && (filesize >=
	  parameters->options().build_id_min_file_size_for_treehash()))
    {
      static const size_t MD5_OUTPUT_SIZE_IN_BYTES = 16;
      const size_t chunk_size =
	  parameters->options().build_id_chunk_size_for_treehash();
      const size_t num_hashes = ((filesize - 1) / chunk_size) + 1;
      Task_token* post_hash_tasks_blocker = new Task_token(true);
      post_hash_tasks_blocker->add_blockers(num_hashes);
      this->size_of_array_of_hashes_ = num_hashes * MD5_OUTPUT_SIZE_IN_BYTES;
      const unsigned char* src = of->get_input_view(0, filesize);
      this->input_view_ = src;
      unsigned char *dst = new unsigned char[this->size_of_array_of_hashes_];
      this->array_of_hashes_ = dst;
      for (size_t i = 0, src_offset = 0; i < num_hashes;
	   i++, dst += MD5_OUTPUT_SIZE_IN_BYTES, src_offset += chunk_size)
	{
	  size_t size = std::min(chunk_size, filesize - src_offset);
	  workqueue->queue(new Hash_task(src + src_offset,
					 size,
					 dst,
					 build_id_blocker,
					 post_hash_tasks_blocker));
	}
      return post_hash_tasks_blocker;
    }
  return build_id_blocker;
}

// If a tree-style build ID was requested, the parallel part of that computation
// is already done, and the final hash-of-hashes is computed here.  For other
// types of build IDs, all the work is done here.

void
Layout::write_build_id(Output_file* of) const
{
  if (this->build_id_note_ == NULL)
    return;

  unsigned char* ov = of->get_output_view(this->build_id_note_->offset(),
					  this->build_id_note_->data_size());

  if (this->array_of_hashes_ == NULL)
    {
      const size_t output_file_size = this->output_file_size();
      const unsigned char* iv = of->get_input_view(0, output_file_size);
      const char* style = parameters->options().build_id();

      // If we get here with style == "tree" then the output must be
      // too small for chunking, and we use SHA-1 in that case.
      if ((strcmp(style, "sha1") == 0) || (strcmp(style, "tree") == 0))
	sha1_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
      else if (strcmp(style, "md5") == 0)
	md5_buffer(reinterpret_cast<const char*>(iv), output_file_size, ov);
      else
	gold_unreachable();

      of->free_input_view(0, output_file_size, iv);
    }
  else
    {
      // Non-overlapping substrings of the output file have been hashed.
      // Compute SHA-1 hash of the hashes.
      sha1_buffer(reinterpret_cast<const char*>(this->array_of_hashes_),
		  this->size_of_array_of_hashes_, ov);
      delete[] this->array_of_hashes_;
      of->free_input_view(0, this->output_file_size(), this->input_view_);
    }

  of->write_output_view(this->build_id_note_->offset(),
			this->build_id_note_->data_size(),
			ov);
}

// Write out a binary file.  This is called after the link is
// complete.  IN is the temporary output file we used to generate the
// ELF code.  We simply walk through the segments, read them from
// their file offset in IN, and write them to their load address in
// the output file.  FIXME: with a bit more work, we could support
// S-records and/or Intel hex format here.

void
Layout::write_binary(Output_file* in) const
{
  gold_assert(parameters->options().oformat_enum()
	      == General_options::OBJECT_FORMAT_BINARY);

  // Get the size of the binary file.
  uint64_t max_load_address = 0;
  for (Segment_list::const_iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    {
      if ((*p)->type() == elfcpp::PT_LOAD && (*p)->filesz() > 0)
	{
	  uint64_t max_paddr = (*p)->paddr() + (*p)->filesz();
	  if (max_paddr > max_load_address)
	    max_load_address = max_paddr;
	}
    }

  Output_file out(parameters->options().output_file_name());
  out.open(max_load_address);

  for (Segment_list::const_iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    {
      if ((*p)->type() == elfcpp::PT_LOAD && (*p)->filesz() > 0)
	{
	  const unsigned char* vin = in->get_input_view((*p)->offset(),
							(*p)->filesz());
	  unsigned char* vout = out.get_output_view((*p)->paddr(),
						    (*p)->filesz());
	  memcpy(vout, vin, (*p)->filesz());
	  out.write_output_view((*p)->paddr(), (*p)->filesz(), vout);
	  in->free_input_view((*p)->offset(), (*p)->filesz(), vin);
	}
    }

  out.close();
}

// Print the output sections to the map file.

void
Layout::print_to_mapfile(Mapfile* mapfile) const
{
  for (Segment_list::const_iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    (*p)->print_sections_to_mapfile(mapfile);
  for (Section_list::const_iterator p = this->unattached_section_list_.begin();
       p != this->unattached_section_list_.end();
       ++p)
    (*p)->print_to_mapfile(mapfile);
}

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

void
Layout::print_stats() const
{
  this->namepool_.print_stats("section name pool");
  this->sympool_.print_stats("output symbol name pool");
  this->dynpool_.print_stats("dynamic name pool");

  for (Section_list::const_iterator p = this->section_list_.begin();
       p != this->section_list_.end();
       ++p)
    (*p)->print_merge_stats();
}

// Write_sections_task methods.

// We can always run this task.

Task_token*
Write_sections_task::is_runnable()
{
  return NULL;
}

// We need to unlock both OUTPUT_SECTIONS_BLOCKER and FINAL_BLOCKER
// when finished.

void
Write_sections_task::locks(Task_locker* tl)
{
  tl->add(this, this->output_sections_blocker_);
  if (this->input_sections_blocker_ != NULL)
    tl->add(this, this->input_sections_blocker_);
  tl->add(this, this->final_blocker_);
}

// Run the task--write out the data.

void
Write_sections_task::run(Workqueue*)
{
  this->layout_->write_output_sections(this->of_);
}

// Write_data_task methods.

// We can always run this task.

Task_token*
Write_data_task::is_runnable()
{
  return NULL;
}

// We need to unlock FINAL_BLOCKER when finished.

void
Write_data_task::locks(Task_locker* tl)
{
  tl->add(this, this->final_blocker_);
}

// Run the task--write out the data.

void
Write_data_task::run(Workqueue*)
{
  this->layout_->write_data(this->symtab_, this->of_);
}

// Write_symbols_task methods.

// We can always run this task.

Task_token*
Write_symbols_task::is_runnable()
{
  return NULL;
}

// We need to unlock FINAL_BLOCKER when finished.

void
Write_symbols_task::locks(Task_locker* tl)
{
  tl->add(this, this->final_blocker_);
}

// Run the task--write out the symbols.

void
Write_symbols_task::run(Workqueue*)
{
  this->symtab_->write_globals(this->sympool_, this->dynpool_,
			       this->layout_->symtab_xindex(),
			       this->layout_->dynsym_xindex(), this->of_);
}

// Write_after_input_sections_task methods.

// We can only run this task after the input sections have completed.

Task_token*
Write_after_input_sections_task::is_runnable()
{
  if (this->input_sections_blocker_->is_blocked())
    return this->input_sections_blocker_;
  return NULL;
}

// We need to unlock FINAL_BLOCKER when finished.

void
Write_after_input_sections_task::locks(Task_locker* tl)
{
  tl->add(this, this->final_blocker_);
}

// Run the task.

void
Write_after_input_sections_task::run(Workqueue*)
{
  this->layout_->write_sections_after_input_sections(this->of_);
}

// Close_task_runner methods.

// Finish up the build ID computation, if necessary, and write a binary file,
// if necessary.  Then close the output file.

void
Close_task_runner::run(Workqueue*, const Task*)
{
  // At this point the multi-threaded part of the build ID computation,
  // if any, is done.  See queue_build_id_tasks().
  this->layout_->write_build_id(this->of_);

  // If we've been asked to create a binary file, we do so here.
  if (this->options_->oformat_enum() != General_options::OBJECT_FORMAT_ELF)
    this->layout_->write_binary(this->of_);

  this->of_->close();
}

// Instantiate the templates we need.  We could use the configure
// script to restrict this to only the ones for implemented targets.

#ifdef HAVE_TARGET_32_LITTLE
template
Output_section*
Layout::init_fixed_output_section<32, false>(
    const char* name,
    elfcpp::Shdr<32, false>& shdr);
#endif

#ifdef HAVE_TARGET_32_BIG
template
Output_section*
Layout::init_fixed_output_section<32, true>(
    const char* name,
    elfcpp::Shdr<32, true>& shdr);
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
Output_section*
Layout::init_fixed_output_section<64, false>(
    const char* name,
    elfcpp::Shdr<64, false>& shdr);
#endif

#ifdef HAVE_TARGET_64_BIG
template
Output_section*
Layout::init_fixed_output_section<64, true>(
    const char* name,
    elfcpp::Shdr<64, true>& shdr);
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
Output_section*
Layout::layout<32, false>(Sized_relobj_file<32, false>* object,
			  unsigned int shndx,
			  const char* name,
			  const elfcpp::Shdr<32, false>& shdr,
			  unsigned int, unsigned int, off_t*);
#endif

#ifdef HAVE_TARGET_32_BIG
template
Output_section*
Layout::layout<32, true>(Sized_relobj_file<32, true>* object,
			 unsigned int shndx,
			 const char* name,
			 const elfcpp::Shdr<32, true>& shdr,
			 unsigned int, unsigned int, off_t*);
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
Output_section*
Layout::layout<64, false>(Sized_relobj_file<64, false>* object,
			  unsigned int shndx,
			  const char* name,
			  const elfcpp::Shdr<64, false>& shdr,
			  unsigned int, unsigned int, off_t*);
#endif

#ifdef HAVE_TARGET_64_BIG
template
Output_section*
Layout::layout<64, true>(Sized_relobj_file<64, true>* object,
			 unsigned int shndx,
			 const char* name,
			 const elfcpp::Shdr<64, true>& shdr,
			 unsigned int, unsigned int, off_t*);
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
Output_section*
Layout::layout_reloc<32, false>(Sized_relobj_file<32, false>* object,
				unsigned int reloc_shndx,
				const elfcpp::Shdr<32, false>& shdr,
				Output_section* data_section,
				Relocatable_relocs* rr);
#endif

#ifdef HAVE_TARGET_32_BIG
template
Output_section*
Layout::layout_reloc<32, true>(Sized_relobj_file<32, true>* object,
			       unsigned int reloc_shndx,
			       const elfcpp::Shdr<32, true>& shdr,
			       Output_section* data_section,
			       Relocatable_relocs* rr);
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
Output_section*
Layout::layout_reloc<64, false>(Sized_relobj_file<64, false>* object,
				unsigned int reloc_shndx,
				const elfcpp::Shdr<64, false>& shdr,
				Output_section* data_section,
				Relocatable_relocs* rr);
#endif

#ifdef HAVE_TARGET_64_BIG
template
Output_section*
Layout::layout_reloc<64, true>(Sized_relobj_file<64, true>* object,
			       unsigned int reloc_shndx,
			       const elfcpp::Shdr<64, true>& shdr,
			       Output_section* data_section,
			       Relocatable_relocs* rr);
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
void
Layout::layout_group<32, false>(Symbol_table* symtab,
				Sized_relobj_file<32, false>* object,
				unsigned int,
				const char* group_section_name,
				const char* signature,
				const elfcpp::Shdr<32, false>& shdr,
				elfcpp::Elf_Word flags,
				std::vector<unsigned int>* shndxes);
#endif

#ifdef HAVE_TARGET_32_BIG
template
void
Layout::layout_group<32, true>(Symbol_table* symtab,
			       Sized_relobj_file<32, true>* object,
			       unsigned int,
			       const char* group_section_name,
			       const char* signature,
			       const elfcpp::Shdr<32, true>& shdr,
			       elfcpp::Elf_Word flags,
			       std::vector<unsigned int>* shndxes);
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
void
Layout::layout_group<64, false>(Symbol_table* symtab,
				Sized_relobj_file<64, false>* object,
				unsigned int,
				const char* group_section_name,
				const char* signature,
				const elfcpp::Shdr<64, false>& shdr,
				elfcpp::Elf_Word flags,
				std::vector<unsigned int>* shndxes);
#endif

#ifdef HAVE_TARGET_64_BIG
template
void
Layout::layout_group<64, true>(Symbol_table* symtab,
			       Sized_relobj_file<64, true>* object,
			       unsigned int,
			       const char* group_section_name,
			       const char* signature,
			       const elfcpp::Shdr<64, true>& shdr,
			       elfcpp::Elf_Word flags,
			       std::vector<unsigned int>* shndxes);
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
Output_section*
Layout::layout_eh_frame<32, false>(Sized_relobj_file<32, false>* 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<32, false>& shdr,
				   unsigned int reloc_shndx,
				   unsigned int reloc_type,
				   off_t* off);
#endif

#ifdef HAVE_TARGET_32_BIG
template
Output_section*
Layout::layout_eh_frame<32, true>(Sized_relobj_file<32, true>* 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<32, true>& shdr,
				  unsigned int reloc_shndx,
				  unsigned int reloc_type,
				  off_t* off);
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
Output_section*
Layout::layout_eh_frame<64, false>(Sized_relobj_file<64, false>* 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<64, false>& shdr,
				   unsigned int reloc_shndx,
				   unsigned int reloc_type,
				   off_t* off);
#endif

#ifdef HAVE_TARGET_64_BIG
template
Output_section*
Layout::layout_eh_frame<64, true>(Sized_relobj_file<64, true>* 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<64, true>& shdr,
				  unsigned int reloc_shndx,
				  unsigned int reloc_type,
				  off_t* off);
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
void
Layout::add_to_gdb_index(bool is_type_unit,
			 Sized_relobj<32, false>* object,
			 const unsigned char* symbols,
			 off_t symbols_size,
			 unsigned int shndx,
			 unsigned int reloc_shndx,
			 unsigned int reloc_type);
#endif

#ifdef HAVE_TARGET_32_BIG
template
void
Layout::add_to_gdb_index(bool is_type_unit,
			 Sized_relobj<32, true>* object,
			 const unsigned char* symbols,
			 off_t symbols_size,
			 unsigned int shndx,
			 unsigned int reloc_shndx,
			 unsigned int reloc_type);
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
void
Layout::add_to_gdb_index(bool is_type_unit,
			 Sized_relobj<64, false>* object,
			 const unsigned char* symbols,
			 off_t symbols_size,
			 unsigned int shndx,
			 unsigned int reloc_shndx,
			 unsigned int reloc_type);
#endif

#ifdef HAVE_TARGET_64_BIG
template
void
Layout::add_to_gdb_index(bool is_type_unit,
			 Sized_relobj<64, true>* object,
			 const unsigned char* symbols,
			 off_t symbols_size,
			 unsigned int shndx,
			 unsigned int reloc_shndx,
			 unsigned int reloc_type);
#endif

} // End namespace gold.
