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

// Copyright (C) 2006-2020 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"
#ifdef __MINGW32__
#include <windows.h>
#include <rpcdce.h>
#endif

#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.

class Hash_task : public Task
{
 public:
  Hash_task(Output_file* of,
	    size_t offset,
	    size_t size,
	    unsigned char* dst,
	    Task_token* final_blocker)
    : of_(of), offset_(offset), size_(size), dst_(dst),
      final_blocker_(final_blocker)
  { }

  void
  run(Workqueue*)
  {
    const unsigned char* iv =
	this->of_->get_input_view(this->offset_, this->size_);
    md5_buffer(reinterpret_cast<const char*>(iv), this->size_, this->dst_);
    this->of_->free_input_view(this->offset_, this->size_, iv);
  }

  Task_token*
  is_runnable()
  { return NULL; }

  // 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:
  Output_file* of_;
  const size_t offset_;
  const size_t size_;
  unsigned char* const dst_;
  Task_token* const final_blocker_;
};

// 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),
    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),
    lto_slim_object_(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_(),
    gnu_properties_()
{
  // 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",
  "gdb_scripts",
  "info",
  "types",
  "line",
  "loc",
  "macinfo",
  "macro",
  // "pubnames",  // not used by gdb as of 7.4
  // "pubtypes",  // not used by gdb as of 7.4
  // "gnu_pubnames",  // Fission extension
  // "gnu_pubtypes",  // Fission extension
  "ranges",
  "str",
  "str_offsets",
};

// 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",
  // "gdb_scripts",
  "info",
  // "types",
  "line",
  // "loc",
  // "macinfo",
  // "macro",
  // "pubnames",  // not used by gdb as of 7.4
  // "pubtypes",  // not used by gdb as of 7.4
  // "gnu_pubnames",  // Fission extension
  // "gnu_pubtypes",  // Fission extension
  // "ranges",
  "str",
  "str_offsets",  // Fission extension
};

// 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));
}

std::string
corresponding_uncompressed_section_name(std::string secname)
{
  gold_assert(secname[0] == '.' && secname[1] == 'z');
  std::string ret(".");
  ret.append(secname, 2, std::string::npos);
  return ret;
}

// 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, true);
  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_COMPRESSED
			    | 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.  MATCH_INPUT_SPEC
// is true if the section name should be matched against input specs
// in a linker script.

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, bool is_reloc,
			      bool match_input_spec)
{
  // 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() && !is_reloc)
    {
      // 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,
				     match_input_spec);

      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);
  std::string uncompressed_name;

  // Compressed debug sections should be mapped to the corresponding
  // uncompressed section.
  if (is_compressed_debug_section(name))
    {
      uncompressed_name =
	  corresponding_uncompressed_section_name(std::string(name, len));
      name = uncompressed_name.c_str();
      len = uncompressed_name.length();
    }

  // 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);

  // 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",
    ".text.sorted"
  };

  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 sh_type, unsigned int reloc_shndx,
	       unsigned int, off_t* off)
{
  *off = 0;

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

  // 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)
    {
      // Some flags in the input section should not be automatically
      // copied to the output section.
      elfcpp::Elf_Xword flags = (shdr.get_sh_flags()
				 & ~ elfcpp::SHF_COMPRESSED);
      name = this->namepool_.add(name, true, NULL);
      os = this->make_output_section(name, sh_type, flags,
				     ORDER_INVALID, false);
    }
  else
    {
      // All ".text.unlikely.*" sections can be moved to a unique
      // segment with --text-unlikely-segment option.
      bool text_unlikely_segment
	  = (parameters->options().text_unlikely_segment()
	     && is_prefix_of(".text.unlikely",
			     object->section_name(shndx).c_str()));
      if (text_unlikely_segment)
	{
	  elfcpp::Elf_Xword flags
	    = this->get_output_section_flags(shdr.get_sh_flags());

	  Stringpool::Key name_key;
	  const char* os_name = this->namepool_.add(".text.unlikely", true,
						    &name_key);
	  os = this->get_output_section(os_name, name_key, sh_type, flags,
					ORDER_INVALID, false);
	  // Map this output section to a unique segment.  This is done to
	  // separate "text" that is not likely to be executed from "text"
	  // that is likely executed.
	  os->set_is_unique_segment();
	}
      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, false,
					       true);
	    }
	  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>*,
		     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();

  // If the output data section already has a reloc section, use that;
  // otherwise, make a new one.
  Output_section* os = data_section->reloc_section();
  if (os == NULL)
    {
      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);
      data_section->set_reloc_section(os);
    }

  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)
{
  const unsigned int unwind_section_type =
      parameters->target().unwind_section_type();

  gold_assert(shdr.get_sh_type() == elfcpp::SHT_PROGBITS
	      || shdr.get_sh_type() == unwind_section_type);
  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)
{
  const unsigned int unwind_section_type =
      parameters->target().unwind_section_type();

  Output_section* os = this->choose_output_section(object, ".eh_frame",
						   unwind_section_type,
						   elfcpp::SHF_ALLOC, false,
						   ORDER_EHFRAME, false, false,
						   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",
					unwind_section_type,
					elfcpp::SHF_ALLOC, false,
					ORDER_EHFRAME, false, false,
					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;
    }
}

// Remove all post-map .eh_frame information for a PLT.

void
Layout::remove_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data,
				size_t cie_length)
{
  if (parameters->incremental())
    {
      // FIXME: Maybe this could work some day....
      return;
    }
  this->eh_frame_data_->remove_ehframe_for_plt(plt, cie_data, cie_length);
}

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

template<int size, bool big_endian>
void
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, false, 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,
						   false, false);
  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;
	  else if (parameters->options().keep_text_section_prefix())
	    {
	      // -z,keep-text-section-prefix introduces additional
	      // output sections.
	      if (strcmp(os->name(), ".text.hot") == 0)
		return ORDER_TEXT_HOT;
	      else if (strcmp(os->name(), ".text.startup") == 0)
		return ORDER_TEXT_STARTUP;
	      else if (strcmp(os->name(), ".text.exit") == 0)
		return ORDER_TEXT_EXIT;
	      else if (strcmp(os->name(), ".text.unlikely") == 0)
		return ORDER_TEXT_UNLIKELY;
	    }
	}
      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)
    {
      uint64_t os_align = os->addralign();

      // 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)->align() == os_align
	      && (((*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);
	  oseg->set_align(os_align);
	}
    }

  // 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())
	    gold_warning(_("%s: requires executable stack"),
			 obj->name().c_str());
	}
    }
}

// Read a value with given size and endianness.

static inline uint64_t
read_sized_value(size_t size, const unsigned char* buf, bool is_big_endian,
		 const Object* object)
{
  uint64_t val = 0;
  if (size == 4)
    {
      if (is_big_endian)
	val = elfcpp::Swap<32, true>::readval(buf);
      else
	val = elfcpp::Swap<32, false>::readval(buf);
    }
  else if (size == 8)
    {
      if (is_big_endian)
	val = elfcpp::Swap<64, true>::readval(buf);
      else
	val = elfcpp::Swap<64, false>::readval(buf);
    }
  else
    {
      gold_warning(_("%s: in .note.gnu.property section, "
		     "pr_datasz must be 4 or 8"),
		   object->name().c_str());
    }
  return val;
}

// Write a value with given size and endianness.

static inline void
write_sized_value(uint64_t value, size_t size, unsigned char* buf,
		  bool is_big_endian)
{
  if (size == 4)
    {
      if (is_big_endian)
	elfcpp::Swap<32, true>::writeval(buf, static_cast<uint32_t>(value));
      else
	elfcpp::Swap<32, false>::writeval(buf, static_cast<uint32_t>(value));
    }
  else if (size == 8)
    {
      if (is_big_endian)
	elfcpp::Swap<64, true>::writeval(buf, value);
      else
	elfcpp::Swap<64, false>::writeval(buf, value);
    }
  else
    {
      // We will have already complained about this.
    }
}

// Handle the .note.gnu.property section at layout time.

void
Layout::layout_gnu_property(unsigned int note_type,
			    unsigned int pr_type,
			    size_t pr_datasz,
			    const unsigned char* pr_data,
			    const Object* object)
{
  // We currently support only the one note type.
  gold_assert(note_type == elfcpp::NT_GNU_PROPERTY_TYPE_0);

  if (pr_type >= elfcpp::GNU_PROPERTY_LOPROC
      && pr_type < elfcpp::GNU_PROPERTY_HIPROC)
    {
      // Target-dependent property value; call the target to record.
      const int size = parameters->target().get_size();
      const bool is_big_endian = parameters->target().is_big_endian();
      if (size == 32)
	{
	  if (is_big_endian)
	    {
#ifdef HAVE_TARGET_32_BIG
	      parameters->sized_target<32, true>()->
		  record_gnu_property(note_type, pr_type, pr_datasz, pr_data,
				      object);
#else
	      gold_unreachable();
#endif
	    }
	  else
	    {
#ifdef HAVE_TARGET_32_LITTLE
	      parameters->sized_target<32, false>()->
		  record_gnu_property(note_type, pr_type, pr_datasz, pr_data,
				      object);
#else
	      gold_unreachable();
#endif
	    }
	}
      else if (size == 64)
	{
	  if (is_big_endian)
	    {
#ifdef HAVE_TARGET_64_BIG
	      parameters->sized_target<64, true>()->
		  record_gnu_property(note_type, pr_type, pr_datasz, pr_data,
				      object);
#else
	      gold_unreachable();
#endif
	    }
	  else
	    {
#ifdef HAVE_TARGET_64_LITTLE
	      parameters->sized_target<64, false>()->
		  record_gnu_property(note_type, pr_type, pr_datasz, pr_data,
				      object);
#else
	      gold_unreachable();
#endif
	    }
	}
      else
	gold_unreachable();
      return;
    }

  Gnu_properties::iterator pprop = this->gnu_properties_.find(pr_type);
  if (pprop == this->gnu_properties_.end())
    {
      Gnu_property prop;
      prop.pr_datasz = pr_datasz;
      prop.pr_data = new unsigned char[pr_datasz];
      memcpy(prop.pr_data, pr_data, pr_datasz);
      this->gnu_properties_[pr_type] = prop;
    }
  else
    {
      const bool is_big_endian = parameters->target().is_big_endian();
      switch (pr_type)
	{
	case elfcpp::GNU_PROPERTY_STACK_SIZE:
	  // Record the maximum value seen.
	  {
	    uint64_t val1 = read_sized_value(pprop->second.pr_datasz,
					     pprop->second.pr_data,
					     is_big_endian, object);
	    uint64_t val2 = read_sized_value(pr_datasz, pr_data,
					     is_big_endian, object);
	    if (val2 > val1)
	      write_sized_value(val2, pprop->second.pr_datasz,
				pprop->second.pr_data, is_big_endian);
	  }
	  break;
	case elfcpp::GNU_PROPERTY_NO_COPY_ON_PROTECTED:
	  // No data to merge.
	  break;
	default:
	  gold_warning(_("%s: unknown program property type %d "
			 "in .note.gnu.property section"),
		       object->name().c_str(), pr_type);
	}
    }
}

// Merge per-object properties with program properties.
// This lets the target identify objects that are missing certain
// properties, in cases where properties must be ANDed together.

void
Layout::merge_gnu_properties(const Object* object)
{
  const int size = parameters->target().get_size();
  const bool is_big_endian = parameters->target().is_big_endian();
  if (size == 32)
    {
      if (is_big_endian)
	{
#ifdef HAVE_TARGET_32_BIG
	  parameters->sized_target<32, true>()->merge_gnu_properties(object);
#else
	  gold_unreachable();
#endif
	}
      else
	{
#ifdef HAVE_TARGET_32_LITTLE
	  parameters->sized_target<32, false>()->merge_gnu_properties(object);
#else
	  gold_unreachable();
#endif
	}
    }
  else if (size == 64)
    {
      if (is_big_endian)
	{
#ifdef HAVE_TARGET_64_BIG
	  parameters->sized_target<64, true>()->merge_gnu_properties(object);
#else
	  gold_unreachable();
#endif
	}
      else
	{
#ifdef HAVE_TARGET_64_LITTLE
	  parameters->sized_target<64, false>()->merge_gnu_properties(object);
#else
	  gold_unreachable();
#endif
	}
    }
  else
    gold_unreachable();
}

// Add a target-specific property for the output .note.gnu.property section.

void
Layout::add_gnu_property(unsigned int note_type,
			 unsigned int pr_type,
			 size_t pr_datasz,
			 const unsigned char* pr_data)
{
  gold_assert(note_type == elfcpp::NT_GNU_PROPERTY_TYPE_0);

  Gnu_property prop;
  prop.pr_datasz = pr_datasz;
  prop.pr_data = new unsigned char[pr_datasz];
  memcpy(prop.pr_data, pr_data, pr_datasz);
  this->gnu_properties_[pr_type] = prop;
}

// Create automatic note sections.

void
Layout::create_notes()
{
  this->create_gnu_properties_note();
  this->create_gold_note();
  this->create_stack_segment();
  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, false, false);

  // 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)
{
  const elfcpp::STV visibility = parameters->options().start_stop_visibility_enum();
  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,
					visibility,
					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,
					visibility,
					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 position 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));

  File_read::record_file_read(filename);

  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)
{
  unsigned int local_dynamic_count = 0;
  unsigned int forced_local_dynamic_count = 0;

  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;
      Versions versions(*this->script_options()->version_script_info(),
			&this->dynpool_);
      this->create_dynamic_symtab(input_objects, symtab, &dynstr,
				  &local_dynamic_count,
				  &forced_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
				     + forced_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));

  // 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,
			       local_dynamic_count);
  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 NT_GNU_PROPERTY_TYPE_0 note is aligned to the pointer size.
  const int addralign = ((note_type == elfcpp::NT_GNU_PROPERTY_TYPE_0
			 ? parameters->target().get_size()
			 : size) / 8);

  // 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,
						   false, true);
  if (os == NULL)
    return NULL;

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

  *trailing_padding = aligned_descsz - descsz;

  return os;
}

// Create a .note.gnu.property section to record program properties
// accumulated from the input files.

void
Layout::create_gnu_properties_note()
{
  parameters->target().finalize_gnu_properties(this);

  if (this->gnu_properties_.empty())
    return;

  const unsigned int size = parameters->target().get_size();
  const bool is_big_endian = parameters->target().is_big_endian();

  // Compute the total size of the properties array.
  size_t descsz = 0;
  for (Gnu_properties::const_iterator prop = this->gnu_properties_.begin();
       prop != this->gnu_properties_.end();
       ++prop)
    {
      descsz = align_address(descsz + 8 + prop->second.pr_datasz, size / 8);
    }

  // Create the note section.
  size_t trailing_padding;
  Output_section* os = this->create_note("GNU", elfcpp::NT_GNU_PROPERTY_TYPE_0,
					 ".note.gnu.property", descsz,
					 true, &trailing_padding);
  if (os == NULL)
    return;
  gold_assert(trailing_padding == 0);

  // Allocate and fill the properties array.
  unsigned char* desc = new unsigned char[descsz];
  unsigned char* p = desc;
  for (Gnu_properties::const_iterator prop = this->gnu_properties_.begin();
       prop != this->gnu_properties_.end();
       ++prop)
    {
      size_t datasz = prop->second.pr_datasz;
      size_t aligned_datasz = align_address(prop->second.pr_datasz, size / 8);
      write_sized_value(prop->first, 4, p, is_big_endian);
      write_sized_value(datasz, 4, p + 4, is_big_endian);
      memcpy(p + 8, prop->second.pr_data, datasz);
      if (aligned_datasz > datasz)
	memset(p + 8 + datasz, 0, aligned_datasz - datasz);
      p += 8 + aligned_datasz;
    }
  Output_section_data* posd = new Output_data_const(desc, descsz, 4);
  os->add_output_section_data(posd);
}

// 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.  If -z stack-size was used to set a p_memsz value for
// PT_GNU_STACK, we generate the segment regardless.  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_stack_segment()
{
  bool is_stack_executable;
  if (parameters->options().is_execstack_set())
    {
      is_stack_executable = parameters->options().is_stack_executable();
      if (!is_stack_executable
	  && this->input_requires_executable_stack_
	  && parameters->options().warn_execstack())
	gold_warning(_("one or more inputs require executable stack, "
		       "but -z noexecstack was given"));
    }
  else if (!this->input_with_gnu_stack_note_
	   && (!parameters->options().user_set_stack_size()
	       || parameters->options().relocatable()))
    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;
      Output_segment* seg =
	this->make_output_segment(elfcpp::PT_GNU_STACK, flags);
      seg->set_size(parameters->options().stack_size());
      // BFD lets targets override this default alignment, but the only
      // targets that do so are ones that Gold does not support so far.
      seg->set_minimum_p_align(16);
    }
}

// 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)
    {
#ifndef __MINGW32__
      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 // __MINGW32__
      UUID uuid;
      typedef RPC_STATUS (RPC_ENTRY *UuidCreateFn)(UUID *Uuid);

      HMODULE rpc_library = LoadLibrary("rpcrt4.dll");
      if (!rpc_library)
	gold_error(_("--build-id=uuid failed: could not load rpcrt4.dll"));
      else
	{
	  UuidCreateFn uuid_create = reinterpret_cast<UuidCreateFn>(
	      GetProcAddress(rpc_library, "UuidCreate"));
	  if (!uuid_create)
	    gold_error(_("--build-id=uuid failed: could not find UuidCreate"));
	  else if (uuid_create(&uuid) != RPC_S_OK)
	    gold_error(_("__build_id=uuid failed: call UuidCreate() failed"));
	  FreeLibrary(rpc_library);
	}
      desc.assign(reinterpret_cast<const char *>(&uuid), sizeof(UUID));
      descsz = sizeof(UUID);
#endif // __MINGW32__
    }
  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)
{
  // In order to produce a stable ordering if we're called with the same pointer
  // return false.
  if (seg1 == seg2)
    return false;

  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;
      uint64_t align1 = seg1->align();
      uint64_t align2 = seg2->align();
      // Place segments with larger alignments first.
      if (align1 != align2)
	return align1 > align2;
      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()
	      || parameters->options().text_unlikely_segment());
  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 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.

	      uint64_t max_align = (*p)->maximum_alignment();
	      if (max_align > abi_pagesize)
		addr = align_address(addr, max_align);
	      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)
    {
      // PT_GNU_STACK was set up correctly when it was created.
      if ((*p)->type() != elfcpp::PT_LOAD
	  && (*p)->type() != elfcpp::PT_GNU_STACK)
	(*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,
			       unsigned int local_dynamic_count)
{
  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 dyncount;
  if (this->dynsym_section_ == NULL)
    {
      dynoff = 0;
      dyncount = 0;
    }
  else
    {
      off_t locsize = local_dynamic_count * 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, local_dynamic_count, 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.
// *PLOCAL_DYNAMIC_COUNT will be set to the number of local symbols
// from input objects, and *PFORCED_LOCAL_DYNAMIC_COUNT will be set
// to the number of global symbols that have been forced local.
// We need to remember the former because the forced-local symbols are
// written along with the global symbols in Symtab::write_globals().

void
Layout::create_dynamic_symtab(const Input_objects* input_objects,
			      Symbol_table* symtab,
			      Output_section** pdynstr,
			      unsigned int* plocal_dynamic_count,
			      unsigned int* pforced_local_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;
  unsigned int forced_local_count = 0;

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

  *plocal_dynamic_count = local_symcount;
  *pforced_local_dynamic_count = forced_local_count;

  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, false, 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 + forced_local_count);
      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, false,
				    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, false, 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 + forced_local_count,
				    &phash, &hashlen);

      Output_section* hashsec =
	this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
				    elfcpp::SHF_ALLOC, false,
				    ORDER_DYNAMIC_LINKER, false, false,
				    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 + forced_local_count,
				    &phash, &hashlen);

      Output_section* hashsec =
	this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
				    elfcpp::SHF_ALLOC, false,
				    ORDER_DYNAMIC_LINKER, false, false,
				    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(parameters->target().hash_entry_size() / 8);
	}

      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, false, 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,
					  false, 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,
					  false, 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, false, 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);
    }
}

void
Layout::add_target_specific_dynamic_tag(elfcpp::DT tag, unsigned int val)
{
  Output_data_dynamic* odyn = this->dynamic_data_;
  if (odyn == NULL)
    return;
  odyn->add_constant(tag, val);
}

// 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().global())
    flags |= elfcpp::DF_1_GLOBAL;
  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 (parameters->options().pie())
    flags |= elfcpp::DF_1_PIE;
  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(".gnu.build.attributes.", ".gnu.build.attributes"),
};

// Mapping for ".text" section prefixes with -z,keep-text-section-prefix.
const Layout::Section_name_mapping Layout::text_section_name_mapping[] =
{
  MAPPING_INIT(".text.hot.", ".text.hot"),
  MAPPING_INIT_EXACT(".text.hot", ".text.hot"),
  MAPPING_INIT(".text.unlikely.", ".text.unlikely"),
  MAPPING_INIT_EXACT(".text.unlikely", ".text.unlikely"),
  MAPPING_INIT(".text.startup.", ".text.startup"),
  MAPPING_INIT_EXACT(".text.startup", ".text.startup"),
  MAPPING_INIT(".text.exit.", ".text.exit"),
  MAPPING_INIT_EXACT(".text.exit", ".text.exit"),
  MAPPING_INIT(".text.", ".text"),
};
#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]));

const int Layout::text_section_name_mapping_count =
  (sizeof(Layout::text_section_name_mapping)
   / sizeof(Layout::text_section_name_mapping[0]));

// Find section name NAME in PSNM and return the mapped name if found
// with the length set in PLEN.
const char *
Layout::match_section_name(const Layout::Section_name_mapping* psnm,
			   const int count,
			   const char* name, size_t* plen)
{
  for (int i = 0; i < 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;
	    }
	}
    }
  return NULL;
}

// 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.

  if (parameters->options().keep_text_section_prefix()
      && is_prefix_of(".text", name))
    {
      const char* match = match_section_name(text_section_name_mapping,
					     text_section_name_mapping_count,
					     name, plen);
      if (match != NULL)
	return match;
    }

  const char* match = match_section_name(section_name_mapping,
					 section_name_mapping_count, name, plen);
  if (match != NULL)
    return match;

  // 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);
}

// 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, unsigned char* array_of_hashes,
		       size_t size_of_hashes) 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 (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*>(array_of_hashes),
		  size_of_hashes, ov);
      delete[] array_of_hashes;
    }

  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_);
}

// 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.

void
Build_id_task_runner::run(Workqueue* workqueue, const Task*)
{
  Task_token* post_hash_tasks_blocker = new Task_token(true);
  const Layout* layout = this->layout_;
  Output_file* of = this->of_;
  const size_t filesize = (layout->output_file_size() <= 0 ? 0
			   : static_cast<size_t>(layout->output_file_size()));
  unsigned char* array_of_hashes = NULL;
  size_t size_of_hashes = 0;

  if (strcmp(this->options_->build_id(), "tree") == 0
      && this->options_->build_id_chunk_size_for_treehash() > 0
      && filesize > 0
      && (filesize >= this->options_->build_id_min_file_size_for_treehash()))
    {
      static const size_t MD5_OUTPUT_SIZE_IN_BYTES = 16;
      const size_t chunk_size =
	  this->options_->build_id_chunk_size_for_treehash();
      const size_t num_hashes = ((filesize - 1) / chunk_size) + 1;
      post_hash_tasks_blocker->add_blockers(num_hashes);
      size_of_hashes = num_hashes * MD5_OUTPUT_SIZE_IN_BYTES;
      array_of_hashes = new unsigned char[size_of_hashes];
      unsigned char *dst = array_of_hashes;
      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(of,
					 src_offset,
					 size,
					 dst,
					 post_hash_tasks_blocker));
	}
    }

  // Queue the final task to write the build id and close the output file.
  workqueue->queue(new Task_function(new Close_task_runner(this->options_,
							   layout,
							   of,
							   array_of_hashes,
							   size_of_hashes),
				     post_hash_tasks_blocker,
				     "Task_function Close_task_runner"));
}

// 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 Build_id_task_runner.
  this->layout_->write_build_id(this->of_, this->array_of_hashes_,
				this->size_of_hashes_);

  // 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_);

  if (this->options_->dependency_file())
    File_read::write_dependency_file(this->options_->dependency_file(),
				     this->options_->output_file_name());

  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, 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, 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, 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, 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.
