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

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

// This file is part of gold.

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

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

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

#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

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

namespace gold
{

// A wrapper around posix_fallocate.  If we don't have posix_fallocate,
// or the --no-posix-fallocate option is set, we try the fallocate
// system call directly.  If that fails, we use ftruncate to set
// the file size and hope that there is enough disk space.

static int
gold_fallocate(int o, off_t offset, off_t len)
{
#ifdef HAVE_POSIX_FALLOCATE
  if (parameters->options().posix_fallocate())
    return ::posix_fallocate(o, offset, len);
#endif // defined(HAVE_POSIX_FALLOCATE)
#ifdef HAVE_FALLOCATE
  if (::fallocate(o, 0, offset, len) == 0)
    return 0;
#endif // defined(HAVE_FALLOCATE)
  if (::ftruncate(o, offset + len) < 0)
    return errno;
  return 0;
}

// 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(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.
  this->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,
    bool is_relative)
  : address_(address), local_sym_index_(SECTION_CODE), type_(type),
    is_relative_(is_relative), is_symbolless_(is_relative),
    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,
    bool is_relative)
  : address_(address), local_sym_index_(SECTION_CODE), type_(type),
    is_relative_(is_relative), is_symbolless_(is_relative),
    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 or relative 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,
    bool is_relative)
  : address_(address), local_sym_index_(0), type_(type),
    is_relative_(is_relative), 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,
    bool is_relative)
  : address_(address), local_sym_index_(0), type_(type),
    is_relative_(is_relative), 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())
	return parameters->target().plt_address_for_global(sym);
      else
	return sym->value() + addend;
    }
  if (this->local_sym_index_ == SECTION_CODE)
    {
      gold_assert(!this->use_plt_offset_);
      return this->u1_.os->address() + addend;
    }
  gold_assert(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_)
    return parameters->target().plt_address_for_local(relobj, 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();
}

// Standard relocation writer, which just calls Output_reloc::write().

template<int sh_type, bool dynamic, int size, bool big_endian>
struct Output_reloc_writer
{
  typedef Output_reloc<sh_type, dynamic, size, big_endian> Output_reloc_type;
  typedef std::vector<Output_reloc_type> Relocs;

  static void
  write(typename Relocs::const_iterator p, unsigned char* pov)
  { p->write(pov); }
};

// 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)
{
  typedef Output_reloc_writer<sh_type, dynamic, size, big_endian> Writer;
  this->do_write_generic<Writer>(of);
}

// 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 got_size, bool big_endian>
void
Output_data_got<got_size, big_endian>::Got_entry::write(
    unsigned int got_indx,
    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_or_tls_offset_ && gsym->has_plt_offset())
	  val = parameters->target().plt_address_for_global(gsym);
	else
	  {
	    switch (parameters->size_and_endianness())
	      {
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
	      case Parameters::TARGET_32_LITTLE:
	      case Parameters::TARGET_32_BIG:
		{
		  // This cast is ugly.  We don't want to put a
		  // virtual method in Symbol, because we want Symbol
		  // to be as small as possible.
		  Sized_symbol<32>::Value_type v;
		  v = static_cast<Sized_symbol<32>*>(gsym)->value();
		  val = convert_types<Valtype, Sized_symbol<32>::Value_type>(v);
		}
		break;
#endif
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
	      case Parameters::TARGET_64_LITTLE:
	      case Parameters::TARGET_64_BIG:
		{
		  Sized_symbol<64>::Value_type v;
		  v = static_cast<Sized_symbol<64>*>(gsym)->value();
		  val = convert_types<Valtype, Sized_symbol<64>::Value_type>(v);
		}
		break;
#endif
	      default:
		gold_unreachable();
	      }
	    if (this->use_plt_or_tls_offset_
		&& gsym->type() == elfcpp::STT_TLS)
	      val += parameters->target().tls_offset_for_global(gsym,
								got_indx);
	  }
      }
      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_;
	bool is_tls = object->local_is_tls(lsi);
	if (this->use_plt_or_tls_offset_ && !is_tls)
	  val = parameters->target().plt_address_for_local(object, lsi);
	else
	  {
	    uint64_t lval = object->local_symbol_value(lsi, this->addend_);
	    val = convert_types<Valtype, uint64_t>(lval);
	    if (this->use_plt_or_tls_offset_ && is_tls)
	      val += parameters->target().tls_offset_for_local(object, lsi,
							       got_indx);
	  }
      }
      break;
    }

  elfcpp::Swap<got_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 got_size, bool big_endian>
bool
Output_data_got<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 got_size, bool big_endian>
bool
Output_data_got<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 got_size, bool big_endian>
void
Output_data_got<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 got_size, bool big_endian>
void
Output_data_got<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 + got_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 got_size, bool big_endian>
bool
Output_data_got<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;
}

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

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

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

// Like add_local, but use the PLT offset.

template<int got_size, bool big_endian>
bool
Output_data_got<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 got_size, bool big_endian>
void
Output_data_got<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 an entry for a local symbol plus ADDEND to the GOT, and add a dynamic
// relocation of type R_TYPE for the GOT entry.

template<int got_size, bool big_endian>
void
Output_data_got<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, uint64_t addend)
{
  if (object->local_has_got_offset(symndx, got_type, addend))
    return;

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

// Add a pair of entries for a local symbol to the GOT, and add
// a dynamic relocation of type R_TYPE using the section symbol of
// the output section to which input section SHNDX maps, on the first.
// The first got entry will have a value of zero, the second the
// value of the local symbol.
template<int got_size, bool big_endian>
void
Output_data_got<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)
{
  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, this, got_offset, 0);
}

// Add a pair of entries for a local symbol plus ADDEND to the GOT, and add
// a dynamic relocation of type R_TYPE using the section symbol of
// the output section to which input section SHNDX maps, on the first.
// The first got entry will have a value of zero, the second the
// value of the local symbol.
template<int got_size, bool big_endian>
void
Output_data_got<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, uint64_t addend)
{
  if (object->local_has_got_offset(symndx, got_type, addend))
    return;

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

// Add a pair of entries for a local symbol to the GOT, and add
// a dynamic relocation of type R_TYPE using STN_UNDEF on the first.
// The first got entry will have a value of zero, the second the
// value of the local symbol offset by Target::tls_offset_for_local.
template<int got_size, bool big_endian>
void
Output_data_got<got_size, big_endian>::add_local_tls_pair(
    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_pair(Got_entry(),
			       Got_entry(object, symndx, true));
  object->set_local_got_offset(symndx, got_type, got_offset);
  rel_dyn->add_local_generic(object, 0, r_type, this, got_offset, 0);
}

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

template<int got_size, bool big_endian>
void
Output_data_got<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 got_size, bool big_endian>
void
Output_data_got<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 got_size, bool big_endian>
void
Output_data_got<got_size, big_endian>::do_write(Output_file* of)
{
  const int add = got_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 (unsigned int i = 0; i < this->entries_.size(); ++i)
    {
      this->entries_[i].write(i, 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 got_size, bool big_endian>
unsigned int
Output_data_got<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(got_size / 8,
						   got_size / 8, 0);
      if (got_offset == -1)
	gold_fallback(_("out of patch space (GOT);"
			" relink with --incremental-full"));
      unsigned int got_index = got_offset / (got_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 got_size, bool big_endian>
unsigned int
Output_data_got<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 * got_size / 8,
						   got_size / 8, 0);
      if (got_offset == -1)
	gold_fallback(_("out of patch space (GOT);"
			" relink with --incremental-full"));
      unsigned int got_index = got_offset / (got_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);
    }
}

// Replace GOT entry I with a new value.

template<int got_size, bool big_endian>
void
Output_data_got<got_size, big_endian>::replace_got_entry(
    unsigned int i,
    Got_entry got_entry)
{
  gold_assert(i < this->entries_.size());
  this->entries_[i] = got_entry;
}

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

    case DYNAMIC_CUSTOM:
      val = parameters->target().dynamic_tag_custom_value(this->tag_);
      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();
}

// Get a dynamic entry offset.

unsigned int
Output_data_dynamic::get_entry_offset(elfcpp::DT tag) const
{
  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();

  for (size_t i = 0; i < entries_.size(); ++i)
    if (entries_[i].tag() == tag)
      return i * dyn_size;

  return -1U;
}

// 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(static_cast<off_t>(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;
    }
}

// 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),
    is_unique_segment_(false),
    tls_offset_(0),
    extra_segment_flags_(0),
    segment_alignment_(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;

  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());
      return offset_in_section;
    }

  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
					+ 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();
	    }
	}
      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 the 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)
{
  // We cannot merge sections with entsize == 0.
  if (entsize == 0)
    return false;

  bool is_string = (flags & elfcpp::SHF_STRINGS) != 0;

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

      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.

const Output_section_data*
Output_section::find_merge_section(const Relobj* object,
				   unsigned int shndx) const
{
  return object->find_merge_section(shndx);
}

// Build the lookup maps for relaxed sections.  This needs
// to be declared as a const method 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_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);
      // By default we assume that the address is mapped. See comment at the
      // end.
      if (!found)
        return true;
      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
{
  const Output_section_data* data = this->find_merge_section(object, shndx);
  if (data == NULL)
    return false;

  // 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_input_section() && p->output_section_data() == data)
	{
	  *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_name_()
  { }

  Input_section_sort_entry(const Input_section& input_section,
			   unsigned int index,
			   bool must_sort_attached_input_sections,
			   const char* output_section_name)
    : input_section_(input_section), index_(index), section_name_()
  {
    if ((input_section.is_input_section()
	 || input_section.is_relaxed_input_section())
	&& 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());
      }
    else if (input_section.is_output_section_data()
    	     && must_sort_attached_input_sections)
      {
	// For linker-generated sections, use the output section name.
	this->section_name_.assign(output_section_name);
      }
  }

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

  // The section name.
  const std::string&
  section_name() const
  {
    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
  {
    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
  {
    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
  {
    if (this->input_section_.is_output_section_data())
      return false;
    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_;
  // 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();
    }

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

// Return true if S1 should come before S2.  This is the sort comparison
// function for .text to sort sections with prefixes
// .text.{unlikely,exit,startup,hot} before other sections.

bool
Output_section::Input_section_sort_section_prefix_special_ordering_compare
  ::operator()(
    const Output_section::Input_section_sort_entry& s1,
    const Output_section::Input_section_sort_entry& s2) const
{
  // Some input section names have special ordering requirements.
  int o1 = Layout::special_ordering_of_input_section(s1.section_name().c_str());
  int o2 = Layout::special_ordering_of_input_section(s2.section_name().c_str());
  if (o1 != o2)
    {
      if (o1 < 0)
	return false;
      else if (o2 < 0)
	return true;
      else
	return o1 < o2;
    }

  // Keep input order otherwise.
  return s1.index() < s2.index();
}

// Return true if S1 should come before S2.  This is the sort comparison
// function for sections to sort them by name.

bool
Output_section::Input_section_sort_section_name_compare
  ::operator()(
    const Output_section::Input_section_sort_entry& s1,
    const Output_section::Input_section_sort_entry& s2) const
{
  // We sort by name.
  int compare = s1.section_name().compare(s2.section_name());
  if (compare != 0)
    return compare < 0;

  // Keep input order otherwise.
  return s1.index() < s2.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())
	{
	  Relobj* 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(),
			    this->name()));

  // 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 if (strcmp(parameters->options().sort_section(), "name") == 0)
	std::sort(sort_list.begin(), sort_list.end(),
		  Input_section_sort_section_name_compare());
      else if (strcmp(this->name(), ".text") == 0)
	std::sort(sort_list.begin(), sort_list.end(),
		  Input_section_sort_section_prefix_special_ordering_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_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),
    is_unique_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_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(const Target* target,
				      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 an abi 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;
		}
	      // Ignore the size of the .tbss section.
	      if ((*p)->is_section_flag_set(elfcpp::SHF_TLS)
		  && (*p)->is_section_type(elfcpp::SHT_NOBITS))
		continue;
	      relro_size = align_address(relro_size, align);
	      if ((*p)->is_address_valid())
		relro_size += (*p)->data_size();
	      else
		{
		  // FIXME: This could be faster.
		  (*p)->set_address_and_file_offset(relro_size,
						    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().abi_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 < off % page_align)
	off += page_align;
      off += desired_align - off % page_align;
      addr += off - orig_off;
      orig_off = off;
      *poff = off;
    }

  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 = 0;
  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;

  // If code segments must contain only code, and this code segment is
  // page-aligned in the file, then fill it out to a whole page with
  // code fill (the tail of the segment will not be within any section).
  // Thus the entire code segment can be mapped from the file as whole
  // pages and that mapping will contain only valid instructions.
  if (target->isolate_execinstr() && (this->flags() & elfcpp::PF_X) != 0)
    {
      uint64_t abi_pagesize = target->abi_pagesize();
      if (orig_off % abi_pagesize == 0 && off % abi_pagesize != 0)
	{
	  size_t fill_size = abi_pagesize - (off % abi_pagesize);

	  std::string fill_data;
	  if (target->has_code_fill())
	    fill_data = target->code_fill(fill_size);
	  else
	    fill_data.resize(fill_size); // Zero fill.

	  Output_data_const* fill = new Output_data_const(fill_data, 0);
	  fill->set_address(this->vaddr_ + this->memsz_);
	  fill->set_file_offset(off);
	  layout->add_relax_output(fill);

	  off += fill_size;
	  gold_assert(off % abi_pagesize == 0);
	  ret += fill_size;
	  gold_assert(ret % abi_pagesize == 0);

	  gold_assert((uint64_t) this->filesz_ == this->memsz_);
	  this->memsz_ = this->filesz_ += fill_size;

	  *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().abi_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 first section.

Output_section*
Output_segment::first_section() 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)->output_section();
	}
    }
  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 = gold_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 (parameters->options().mmap_output_file()
      && 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

template
class Output_data_got<32, false>;

template
class Output_data_got<32, true>;

template
class Output_data_got<64, false>;

template
class Output_data_got<64, true>;

} // End namespace gold.
