// output.cc -- manage the output file for gold

// Copyright 2006, 2007, 2008, 2009, 2010, 2011 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 <cstdlib>
#include <cstring>
#include <cerrno>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <algorithm>

#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif

#include "libiberty.h"

#include "dwarf.h"
#include "parameters.h"
#include "object.h"
#include "symtab.h"
#include "reloc.h"
#include "merge.h"
#include "descriptors.h"
#include "layout.h"
#include "output.h"

// For systems without mmap support.
#ifndef HAVE_MMAP
# define mmap gold_mmap
# define munmap gold_munmap
# define mremap gold_mremap
# ifndef MAP_FAILED
#  define MAP_FAILED (reinterpret_cast<void*>(-1))
# endif
# ifndef PROT_READ
#  define PROT_READ 0
# endif
# ifndef PROT_WRITE
#  define PROT_WRITE 0
# endif
# ifndef MAP_PRIVATE
#  define MAP_PRIVATE 0
# endif
# ifndef MAP_ANONYMOUS
#  define MAP_ANONYMOUS 0
# endif
# ifndef MAP_SHARED
#  define MAP_SHARED 0
# endif

# ifndef ENOSYS
#  define ENOSYS EINVAL
# endif

static void *
gold_mmap(void *, size_t, int, int, int, off_t)
{
  errno = ENOSYS;
  return MAP_FAILED;
}

static int
gold_munmap(void *, size_t)
{
  errno = ENOSYS;
  return -1;
}

static void *
gold_mremap(void *, size_t, size_t, int)
{
  errno = ENOSYS;
  return MAP_FAILED;
}

#endif

#if defined(HAVE_MMAP) && !defined(HAVE_MREMAP)
# define mremap gold_mremap
extern "C" void *gold_mremap(void *, size_t, size_t, int);
#endif

// Some BSD systems still use MAP_ANON instead of MAP_ANONYMOUS
#ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS  MAP_ANON
#endif

#ifndef MREMAP_MAYMOVE
# define MREMAP_MAYMOVE 1
#endif

#ifndef HAVE_POSIX_FALLOCATE
// A dummy, non general, version of posix_fallocate.  Here we just set
// the file size and hope that there is enough disk space.  FIXME: We
// could allocate disk space by walking block by block and writing a
// zero byte into each block.
static int
posix_fallocate(int o, off_t offset, off_t len)
{
  if (ftruncate(o, offset + len) < 0)
    return errno;
  return 0;
}
#endif // !defined(HAVE_POSIX_FALLOCATE)

// Mingw does not have S_ISLNK.
#ifndef S_ISLNK
# define S_ISLNK(mode) 0
#endif

namespace gold
{

// Output_data variables.

bool Output_data::allocated_sizes_are_fixed;

// Output_data methods.

Output_data::~Output_data()
{
}

// Return the default alignment for the target size.

uint64_t
Output_data::default_alignment()
{
  return Output_data::default_alignment_for_size(
      parameters->target().get_size());
}

// Return the default alignment for a size--32 or 64.

uint64_t
Output_data::default_alignment_for_size(int size)
{
  if (size == 32)
    return 4;
  else if (size == 64)
    return 8;
  else
    gold_unreachable();
}

// Output_section_header methods.  This currently assumes that the
// segment and section lists are complete at construction time.

Output_section_headers::Output_section_headers(
    const Layout* layout,
    const Layout::Segment_list* segment_list,
    const Layout::Section_list* section_list,
    const Layout::Section_list* unattached_section_list,
    const Stringpool* secnamepool,
    const Output_section* shstrtab_section)
  : layout_(layout),
    segment_list_(segment_list),
    section_list_(section_list),
    unattached_section_list_(unattached_section_list),
    secnamepool_(secnamepool),
    shstrtab_section_(shstrtab_section)
{
}

// Compute the current data size.

off_t
Output_section_headers::do_size() const
{
  // Count all the sections.  Start with 1 for the null section.
  off_t count = 1;
  if (!parameters->options().relocatable())
    {
      for (Layout::Segment_list::const_iterator p =
	     this->segment_list_->begin();
	   p != this->segment_list_->end();
	   ++p)
	if ((*p)->type() == elfcpp::PT_LOAD)
	  count += (*p)->output_section_count();
    }
  else
    {
      for (Layout::Section_list::const_iterator p =
	     this->section_list_->begin();
	   p != this->section_list_->end();
	   ++p)
	if (((*p)->flags() & elfcpp::SHF_ALLOC) != 0)
	  ++count;
    }
  count += this->unattached_section_list_->size();

  const int size = parameters->target().get_size();
  int shdr_size;
  if (size == 32)
    shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
  else if (size == 64)
    shdr_size = elfcpp::Elf_sizes<64>::shdr_size;
  else
    gold_unreachable();

  return count * shdr_size;
}

// Write out the section headers.

void
Output_section_headers::do_write(Output_file* of)
{
  switch (parameters->size_and_endianness())
    {
#ifdef HAVE_TARGET_32_LITTLE
    case Parameters::TARGET_32_LITTLE:
      this->do_sized_write<32, false>(of);
      break;
#endif
#ifdef HAVE_TARGET_32_BIG
    case Parameters::TARGET_32_BIG:
      this->do_sized_write<32, true>(of);
      break;
#endif
#ifdef HAVE_TARGET_64_LITTLE
    case Parameters::TARGET_64_LITTLE:
      this->do_sized_write<64, false>(of);
      break;
#endif
#ifdef HAVE_TARGET_64_BIG
    case Parameters::TARGET_64_BIG:
      this->do_sized_write<64, true>(of);
      break;
#endif
    default:
      gold_unreachable();
    }
}

template<int size, bool big_endian>
void
Output_section_headers::do_sized_write(Output_file* of)
{
  off_t all_shdrs_size = this->data_size();
  unsigned char* view = of->get_output_view(this->offset(), all_shdrs_size);

  const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  unsigned char* v = view;

  {
    typename elfcpp::Shdr_write<size, big_endian> oshdr(v);
    oshdr.put_sh_name(0);
    oshdr.put_sh_type(elfcpp::SHT_NULL);
    oshdr.put_sh_flags(0);
    oshdr.put_sh_addr(0);
    oshdr.put_sh_offset(0);

    size_t section_count = (this->data_size()
			    / elfcpp::Elf_sizes<size>::shdr_size);
    if (section_count < elfcpp::SHN_LORESERVE)
      oshdr.put_sh_size(0);
    else
      oshdr.put_sh_size(section_count);

    unsigned int shstrndx = this->shstrtab_section_->out_shndx();
    if (shstrndx < elfcpp::SHN_LORESERVE)
      oshdr.put_sh_link(0);
    else
      oshdr.put_sh_link(shstrndx);

    size_t segment_count = this->segment_list_->size();
    oshdr.put_sh_info(segment_count >= elfcpp::PN_XNUM ? segment_count : 0);

    oshdr.put_sh_addralign(0);
    oshdr.put_sh_entsize(0);
  }

  v += shdr_size;

  unsigned int shndx = 1;
  if (!parameters->options().relocatable())
    {
      for (Layout::Segment_list::const_iterator p =
	     this->segment_list_->begin();
	   p != this->segment_list_->end();
	   ++p)
	v = (*p)->write_section_headers<size, big_endian>(this->layout_,
							  this->secnamepool_,
							  v,
							  &shndx);
    }
  else
    {
      for (Layout::Section_list::const_iterator p =
	     this->section_list_->begin();
	   p != this->section_list_->end();
	   ++p)
	{
	  // We do unallocated sections below, except that group
	  // sections have to come first.
	  if (((*p)->flags() & elfcpp::SHF_ALLOC) == 0
	      && (*p)->type() != elfcpp::SHT_GROUP)
	    continue;
	  gold_assert(shndx == (*p)->out_shndx());
	  elfcpp::Shdr_write<size, big_endian> oshdr(v);
	  (*p)->write_header(this->layout_, this->secnamepool_, &oshdr);
	  v += shdr_size;
	  ++shndx;
	}
    }

  for (Layout::Section_list::const_iterator p =
	 this->unattached_section_list_->begin();
       p != this->unattached_section_list_->end();
       ++p)
    {
      // For a relocatable link, we did unallocated group sections
      // above, since they have to come first.
      if ((*p)->type() == elfcpp::SHT_GROUP
	  && parameters->options().relocatable())
	continue;
      gold_assert(shndx == (*p)->out_shndx());
      elfcpp::Shdr_write<size, big_endian> oshdr(v);
      (*p)->write_header(this->layout_, this->secnamepool_, &oshdr);
      v += shdr_size;
      ++shndx;
    }

  of->write_output_view(this->offset(), all_shdrs_size, view);
}

// Output_segment_header methods.

Output_segment_headers::Output_segment_headers(
    const Layout::Segment_list& segment_list)
  : segment_list_(segment_list)
{
  this->set_current_data_size_for_child(this->do_size());
}

void
Output_segment_headers::do_write(Output_file* of)
{
  switch (parameters->size_and_endianness())
    {
#ifdef HAVE_TARGET_32_LITTLE
    case Parameters::TARGET_32_LITTLE:
      this->do_sized_write<32, false>(of);
      break;
#endif
#ifdef HAVE_TARGET_32_BIG
    case Parameters::TARGET_32_BIG:
      this->do_sized_write<32, true>(of);
      break;
#endif
#ifdef HAVE_TARGET_64_LITTLE
    case Parameters::TARGET_64_LITTLE:
      this->do_sized_write<64, false>(of);
      break;
#endif
#ifdef HAVE_TARGET_64_BIG
    case Parameters::TARGET_64_BIG:
      this->do_sized_write<64, true>(of);
      break;
#endif
    default:
      gold_unreachable();
    }
}

template<int size, bool big_endian>
void
Output_segment_headers::do_sized_write(Output_file* of)
{
  const int phdr_size = elfcpp::Elf_sizes<size>::phdr_size;
  off_t all_phdrs_size = this->segment_list_.size() * phdr_size;
  gold_assert(all_phdrs_size == this->data_size());
  unsigned char* view = of->get_output_view(this->offset(),
					    all_phdrs_size);
  unsigned char* v = view;
  for (Layout::Segment_list::const_iterator p = this->segment_list_.begin();
       p != this->segment_list_.end();
       ++p)
    {
      elfcpp::Phdr_write<size, big_endian> ophdr(v);
      (*p)->write_header(&ophdr);
      v += phdr_size;
    }

  gold_assert(v - view == all_phdrs_size);

  of->write_output_view(this->offset(), all_phdrs_size, view);
}

off_t
Output_segment_headers::do_size() const
{
  const int size = parameters->target().get_size();
  int phdr_size;
  if (size == 32)
    phdr_size = elfcpp::Elf_sizes<32>::phdr_size;
  else if (size == 64)
    phdr_size = elfcpp::Elf_sizes<64>::phdr_size;
  else
    gold_unreachable();

  return this->segment_list_.size() * phdr_size;
}

// Output_file_header methods.

Output_file_header::Output_file_header(const Target* target,
				       const Symbol_table* symtab,
				       const Output_segment_headers* osh)
  : target_(target),
    symtab_(symtab),
    segment_header_(osh),
    section_header_(NULL),
    shstrtab_(NULL)
{
  this->set_data_size(this->do_size());
}

// Set the section table information for a file header.

void
Output_file_header::set_section_info(const Output_section_headers* shdrs,
				     const Output_section* shstrtab)
{
  this->section_header_ = shdrs;
  this->shstrtab_ = shstrtab;
}

// Write out the file header.

void
Output_file_header::do_write(Output_file* of)
{
  gold_assert(this->offset() == 0);

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

// Write out the file header with appropriate size and endianness.

template<int size, bool big_endian>
void
Output_file_header::do_sized_write(Output_file* of)
{
  gold_assert(this->offset() == 0);

  int ehdr_size = elfcpp::Elf_sizes<size>::ehdr_size;
  unsigned char* view = of->get_output_view(0, ehdr_size);
  elfcpp::Ehdr_write<size, big_endian> oehdr(view);

  unsigned char e_ident[elfcpp::EI_NIDENT];
  memset(e_ident, 0, elfcpp::EI_NIDENT);
  e_ident[elfcpp::EI_MAG0] = elfcpp::ELFMAG0;
  e_ident[elfcpp::EI_MAG1] = elfcpp::ELFMAG1;
  e_ident[elfcpp::EI_MAG2] = elfcpp::ELFMAG2;
  e_ident[elfcpp::EI_MAG3] = elfcpp::ELFMAG3;
  if (size == 32)
    e_ident[elfcpp::EI_CLASS] = elfcpp::ELFCLASS32;
  else if (size == 64)
    e_ident[elfcpp::EI_CLASS] = elfcpp::ELFCLASS64;
  else
    gold_unreachable();
  e_ident[elfcpp::EI_DATA] = (big_endian
			      ? elfcpp::ELFDATA2MSB
			      : elfcpp::ELFDATA2LSB);
  e_ident[elfcpp::EI_VERSION] = elfcpp::EV_CURRENT;
  oehdr.put_e_ident(e_ident);

  elfcpp::ET e_type;
  if (parameters->options().relocatable())
    e_type = elfcpp::ET_REL;
  else if (parameters->options().output_is_position_independent())
    e_type = elfcpp::ET_DYN;
  else
    e_type = elfcpp::ET_EXEC;
  oehdr.put_e_type(e_type);

  oehdr.put_e_machine(this->target_->machine_code());
  oehdr.put_e_version(elfcpp::EV_CURRENT);

  oehdr.put_e_entry(this->entry<size>());

  if (this->segment_header_ == NULL)
    oehdr.put_e_phoff(0);
  else
    oehdr.put_e_phoff(this->segment_header_->offset());

  oehdr.put_e_shoff(this->section_header_->offset());
  oehdr.put_e_flags(this->target_->processor_specific_flags());
  oehdr.put_e_ehsize(elfcpp::Elf_sizes<size>::ehdr_size);

  if (this->segment_header_ == NULL)
    {
      oehdr.put_e_phentsize(0);
      oehdr.put_e_phnum(0);
    }
  else
    {
      oehdr.put_e_phentsize(elfcpp::Elf_sizes<size>::phdr_size);
      size_t phnum = (this->segment_header_->data_size()
		      / elfcpp::Elf_sizes<size>::phdr_size);
      if (phnum > elfcpp::PN_XNUM)
	phnum = elfcpp::PN_XNUM;
      oehdr.put_e_phnum(phnum);
    }

  oehdr.put_e_shentsize(elfcpp::Elf_sizes<size>::shdr_size);
  size_t section_count = (this->section_header_->data_size()
			  / elfcpp::Elf_sizes<size>::shdr_size);

  if (section_count < elfcpp::SHN_LORESERVE)
    oehdr.put_e_shnum(this->section_header_->data_size()
		      / elfcpp::Elf_sizes<size>::shdr_size);
  else
    oehdr.put_e_shnum(0);

  unsigned int shstrndx = this->shstrtab_->out_shndx();
  if (shstrndx < elfcpp::SHN_LORESERVE)
    oehdr.put_e_shstrndx(this->shstrtab_->out_shndx());
  else
    oehdr.put_e_shstrndx(elfcpp::SHN_XINDEX);

  // Let the target adjust the ELF header, e.g., to set EI_OSABI in
  // the e_ident field.
  parameters->target().adjust_elf_header(view, ehdr_size);

  of->write_output_view(0, ehdr_size, view);
}

// Return the value to use for the entry address.

template<int size>
typename elfcpp::Elf_types<size>::Elf_Addr
Output_file_header::entry()
{
  const bool should_issue_warning = (parameters->options().entry() != NULL
				     && !parameters->options().relocatable()
                                     && !parameters->options().shared());
  const char* entry = parameters->entry();
  Symbol* sym = this->symtab_->lookup(entry);

  typename Sized_symbol<size>::Value_type v;
  if (sym != NULL)
    {
      Sized_symbol<size>* ssym;
      ssym = this->symtab_->get_sized_symbol<size>(sym);
      if (!ssym->is_defined() && should_issue_warning)
	gold_warning("entry symbol '%s' exists but is not defined", entry);
      v = ssym->value();
    }
  else
    {
      // We couldn't find the entry symbol.  See if we can parse it as
      // a number.  This supports, e.g., -e 0x1000.
      char* endptr;
      v = strtoull(entry, &endptr, 0);
      if (*endptr != '\0')
	{
	  if (should_issue_warning)
	    gold_warning("cannot find entry symbol '%s'", entry);
	  v = 0;
	}
    }

  return v;
}

// Compute the current data size.

off_t
Output_file_header::do_size() const
{
  const int size = parameters->target().get_size();
  if (size == 32)
    return elfcpp::Elf_sizes<32>::ehdr_size;
  else if (size == 64)
    return elfcpp::Elf_sizes<64>::ehdr_size;
  else
    gold_unreachable();
}

// Output_data_const methods.

void
Output_data_const::do_write(Output_file* of)
{
  of->write(this->offset(), this->data_.data(), this->data_.size());
}

// Output_data_const_buffer methods.

void
Output_data_const_buffer::do_write(Output_file* of)
{
  of->write(this->offset(), this->p_, this->data_size());
}

// Output_section_data methods.

// Record the output section, and set the entry size and such.

void
Output_section_data::set_output_section(Output_section* os)
{
  gold_assert(this->output_section_ == NULL);
  this->output_section_ = os;
  this->do_adjust_output_section(os);
}

// Return the section index of the output section.

unsigned int
Output_section_data::do_out_shndx() const
{
  gold_assert(this->output_section_ != NULL);
  return this->output_section_->out_shndx();
}

// Set the alignment, which means we may need to update the alignment
// of the output section.

void
Output_section_data::set_addralign(uint64_t addralign)
{
  this->addralign_ = addralign;
  if (this->output_section_ != NULL
      && this->output_section_->addralign() < addralign)
    this->output_section_->set_addralign(addralign);
}

// Output_data_strtab methods.

// Set the final data size.

void
Output_data_strtab::set_final_data_size()
{
  this->strtab_->set_string_offsets();
  this->set_data_size(this->strtab_->get_strtab_size());
}

// Write out a string table.

void
Output_data_strtab::do_write(Output_file* of)
{
  this->strtab_->write(of, this->offset());
}

// Output_reloc methods.

// A reloc against a global symbol.

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    Symbol* gsym,
    unsigned int type,
    Output_data* od,
    Address address,
    bool is_relative,
    bool is_symbolless,
    bool use_plt_offset)
  : address_(address), local_sym_index_(GSYM_CODE), type_(type),
    is_relative_(is_relative), is_symbolless_(is_symbolless),
    is_section_symbol_(false), use_plt_offset_(use_plt_offset), shndx_(INVALID_CODE)
{
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.gsym = gsym;
  this->u2_.od = od;
  if (dynamic)
    this->set_needs_dynsym_index();
}

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    Symbol* gsym,
    unsigned int type,
    Sized_relobj<size, big_endian>* relobj,
    unsigned int shndx,
    Address address,
    bool is_relative,
    bool is_symbolless,
    bool use_plt_offset)
  : address_(address), local_sym_index_(GSYM_CODE), type_(type),
    is_relative_(is_relative), is_symbolless_(is_symbolless),
    is_section_symbol_(false), use_plt_offset_(use_plt_offset), shndx_(shndx)
{
  gold_assert(shndx != INVALID_CODE);
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.gsym = gsym;
  this->u2_.relobj = relobj;
  if (dynamic)
    this->set_needs_dynsym_index();
}

// A reloc against a local symbol.

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    Sized_relobj<size, big_endian>* relobj,
    unsigned int local_sym_index,
    unsigned int type,
    Output_data* od,
    Address address,
    bool is_relative,
    bool is_symbolless,
    bool is_section_symbol,
    bool use_plt_offset)
  : address_(address), local_sym_index_(local_sym_index), type_(type),
    is_relative_(is_relative), is_symbolless_(is_symbolless),
    is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset),
    shndx_(INVALID_CODE)
{
  gold_assert(local_sym_index != GSYM_CODE
              && local_sym_index != INVALID_CODE);
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.relobj = relobj;
  this->u2_.od = od;
  if (dynamic)
    this->set_needs_dynsym_index();
}

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    Sized_relobj<size, big_endian>* relobj,
    unsigned int local_sym_index,
    unsigned int type,
    unsigned int shndx,
    Address address,
    bool is_relative,
    bool is_symbolless,
    bool is_section_symbol,
    bool use_plt_offset)
  : address_(address), local_sym_index_(local_sym_index), type_(type),
    is_relative_(is_relative), is_symbolless_(is_symbolless),
    is_section_symbol_(is_section_symbol), use_plt_offset_(use_plt_offset),
    shndx_(shndx)
{
  gold_assert(local_sym_index != GSYM_CODE
              && local_sym_index != INVALID_CODE);
  gold_assert(shndx != INVALID_CODE);
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.relobj = relobj;
  this->u2_.relobj = relobj;
  if (dynamic)
    this->set_needs_dynsym_index();
}

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

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    Output_section* os,
    unsigned int type,
    Output_data* od,
    Address address)
  : address_(address), local_sym_index_(SECTION_CODE), type_(type),
    is_relative_(false), is_symbolless_(false),
    is_section_symbol_(true), use_plt_offset_(false), shndx_(INVALID_CODE)
{
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.os = os;
  this->u2_.od = od;
  if (dynamic)
    this->set_needs_dynsym_index();
  else
    os->set_needs_symtab_index();
}

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    Output_section* os,
    unsigned int type,
    Sized_relobj<size, big_endian>* relobj,
    unsigned int shndx,
    Address address)
  : address_(address), local_sym_index_(SECTION_CODE), type_(type),
    is_relative_(false), is_symbolless_(false),
    is_section_symbol_(true), use_plt_offset_(false), shndx_(shndx)
{
  gold_assert(shndx != INVALID_CODE);
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.os = os;
  this->u2_.relobj = relobj;
  if (dynamic)
    this->set_needs_dynsym_index();
  else
    os->set_needs_symtab_index();
}

// An absolute relocation.

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    unsigned int type,
    Output_data* od,
    Address address)
  : address_(address), local_sym_index_(0), type_(type),
    is_relative_(false), is_symbolless_(false),
    is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE)
{
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.relobj = NULL;
  this->u2_.od = od;
}

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    unsigned int type,
    Sized_relobj<size, big_endian>* relobj,
    unsigned int shndx,
    Address address)
  : address_(address), local_sym_index_(0), type_(type),
    is_relative_(false), is_symbolless_(false),
    is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx)
{
  gold_assert(shndx != INVALID_CODE);
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.relobj = NULL;
  this->u2_.relobj = relobj;
}

// A target specific relocation.

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    unsigned int type,
    void* arg,
    Output_data* od,
    Address address)
  : address_(address), local_sym_index_(TARGET_CODE), type_(type),
    is_relative_(false), is_symbolless_(false),
    is_section_symbol_(false), use_plt_offset_(false), shndx_(INVALID_CODE)
{
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.arg = arg;
  this->u2_.od = od;
}

template<bool dynamic, int size, bool big_endian>
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
    unsigned int type,
    void* arg,
    Sized_relobj<size, big_endian>* relobj,
    unsigned int shndx,
    Address address)
  : address_(address), local_sym_index_(TARGET_CODE), type_(type),
    is_relative_(false), is_symbolless_(false),
    is_section_symbol_(false), use_plt_offset_(false), shndx_(shndx)
{
  gold_assert(shndx != INVALID_CODE);
  // this->type_ is a bitfield; make sure TYPE fits.
  gold_assert(this->type_ == type);
  this->u1_.arg = arg;
  this->u2_.relobj = relobj;
}

// Record that we need a dynamic symbol index for this relocation.

template<bool dynamic, int size, bool big_endian>
void
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
set_needs_dynsym_index()
{
  if (this->is_symbolless_)
    return;
  switch (this->local_sym_index_)
    {
    case INVALID_CODE:
      gold_unreachable();

    case GSYM_CODE:
      this->u1_.gsym->set_needs_dynsym_entry();
      break;

    case SECTION_CODE:
      this->u1_.os->set_needs_dynsym_index();
      break;

    case TARGET_CODE:
      // The target must take care of this if necessary.
      break;

    case 0:
      break;

    default:
      {
        const unsigned int lsi = this->local_sym_index_;
	Sized_relobj_file<size, big_endian>* relobj =
	    this->u1_.relobj->sized_relobj();
	gold_assert(relobj != NULL);
        if (!this->is_section_symbol_)
          relobj->set_needs_output_dynsym_entry(lsi);
        else
          relobj->output_section(lsi)->set_needs_dynsym_index();
      }
      break;
    }
}

// Get the symbol index of a relocation.

template<bool dynamic, int size, bool big_endian>
unsigned int
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
  const
{
  unsigned int index;
  if (this->is_symbolless_)
    return 0;
  switch (this->local_sym_index_)
    {
    case INVALID_CODE:
      gold_unreachable();

    case GSYM_CODE:
      if (this->u1_.gsym == NULL)
	index = 0;
      else if (dynamic)
	index = this->u1_.gsym->dynsym_index();
      else
	index = this->u1_.gsym->symtab_index();
      break;

    case SECTION_CODE:
      if (dynamic)
	index = this->u1_.os->dynsym_index();
      else
	index = this->u1_.os->symtab_index();
      break;

    case TARGET_CODE:
      index = parameters->target().reloc_symbol_index(this->u1_.arg,
						      this->type_);
      break;

    case 0:
      // Relocations without symbols use a symbol index of 0.
      index = 0;
      break;

    default:
      {
        const unsigned int lsi = this->local_sym_index_;
	Sized_relobj_file<size, big_endian>* relobj =
	    this->u1_.relobj->sized_relobj();
	gold_assert(relobj != NULL);
        if (!this->is_section_symbol_)
          {
            if (dynamic)
              index = relobj->dynsym_index(lsi);
            else
              index = relobj->symtab_index(lsi);
          }
        else
          {
            Output_section* os = relobj->output_section(lsi);
            gold_assert(os != NULL);
            if (dynamic)
              index = os->dynsym_index();
            else
              index = os->symtab_index();
          }
      }
      break;
    }
  gold_assert(index != -1U);
  return index;
}

// For a local section symbol, get the address of the offset ADDEND
// within the input section.

template<bool dynamic, int size, bool big_endian>
typename elfcpp::Elf_types<size>::Elf_Addr
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
  local_section_offset(Addend addend) const
{
  gold_assert(this->local_sym_index_ != GSYM_CODE
              && this->local_sym_index_ != SECTION_CODE
	      && this->local_sym_index_ != TARGET_CODE
              && this->local_sym_index_ != INVALID_CODE
	      && this->local_sym_index_ != 0
              && this->is_section_symbol_);
  const unsigned int lsi = this->local_sym_index_;
  Output_section* os = this->u1_.relobj->output_section(lsi);
  gold_assert(os != NULL);
  Address offset = this->u1_.relobj->get_output_section_offset(lsi);
  if (offset != invalid_address)
    return offset + addend;
  // This is a merge section.
  Sized_relobj_file<size, big_endian>* relobj =
      this->u1_.relobj->sized_relobj();
  gold_assert(relobj != NULL);
  offset = os->output_address(relobj, lsi, addend);
  gold_assert(offset != invalid_address);
  return offset;
}

// Get the output address of a relocation.

template<bool dynamic, int size, bool big_endian>
typename elfcpp::Elf_types<size>::Elf_Addr
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_address() const
{
  Address address = this->address_;
  if (this->shndx_ != INVALID_CODE)
    {
      Output_section* os = this->u2_.relobj->output_section(this->shndx_);
      gold_assert(os != NULL);
      Address off = this->u2_.relobj->get_output_section_offset(this->shndx_);
      if (off != invalid_address)
	address += os->address() + off;
      else
	{
	  Sized_relobj_file<size, big_endian>* relobj =
	      this->u2_.relobj->sized_relobj();
	  gold_assert(relobj != NULL);
	  address = os->output_address(relobj, this->shndx_, address);
	  gold_assert(address != invalid_address);
	}
    }
  else if (this->u2_.od != NULL)
    address += this->u2_.od->address();
  return address;
}

// Write out the offset and info fields of a Rel or Rela relocation
// entry.

template<bool dynamic, int size, bool big_endian>
template<typename Write_rel>
void
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::write_rel(
    Write_rel* wr) const
{
  wr->put_r_offset(this->get_address());
  unsigned int sym_index = this->get_symbol_index();
  wr->put_r_info(elfcpp::elf_r_info<size>(sym_index, this->type_));
}

// Write out a Rel relocation.

template<bool dynamic, int size, bool big_endian>
void
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::write(
    unsigned char* pov) const
{
  elfcpp::Rel_write<size, big_endian> orel(pov);
  this->write_rel(&orel);
}

// Get the value of the symbol referred to by a Rel relocation.

template<bool dynamic, int size, bool big_endian>
typename elfcpp::Elf_types<size>::Elf_Addr
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::symbol_value(
    Addend addend) const
{
  if (this->local_sym_index_ == GSYM_CODE)
    {
      const Sized_symbol<size>* sym;
      sym = static_cast<const Sized_symbol<size>*>(this->u1_.gsym);
      if (this->use_plt_offset_ && sym->has_plt_offset())
	{
	  uint64_t plt_address =
	    parameters->target().plt_address_for_global(sym);
	  return plt_address + sym->plt_offset();
	}
      else
	return sym->value() + addend;
    }
  gold_assert(this->local_sym_index_ != SECTION_CODE
	      && this->local_sym_index_ != TARGET_CODE
              && this->local_sym_index_ != INVALID_CODE
	      && this->local_sym_index_ != 0
              && !this->is_section_symbol_);
  const unsigned int lsi = this->local_sym_index_;
  Sized_relobj_file<size, big_endian>* relobj =
      this->u1_.relobj->sized_relobj();
  gold_assert(relobj != NULL);
  if (this->use_plt_offset_)
    {
      uint64_t plt_address =
	  parameters->target().plt_address_for_local(relobj, lsi);
      return plt_address + relobj->local_plt_offset(lsi);
    }
  const Symbol_value<size>* symval = relobj->local_symbol(lsi);
  return symval->value(relobj, addend);
}

// Reloc comparison.  This function sorts the dynamic relocs for the
// benefit of the dynamic linker.  First we sort all relative relocs
// to the front.  Among relative relocs, we sort by output address.
// Among non-relative relocs, we sort by symbol index, then by output
// address.

template<bool dynamic, int size, bool big_endian>
int
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
  compare(const Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>& r2)
    const
{
  if (this->is_relative_)
    {
      if (!r2.is_relative_)
	return -1;
      // Otherwise sort by reloc address below.
    }
  else if (r2.is_relative_)
    return 1;
  else
    {
      unsigned int sym1 = this->get_symbol_index();
      unsigned int sym2 = r2.get_symbol_index();
      if (sym1 < sym2)
	return -1;
      else if (sym1 > sym2)
	return 1;
      // Otherwise sort by reloc address.
    }

  section_offset_type addr1 = this->get_address();
  section_offset_type addr2 = r2.get_address();
  if (addr1 < addr2)
    return -1;
  else if (addr1 > addr2)
    return 1;

  // Final tie breaker, in order to generate the same output on any
  // host: reloc type.
  unsigned int type1 = this->type_;
  unsigned int type2 = r2.type_;
  if (type1 < type2)
    return -1;
  else if (type1 > type2)
    return 1;

  // These relocs appear to be exactly the same.
  return 0;
}

// Write out a Rela relocation.

template<bool dynamic, int size, bool big_endian>
void
Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>::write(
    unsigned char* pov) const
{
  elfcpp::Rela_write<size, big_endian> orel(pov);
  this->rel_.write_rel(&orel);
  Addend addend = this->addend_;
  if (this->rel_.is_target_specific())
    addend = parameters->target().reloc_addend(this->rel_.target_arg(),
					       this->rel_.type(), addend);
  else if (this->rel_.is_symbolless())
    addend = this->rel_.symbol_value(addend);
  else if (this->rel_.is_local_section_symbol())
    addend = this->rel_.local_section_offset(addend);
  orel.put_r_addend(addend);
}

// Output_data_reloc_base methods.

// Adjust the output section.

template<int sh_type, bool dynamic, int size, bool big_endian>
void
Output_data_reloc_base<sh_type, dynamic, size, big_endian>
    ::do_adjust_output_section(Output_section* os)
{
  if (sh_type == elfcpp::SHT_REL)
    os->set_entsize(elfcpp::Elf_sizes<size>::rel_size);
  else if (sh_type == elfcpp::SHT_RELA)
    os->set_entsize(elfcpp::Elf_sizes<size>::rela_size);
  else
    gold_unreachable();

  // A STT_GNU_IFUNC symbol may require a IRELATIVE reloc when doing a
  // static link.  The backends will generate a dynamic reloc section
  // to hold this.  In that case we don't want to link to the dynsym
  // section, because there isn't one.
  if (!dynamic)
    os->set_should_link_to_symtab();
  else if (parameters->doing_static_link())
    ;
  else
    os->set_should_link_to_dynsym();
}

// Write out relocation data.

template<int sh_type, bool dynamic, int size, bool big_endian>
void
Output_data_reloc_base<sh_type, dynamic, size, big_endian>::do_write(
    Output_file* of)
{
  const off_t off = this->offset();
  const off_t oview_size = this->data_size();
  unsigned char* const oview = of->get_output_view(off, oview_size);

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

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

  gold_assert(pov - oview == oview_size);

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

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

// Class Output_relocatable_relocs.

template<int sh_type, int size, bool big_endian>
void
Output_relocatable_relocs<sh_type, size, big_endian>::set_final_data_size()
{
  this->set_data_size(this->rr_->output_reloc_count()
		      * Reloc_types<sh_type, size, big_endian>::reloc_size);
}

// class Output_data_group.

template<int size, bool big_endian>
Output_data_group<size, big_endian>::Output_data_group(
    Sized_relobj_file<size, big_endian>* relobj,
    section_size_type entry_count,
    elfcpp::Elf_Word flags,
    std::vector<unsigned int>* input_shndxes)
  : Output_section_data(entry_count * 4, 4, false),
    relobj_(relobj),
    flags_(flags)
{
  this->input_shndxes_.swap(*input_shndxes);
}

// Write out the section group, which means translating the section
// indexes to apply to the output file.

template<int size, bool big_endian>
void
Output_data_group<size, big_endian>::do_write(Output_file* of)
{
  const off_t off = this->offset();
  const section_size_type oview_size =
    convert_to_section_size_type(this->data_size());
  unsigned char* const oview = of->get_output_view(off, oview_size);

  elfcpp::Elf_Word* contents = reinterpret_cast<elfcpp::Elf_Word*>(oview);
  elfcpp::Swap<32, big_endian>::writeval(contents, this->flags_);
  ++contents;

  for (std::vector<unsigned int>::const_iterator p =
	 this->input_shndxes_.begin();
       p != this->input_shndxes_.end();
       ++p, ++contents)
    {
      Output_section* os = this->relobj_->output_section(*p);

      unsigned int output_shndx;
      if (os != NULL)
	output_shndx = os->out_shndx();
      else
	{
	  this->relobj_->error(_("section group retained but "
				 "group element discarded"));
	  output_shndx = 0;
	}

      elfcpp::Swap<32, big_endian>::writeval(contents, output_shndx);
    }

  size_t wrote = reinterpret_cast<unsigned char*>(contents) - oview;
  gold_assert(wrote == oview_size);

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

  // We no longer need this information.
  this->input_shndxes_.clear();
}

// Output_data_got::Got_entry methods.

// Write out the entry.

template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::Got_entry::write(unsigned char* pov) const
{
  Valtype val = 0;

  switch (this->local_sym_index_)
    {
    case GSYM_CODE:
      {
	// If the symbol is resolved locally, we need to write out the
	// link-time value, which will be relocated dynamically by a
	// RELATIVE relocation.
	Symbol* gsym = this->u_.gsym;
	if (this->use_plt_offset_ && gsym->has_plt_offset())
	  val = (parameters->target().plt_address_for_global(gsym)
		 + gsym->plt_offset());
	else
	  {
	    Sized_symbol<size>* sgsym;
	    // This cast is a bit ugly.  We don't want to put a
	    // virtual method in Symbol, because we want Symbol to be
	    // as small as possible.
	    sgsym = static_cast<Sized_symbol<size>*>(gsym);
	    val = sgsym->value();
	  }
      }
      break;

    case CONSTANT_CODE:
      val = this->u_.constant;
      break;

    case RESERVED_CODE:
      // If we're doing an incremental update, don't touch this GOT entry.
      if (parameters->incremental_update())
        return;
      val = this->u_.constant;
      break;

    default:
      {
	const Relobj* object = this->u_.object;
        const unsigned int lsi = this->local_sym_index_;
	if (!this->use_plt_offset_)
	  {
	    uint64_t lval = object->local_symbol_value(lsi, 0);
	    val = convert_types<Valtype, uint64_t>(lval);
	  }
	else
	  {
	    uint64_t plt_address =
	      parameters->target().plt_address_for_local(object, lsi);
	    val = plt_address + object->local_plt_offset(lsi);
	  }
      }
      break;
    }

  elfcpp::Swap<size, big_endian>::writeval(pov, val);
}

// Output_data_got methods.

// Add an entry for a global symbol to the GOT.  This returns true if
// this is a new GOT entry, false if the symbol already had a GOT
// entry.

template<int size, bool big_endian>
bool
Output_data_got<size, big_endian>::add_global(
    Symbol* gsym,
    unsigned int got_type)
{
  if (gsym->has_got_offset(got_type))
    return false;

  unsigned int got_offset = this->add_got_entry(Got_entry(gsym, false));
  gsym->set_got_offset(got_type, got_offset);
  return true;
}

// Like add_global, but use the PLT offset.

template<int size, bool big_endian>
bool
Output_data_got<size, big_endian>::add_global_plt(Symbol* gsym,
						  unsigned int got_type)
{
  if (gsym->has_got_offset(got_type))
    return false;

  unsigned int got_offset = this->add_got_entry(Got_entry(gsym, true));
  gsym->set_got_offset(got_type, got_offset);
  return true;
}

// Add an entry for a global symbol to the GOT, and add a dynamic
// relocation of type R_TYPE for the GOT entry.

template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::add_global_with_rel(
    Symbol* gsym,
    unsigned int got_type,
    Output_data_reloc_generic* rel_dyn,
    unsigned int r_type)
{
  if (gsym->has_got_offset(got_type))
    return;

  unsigned int got_offset = this->add_got_entry(Got_entry());
  gsym->set_got_offset(got_type, got_offset);
  rel_dyn->add_global_generic(gsym, r_type, this, got_offset, 0);
}

// Add a pair of entries for a global symbol to the GOT, and add
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
// If R_TYPE_2 == 0, add the second entry with no relocation.
template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::add_global_pair_with_rel(
    Symbol* gsym,
    unsigned int got_type,
    Output_data_reloc_generic* rel_dyn,
    unsigned int r_type_1,
    unsigned int r_type_2)
{
  if (gsym->has_got_offset(got_type))
    return;

  unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry());
  gsym->set_got_offset(got_type, got_offset);
  rel_dyn->add_global_generic(gsym, r_type_1, this, got_offset, 0);

  if (r_type_2 != 0)
    rel_dyn->add_global_generic(gsym, r_type_2, this,
				got_offset + size / 8, 0);
}

// Add an entry for a local symbol to the GOT.  This returns true if
// this is a new GOT entry, false if the symbol already has a GOT
// entry.

template<int size, bool big_endian>
bool
Output_data_got<size, big_endian>::add_local(
    Relobj* object,
    unsigned int symndx,
    unsigned int got_type)
{
  if (object->local_has_got_offset(symndx, got_type))
    return false;

  unsigned int got_offset = this->add_got_entry(Got_entry(object, symndx,
							  false));
  object->set_local_got_offset(symndx, got_type, got_offset);
  return true;
}

// Like add_local, but use the PLT offset.

template<int size, bool big_endian>
bool
Output_data_got<size, big_endian>::add_local_plt(
    Relobj* object,
    unsigned int symndx,
    unsigned int got_type)
{
  if (object->local_has_got_offset(symndx, got_type))
    return false;

  unsigned int got_offset = this->add_got_entry(Got_entry(object, symndx,
							  true));
  object->set_local_got_offset(symndx, got_type, got_offset);
  return true;
}

// Add an entry for a local symbol to the GOT, and add a dynamic
// relocation of type R_TYPE for the GOT entry.

template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::add_local_with_rel(
    Relobj* object,
    unsigned int symndx,
    unsigned int got_type,
    Output_data_reloc_generic* rel_dyn,
    unsigned int r_type)
{
  if (object->local_has_got_offset(symndx, got_type))
    return;

  unsigned int got_offset = this->add_got_entry(Got_entry());
  object->set_local_got_offset(symndx, got_type, got_offset);
  rel_dyn->add_local_generic(object, symndx, r_type, this, got_offset, 0);
}

// Add a pair of entries for a local symbol to the GOT, and add
// dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively.
// If R_TYPE_2 == 0, add the second entry with no relocation.
template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::add_local_pair_with_rel(
    Relobj* object,
    unsigned int symndx,
    unsigned int shndx,
    unsigned int got_type,
    Output_data_reloc_generic* rel_dyn,
    unsigned int r_type_1,
    unsigned int r_type_2)
{
  if (object->local_has_got_offset(symndx, got_type))
    return;

  unsigned int got_offset =
      this->add_got_entry_pair(Got_entry(),
			       Got_entry(object, symndx, false));
  object->set_local_got_offset(symndx, got_type, got_offset);
  Output_section* os = object->output_section(shndx);
  rel_dyn->add_output_section_generic(os, r_type_1, this, got_offset, 0);

  if (r_type_2 != 0)
    rel_dyn->add_output_section_generic(os, r_type_2, this,
					got_offset + size / 8, 0);
}

// Reserve a slot in the GOT for a local symbol or the second slot of a pair.

template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::reserve_local(
    unsigned int i,
    Relobj* object,
    unsigned int sym_index,
    unsigned int got_type)
{
  this->do_reserve_slot(i);
  object->set_local_got_offset(sym_index, got_type, this->got_offset(i));
}

// Reserve a slot in the GOT for a global symbol.

template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::reserve_global(
    unsigned int i,
    Symbol* gsym,
    unsigned int got_type)
{
  this->do_reserve_slot(i);
  gsym->set_got_offset(got_type, this->got_offset(i));
}

// Write out the GOT.

template<int size, bool big_endian>
void
Output_data_got<size, big_endian>::do_write(Output_file* of)
{
  const int add = size / 8;

  const off_t off = this->offset();
  const off_t oview_size = this->data_size();
  unsigned char* const oview = of->get_output_view(off, oview_size);

  unsigned char* pov = oview;
  for (typename Got_entries::const_iterator p = this->entries_.begin();
       p != this->entries_.end();
       ++p)
    {
      p->write(pov);
      pov += add;
    }

  gold_assert(pov - oview == oview_size);

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

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

// Create a new GOT entry and return its offset.

template<int size, bool big_endian>
unsigned int
Output_data_got<size, big_endian>::add_got_entry(Got_entry got_entry)
{
  if (!this->is_data_size_valid())
    {
      this->entries_.push_back(got_entry);
      this->set_got_size();
      return this->last_got_offset();
    }
  else
    {
      // For an incremental update, find an available slot.
      off_t got_offset = this->free_list_.allocate(size / 8, size / 8, 0);
      if (got_offset == -1)
	gold_fallback(_("out of patch space (GOT);"
			" relink with --incremental-full"));
      unsigned int got_index = got_offset / (size / 8);
      gold_assert(got_index < this->entries_.size());
      this->entries_[got_index] = got_entry;
      return static_cast<unsigned int>(got_offset);
    }
}

// Create a pair of new GOT entries and return the offset of the first.

template<int size, bool big_endian>
unsigned int
Output_data_got<size, big_endian>::add_got_entry_pair(Got_entry got_entry_1,
						      Got_entry got_entry_2)
{
  if (!this->is_data_size_valid())
    {
      unsigned int got_offset;
      this->entries_.push_back(got_entry_1);
      got_offset = this->last_got_offset();
      this->entries_.push_back(got_entry_2);
      this->set_got_size();
      return got_offset;
    }
  else
    {
      // For an incremental update, find an available pair of slots.
      off_t got_offset = this->free_list_.allocate(2 * size / 8, size / 8, 0);
      if (got_offset == -1)
	gold_fallback(_("out of patch space (GOT);"
			" relink with --incremental-full"));
      unsigned int got_index = got_offset / (size / 8);
      gold_assert(got_index < this->entries_.size());
      this->entries_[got_index] = got_entry_1;
      this->entries_[got_index + 1] = got_entry_2;
      return static_cast<unsigned int>(got_offset);
    }
}

// Output_data_dynamic::Dynamic_entry methods.

// Write out the entry.

template<int size, bool big_endian>
void
Output_data_dynamic::Dynamic_entry::write(
    unsigned char* pov,
    const Stringpool* pool) const
{
  typename elfcpp::Elf_types<size>::Elf_WXword val;
  switch (this->offset_)
    {
    case DYNAMIC_NUMBER:
      val = this->u_.val;
      break;

    case DYNAMIC_SECTION_SIZE:
      val = this->u_.od->data_size();
      if (this->od2 != NULL)
	val += this->od2->data_size();
      break;

    case DYNAMIC_SYMBOL:
      {
	const Sized_symbol<size>* s =
	  static_cast<const Sized_symbol<size>*>(this->u_.sym);
	val = s->value();
      }
      break;

    case DYNAMIC_STRING:
      val = pool->get_offset(this->u_.str);
      break;

    default:
      val = this->u_.od->address() + this->offset_;
      break;
    }

  elfcpp::Dyn_write<size, big_endian> dw(pov);
  dw.put_d_tag(this->tag_);
  dw.put_d_val(val);
}

// Output_data_dynamic methods.

// Adjust the output section to set the entry size.

void
Output_data_dynamic::do_adjust_output_section(Output_section* os)
{
  if (parameters->target().get_size() == 32)
    os->set_entsize(elfcpp::Elf_sizes<32>::dyn_size);
  else if (parameters->target().get_size() == 64)
    os->set_entsize(elfcpp::Elf_sizes<64>::dyn_size);
  else
    gold_unreachable();
}

// Set the final data size.

void
Output_data_dynamic::set_final_data_size()
{
  // Add the terminating entry if it hasn't been added.
  // Because of relaxation, we can run this multiple times.
  if (this->entries_.empty() || this->entries_.back().tag() != elfcpp::DT_NULL)
    {
      int extra = parameters->options().spare_dynamic_tags();
      for (int i = 0; i < extra; ++i)
	this->add_constant(elfcpp::DT_NULL, 0);
      this->add_constant(elfcpp::DT_NULL, 0);
    }

  int dyn_size;
  if (parameters->target().get_size() == 32)
    dyn_size = elfcpp::Elf_sizes<32>::dyn_size;
  else if (parameters->target().get_size() == 64)
    dyn_size = elfcpp::Elf_sizes<64>::dyn_size;
  else
    gold_unreachable();
  this->set_data_size(this->entries_.size() * dyn_size);
}

// Write out the dynamic entries.

void
Output_data_dynamic::do_write(Output_file* of)
{
  switch (parameters->size_and_endianness())
    {
#ifdef HAVE_TARGET_32_LITTLE
    case Parameters::TARGET_32_LITTLE:
      this->sized_write<32, false>(of);
      break;
#endif
#ifdef HAVE_TARGET_32_BIG
    case Parameters::TARGET_32_BIG:
      this->sized_write<32, true>(of);
      break;
#endif
#ifdef HAVE_TARGET_64_LITTLE
    case Parameters::TARGET_64_LITTLE:
      this->sized_write<64, false>(of);
      break;
#endif
#ifdef HAVE_TARGET_64_BIG
    case Parameters::TARGET_64_BIG:
      this->sized_write<64, true>(of);
      break;
#endif
    default:
      gold_unreachable();
    }
}

template<int size, bool big_endian>
void
Output_data_dynamic::sized_write(Output_file* of)
{
  const int dyn_size = elfcpp::Elf_sizes<size>::dyn_size;

  const off_t offset = this->offset();
  const off_t oview_size = this->data_size();
  unsigned char* const oview = of->get_output_view(offset, oview_size);

  unsigned char* pov = oview;
  for (typename Dynamic_entries::const_iterator p = this->entries_.begin();
       p != this->entries_.end();
       ++p)
    {
      p->write<size, big_endian>(pov, this->pool_);
      pov += dyn_size;
    }

  gold_assert(pov - oview == oview_size);

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

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

// Class Output_symtab_xindex.

void
Output_symtab_xindex::do_write(Output_file* of)
{
  const off_t offset = this->offset();
  const off_t oview_size = this->data_size();
  unsigned char* const oview = of->get_output_view(offset, oview_size);

  memset(oview, 0, oview_size);

  if (parameters->target().is_big_endian())
    this->endian_do_write<true>(oview);
  else
    this->endian_do_write<false>(oview);

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

  // We no longer need the data.
  this->entries_.clear();
}

template<bool big_endian>
void
Output_symtab_xindex::endian_do_write(unsigned char* const oview)
{
  for (Xindex_entries::const_iterator p = this->entries_.begin();
       p != this->entries_.end();
       ++p)
    {
      unsigned int symndx = p->first;
      gold_assert(symndx * 4 < this->data_size());
      elfcpp::Swap<32, big_endian>::writeval(oview + symndx * 4, p->second);
    }
}

// Output_fill_debug_info methods.

// Return the minimum size needed for a dummy compilation unit header.

size_t
Output_fill_debug_info::do_minimum_hole_size() const
{
  // Compile unit header fields: unit_length, version, debug_abbrev_offset,
  // address_size.
  const size_t len = 4 + 2 + 4 + 1;
  // For type units, add type_signature, type_offset.
  if (this->is_debug_types_)
    return len + 8 + 4;
  return len;
}

// Write a dummy compilation unit header to fill a hole in the
// .debug_info or .debug_types section.

void
Output_fill_debug_info::do_write(Output_file* of, off_t off, size_t len) const
{
  gold_debug(DEBUG_INCREMENTAL, "fill_debug_info(%08lx, %08lx)",
	     static_cast<long>(off), static_cast<long>(len));

  gold_assert(len >= this->do_minimum_hole_size());

  unsigned char* const oview = of->get_output_view(off, len);
  unsigned char* pov = oview;

  // Write header fields: unit_length, version, debug_abbrev_offset,
  // address_size.
  if (this->is_big_endian())
    {
      elfcpp::Swap_unaligned<32, true>::writeval(pov, len - 4);
      elfcpp::Swap_unaligned<16, true>::writeval(pov + 4, this->version);
      elfcpp::Swap_unaligned<32, true>::writeval(pov + 6, 0);
    }
  else
    {
      elfcpp::Swap_unaligned<32, false>::writeval(pov, len - 4);
      elfcpp::Swap_unaligned<16, false>::writeval(pov + 4, this->version);
      elfcpp::Swap_unaligned<32, false>::writeval(pov + 6, 0);
    }
  pov += 4 + 2 + 4;
  *pov++ = 4;

  // For type units, the additional header fields -- type_signature,
  // type_offset -- can be filled with zeroes.

  // Fill the remainder of the free space with zeroes.  The first
  // zero should tell the consumer there are no DIEs to read in this
  // compilation unit.
  if (pov < oview + len)
    memset(pov, 0, oview + len - pov);

  of->write_output_view(off, len, oview);
}

// Output_fill_debug_line methods.

// Return the minimum size needed for a dummy line number program header.

size_t
Output_fill_debug_line::do_minimum_hole_size() const
{
  // Line number program header fields: unit_length, version, header_length,
  // minimum_instruction_length, default_is_stmt, line_base, line_range,
  // opcode_base, standard_opcode_lengths[], include_directories, filenames.
  const size_t len = 4 + 2 + 4 + this->header_length;
  return len;
}

// Write a dummy line number program header to fill a hole in the
// .debug_line section.

void
Output_fill_debug_line::do_write(Output_file* of, off_t off, size_t len) const
{
  gold_debug(DEBUG_INCREMENTAL, "fill_debug_line(%08lx, %08lx)",
	     static_cast<long>(off), static_cast<long>(len));

  gold_assert(len >= this->do_minimum_hole_size());

  unsigned char* const oview = of->get_output_view(off, len);
  unsigned char* pov = oview;

  // Write header fields: unit_length, version, header_length,
  // minimum_instruction_length, default_is_stmt, line_base, line_range,
  // opcode_base, standard_opcode_lengths[], include_directories, filenames.
  // We set the header_length field to cover the entire hole, so the
  // line number program is empty.
  if (this->is_big_endian())
    {
      elfcpp::Swap_unaligned<32, true>::writeval(pov, len - 4);
      elfcpp::Swap_unaligned<16, true>::writeval(pov + 4, this->version);
      elfcpp::Swap_unaligned<32, true>::writeval(pov + 6, len - (4 + 2 + 4));
    }
  else
    {
      elfcpp::Swap_unaligned<32, false>::writeval(pov, len - 4);
      elfcpp::Swap_unaligned<16, false>::writeval(pov + 4, this->version);
      elfcpp::Swap_unaligned<32, false>::writeval(pov + 6, len - (4 + 2 + 4));
    }
  pov += 4 + 2 + 4;
  *pov++ = 1;	// minimum_instruction_length
  *pov++ = 0;	// default_is_stmt
  *pov++ = 0;	// line_base
  *pov++ = 5;	// line_range
  *pov++ = 13;	// opcode_base
  *pov++ = 0;	// standard_opcode_lengths[1]
  *pov++ = 1;	// standard_opcode_lengths[2]
  *pov++ = 1;	// standard_opcode_lengths[3]
  *pov++ = 1;	// standard_opcode_lengths[4]
  *pov++ = 1;	// standard_opcode_lengths[5]
  *pov++ = 0;	// standard_opcode_lengths[6]
  *pov++ = 0;	// standard_opcode_lengths[7]
  *pov++ = 0;	// standard_opcode_lengths[8]
  *pov++ = 1;	// standard_opcode_lengths[9]
  *pov++ = 0;	// standard_opcode_lengths[10]
  *pov++ = 0;	// standard_opcode_lengths[11]
  *pov++ = 1;	// standard_opcode_lengths[12]
  *pov++ = 0;	// include_directories (empty)
  *pov++ = 0;	// filenames (empty)

  // Some consumers don't check the header_length field, and simply
  // start reading the line number program immediately following the
  // header.  For those consumers, we fill the remainder of the free
  // space with DW_LNS_set_basic_block opcodes.  These are effectively
  // no-ops: the resulting line table program will not create any rows.
  if (pov < oview + len)
    memset(pov, elfcpp::DW_LNS_set_basic_block, oview + len - pov);

  of->write_output_view(off, len, oview);
}

// Output_section::Input_section methods.

// Return the current data size.  For an input section we store the size here.
// For an Output_section_data, we have to ask it for the size.

off_t
Output_section::Input_section::current_data_size() const
{
  if (this->is_input_section())
    return this->u1_.data_size;
  else
    {
      this->u2_.posd->pre_finalize_data_size();
      return this->u2_.posd->current_data_size();
    }
}

// Return the data size.  For an input section we store the size here.
// For an Output_section_data, we have to ask it for the size.

off_t
Output_section::Input_section::data_size() const
{
  if (this->is_input_section())
    return this->u1_.data_size;
  else
    return this->u2_.posd->data_size();
}

// Return the object for an input section.

Relobj*
Output_section::Input_section::relobj() const
{
  if (this->is_input_section())
    return this->u2_.object;
  else if (this->is_merge_section())
    {
      gold_assert(this->u2_.pomb->first_relobj() != NULL);
      return this->u2_.pomb->first_relobj();
    }
  else if (this->is_relaxed_input_section())
    return this->u2_.poris->relobj();
  else
    gold_unreachable();
}

// Return the input section index for an input section.

unsigned int
Output_section::Input_section::shndx() const
{
  if (this->is_input_section())
    return this->shndx_;
  else if (this->is_merge_section())
    {
      gold_assert(this->u2_.pomb->first_relobj() != NULL);
      return this->u2_.pomb->first_shndx();
    }
  else if (this->is_relaxed_input_section())
    return this->u2_.poris->shndx();
  else
    gold_unreachable();
}

// Set the address and file offset.

void
Output_section::Input_section::set_address_and_file_offset(
    uint64_t address,
    off_t file_offset,
    off_t section_file_offset)
{
  if (this->is_input_section())
    this->u2_.object->set_section_offset(this->shndx_,
					 file_offset - section_file_offset);
  else
    this->u2_.posd->set_address_and_file_offset(address, file_offset);
}

// Reset the address and file offset.

void
Output_section::Input_section::reset_address_and_file_offset()
{
  if (!this->is_input_section())
    this->u2_.posd->reset_address_and_file_offset();
}

// Finalize the data size.

void
Output_section::Input_section::finalize_data_size()
{
  if (!this->is_input_section())
    this->u2_.posd->finalize_data_size();
}

// Try to turn an input offset into an output offset.  We want to
// return the output offset relative to the start of this
// Input_section in the output section.

inline bool
Output_section::Input_section::output_offset(
    const Relobj* object,
    unsigned int shndx,
    section_offset_type offset,
    section_offset_type* poutput) const
{
  if (!this->is_input_section())
    return this->u2_.posd->output_offset(object, shndx, offset, poutput);
  else
    {
      if (this->shndx_ != shndx || this->u2_.object != object)
	return false;
      *poutput = offset;
      return true;
    }
}

// Return whether this is the merge section for the input section
// SHNDX in OBJECT.

inline bool
Output_section::Input_section::is_merge_section_for(const Relobj* object,
						    unsigned int shndx) const
{
  if (this->is_input_section())
    return false;
  return this->u2_.posd->is_merge_section_for(object, shndx);
}

// Write out the data.  We don't have to do anything for an input
// section--they are handled via Object::relocate--but this is where
// we write out the data for an Output_section_data.

void
Output_section::Input_section::write(Output_file* of)
{
  if (!this->is_input_section())
    this->u2_.posd->write(of);
}

// Write the data to a buffer.  As for write(), we don't have to do
// anything for an input section.

void
Output_section::Input_section::write_to_buffer(unsigned char* buffer)
{
  if (!this->is_input_section())
    this->u2_.posd->write_to_buffer(buffer);
}

// Print to a map file.

void
Output_section::Input_section::print_to_mapfile(Mapfile* mapfile) const
{
  switch (this->shndx_)
    {
    case OUTPUT_SECTION_CODE:
    case MERGE_DATA_SECTION_CODE:
    case MERGE_STRING_SECTION_CODE:
      this->u2_.posd->print_to_mapfile(mapfile);
      break;

    case RELAXED_INPUT_SECTION_CODE:
      {
        Output_relaxed_input_section* relaxed_section =
	  this->relaxed_input_section();
        mapfile->print_input_section(relaxed_section->relobj(),
				     relaxed_section->shndx());
      }
      break;
    default:
      mapfile->print_input_section(this->u2_.object, this->shndx_);
      break;
    }
}

// Output_section methods.

// Construct an Output_section.  NAME will point into a Stringpool.

Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
			       elfcpp::Elf_Xword flags)
  : name_(name),
    addralign_(0),
    entsize_(0),
    load_address_(0),
    link_section_(NULL),
    link_(0),
    info_section_(NULL),
    info_symndx_(NULL),
    info_(0),
    type_(type),
    flags_(flags),
    order_(ORDER_INVALID),
    out_shndx_(-1U),
    symtab_index_(0),
    dynsym_index_(0),
    input_sections_(),
    first_input_offset_(0),
    fills_(),
    postprocessing_buffer_(NULL),
    needs_symtab_index_(false),
    needs_dynsym_index_(false),
    should_link_to_symtab_(false),
    should_link_to_dynsym_(false),
    after_input_sections_(false),
    requires_postprocessing_(false),
    found_in_sections_clause_(false),
    has_load_address_(false),
    info_uses_section_index_(false),
    input_section_order_specified_(false),
    may_sort_attached_input_sections_(false),
    must_sort_attached_input_sections_(false),
    attached_input_sections_are_sorted_(false),
    is_relro_(false),
    is_small_section_(false),
    is_large_section_(false),
    generate_code_fills_at_write_(false),
    is_entsize_zero_(false),
    section_offsets_need_adjustment_(false),
    is_noload_(false),
    always_keeps_input_sections_(false),
    has_fixed_layout_(false),
    is_patch_space_allowed_(false),
    tls_offset_(0),
    checkpoint_(NULL),
    lookup_maps_(new Output_section_lookup_maps),
    free_list_(),
    free_space_fill_(NULL),
    patch_space_(0)
{
  // An unallocated section has no address.  Forcing this means that
  // we don't need special treatment for symbols defined in debug
  // sections.
  if ((flags & elfcpp::SHF_ALLOC) == 0)
    this->set_address(0);
}

Output_section::~Output_section()
{
  delete this->checkpoint_;
}

// Set the entry size.

void
Output_section::set_entsize(uint64_t v)
{
  if (this->is_entsize_zero_)
    ;
  else if (this->entsize_ == 0)
    this->entsize_ = v;
  else if (this->entsize_ != v)
    {
      this->entsize_ = 0;
      this->is_entsize_zero_ = 1;
    }
}

// Add the input section SHNDX, with header SHDR, named SECNAME, in
// OBJECT, to the Output_section.  RELOC_SHNDX is the index of a
// relocation section which applies to this section, or 0 if none, or
// -1U if more than one.  Return the offset of the input section
// within the output section.  Return -1 if the input section will
// receive special handling.  In the normal case we don't always keep
// track of input sections for an Output_section.  Instead, each
// Object keeps track of the Output_section for each of its input
// sections.  However, if HAVE_SECTIONS_SCRIPT is true, we do keep
// track of input sections here; this is used when SECTIONS appears in
// a linker script.

template<int size, bool big_endian>
off_t
Output_section::add_input_section(Layout* layout,
				  Sized_relobj_file<size, big_endian>* object,
				  unsigned int shndx,
				  const char* secname,
				  const elfcpp::Shdr<size, big_endian>& shdr,
				  unsigned int reloc_shndx,
				  bool have_sections_script)
{
  elfcpp::Elf_Xword addralign = shdr.get_sh_addralign();
  if ((addralign & (addralign - 1)) != 0)
    {
      object->error(_("invalid alignment %lu for section \"%s\""),
		    static_cast<unsigned long>(addralign), secname);
      addralign = 1;
    }

  if (addralign > this->addralign_)
    this->addralign_ = addralign;

  typename elfcpp::Elf_types<size>::Elf_WXword sh_flags = shdr.get_sh_flags();
  uint64_t entsize = shdr.get_sh_entsize();

  // .debug_str is a mergeable string section, but is not always so
  // marked by compilers.  Mark manually here so we can optimize.
  if (strcmp(secname, ".debug_str") == 0)
    {
      sh_flags |= (elfcpp::SHF_MERGE | elfcpp::SHF_STRINGS);
      entsize = 1;
    }

  this->update_flags_for_input_section(sh_flags);
  this->set_entsize(entsize);

  // If this is a SHF_MERGE section, we pass all the input sections to
  // a Output_data_merge.  We don't try to handle relocations for such
  // a section.  We don't try to handle empty merge sections--they
  // mess up the mappings, and are useless anyhow.
  // FIXME: Need to handle merge sections during incremental update.
  if ((sh_flags & elfcpp::SHF_MERGE) != 0
      && reloc_shndx == 0
      && shdr.get_sh_size() > 0
      && !parameters->incremental())
    {
      // Keep information about merged input sections for rebuilding fast
      // lookup maps if we have sections-script or we do relaxation.
      bool keeps_input_sections = (this->always_keeps_input_sections_
				   || have_sections_script
				   || parameters->target().may_relax());

      if (this->add_merge_input_section(object, shndx, sh_flags, entsize,
					addralign, keeps_input_sections))
	{
	  // Tell the relocation routines that they need to call the
	  // output_offset method to determine the final address.
	  return -1;
	}
    }

  section_size_type input_section_size = shdr.get_sh_size();
  section_size_type uncompressed_size;
  if (object->section_is_compressed(shndx, &uncompressed_size))
    input_section_size = uncompressed_size;

  off_t offset_in_section;
  off_t aligned_offset_in_section;
  if (this->has_fixed_layout())
    {
      // For incremental updates, find a chunk of unused space in the section.
      offset_in_section = this->free_list_.allocate(input_section_size,
						    addralign, 0);
      if (offset_in_section == -1)
        gold_fallback(_("out of patch space in section %s; "
			"relink with --incremental-full"),
		      this->name());
      aligned_offset_in_section = offset_in_section;
    }
  else
    {
      offset_in_section = this->current_data_size_for_child();
      aligned_offset_in_section = align_address(offset_in_section,
						addralign);
      this->set_current_data_size_for_child(aligned_offset_in_section
					    + input_section_size);
    }

  // Determine if we want to delay code-fill generation until the output
  // section is written.  When the target is relaxing, we want to delay fill
  // generating to avoid adjusting them during relaxation.  Also, if we are
  // sorting input sections we must delay fill generation.
  if (!this->generate_code_fills_at_write_
      && !have_sections_script
      && (sh_flags & elfcpp::SHF_EXECINSTR) != 0
      && parameters->target().has_code_fill()
      && (parameters->target().may_relax()
          || layout->is_section_ordering_specified()))
    {
      gold_assert(this->fills_.empty());
      this->generate_code_fills_at_write_ = true;
    }

  if (aligned_offset_in_section > offset_in_section
      && !this->generate_code_fills_at_write_
      && !have_sections_script
      && (sh_flags & elfcpp::SHF_EXECINSTR) != 0
      && parameters->target().has_code_fill())
    {
      // We need to add some fill data.  Using fill_list_ when
      // possible is an optimization, since we will often have fill
      // sections without input sections.
      off_t fill_len = aligned_offset_in_section - offset_in_section;
      if (this->input_sections_.empty())
        this->fills_.push_back(Fill(offset_in_section, fill_len));
      else
        {
          std::string fill_data(parameters->target().code_fill(fill_len));
          Output_data_const* odc = new Output_data_const(fill_data, 1);
          this->input_sections_.push_back(Input_section(odc));
        }
    }

  // We need to keep track of this section if we are already keeping
  // track of sections, or if we are relaxing.  Also, if this is a
  // section which requires sorting, or which may require sorting in
  // the future, we keep track of the sections.  If the
  // --section-ordering-file option is used to specify the order of
  // sections, we need to keep track of sections.
  if (this->always_keeps_input_sections_
      || have_sections_script
      || !this->input_sections_.empty()
      || this->may_sort_attached_input_sections()
      || this->must_sort_attached_input_sections()
      || parameters->options().user_set_Map()
      || parameters->target().may_relax()
      || layout->is_section_ordering_specified())
    {
      Input_section isecn(object, shndx, input_section_size, addralign);
      /* If section ordering is requested by specifying a ordering file,
	 using --section-ordering-file, match the section name with
	 a pattern.  */
      if (parameters->options().section_ordering_file())
        {
          unsigned int section_order_index =
            layout->find_section_order_index(std::string(secname));
	  if (section_order_index != 0)
            {
              isecn.set_section_order_index(section_order_index);
              this->set_input_section_order_specified();
            }
        }
      if (this->has_fixed_layout())
	{
	  // For incremental updates, finalize the address and offset now.
	  uint64_t addr = this->address();
	  isecn.set_address_and_file_offset(addr + aligned_offset_in_section,
					    aligned_offset_in_section,
					    this->offset());
	}
      this->input_sections_.push_back(isecn);
    }

  return aligned_offset_in_section;
}

// Add arbitrary data to an output section.

void
Output_section::add_output_section_data(Output_section_data* posd)
{
  Input_section inp(posd);
  this->add_output_section_data(&inp);

  if (posd->is_data_size_valid())
    {
      off_t offset_in_section;
      if (this->has_fixed_layout())
	{
	  // For incremental updates, find a chunk of unused space.
	  offset_in_section = this->free_list_.allocate(posd->data_size(),
							posd->addralign(), 0);
	  if (offset_in_section == -1)
	    gold_fallback(_("out of patch space in section %s; "
			    "relink with --incremental-full"),
			  this->name());
	  // Finalize the address and offset now.
	  uint64_t addr = this->address();
	  off_t offset = this->offset();
	  posd->set_address_and_file_offset(addr + offset_in_section,
					    offset + offset_in_section);
	}
      else
	{
	  offset_in_section = this->current_data_size_for_child();
	  off_t aligned_offset_in_section = align_address(offset_in_section,
							  posd->addralign());
	  this->set_current_data_size_for_child(aligned_offset_in_section
						+ posd->data_size());
	}
    }
  else if (this->has_fixed_layout())
    {
      // For incremental updates, arrange for the data to have a fixed layout.
      // This will mean that additions to the data must be allocated from
      // free space within the containing output section.
      uint64_t addr = this->address();
      posd->set_address(addr);
      posd->set_file_offset(0);
      // FIXME: This should eventually be unreachable.
      // gold_unreachable();
    }
}

// Add a relaxed input section.

void
Output_section::add_relaxed_input_section(Layout* layout,
					  Output_relaxed_input_section* poris,
					  const std::string& name)
{
  Input_section inp(poris);

  // If the --section-ordering-file option is used to specify the order of
  // sections, we need to keep track of sections.
  if (layout->is_section_ordering_specified())
    {
      unsigned int section_order_index =
        layout->find_section_order_index(name);
      if (section_order_index != 0)
        {
          inp.set_section_order_index(section_order_index);
          this->set_input_section_order_specified();
        }
    }

  this->add_output_section_data(&inp);
  if (this->lookup_maps_->is_valid())
    this->lookup_maps_->add_relaxed_input_section(poris->relobj(),
						  poris->shndx(), poris);

  // For a relaxed section, we use the current data size.  Linker scripts
  // get all the input sections, including relaxed one from an output
  // section and add them back to them same output section to compute the
  // output section size.  If we do not account for sizes of relaxed input
  // sections,  an output section would be incorrectly sized.
  off_t offset_in_section = this->current_data_size_for_child();
  off_t aligned_offset_in_section = align_address(offset_in_section,
						  poris->addralign());
  this->set_current_data_size_for_child(aligned_offset_in_section
					+ poris->current_data_size());
}

// Add arbitrary data to an output section by Input_section.

void
Output_section::add_output_section_data(Input_section* inp)
{
  if (this->input_sections_.empty())
    this->first_input_offset_ = this->current_data_size_for_child();

  this->input_sections_.push_back(*inp);

  uint64_t addralign = inp->addralign();
  if (addralign > this->addralign_)
    this->addralign_ = addralign;

  inp->set_output_section(this);
}

// Add a merge section to an output section.

void
Output_section::add_output_merge_section(Output_section_data* posd,
					 bool is_string, uint64_t entsize)
{
  Input_section inp(posd, is_string, entsize);
  this->add_output_section_data(&inp);
}

// Add an input section to a SHF_MERGE section.

bool
Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
					uint64_t flags, uint64_t entsize,
					uint64_t addralign,
					bool keeps_input_sections)
{
  bool is_string = (flags & elfcpp::SHF_STRINGS) != 0;

  // We only merge strings if the alignment is not more than the
  // character size.  This could be handled, but it's unusual.
  if (is_string && addralign > entsize)
    return false;

  // We cannot restore merged input section states.
  gold_assert(this->checkpoint_ == NULL);

  // Look up merge sections by required properties.
  // Currently, we only invalidate the lookup maps in script processing
  // and relaxation.  We should not have done either when we reach here.
  // So we assume that the lookup maps are valid to simply code.
  gold_assert(this->lookup_maps_->is_valid());
  Merge_section_properties msp(is_string, entsize, addralign);
  Output_merge_base* pomb = this->lookup_maps_->find_merge_section(msp);
  bool is_new = false;
  if (pomb != NULL)
    {
      gold_assert(pomb->is_string() == is_string
		  && pomb->entsize() == entsize
		  && pomb->addralign() == addralign);
    }
  else
    {
      // Create a new Output_merge_data or Output_merge_string_data.
      if (!is_string)
	pomb = new Output_merge_data(entsize, addralign);
      else
	{
	  switch (entsize)
	    {
	    case 1:
	      pomb = new Output_merge_string<char>(addralign);
	      break;
	    case 2:
	      pomb = new Output_merge_string<uint16_t>(addralign);
	      break;
	    case 4:
	      pomb = new Output_merge_string<uint32_t>(addralign);
	      break;
	    default:
	      return false;
	    }
	}
      // If we need to do script processing or relaxation, we need to keep
      // the original input sections to rebuild the fast lookup maps.
      if (keeps_input_sections)
	pomb->set_keeps_input_sections();
      is_new = true;
    }

  if (pomb->add_input_section(object, shndx))
    {
      // Add new merge section to this output section and link merge
      // section properties to new merge section in map.
      if (is_new)
	{
	  this->add_output_merge_section(pomb, is_string, entsize);
	  this->lookup_maps_->add_merge_section(msp, pomb);
	}

      // Add input section to new merge section and link input section to new
      // merge section in map.
      this->lookup_maps_->add_merge_input_section(object, shndx, pomb);
      return true;
    }
  else
    {
      // If add_input_section failed, delete new merge section to avoid
      // exporting empty merge sections in Output_section::get_input_section.
      if (is_new)
	delete pomb;
      return false;
    }
}

// Build a relaxation map to speed up relaxation of existing input sections.
// Look up to the first LIMIT elements in INPUT_SECTIONS.

void
Output_section::build_relaxation_map(
  const Input_section_list& input_sections,
  size_t limit,
  Relaxation_map* relaxation_map) const
{
  for (size_t i = 0; i < limit; ++i)
    {
      const Input_section& is(input_sections[i]);
      if (is.is_input_section() || is.is_relaxed_input_section())
	{
	  Section_id sid(is.relobj(), is.shndx());
	  (*relaxation_map)[sid] = i;
	}
    }
}

// Convert regular input sections in INPUT_SECTIONS into relaxed input
// sections in RELAXED_SECTIONS.  MAP is a prebuilt map from section id
// indices of INPUT_SECTIONS.

void
Output_section::convert_input_sections_in_list_to_relaxed_sections(
  const std::vector<Output_relaxed_input_section*>& relaxed_sections,
  const Relaxation_map& map,
  Input_section_list* input_sections)
{
  for (size_t i = 0; i < relaxed_sections.size(); ++i)
    {
      Output_relaxed_input_section* poris = relaxed_sections[i];
      Section_id sid(poris->relobj(), poris->shndx());
      Relaxation_map::const_iterator p = map.find(sid);
      gold_assert(p != map.end());
      gold_assert((*input_sections)[p->second].is_input_section());

      // Remember section order index of original input section
      // if it is set.  Copy it to the relaxed input section.
      unsigned int soi =
	(*input_sections)[p->second].section_order_index();
      (*input_sections)[p->second] = Input_section(poris);
      (*input_sections)[p->second].set_section_order_index(soi);
    }
}
  
// Convert regular input sections into relaxed input sections. RELAXED_SECTIONS
// is a vector of pointers to Output_relaxed_input_section or its derived
// classes.  The relaxed sections must correspond to existing input sections.

void
Output_section::convert_input_sections_to_relaxed_sections(
  const std::vector<Output_relaxed_input_section*>& relaxed_sections)
{
  gold_assert(parameters->target().may_relax());

  // We want to make sure that restore_states does not undo the effect of
  // this.  If there is no checkpoint active, just search the current
  // input section list and replace the sections there.  If there is
  // a checkpoint, also replace the sections there.
  
  // By default, we look at the whole list.
  size_t limit = this->input_sections_.size();

  if (this->checkpoint_ != NULL)
    {
      // Replace input sections with relaxed input section in the saved
      // copy of the input section list.
      if (this->checkpoint_->input_sections_saved())
	{
	  Relaxation_map map;
	  this->build_relaxation_map(
		    *(this->checkpoint_->input_sections()),
		    this->checkpoint_->input_sections()->size(),
		    &map);
	  this->convert_input_sections_in_list_to_relaxed_sections(
		    relaxed_sections,
		    map,
		    this->checkpoint_->input_sections());
	}
      else
	{
	  // We have not copied the input section list yet.  Instead, just
	  // look at the portion that would be saved.
	  limit = this->checkpoint_->input_sections_size();
	}
    }

  // Convert input sections in input_section_list.
  Relaxation_map map;
  this->build_relaxation_map(this->input_sections_, limit, &map);
  this->convert_input_sections_in_list_to_relaxed_sections(
	    relaxed_sections,
	    map,
	    &this->input_sections_);

  // Update fast look-up map.
  if (this->lookup_maps_->is_valid())
    for (size_t i = 0; i < relaxed_sections.size(); ++i)
      {
	Output_relaxed_input_section* poris = relaxed_sections[i];
	this->lookup_maps_->add_relaxed_input_section(poris->relobj(),
						      poris->shndx(), poris);
      }
}

// Update the output section flags based on input section flags.

void
Output_section::update_flags_for_input_section(elfcpp::Elf_Xword flags)
{
  // If we created the section with SHF_ALLOC clear, we set the
  // address.  If we are now setting the SHF_ALLOC flag, we need to
  // undo that.
  if ((this->flags_ & elfcpp::SHF_ALLOC) == 0
      && (flags & elfcpp::SHF_ALLOC) != 0)
    this->mark_address_invalid();

  this->flags_ |= (flags
		   & (elfcpp::SHF_WRITE
		      | elfcpp::SHF_ALLOC
		      | elfcpp::SHF_EXECINSTR));

  if ((flags & elfcpp::SHF_MERGE) == 0)
    this->flags_ &=~ elfcpp::SHF_MERGE;
  else
    {
      if (this->current_data_size_for_child() == 0)
	this->flags_ |= elfcpp::SHF_MERGE;
    }

  if ((flags & elfcpp::SHF_STRINGS) == 0)
    this->flags_ &=~ elfcpp::SHF_STRINGS;
  else
    {
      if (this->current_data_size_for_child() == 0)
	this->flags_ |= elfcpp::SHF_STRINGS;
    }
}

// Find the merge section into which an input section with index SHNDX in
// OBJECT has been added.  Return NULL if none found.

Output_section_data*
Output_section::find_merge_section(const Relobj* object,
				   unsigned int shndx) const
{
  if (!this->lookup_maps_->is_valid())
    this->build_lookup_maps();
  return this->lookup_maps_->find_merge_section(object, shndx);
}

// Build the lookup maps for merge and relaxed sections.  This is needs
// to be declared as a const methods so that it is callable with a const
// Output_section pointer.  The method only updates states of the maps.

void
Output_section::build_lookup_maps() const
{
  this->lookup_maps_->clear();
  for (Input_section_list::const_iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      if (p->is_merge_section())
	{
	  Output_merge_base* pomb = p->output_merge_base();
	  Merge_section_properties msp(pomb->is_string(), pomb->entsize(),
				       pomb->addralign());
	  this->lookup_maps_->add_merge_section(msp, pomb);
	  for (Output_merge_base::Input_sections::const_iterator is =
		 pomb->input_sections_begin();
	       is != pomb->input_sections_end();
	       ++is) 
	    {
	      const Const_section_id& csid = *is;
	    this->lookup_maps_->add_merge_input_section(csid.first,
							csid.second, pomb);
	    }
	    
	}
      else if (p->is_relaxed_input_section())
	{
	  Output_relaxed_input_section* poris = p->relaxed_input_section();
	  this->lookup_maps_->add_relaxed_input_section(poris->relobj(),
							poris->shndx(), poris);
	}
    }
}

// Find an relaxed input section corresponding to an input section
// in OBJECT with index SHNDX.

const Output_relaxed_input_section*
Output_section::find_relaxed_input_section(const Relobj* object,
					   unsigned int shndx) const
{
  if (!this->lookup_maps_->is_valid())
    this->build_lookup_maps();
  return this->lookup_maps_->find_relaxed_input_section(object, shndx);
}

// Given an address OFFSET relative to the start of input section
// SHNDX in OBJECT, return whether this address is being included in
// the final link.  This should only be called if SHNDX in OBJECT has
// a special mapping.

bool
Output_section::is_input_address_mapped(const Relobj* object,
					unsigned int shndx,
					off_t offset) const
{
  // Look at the Output_section_data_maps first.
  const Output_section_data* posd = this->find_merge_section(object, shndx);
  if (posd == NULL)
    posd = this->find_relaxed_input_section(object, shndx);

  if (posd != NULL)
    {
      section_offset_type output_offset;
      bool found = posd->output_offset(object, shndx, offset, &output_offset);
      gold_assert(found);   
      return output_offset != -1;
    }

  // Fall back to the slow look-up.
  for (Input_section_list::const_iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      section_offset_type output_offset;
      if (p->output_offset(object, shndx, offset, &output_offset))
	return output_offset != -1;
    }

  // By default we assume that the address is mapped.  This should
  // only be called after we have passed all sections to Layout.  At
  // that point we should know what we are discarding.
  return true;
}

// Given an address OFFSET relative to the start of input section
// SHNDX in object OBJECT, return the output offset relative to the
// start of the input section in the output section.  This should only
// be called if SHNDX in OBJECT has a special mapping.

section_offset_type
Output_section::output_offset(const Relobj* object, unsigned int shndx,
			      section_offset_type offset) const
{
  // This can only be called meaningfully when we know the data size
  // of this.
  gold_assert(this->is_data_size_valid());

  // Look at the Output_section_data_maps first.
  const Output_section_data* posd = this->find_merge_section(object, shndx);
  if (posd == NULL) 
    posd = this->find_relaxed_input_section(object, shndx);
  if (posd != NULL)
    {
      section_offset_type output_offset;
      bool found = posd->output_offset(object, shndx, offset, &output_offset);
      gold_assert(found);   
      return output_offset;
    }

  // Fall back to the slow look-up.
  for (Input_section_list::const_iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      section_offset_type output_offset;
      if (p->output_offset(object, shndx, offset, &output_offset))
	return output_offset;
    }
  gold_unreachable();
}

// Return the output virtual address of OFFSET relative to the start
// of input section SHNDX in object OBJECT.

uint64_t
Output_section::output_address(const Relobj* object, unsigned int shndx,
			       off_t offset) const
{
  uint64_t addr = this->address() + this->first_input_offset_;

  // Look at the Output_section_data_maps first.
  const Output_section_data* posd = this->find_merge_section(object, shndx);
  if (posd == NULL) 
    posd = this->find_relaxed_input_section(object, shndx);
  if (posd != NULL && posd->is_address_valid())
    {
      section_offset_type output_offset;
      bool found = posd->output_offset(object, shndx, offset, &output_offset);
      gold_assert(found);
      return posd->address() + output_offset;
    }

  // Fall back to the slow look-up.
  for (Input_section_list::const_iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      addr = align_address(addr, p->addralign());
      section_offset_type output_offset;
      if (p->output_offset(object, shndx, offset, &output_offset))
	{
	  if (output_offset == -1)
	    return -1ULL;
	  return addr + output_offset;
	}
      addr += p->data_size();
    }

  // If we get here, it means that we don't know the mapping for this
  // input section.  This might happen in principle if
  // add_input_section were called before add_output_section_data.
  // But it should never actually happen.

  gold_unreachable();
}

// Find the output address of the start of the merged section for
// input section SHNDX in object OBJECT.

bool
Output_section::find_starting_output_address(const Relobj* object,
					     unsigned int shndx,
					     uint64_t* paddr) const
{
  // FIXME: This becomes a bottle-neck if we have many relaxed sections.
  // Looking up the merge section map does not always work as we sometimes
  // find a merge section without its address set.
  uint64_t addr = this->address() + this->first_input_offset_;
  for (Input_section_list::const_iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      addr = align_address(addr, p->addralign());

      // It would be nice if we could use the existing output_offset
      // method to get the output offset of input offset 0.
      // Unfortunately we don't know for sure that input offset 0 is
      // mapped at all.
      if (p->is_merge_section_for(object, shndx))
	{
	  *paddr = addr;
	  return true;
	}

      addr += p->data_size();
    }

  // We couldn't find a merge output section for this input section.
  return false;
}

// Update the data size of an Output_section.

void
Output_section::update_data_size()
{
  if (this->input_sections_.empty())
      return;

  if (this->must_sort_attached_input_sections()
      || this->input_section_order_specified())
    this->sort_attached_input_sections();

  off_t off = this->first_input_offset_;
  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      off = align_address(off, p->addralign());
      off += p->current_data_size();
    }

  this->set_current_data_size_for_child(off);
}

// Set the data size of an Output_section.  This is where we handle
// setting the addresses of any Output_section_data objects.

void
Output_section::set_final_data_size()
{
  off_t data_size;

  if (this->input_sections_.empty())
    data_size = this->current_data_size_for_child();
  else
    {
      if (this->must_sort_attached_input_sections()
	  || this->input_section_order_specified())
	this->sort_attached_input_sections();

      uint64_t address = this->address();
      off_t startoff = this->offset();
      off_t off = startoff + this->first_input_offset_;
      for (Input_section_list::iterator p = this->input_sections_.begin();
	   p != this->input_sections_.end();
	   ++p)
	{
	  off = align_address(off, p->addralign());
	  p->set_address_and_file_offset(address + (off - startoff), off,
					 startoff);
	  off += p->data_size();
	}
      data_size = off - startoff;
    }

  // For full incremental links, we want to allocate some patch space
  // in most sections for subsequent incremental updates.
  if (this->is_patch_space_allowed_ && parameters->incremental_full())
    {
      double pct = parameters->options().incremental_patch();
      size_t extra = static_cast<size_t>(data_size * pct);
      if (this->free_space_fill_ != NULL
          && this->free_space_fill_->minimum_hole_size() > extra)
	extra = this->free_space_fill_->minimum_hole_size();
      off_t new_size = align_address(data_size + extra, this->addralign());
      this->patch_space_ = new_size - data_size;
      gold_debug(DEBUG_INCREMENTAL,
		 "set_final_data_size: %08lx + %08lx: section %s",
		 static_cast<long>(data_size),
		 static_cast<long>(this->patch_space_),
		 this->name());
      data_size = new_size;
    }

  this->set_data_size(data_size);
}

// Reset the address and file offset.

void
Output_section::do_reset_address_and_file_offset()
{
  // An unallocated section has no address.  Forcing this means that
  // we don't need special treatment for symbols defined in debug
  // sections.  We do the same in the constructor.  This does not
  // apply to NOLOAD sections though.
  if (((this->flags_ & elfcpp::SHF_ALLOC) == 0) && !this->is_noload_)
     this->set_address(0);

  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    p->reset_address_and_file_offset();

  // Remove any patch space that was added in set_final_data_size.
  if (this->patch_space_ > 0)
    {
      this->set_current_data_size_for_child(this->current_data_size_for_child()
					    - this->patch_space_);
      this->patch_space_ = 0;
    }
}

// Return true if address and file offset have the values after reset.

bool
Output_section::do_address_and_file_offset_have_reset_values() const
{
  if (this->is_offset_valid())
    return false;

  // An unallocated section has address 0 after its construction or a reset.
  if ((this->flags_ & elfcpp::SHF_ALLOC) == 0)
    return this->is_address_valid() && this->address() == 0;
  else
    return !this->is_address_valid();
}

// Set the TLS offset.  Called only for SHT_TLS sections.

void
Output_section::do_set_tls_offset(uint64_t tls_base)
{
  this->tls_offset_ = this->address() - tls_base;
}

// In a few cases we need to sort the input sections attached to an
// output section.  This is used to implement the type of constructor
// priority ordering implemented by the GNU linker, in which the
// priority becomes part of the section name and the sections are
// sorted by name.  We only do this for an output section if we see an
// attached input section matching ".ctors.*", ".dtors.*",
// ".init_array.*" or ".fini_array.*".

class Output_section::Input_section_sort_entry
{
 public:
  Input_section_sort_entry()
    : input_section_(), index_(-1U), section_has_name_(false),
      section_name_()
  { }

  Input_section_sort_entry(const Input_section& input_section,
			   unsigned int index,
			   bool must_sort_attached_input_sections)
    : input_section_(input_section), index_(index),
      section_has_name_(input_section.is_input_section()
			|| input_section.is_relaxed_input_section())
  {
    if (this->section_has_name_
        && must_sort_attached_input_sections)
      {
	// This is only called single-threaded from Layout::finalize,
	// so it is OK to lock.  Unfortunately we have no way to pass
	// in a Task token.
	const Task* dummy_task = reinterpret_cast<const Task*>(-1);
	Object* obj = (input_section.is_input_section()
		       ? input_section.relobj()
		       : input_section.relaxed_input_section()->relobj());
	Task_lock_obj<Object> tl(dummy_task, obj);

	// This is a slow operation, which should be cached in
	// Layout::layout if this becomes a speed problem.
	this->section_name_ = obj->section_name(input_section.shndx());
      }
  }

  // Return the Input_section.
  const Input_section&
  input_section() const
  {
    gold_assert(this->index_ != -1U);
    return this->input_section_;
  }

  // The index of this entry in the original list.  This is used to
  // make the sort stable.
  unsigned int
  index() const
  {
    gold_assert(this->index_ != -1U);
    return this->index_;
  }

  // Whether there is a section name.
  bool
  section_has_name() const
  { return this->section_has_name_; }

  // The section name.
  const std::string&
  section_name() const
  {
    gold_assert(this->section_has_name_);
    return this->section_name_;
  }

  // Return true if the section name has a priority.  This is assumed
  // to be true if it has a dot after the initial dot.
  bool
  has_priority() const
  {
    gold_assert(this->section_has_name_);
    return this->section_name_.find('.', 1) != std::string::npos;
  }

  // Return the priority.  Believe it or not, gcc encodes the priority
  // differently for .ctors/.dtors and .init_array/.fini_array
  // sections.
  unsigned int
  get_priority() const
  {
    gold_assert(this->section_has_name_);
    bool is_ctors;
    if (is_prefix_of(".ctors.", this->section_name_.c_str())
	|| is_prefix_of(".dtors.", this->section_name_.c_str()))
      is_ctors = true;
    else if (is_prefix_of(".init_array.", this->section_name_.c_str())
	     || is_prefix_of(".fini_array.", this->section_name_.c_str()))
      is_ctors = false;
    else
      return 0;
    char* end;
    unsigned long prio = strtoul((this->section_name_.c_str()
				  + (is_ctors ? 7 : 12)),
				 &end, 10);
    if (*end != '\0')
      return 0;
    else if (is_ctors)
      return 65535 - prio;
    else
      return prio;
  }

  // Return true if this 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
  match_file_name(const char* file_name) const
  { return Layout::match_file_name(this->input_section_.relobj(), file_name); }

  // Returns 1 if THIS should appear before S in section order, -1 if S
  // appears before THIS and 0 if they are not comparable.
  int
  compare_section_ordering(const Input_section_sort_entry& s) const
  {
    unsigned int this_secn_index = this->input_section_.section_order_index();
    unsigned int s_secn_index = s.input_section().section_order_index();
    if (this_secn_index > 0 && s_secn_index > 0)
      {
        if (this_secn_index < s_secn_index)
          return 1;
        else if (this_secn_index > s_secn_index)
          return -1;
      }
    return 0;
  }

 private:
  // The Input_section we are sorting.
  Input_section input_section_;
  // The index of this Input_section in the original list.
  unsigned int index_;
  // Whether this Input_section has a section name--it won't if this
  // is some random Output_section_data.
  bool section_has_name_;
  // The section name if there is one.
  std::string section_name_;
};

// Return true if S1 should come before S2 in the output section.

bool
Output_section::Input_section_sort_compare::operator()(
    const Output_section::Input_section_sort_entry& s1,
    const Output_section::Input_section_sort_entry& s2) const
{
  // crtbegin.o must come first.
  bool s1_begin = s1.match_file_name("crtbegin");
  bool s2_begin = s2.match_file_name("crtbegin");
  if (s1_begin || s2_begin)
    {
      if (!s1_begin)
	return false;
      if (!s2_begin)
	return true;
      return s1.index() < s2.index();
    }

  // crtend.o must come last.
  bool s1_end = s1.match_file_name("crtend");
  bool s2_end = s2.match_file_name("crtend");
  if (s1_end || s2_end)
    {
      if (!s1_end)
	return true;
      if (!s2_end)
	return false;
      return s1.index() < s2.index();
    }

  // We sort all the sections with no names to the end.
  if (!s1.section_has_name() || !s2.section_has_name())
    {
      if (s1.section_has_name())
	return true;
      if (s2.section_has_name())
	return false;
      return s1.index() < s2.index();
    }

  // A section with a priority follows a section without a priority.
  bool s1_has_priority = s1.has_priority();
  bool s2_has_priority = s2.has_priority();
  if (s1_has_priority && !s2_has_priority)
    return false;
  if (!s1_has_priority && s2_has_priority)
    return true;

  // Check if a section order exists for these sections through a section
  // ordering file.  If sequence_num is 0, an order does not exist.
  int sequence_num = s1.compare_section_ordering(s2);
  if (sequence_num != 0)
    return sequence_num == 1;

  // Otherwise we sort by name.
  int compare = s1.section_name().compare(s2.section_name());
  if (compare != 0)
    return compare < 0;

  // Otherwise we keep the input order.
  return s1.index() < s2.index();
}

// Return true if S1 should come before S2 in an .init_array or .fini_array
// output section.

bool
Output_section::Input_section_sort_init_fini_compare::operator()(
    const Output_section::Input_section_sort_entry& s1,
    const Output_section::Input_section_sort_entry& s2) const
{
  // We sort all the sections with no names to the end.
  if (!s1.section_has_name() || !s2.section_has_name())
    {
      if (s1.section_has_name())
	return true;
      if (s2.section_has_name())
	return false;
      return s1.index() < s2.index();
    }

  // A section without a priority follows a section with a priority.
  // This is the reverse of .ctors and .dtors sections.
  bool s1_has_priority = s1.has_priority();
  bool s2_has_priority = s2.has_priority();
  if (s1_has_priority && !s2_has_priority)
    return true;
  if (!s1_has_priority && s2_has_priority)
    return false;

  // .ctors and .dtors sections without priority come after
  // .init_array and .fini_array sections without priority.
  if (!s1_has_priority
      && (s1.section_name() == ".ctors" || s1.section_name() == ".dtors")
      && s1.section_name() != s2.section_name())
    return false;
  if (!s2_has_priority
      && (s2.section_name() == ".ctors" || s2.section_name() == ".dtors")
      && s2.section_name() != s1.section_name())
    return true;

  // Sort by priority if we can.
  if (s1_has_priority)
    {
      unsigned int s1_prio = s1.get_priority();
      unsigned int s2_prio = s2.get_priority();
      if (s1_prio < s2_prio)
	return true;
      else if (s1_prio > s2_prio)
	return false;
    }

  // Check if a section order exists for these sections through a section
  // ordering file.  If sequence_num is 0, an order does not exist.
  int sequence_num = s1.compare_section_ordering(s2);
  if (sequence_num != 0)
    return sequence_num == 1;

  // Otherwise we sort by name.
  int compare = s1.section_name().compare(s2.section_name());
  if (compare != 0)
    return compare < 0;

  // Otherwise we keep the input order.
  return s1.index() < s2.index();
}

// Return true if S1 should come before S2.  Sections that do not match
// any pattern in the section ordering file are placed ahead of the sections
// that match some pattern.

bool
Output_section::Input_section_sort_section_order_index_compare::operator()(
    const Output_section::Input_section_sort_entry& s1,
    const Output_section::Input_section_sort_entry& s2) const
{
  unsigned int s1_secn_index = s1.input_section().section_order_index();
  unsigned int s2_secn_index = s2.input_section().section_order_index();

  // Keep input order if section ordering cannot determine order.
  if (s1_secn_index == s2_secn_index)
    return s1.index() < s2.index();
  
  return s1_secn_index < s2_secn_index;
}

// This updates the section order index of input sections according to the
// the order specified in the mapping from Section id to order index.

void
Output_section::update_section_layout(
  const Section_layout_order* order_map)
{
  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      if (p->is_input_section()
	  || p->is_relaxed_input_section())
        {
	  Object* obj = (p->is_input_section()
			 ? p->relobj()
		         : p->relaxed_input_section()->relobj());
	  unsigned int shndx = p->shndx();
	  Section_layout_order::const_iterator it
	    = order_map->find(Section_id(obj, shndx));
	  if (it == order_map->end())
	    continue;
	  unsigned int section_order_index = it->second;
	  if (section_order_index != 0)
            {
              p->set_section_order_index(section_order_index);
              this->set_input_section_order_specified();
	    }
        }
    }
}

// Sort the input sections attached to an output section.

void
Output_section::sort_attached_input_sections()
{
  if (this->attached_input_sections_are_sorted_)
    return;

  if (this->checkpoint_ != NULL
      && !this->checkpoint_->input_sections_saved())
    this->checkpoint_->save_input_sections();

  // The only thing we know about an input section is the object and
  // the section index.  We need the section name.  Recomputing this
  // is slow but this is an unusual case.  If this becomes a speed
  // problem we can cache the names as required in Layout::layout.

  // We start by building a larger vector holding a copy of each
  // Input_section, plus its current index in the list and its name.
  std::vector<Input_section_sort_entry> sort_list;

  unsigned int i = 0;
  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p, ++i)
      sort_list.push_back(Input_section_sort_entry(*p, i,
                            this->must_sort_attached_input_sections()));

  // Sort the input sections.
  if (this->must_sort_attached_input_sections())
    {
      if (this->type() == elfcpp::SHT_PREINIT_ARRAY
          || this->type() == elfcpp::SHT_INIT_ARRAY
          || this->type() == elfcpp::SHT_FINI_ARRAY)
        std::sort(sort_list.begin(), sort_list.end(),
	          Input_section_sort_init_fini_compare());
      else
        std::sort(sort_list.begin(), sort_list.end(),
	          Input_section_sort_compare());
    }
  else
    {
      gold_assert(this->input_section_order_specified());
      std::sort(sort_list.begin(), sort_list.end(),
	        Input_section_sort_section_order_index_compare());
    }

  // Copy the sorted input sections back to our list.
  this->input_sections_.clear();
  for (std::vector<Input_section_sort_entry>::iterator p = sort_list.begin();
       p != sort_list.end();
       ++p)
    this->input_sections_.push_back(p->input_section());
  sort_list.clear();

  // Remember that we sorted the input sections, since we might get
  // called again.
  this->attached_input_sections_are_sorted_ = true;
}

// Write the section header to *OSHDR.

template<int size, bool big_endian>
void
Output_section::write_header(const Layout* layout,
			     const Stringpool* secnamepool,
			     elfcpp::Shdr_write<size, big_endian>* oshdr) const
{
  oshdr->put_sh_name(secnamepool->get_offset(this->name_));
  oshdr->put_sh_type(this->type_);

  elfcpp::Elf_Xword flags = this->flags_;
  if (this->info_section_ != NULL && this->info_uses_section_index_)
    flags |= elfcpp::SHF_INFO_LINK;
  oshdr->put_sh_flags(flags);

  oshdr->put_sh_addr(this->address());
  oshdr->put_sh_offset(this->offset());
  oshdr->put_sh_size(this->data_size());
  if (this->link_section_ != NULL)
    oshdr->put_sh_link(this->link_section_->out_shndx());
  else if (this->should_link_to_symtab_)
    oshdr->put_sh_link(layout->symtab_section_shndx());
  else if (this->should_link_to_dynsym_)
    oshdr->put_sh_link(layout->dynsym_section()->out_shndx());
  else
    oshdr->put_sh_link(this->link_);

  elfcpp::Elf_Word info;
  if (this->info_section_ != NULL)
    {
      if (this->info_uses_section_index_)
	info = this->info_section_->out_shndx();
      else
	info = this->info_section_->symtab_index();
    }
  else if (this->info_symndx_ != NULL)
    info = this->info_symndx_->symtab_index();
  else
    info = this->info_;
  oshdr->put_sh_info(info);

  oshdr->put_sh_addralign(this->addralign_);
  oshdr->put_sh_entsize(this->entsize_);
}

// Write out the data.  For input sections the data is written out by
// Object::relocate, but we have to handle Output_section_data objects
// here.

void
Output_section::do_write(Output_file* of)
{
  gold_assert(!this->requires_postprocessing());

  // If the target performs relaxation, we delay filler generation until now.
  gold_assert(!this->generate_code_fills_at_write_ || this->fills_.empty());

  off_t output_section_file_offset = this->offset();
  for (Fill_list::iterator p = this->fills_.begin();
       p != this->fills_.end();
       ++p)
    {
      std::string fill_data(parameters->target().code_fill(p->length()));
      of->write(output_section_file_offset + p->section_offset(),
		fill_data.data(), fill_data.size());
    }

  off_t off = this->offset() + this->first_input_offset_;
  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      off_t aligned_off = align_address(off, p->addralign());
      if (this->generate_code_fills_at_write_ && (off != aligned_off))
	{
	  size_t fill_len = aligned_off - off;
	  std::string fill_data(parameters->target().code_fill(fill_len));
	  of->write(off, fill_data.data(), fill_data.size());
	}

      p->write(of);
      off = aligned_off + p->data_size();
    }

  // For incremental links, fill in unused chunks in debug sections
  // with dummy compilation unit headers.
  if (this->free_space_fill_ != NULL)
    {
      for (Free_list::Const_iterator p = this->free_list_.begin();
	   p != this->free_list_.end();
	   ++p)
	{
	  off_t off = p->start_;
	  size_t len = p->end_ - off;
	  this->free_space_fill_->write(of, this->offset() + off, len);
	}
      if (this->patch_space_ > 0)
	{
	  off_t off = this->current_data_size_for_child() - this->patch_space_;
	  this->free_space_fill_->write(of, this->offset() + off,
					this->patch_space_);
	}
    }
}

// If a section requires postprocessing, create the buffer to use.

void
Output_section::create_postprocessing_buffer()
{
  gold_assert(this->requires_postprocessing());

  if (this->postprocessing_buffer_ != NULL)
    return;

  if (!this->input_sections_.empty())
    {
      off_t off = this->first_input_offset_;
      for (Input_section_list::iterator p = this->input_sections_.begin();
	   p != this->input_sections_.end();
	   ++p)
	{
	  off = align_address(off, p->addralign());
	  p->finalize_data_size();
	  off += p->data_size();
	}
      this->set_current_data_size_for_child(off);
    }

  off_t buffer_size = this->current_data_size_for_child();
  this->postprocessing_buffer_ = new unsigned char[buffer_size];
}

// Write all the data of an Output_section into the postprocessing
// buffer.  This is used for sections which require postprocessing,
// such as compression.  Input sections are handled by
// Object::Relocate.

void
Output_section::write_to_postprocessing_buffer()
{
  gold_assert(this->requires_postprocessing());

  // If the target performs relaxation, we delay filler generation until now.
  gold_assert(!this->generate_code_fills_at_write_ || this->fills_.empty());

  unsigned char* buffer = this->postprocessing_buffer();
  for (Fill_list::iterator p = this->fills_.begin();
       p != this->fills_.end();
       ++p)
    {
      std::string fill_data(parameters->target().code_fill(p->length()));
      memcpy(buffer + p->section_offset(), fill_data.data(),
	     fill_data.size());
    }

  off_t off = this->first_input_offset_;
  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      off_t aligned_off = align_address(off, p->addralign());
      if (this->generate_code_fills_at_write_ && (off != aligned_off))
	{
	  size_t fill_len = aligned_off - off;
	  std::string fill_data(parameters->target().code_fill(fill_len));
	  memcpy(buffer + off, fill_data.data(), fill_data.size());
	}

      p->write_to_buffer(buffer + aligned_off);
      off = aligned_off + p->data_size();
    }
}

// Get the input sections for linker script processing.  We leave
// behind the Output_section_data entries.  Note that this may be
// slightly incorrect for merge sections.  We will leave them behind,
// but it is possible that the script says that they should follow
// some other input sections, as in:
//    .rodata { *(.rodata) *(.rodata.cst*) }
// For that matter, we don't handle this correctly:
//    .rodata { foo.o(.rodata.cst*) *(.rodata.cst*) }
// With luck this will never matter.

uint64_t
Output_section::get_input_sections(
    uint64_t address,
    const std::string& fill,
    std::list<Input_section>* input_sections)
{
  if (this->checkpoint_ != NULL
      && !this->checkpoint_->input_sections_saved())
    this->checkpoint_->save_input_sections();

  // Invalidate fast look-up maps.
  this->lookup_maps_->invalidate();

  uint64_t orig_address = address;

  address = align_address(address, this->addralign());

  Input_section_list remaining;
  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      if (p->is_input_section()
	  || p->is_relaxed_input_section()
	  || p->is_merge_section())
	input_sections->push_back(*p);
      else
	{
	  uint64_t aligned_address = align_address(address, p->addralign());
	  if (aligned_address != address && !fill.empty())
	    {
	      section_size_type length =
		convert_to_section_size_type(aligned_address - address);
	      std::string this_fill;
	      this_fill.reserve(length);
	      while (this_fill.length() + fill.length() <= length)
		this_fill += fill;
	      if (this_fill.length() < length)
		this_fill.append(fill, 0, length - this_fill.length());

	      Output_section_data* posd = new Output_data_const(this_fill, 0);
	      remaining.push_back(Input_section(posd));
	    }
	  address = aligned_address;

	  remaining.push_back(*p);

	  p->finalize_data_size();
	  address += p->data_size();
	}
    }

  this->input_sections_.swap(remaining);
  this->first_input_offset_ = 0;

  uint64_t data_size = address - orig_address;
  this->set_current_data_size_for_child(data_size);
  return data_size;
}

// Add a script input section.  SIS is an Output_section::Input_section,
// which can be either a plain input section or a special input section like
// a relaxed input section.  For a special input section, its size must be
// finalized.

void
Output_section::add_script_input_section(const Input_section& sis)
{
  uint64_t data_size = sis.data_size();
  uint64_t addralign = sis.addralign();
  if (addralign > this->addralign_)
    this->addralign_ = addralign;

  off_t offset_in_section = this->current_data_size_for_child();
  off_t aligned_offset_in_section = align_address(offset_in_section,
						  addralign);

  this->set_current_data_size_for_child(aligned_offset_in_section
					+ data_size);

  this->input_sections_.push_back(sis);

  // Update fast lookup maps if necessary. 
  if (this->lookup_maps_->is_valid())
    {
      if (sis.is_merge_section())
	{
	  Output_merge_base* pomb = sis.output_merge_base();
	  Merge_section_properties msp(pomb->is_string(), pomb->entsize(),
				       pomb->addralign());
	  this->lookup_maps_->add_merge_section(msp, pomb);
	  for (Output_merge_base::Input_sections::const_iterator p =
		 pomb->input_sections_begin();
	       p != pomb->input_sections_end();
	       ++p)
	    this->lookup_maps_->add_merge_input_section(p->first, p->second,
							pomb);
	}
      else if (sis.is_relaxed_input_section())
	{
	  Output_relaxed_input_section* poris = sis.relaxed_input_section();
	  this->lookup_maps_->add_relaxed_input_section(poris->relobj(),
							poris->shndx(), poris);
	}
    }
}

// Save states for relaxation.

void
Output_section::save_states()
{
  gold_assert(this->checkpoint_ == NULL);
  Checkpoint_output_section* checkpoint =
    new Checkpoint_output_section(this->addralign_, this->flags_,
				  this->input_sections_,
				  this->first_input_offset_,
				  this->attached_input_sections_are_sorted_);
  this->checkpoint_ = checkpoint;
  gold_assert(this->fills_.empty());
}

void
Output_section::discard_states()
{
  gold_assert(this->checkpoint_ != NULL);
  delete this->checkpoint_;
  this->checkpoint_ = NULL;
  gold_assert(this->fills_.empty());

  // Simply invalidate the fast lookup maps since we do not keep
  // track of them.
  this->lookup_maps_->invalidate();
}

void
Output_section::restore_states()
{
  gold_assert(this->checkpoint_ != NULL);
  Checkpoint_output_section* checkpoint = this->checkpoint_;

  this->addralign_ = checkpoint->addralign();
  this->flags_ = checkpoint->flags();
  this->first_input_offset_ = checkpoint->first_input_offset();

  if (!checkpoint->input_sections_saved())
    {
      // If we have not copied the input sections, just resize it.
      size_t old_size = checkpoint->input_sections_size();
      gold_assert(this->input_sections_.size() >= old_size);
      this->input_sections_.resize(old_size);
    }
  else
    {
      // We need to copy the whole list.  This is not efficient for
      // extremely large output with hundreads of thousands of input
      // objects.  We may need to re-think how we should pass sections
      // to scripts.
      this->input_sections_ = *checkpoint->input_sections();
    }

  this->attached_input_sections_are_sorted_ =
    checkpoint->attached_input_sections_are_sorted();

  // Simply invalidate the fast lookup maps since we do not keep
  // track of them.
  this->lookup_maps_->invalidate();
}

// Update the section offsets of input sections in this.  This is required if
// relaxation causes some input sections to change sizes.

void
Output_section::adjust_section_offsets()
{
  if (!this->section_offsets_need_adjustment_)
    return;

  off_t off = 0;
  for (Input_section_list::iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    {
      off = align_address(off, p->addralign());
      if (p->is_input_section())
	p->relobj()->set_section_offset(p->shndx(), off);
      off += p->data_size();
    }

  this->section_offsets_need_adjustment_ = false;
}

// Print to the map file.

void
Output_section::do_print_to_mapfile(Mapfile* mapfile) const
{
  mapfile->print_output_section(this);

  for (Input_section_list::const_iterator p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    p->print_to_mapfile(mapfile);
}

// Print stats for merge sections to stderr.

void
Output_section::print_merge_stats()
{
  Input_section_list::iterator p;
  for (p = this->input_sections_.begin();
       p != this->input_sections_.end();
       ++p)
    p->print_merge_stats(this->name_);
}

// Set a fixed layout for the section.  Used for incremental update links.

void
Output_section::set_fixed_layout(uint64_t sh_addr, off_t sh_offset,
				 off_t sh_size, uint64_t sh_addralign)
{
  this->addralign_ = sh_addralign;
  this->set_current_data_size(sh_size);
  if ((this->flags_ & elfcpp::SHF_ALLOC) != 0)
    this->set_address(sh_addr);
  this->set_file_offset(sh_offset);
  this->finalize_data_size();
  this->free_list_.init(sh_size, false);
  this->has_fixed_layout_ = true;
}

// Reserve space within the fixed layout for the section.  Used for
// incremental update links.

void
Output_section::reserve(uint64_t sh_offset, uint64_t sh_size)
{
  this->free_list_.remove(sh_offset, sh_offset + sh_size);
}

// Allocate space from the free list for the section.  Used for
// incremental update links.

off_t
Output_section::allocate(off_t len, uint64_t addralign)
{
  return this->free_list_.allocate(len, addralign, 0);
}

// Output segment methods.

Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
  : vaddr_(0),
    paddr_(0),
    memsz_(0),
    max_align_(0),
    min_p_align_(0),
    offset_(0),
    filesz_(0),
    type_(type),
    flags_(flags),
    is_max_align_known_(false),
    are_addresses_set_(false),
    is_large_data_segment_(false)
{
  // The ELF ABI specifies that a PT_TLS segment always has PF_R as
  // the flags.
  if (type == elfcpp::PT_TLS)
    this->flags_ = elfcpp::PF_R;
}

// Add an Output_section to a PT_LOAD Output_segment.

void
Output_segment::add_output_section_to_load(Layout* layout,
					   Output_section* os,
					   elfcpp::Elf_Word seg_flags)
{
  gold_assert(this->type() == elfcpp::PT_LOAD);
  gold_assert((os->flags() & elfcpp::SHF_ALLOC) != 0);
  gold_assert(!this->is_max_align_known_);
  gold_assert(os->is_large_data_section() == this->is_large_data_segment());

  this->update_flags_for_output_section(seg_flags);

  // We don't want to change the ordering if we have a linker script
  // with a SECTIONS clause.
  Output_section_order order = os->order();
  if (layout->script_options()->saw_sections_clause())
    order = static_cast<Output_section_order>(0);
  else
    gold_assert(order != ORDER_INVALID);

  this->output_lists_[order].push_back(os);
}

// Add an Output_section to a non-PT_LOAD Output_segment.

void
Output_segment::add_output_section_to_nonload(Output_section* os,
					      elfcpp::Elf_Word seg_flags)
{
  gold_assert(this->type() != elfcpp::PT_LOAD);
  gold_assert((os->flags() & elfcpp::SHF_ALLOC) != 0);
  gold_assert(!this->is_max_align_known_);

  this->update_flags_for_output_section(seg_flags);

  this->output_lists_[0].push_back(os);
}

// Remove an Output_section from this segment.  It is an error if it
// is not present.

void
Output_segment::remove_output_section(Output_section* os)
{
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    {
      Output_data_list* pdl = &this->output_lists_[i];
      for (Output_data_list::iterator p = pdl->begin(); p != pdl->end(); ++p)
	{
	  if (*p == os)
	    {
	      pdl->erase(p);
	      return;
	    }
	}
    }
  gold_unreachable();
}

// Add an Output_data (which need not be an Output_section) to the
// start of a segment.

void
Output_segment::add_initial_output_data(Output_data* od)
{
  gold_assert(!this->is_max_align_known_);
  Output_data_list::iterator p = this->output_lists_[0].begin();
  this->output_lists_[0].insert(p, od);
}

// Return true if this segment has any sections which hold actual
// data, rather than being a BSS section.

bool
Output_segment::has_any_data_sections() const
{
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    {
      const Output_data_list* pdl = &this->output_lists_[i];
      for (Output_data_list::const_iterator p = pdl->begin();
	   p != pdl->end();
	   ++p)
	{
	  if (!(*p)->is_section())
	    return true;
	  if ((*p)->output_section()->type() != elfcpp::SHT_NOBITS)
	    return true;
	}
    }
  return false;
}

// Return whether the first data section (not counting TLS sections)
// is a relro section.

bool
Output_segment::is_first_section_relro() const
{
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    {
      if (i == static_cast<int>(ORDER_TLS_DATA)
	  || i == static_cast<int>(ORDER_TLS_BSS))
	continue;
      const Output_data_list* pdl = &this->output_lists_[i];
      if (!pdl->empty())
	{
	  Output_data* p = pdl->front();
	  return p->is_section() && p->output_section()->is_relro();
	}
    }
  return false;
}

// Return the maximum alignment of the Output_data in Output_segment.

uint64_t
Output_segment::maximum_alignment()
{
  if (!this->is_max_align_known_)
    {
      for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
	{	
	  const Output_data_list* pdl = &this->output_lists_[i];
	  uint64_t addralign = Output_segment::maximum_alignment_list(pdl);
	  if (addralign > this->max_align_)
	    this->max_align_ = addralign;
	}
      this->is_max_align_known_ = true;
    }

  return this->max_align_;
}

// Return the maximum alignment of a list of Output_data.

uint64_t
Output_segment::maximum_alignment_list(const Output_data_list* pdl)
{
  uint64_t ret = 0;
  for (Output_data_list::const_iterator p = pdl->begin();
       p != pdl->end();
       ++p)
    {
      uint64_t addralign = (*p)->addralign();
      if (addralign > ret)
	ret = addralign;
    }
  return ret;
}

// Return whether this segment has any dynamic relocs.

bool
Output_segment::has_dynamic_reloc() const
{
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    if (this->has_dynamic_reloc_list(&this->output_lists_[i]))
      return true;
  return false;
}

// Return whether this Output_data_list has any dynamic relocs.

bool
Output_segment::has_dynamic_reloc_list(const Output_data_list* pdl) const
{
  for (Output_data_list::const_iterator p = pdl->begin();
       p != pdl->end();
       ++p)
    if ((*p)->has_dynamic_reloc())
      return true;
  return false;
}

// Set the section addresses for an Output_segment.  If RESET is true,
// reset the addresses first.  ADDR is the address and *POFF is the
// file offset.  Set the section indexes starting with *PSHNDX.
// INCREASE_RELRO is the size of the portion of the first non-relro
// section that should be included in the PT_GNU_RELRO segment.
// If this segment has relro sections, and has been aligned for
// that purpose, set *HAS_RELRO to TRUE.  Return the address of
// the immediately following segment.  Update *HAS_RELRO, *POFF,
// and *PSHNDX.

uint64_t
Output_segment::set_section_addresses(Layout* layout, bool reset,
                                      uint64_t addr,
				      unsigned int* increase_relro,
				      bool* has_relro,
				      off_t* poff,
				      unsigned int* pshndx)
{
  gold_assert(this->type_ == elfcpp::PT_LOAD);

  uint64_t last_relro_pad = 0;
  off_t orig_off = *poff;

  bool in_tls = false;

  // If we have relro sections, we need to pad forward now so that the
  // relro sections plus INCREASE_RELRO end on a common page boundary.
  if (parameters->options().relro()
      && this->is_first_section_relro()
      && (!this->are_addresses_set_ || reset))
    {
      uint64_t relro_size = 0;
      off_t off = *poff;
      uint64_t max_align = 0;
      for (int i = 0; i <= static_cast<int>(ORDER_RELRO_LAST); ++i)
	{
	  Output_data_list* pdl = &this->output_lists_[i];
	  Output_data_list::iterator p;
	  for (p = pdl->begin(); p != pdl->end(); ++p)
	    {
	      if (!(*p)->is_section())
		break;
	      uint64_t align = (*p)->addralign();
	      if (align > max_align)
		max_align = align;
	      if ((*p)->is_section_flag_set(elfcpp::SHF_TLS))
		in_tls = true;
	      else if (in_tls)
		{
		  // Align the first non-TLS section to the alignment
		  // of the TLS segment.
		  align = max_align;
		  in_tls = false;
		}
	      relro_size = align_address(relro_size, align);
	      // Ignore the size of the .tbss section.
	      if ((*p)->is_section_flag_set(elfcpp::SHF_TLS)
		  && (*p)->is_section_type(elfcpp::SHT_NOBITS))
		continue;
	      if ((*p)->is_address_valid())
		relro_size += (*p)->data_size();
	      else
		{
		  // FIXME: This could be faster.
		  (*p)->set_address_and_file_offset(addr + relro_size,
						    off + relro_size);
		  relro_size += (*p)->data_size();
		  (*p)->reset_address_and_file_offset();
		}
	    }
	  if (p != pdl->end())
	    break;
	}
      relro_size += *increase_relro;
      // Pad the total relro size to a multiple of the maximum
      // section alignment seen.
      uint64_t aligned_size = align_address(relro_size, max_align);
      // Note the amount of padding added after the last relro section.
      last_relro_pad = aligned_size - relro_size;
      *has_relro = true;

      uint64_t page_align = parameters->target().common_pagesize();

      // Align to offset N such that (N + RELRO_SIZE) % PAGE_ALIGN == 0.
      uint64_t desired_align = page_align - (aligned_size % page_align);
      if (desired_align < *poff % page_align)
	*poff += page_align - *poff % page_align;
      *poff += desired_align - *poff % page_align;
      addr += *poff - orig_off;
      orig_off = *poff;
    }

  if (!reset && this->are_addresses_set_)
    {
      gold_assert(this->paddr_ == addr);
      addr = this->vaddr_;
    }
  else
    {
      this->vaddr_ = addr;
      this->paddr_ = addr;
      this->are_addresses_set_ = true;
    }

  in_tls = false;

  this->offset_ = orig_off;

  off_t off = 0;
  uint64_t ret;
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    {
      if (i == static_cast<int>(ORDER_RELRO_LAST))
	{
	  *poff += last_relro_pad;
	  addr += last_relro_pad;
	  if (this->output_lists_[i].empty())
	    {
	      // If there is nothing in the ORDER_RELRO_LAST list,
	      // the padding will occur at the end of the relro
	      // segment, and we need to add it to *INCREASE_RELRO.
	      *increase_relro += last_relro_pad;
	    }
	}
      addr = this->set_section_list_addresses(layout, reset,
					      &this->output_lists_[i],
					      addr, poff, pshndx, &in_tls);
      if (i < static_cast<int>(ORDER_SMALL_BSS))
	{
	  this->filesz_ = *poff - orig_off;
	  off = *poff;
	}

      ret = addr;
    }

  // If the last section was a TLS section, align upward to the
  // alignment of the TLS segment, so that the overall size of the TLS
  // segment is aligned.
  if (in_tls)
    {
      uint64_t segment_align = layout->tls_segment()->maximum_alignment();
      *poff = align_address(*poff, segment_align);
    }

  this->memsz_ = *poff - orig_off;

  // Ignore the file offset adjustments made by the BSS Output_data
  // objects.
  *poff = off;

  return ret;
}

// Set the addresses and file offsets in a list of Output_data
// structures.

uint64_t
Output_segment::set_section_list_addresses(Layout* layout, bool reset,
                                           Output_data_list* pdl,
					   uint64_t addr, off_t* poff,
					   unsigned int* pshndx,
                                           bool* in_tls)
{
  off_t startoff = *poff;
  // For incremental updates, we may allocate non-fixed sections from
  // free space in the file.  This keeps track of the high-water mark.
  off_t maxoff = startoff;

  off_t off = startoff;
  for (Output_data_list::iterator p = pdl->begin();
       p != pdl->end();
       ++p)
    {
      if (reset)
	(*p)->reset_address_and_file_offset();

      // When doing an incremental update or when using a linker script,
      // the section will most likely already have an address.
      if (!(*p)->is_address_valid())
	{
          uint64_t align = (*p)->addralign();

          if ((*p)->is_section_flag_set(elfcpp::SHF_TLS))
            {
              // Give the first TLS section the alignment of the
              // entire TLS segment.  Otherwise the TLS segment as a
              // whole may be misaligned.
              if (!*in_tls)
                {
                  Output_segment* tls_segment = layout->tls_segment();
                  gold_assert(tls_segment != NULL);
                  uint64_t segment_align = tls_segment->maximum_alignment();
                  gold_assert(segment_align >= align);
                  align = segment_align;

                  *in_tls = true;
                }
            }
          else
            {
              // If this is the first section after the TLS segment,
              // align it to at least the alignment of the TLS
              // segment, so that the size of the overall TLS segment
              // is aligned.
              if (*in_tls)
                {
                  uint64_t segment_align =
                      layout->tls_segment()->maximum_alignment();
                  if (segment_align > align)
                    align = segment_align;

                  *in_tls = false;
                }
            }

	  if (!parameters->incremental_update())
	    {
	      off = align_address(off, align);
	      (*p)->set_address_and_file_offset(addr + (off - startoff), off);
	    }
	  else
	    {
	      // Incremental update: allocate file space from free list.
	      (*p)->pre_finalize_data_size();
	      off_t current_size = (*p)->current_data_size();
	      off = layout->allocate(current_size, align, startoff);
	      if (off == -1)
	        {
		  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_address_and_file_offset(addr + (off - startoff), off);
	      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());
		}
	    }
	}
      else if (parameters->incremental_update())
        {
          // For incremental updates, use the fixed offset for the
          // high-water mark computation.
          off = (*p)->offset();
        }
      else
	{
	  // The script may have inserted a skip forward, but it
	  // better not have moved backward.
	  if ((*p)->address() >= addr + (off - startoff))
	    off += (*p)->address() - (addr + (off - startoff));
	  else
	    {
	      if (!layout->script_options()->saw_sections_clause())
		gold_unreachable();
	      else
		{
		  Output_section* os = (*p)->output_section();

		  // Cast to unsigned long long to avoid format warnings.
		  unsigned long long previous_dot =
		    static_cast<unsigned long long>(addr + (off - startoff));
		  unsigned long long dot =
		    static_cast<unsigned long long>((*p)->address());

		  if (os == NULL)
		    gold_error(_("dot moves backward in linker script "
				 "from 0x%llx to 0x%llx"), previous_dot, dot);
		  else
		    gold_error(_("address of section '%s' moves backward "
				 "from 0x%llx to 0x%llx"),
			       os->name(), previous_dot, dot);
		}
	    }
	  (*p)->set_file_offset(off);
	  (*p)->finalize_data_size();
	}

      if (parameters->incremental_update())
	gold_debug(DEBUG_INCREMENTAL,
		   "set_section_list_addresses: %08lx %08lx %s",
		   static_cast<long>(off),
		   static_cast<long>((*p)->data_size()),
		   ((*p)->output_section() != NULL
		    ? (*p)->output_section()->name() : "(special)"));

      // We want to ignore the size of a SHF_TLS SHT_NOBITS
      // section.  Such a section does not affect the size of a
      // PT_LOAD segment.
      if (!(*p)->is_section_flag_set(elfcpp::SHF_TLS)
	  || !(*p)->is_section_type(elfcpp::SHT_NOBITS))
	off += (*p)->data_size();

      if (off > maxoff)
        maxoff = off;

      if ((*p)->is_section())
	{
	  (*p)->set_out_shndx(*pshndx);
	  ++*pshndx;
	}
    }

  *poff = maxoff;
  return addr + (maxoff - startoff);
}

// For a non-PT_LOAD segment, set the offset from the sections, if
// any.  Add INCREASE to the file size and the memory size.

void
Output_segment::set_offset(unsigned int increase)
{
  gold_assert(this->type_ != elfcpp::PT_LOAD);

  gold_assert(!this->are_addresses_set_);

  // A non-load section only uses output_lists_[0].

  Output_data_list* pdl = &this->output_lists_[0];

  if (pdl->empty())
    {
      gold_assert(increase == 0);
      this->vaddr_ = 0;
      this->paddr_ = 0;
      this->are_addresses_set_ = true;
      this->memsz_ = 0;
      this->min_p_align_ = 0;
      this->offset_ = 0;
      this->filesz_ = 0;
      return;
    }

  // Find the first and last section by address.
  const Output_data* first = NULL;
  const Output_data* last_data = NULL;
  const Output_data* last_bss = NULL;
  for (Output_data_list::const_iterator p = pdl->begin();
       p != pdl->end();
       ++p)
    {
      if (first == NULL
	  || (*p)->address() < first->address()
	  || ((*p)->address() == first->address()
	      && (*p)->data_size() < first->data_size()))
	first = *p;
      const Output_data** plast;
      if ((*p)->is_section()
	  && (*p)->output_section()->type() == elfcpp::SHT_NOBITS)
	plast = &last_bss;
      else
	plast = &last_data;
      if (*plast == NULL
	  || (*p)->address() > (*plast)->address()
	  || ((*p)->address() == (*plast)->address()
	      && (*p)->data_size() > (*plast)->data_size()))
	*plast = *p;
    }

  this->vaddr_ = first->address();
  this->paddr_ = (first->has_load_address()
		  ? first->load_address()
		  : this->vaddr_);
  this->are_addresses_set_ = true;
  this->offset_ = first->offset();

  if (last_data == NULL)
    this->filesz_ = 0;
  else
    this->filesz_ = (last_data->address()
		     + last_data->data_size()
		     - this->vaddr_);

  const Output_data* last = last_bss != NULL ? last_bss : last_data;
  this->memsz_ = (last->address()
		  + last->data_size()
		  - this->vaddr_);

  this->filesz_ += increase;
  this->memsz_ += increase;

  // If this is a RELRO segment, verify that the segment ends at a
  // page boundary.
  if (this->type_ == elfcpp::PT_GNU_RELRO)
    {
      uint64_t page_align = parameters->target().common_pagesize();
      uint64_t segment_end = this->vaddr_ + this->memsz_;
      if (parameters->incremental_update())
	{
	  // The INCREASE_RELRO calculation is bypassed for an incremental
	  // update, so we need to adjust the segment size manually here.
	  segment_end = align_address(segment_end, page_align);
	  this->memsz_ = segment_end - this->vaddr_;
	}
      else
	gold_assert(segment_end == align_address(segment_end, page_align));
    }

  // If this is a TLS segment, align the memory size.  The code in
  // set_section_list ensures that the section after the TLS segment
  // is aligned to give us room.
  if (this->type_ == elfcpp::PT_TLS)
    {
      uint64_t segment_align = this->maximum_alignment();
      gold_assert(this->vaddr_ == align_address(this->vaddr_, segment_align));
      this->memsz_ = align_address(this->memsz_, segment_align);
    }
}

// Set the TLS offsets of the sections in the PT_TLS segment.

void
Output_segment::set_tls_offsets()
{
  gold_assert(this->type_ == elfcpp::PT_TLS);

  for (Output_data_list::iterator p = this->output_lists_[0].begin();
       p != this->output_lists_[0].end();
       ++p)
    (*p)->set_tls_offset(this->vaddr_);
}

// Return the load address of the first section.

uint64_t
Output_segment::first_section_load_address() const
{
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    {
      const Output_data_list* pdl = &this->output_lists_[i];
      for (Output_data_list::const_iterator p = pdl->begin();
	   p != pdl->end();
	   ++p)
	{
	  if ((*p)->is_section())
	    return ((*p)->has_load_address()
		    ? (*p)->load_address()
		    : (*p)->address());
	}
    }
  gold_unreachable();
}

// Return the number of Output_sections in an Output_segment.

unsigned int
Output_segment::output_section_count() const
{
  unsigned int ret = 0;
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    ret += this->output_section_count_list(&this->output_lists_[i]);
  return ret;
}

// Return the number of Output_sections in an Output_data_list.

unsigned int
Output_segment::output_section_count_list(const Output_data_list* pdl) const
{
  unsigned int count = 0;
  for (Output_data_list::const_iterator p = pdl->begin();
       p != pdl->end();
       ++p)
    {
      if ((*p)->is_section())
	++count;
    }
  return count;
}

// Return the section attached to the list segment with the lowest
// load address.  This is used when handling a PHDRS clause in a
// linker script.

Output_section*
Output_segment::section_with_lowest_load_address() const
{
  Output_section* found = NULL;
  uint64_t found_lma = 0;
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    this->lowest_load_address_in_list(&this->output_lists_[i], &found,
				      &found_lma);
  return found;
}

// Look through a list for a section with a lower load address.

void
Output_segment::lowest_load_address_in_list(const Output_data_list* pdl,
					    Output_section** found,
					    uint64_t* found_lma) const
{
  for (Output_data_list::const_iterator p = pdl->begin();
       p != pdl->end();
       ++p)
    {
      if (!(*p)->is_section())
	continue;
      Output_section* os = static_cast<Output_section*>(*p);
      uint64_t lma = (os->has_load_address()
		      ? os->load_address()
		      : os->address());
      if (*found == NULL || lma < *found_lma)
	{
	  *found = os;
	  *found_lma = lma;
	}
    }
}

// Write the segment data into *OPHDR.

template<int size, bool big_endian>
void
Output_segment::write_header(elfcpp::Phdr_write<size, big_endian>* ophdr)
{
  ophdr->put_p_type(this->type_);
  ophdr->put_p_offset(this->offset_);
  ophdr->put_p_vaddr(this->vaddr_);
  ophdr->put_p_paddr(this->paddr_);
  ophdr->put_p_filesz(this->filesz_);
  ophdr->put_p_memsz(this->memsz_);
  ophdr->put_p_flags(this->flags_);
  ophdr->put_p_align(std::max(this->min_p_align_, this->maximum_alignment()));
}

// Write the section headers into V.

template<int size, bool big_endian>
unsigned char*
Output_segment::write_section_headers(const Layout* layout,
				      const Stringpool* secnamepool,
				      unsigned char* v,
				      unsigned int* pshndx) const
{
  // Every section that is attached to a segment must be attached to a
  // PT_LOAD segment, so we only write out section headers for PT_LOAD
  // segments.
  if (this->type_ != elfcpp::PT_LOAD)
    return v;

  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    {
      const Output_data_list* pdl = &this->output_lists_[i];
      v = this->write_section_headers_list<size, big_endian>(layout,
							     secnamepool,
							     pdl,
							     v, pshndx);
    }

  return v;
}

template<int size, bool big_endian>
unsigned char*
Output_segment::write_section_headers_list(const Layout* layout,
					   const Stringpool* secnamepool,
					   const Output_data_list* pdl,
					   unsigned char* v,
					   unsigned int* pshndx) const
{
  const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  for (Output_data_list::const_iterator p = pdl->begin();
       p != pdl->end();
       ++p)
    {
      if ((*p)->is_section())
	{
	  const Output_section* ps = static_cast<const Output_section*>(*p);
	  gold_assert(*pshndx == ps->out_shndx());
	  elfcpp::Shdr_write<size, big_endian> oshdr(v);
	  ps->write_header(layout, secnamepool, &oshdr);
	  v += shdr_size;
	  ++*pshndx;
	}
    }
  return v;
}

// Print the output sections to the map file.

void
Output_segment::print_sections_to_mapfile(Mapfile* mapfile) const
{
  if (this->type() != elfcpp::PT_LOAD)
    return;
  for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
    this->print_section_list_to_mapfile(mapfile, &this->output_lists_[i]);
}

// Print an output section list to the map file.

void
Output_segment::print_section_list_to_mapfile(Mapfile* mapfile,
					      const Output_data_list* pdl) const
{
  for (Output_data_list::const_iterator p = pdl->begin();
       p != pdl->end();
       ++p)
    (*p)->print_to_mapfile(mapfile);
}

// Output_file methods.

Output_file::Output_file(const char* name)
  : name_(name),
    o_(-1),
    file_size_(0),
    base_(NULL),
    map_is_anonymous_(false),
    map_is_allocated_(false),
    is_temporary_(false)
{
}

// Try to open an existing file.  Returns false if the file doesn't
// exist, has a size of 0 or can't be mmapped.  If BASE_NAME is not
// NULL, open that file as the base for incremental linking, and
// copy its contents to the new output file.  This routine can
// be called for incremental updates, in which case WRITABLE should
// be true, or by the incremental-dump utility, in which case
// WRITABLE should be false.

bool
Output_file::open_base_file(const char* base_name, bool writable)
{
  // The name "-" means "stdout".
  if (strcmp(this->name_, "-") == 0)
    return false;

  bool use_base_file = base_name != NULL;
  if (!use_base_file)
    base_name = this->name_;
  else if (strcmp(base_name, this->name_) == 0)
    gold_fatal(_("%s: incremental base and output file name are the same"),
	       base_name);

  // Don't bother opening files with a size of zero.
  struct stat s;
  if (::stat(base_name, &s) != 0)
    {
      gold_info(_("%s: stat: %s"), base_name, strerror(errno));
      return false;
    }
  if (s.st_size == 0)
    {
      gold_info(_("%s: incremental base file is empty"), base_name);
      return false;
    }

  // If we're using a base file, we want to open it read-only.
  if (use_base_file)
    writable = false;

  int oflags = writable ? O_RDWR : O_RDONLY;
  int o = open_descriptor(-1, base_name, oflags, 0);
  if (o < 0)
    {
      gold_info(_("%s: open: %s"), base_name, strerror(errno));
      return false;
    }

  // If the base file and the output file are different, open a
  // new output file and read the contents from the base file into
  // the newly-mapped region.
  if (use_base_file)
    {
      this->open(s.st_size);
      ssize_t bytes_to_read = s.st_size;
      unsigned char* p = this->base_;
      while (bytes_to_read > 0)
	{
	  ssize_t len = ::read(o, p, bytes_to_read);
	  if (len < 0)
	    {
	      gold_info(_("%s: read failed: %s"), base_name, strerror(errno));
	      return false;
	    }
	  if (len == 0)
	    {
	      gold_info(_("%s: file too short: read only %lld of %lld bytes"),
			base_name,
			static_cast<long long>(s.st_size - bytes_to_read),
			static_cast<long long>(s.st_size));
	      return false;
	    }
	  p += len;
	  bytes_to_read -= len;
	}
      ::close(o);
      return true;
    }

  this->o_ = o;
  this->file_size_ = s.st_size;

  if (!this->map_no_anonymous(writable))
    {
      release_descriptor(o, true);
      this->o_ = -1;
      this->file_size_ = 0;
      return false;
    }

  return true;
}

// Open the output file.

void
Output_file::open(off_t file_size)
{
  this->file_size_ = file_size;

  // Unlink the file first; otherwise the open() may fail if the file
  // is busy (e.g. it's an executable that's currently being executed).
  //
  // However, the linker may be part of a system where a zero-length
  // file is created for it to write to, with tight permissions (gcc
  // 2.95 did something like this).  Unlinking the file would work
  // around those permission controls, so we only unlink if the file
  // has a non-zero size.  We also unlink only regular files to avoid
  // trouble with directories/etc.
  //
  // If we fail, continue; this command is merely a best-effort attempt
  // to improve the odds for open().

  // We let the name "-" mean "stdout"
  if (!this->is_temporary_)
    {
      if (strcmp(this->name_, "-") == 0)
	this->o_ = STDOUT_FILENO;
      else
	{
	  struct stat s;
	  if (::stat(this->name_, &s) == 0
	      && (S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
	    {
	      if (s.st_size != 0)
		::unlink(this->name_);
	      else if (!parameters->options().relocatable())
		{
		  // If we don't unlink the existing file, add execute
		  // permission where read permissions already exist
		  // and where the umask permits.
		  int mask = ::umask(0);
		  ::umask(mask);
		  s.st_mode |= (s.st_mode & 0444) >> 2;
		  ::chmod(this->name_, s.st_mode & ~mask);
		}
	    }

	  int mode = parameters->options().relocatable() ? 0666 : 0777;
	  int o = open_descriptor(-1, this->name_, O_RDWR | O_CREAT | O_TRUNC,
				  mode);
	  if (o < 0)
	    gold_fatal(_("%s: open: %s"), this->name_, strerror(errno));
	  this->o_ = o;
	}
    }

  this->map();
}

// Resize the output file.

void
Output_file::resize(off_t file_size)
{
  // If the mmap is mapping an anonymous memory buffer, this is easy:
  // just mremap to the new size.  If it's mapping to a file, we want
  // to unmap to flush to the file, then remap after growing the file.
  if (this->map_is_anonymous_)
    {
      void* base;
      if (!this->map_is_allocated_)
	{
	  base = ::mremap(this->base_, this->file_size_, file_size,
			  MREMAP_MAYMOVE);
	  if (base == MAP_FAILED)
	    gold_fatal(_("%s: mremap: %s"), this->name_, strerror(errno));
	}
      else
	{
	  base = realloc(this->base_, file_size);
	  if (base == NULL)
	    gold_nomem();
	  if (file_size > this->file_size_)
	    memset(static_cast<char*>(base) + this->file_size_, 0,
		   file_size - this->file_size_);
	}
      this->base_ = static_cast<unsigned char*>(base);
      this->file_size_ = file_size;
    }
  else
    {
      this->unmap();
      this->file_size_ = file_size;
      if (!this->map_no_anonymous(true))
	gold_fatal(_("%s: mmap: %s"), this->name_, strerror(errno));
    }
}

// Map an anonymous block of memory which will later be written to the
// file.  Return whether the map succeeded.

bool
Output_file::map_anonymous()
{
  void* base = ::mmap(NULL, this->file_size_, PROT_READ | PROT_WRITE,
		      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (base == MAP_FAILED)
    {
      base = malloc(this->file_size_);
      if (base == NULL)
	return false;
      memset(base, 0, this->file_size_);
      this->map_is_allocated_ = true;
    }
  this->base_ = static_cast<unsigned char*>(base);
  this->map_is_anonymous_ = true;
  return true;
}

// Map the file into memory.  Return whether the mapping succeeded.
// If WRITABLE is true, map with write access.

bool
Output_file::map_no_anonymous(bool writable)
{
  const int o = this->o_;

  // If the output file is not a regular file, don't try to mmap it;
  // instead, we'll mmap a block of memory (an anonymous buffer), and
  // then later write the buffer to the file.
  void* base;
  struct stat statbuf;
  if (o == STDOUT_FILENO || o == STDERR_FILENO
      || ::fstat(o, &statbuf) != 0
      || !S_ISREG(statbuf.st_mode)
      || this->is_temporary_)
    return false;

  // Ensure that we have disk space available for the file.  If we
  // don't do this, it is possible that we will call munmap, close,
  // and exit with dirty buffers still in the cache with no assigned
  // disk blocks.  If the disk is out of space at that point, the
  // output file will wind up incomplete, but we will have already
  // exited.  The alternative to fallocate would be to use fdatasync,
  // but that would be a more significant performance hit.
  if (writable)
    {
      int err = ::posix_fallocate(o, 0, this->file_size_);
      if (err != 0)
       gold_fatal(_("%s: %s"), this->name_, strerror(err));
    }

  // Map the file into memory.
  int prot = PROT_READ;
  if (writable)
    prot |= PROT_WRITE;
  base = ::mmap(NULL, this->file_size_, prot, MAP_SHARED, o, 0);

  // The mmap call might fail because of file system issues: the file
  // system might not support mmap at all, or it might not support
  // mmap with PROT_WRITE.
  if (base == MAP_FAILED)
    return false;

  this->map_is_anonymous_ = false;
  this->base_ = static_cast<unsigned char*>(base);
  return true;
}

// Map the file into memory.

void
Output_file::map()
{
  if (this->map_no_anonymous(true))
    return;

  // The mmap call might fail because of file system issues: the file
  // system might not support mmap at all, or it might not support
  // mmap with PROT_WRITE.  I'm not sure which errno values we will
  // see in all cases, so if the mmap fails for any reason and we
  // don't care about file contents, try for an anonymous map.
  if (this->map_anonymous())
    return;

  gold_fatal(_("%s: mmap: failed to allocate %lu bytes for output file: %s"),
             this->name_, static_cast<unsigned long>(this->file_size_),
             strerror(errno));
}

// Unmap the file from memory.

void
Output_file::unmap()
{
  if (this->map_is_anonymous_)
    {
      // We've already written out the data, so there is no reason to
      // waste time unmapping or freeing the memory.
    }
  else
    {
      if (::munmap(this->base_, this->file_size_) < 0)
	gold_error(_("%s: munmap: %s"), this->name_, strerror(errno));
    }
  this->base_ = NULL;
}

// Close the output file.

void
Output_file::close()
{
  // If the map isn't file-backed, we need to write it now.
  if (this->map_is_anonymous_ && !this->is_temporary_)
    {
      size_t bytes_to_write = this->file_size_;
      size_t offset = 0;
      while (bytes_to_write > 0)
        {
          ssize_t bytes_written = ::write(this->o_, this->base_ + offset,
                                          bytes_to_write);
          if (bytes_written == 0)
            gold_error(_("%s: write: unexpected 0 return-value"), this->name_);
          else if (bytes_written < 0)
            gold_error(_("%s: write: %s"), this->name_, strerror(errno));
          else
            {
              bytes_to_write -= bytes_written;
              offset += bytes_written;
            }
        }
    }
  this->unmap();

  // We don't close stdout or stderr
  if (this->o_ != STDOUT_FILENO
      && this->o_ != STDERR_FILENO
      && !this->is_temporary_)
    if (::close(this->o_) < 0)
      gold_error(_("%s: close: %s"), this->name_, strerror(errno));
  this->o_ = -1;
}

// 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
off_t
Output_section::add_input_section<32, false>(
    Layout* layout,
    Sized_relobj_file<32, false>* object,
    unsigned int shndx,
    const char* secname,
    const elfcpp::Shdr<32, false>& shdr,
    unsigned int reloc_shndx,
    bool have_sections_script);
#endif

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

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

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

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_reloc<elfcpp::SHT_REL, false, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_reloc<elfcpp::SHT_REL, false, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_reloc<elfcpp::SHT_REL, false, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_reloc<elfcpp::SHT_REL, false, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_reloc<elfcpp::SHT_REL, true, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_reloc<elfcpp::SHT_REL, true, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_reloc<elfcpp::SHT_REL, true, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_reloc<elfcpp::SHT_REL, true, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_reloc<elfcpp::SHT_RELA, false, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_reloc<elfcpp::SHT_RELA, false, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_reloc<elfcpp::SHT_RELA, false, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_reloc<elfcpp::SHT_RELA, false, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_reloc<elfcpp::SHT_RELA, true, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_reloc<elfcpp::SHT_RELA, true, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_reloc<elfcpp::SHT_RELA, true, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_reloc<elfcpp::SHT_RELA, true, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_data_reloc<elfcpp::SHT_REL, false, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_data_reloc<elfcpp::SHT_REL, false, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_data_reloc<elfcpp::SHT_REL, false, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_data_reloc<elfcpp::SHT_REL, false, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_data_reloc<elfcpp::SHT_REL, true, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_data_reloc<elfcpp::SHT_REL, true, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_data_reloc<elfcpp::SHT_REL, true, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_data_reloc<elfcpp::SHT_REL, true, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_data_reloc<elfcpp::SHT_RELA, false, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_data_reloc<elfcpp::SHT_RELA, false, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_data_reloc<elfcpp::SHT_RELA, false, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_data_reloc<elfcpp::SHT_RELA, false, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_data_reloc<elfcpp::SHT_RELA, true, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_data_reloc<elfcpp::SHT_RELA, true, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_data_reloc<elfcpp::SHT_RELA, true, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_data_reloc<elfcpp::SHT_RELA, true, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_relocatable_relocs<elfcpp::SHT_REL, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_relocatable_relocs<elfcpp::SHT_REL, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_relocatable_relocs<elfcpp::SHT_REL, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_relocatable_relocs<elfcpp::SHT_REL, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_relocatable_relocs<elfcpp::SHT_RELA, 32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_relocatable_relocs<elfcpp::SHT_RELA, 32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_relocatable_relocs<elfcpp::SHT_RELA, 64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_relocatable_relocs<elfcpp::SHT_RELA, 64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_data_group<32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_data_group<32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_data_group<64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_data_group<64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
class Output_data_got<32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
class Output_data_got<32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
class Output_data_got<64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
class Output_data_got<64, true>;
#endif

} // End namespace gold.
