// object.cc -- support for an object file for linking in gold

// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
// Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// This file is part of gold.

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

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

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

#include "gold.h"

#include <cerrno>
#include <cstring>
#include <cstdarg>
#include "demangle.h"
#include "libiberty.h"

#include "gc.h"
#include "target-select.h"
#include "dwarf_reader.h"
#include "layout.h"
#include "output.h"
#include "symtab.h"
#include "cref.h"
#include "reloc.h"
#include "object.h"
#include "dynobj.h"
#include "plugin.h"
#include "compressed_output.h"
#include "incremental.h"

namespace gold
{

// Struct Read_symbols_data.

// Destroy any remaining File_view objects.

Read_symbols_data::~Read_symbols_data()
{
  if (this->section_headers != NULL)
    delete this->section_headers;
  if (this->section_names != NULL)
    delete this->section_names;
  if (this->symbols != NULL)
    delete this->symbols;
  if (this->symbol_names != NULL)
    delete this->symbol_names;
  if (this->versym != NULL)
    delete this->versym;
  if (this->verdef != NULL)
    delete this->verdef;
  if (this->verneed != NULL)
    delete this->verneed;
}

// Class Xindex.

// Initialize the symtab_xindex_ array.  Find the SHT_SYMTAB_SHNDX
// section and read it in.  SYMTAB_SHNDX is the index of the symbol
// table we care about.

template<int size, bool big_endian>
void
Xindex::initialize_symtab_xindex(Object* object, unsigned int symtab_shndx)
{
  if (!this->symtab_xindex_.empty())
    return;

  gold_assert(symtab_shndx != 0);

  // Look through the sections in reverse order, on the theory that it
  // is more likely to be near the end than the beginning.
  unsigned int i = object->shnum();
  while (i > 0)
    {
      --i;
      if (object->section_type(i) == elfcpp::SHT_SYMTAB_SHNDX
	  && this->adjust_shndx(object->section_link(i)) == symtab_shndx)
	{
	  this->read_symtab_xindex<size, big_endian>(object, i, NULL);
	  return;
	}
    }

  object->error(_("missing SHT_SYMTAB_SHNDX section"));
}

// Read in the symtab_xindex_ array, given the section index of the
// SHT_SYMTAB_SHNDX section.  If PSHDRS is not NULL, it points at the
// section headers.

template<int size, bool big_endian>
void
Xindex::read_symtab_xindex(Object* object, unsigned int xindex_shndx,
			   const unsigned char* pshdrs)
{
  section_size_type bytecount;
  const unsigned char* contents;
  if (pshdrs == NULL)
    contents = object->section_contents(xindex_shndx, &bytecount, false);
  else
    {
      const unsigned char* p = (pshdrs
				+ (xindex_shndx
				   * elfcpp::Elf_sizes<size>::shdr_size));
      typename elfcpp::Shdr<size, big_endian> shdr(p);
      bytecount = convert_to_section_size_type(shdr.get_sh_size());
      contents = object->get_view(shdr.get_sh_offset(), bytecount, true, false);
    }

  gold_assert(this->symtab_xindex_.empty());
  this->symtab_xindex_.reserve(bytecount / 4);
  for (section_size_type i = 0; i < bytecount; i += 4)
    {
      unsigned int shndx = elfcpp::Swap<32, big_endian>::readval(contents + i);
      // We preadjust the section indexes we save.
      this->symtab_xindex_.push_back(this->adjust_shndx(shndx));
    }
}

// Symbol symndx has a section of SHN_XINDEX; return the real section
// index.

unsigned int
Xindex::sym_xindex_to_shndx(Object* object, unsigned int symndx)
{
  if (symndx >= this->symtab_xindex_.size())
    {
      object->error(_("symbol %u out of range for SHT_SYMTAB_SHNDX section"),
		    symndx);
      return elfcpp::SHN_UNDEF;
    }
  unsigned int shndx = this->symtab_xindex_[symndx];
  if (shndx < elfcpp::SHN_LORESERVE || shndx >= object->shnum())
    {
      object->error(_("extended index for symbol %u out of range: %u"),
		    symndx, shndx);
      return elfcpp::SHN_UNDEF;
    }
  return shndx;
}

// Class Object.

// Report an error for this object file.  This is used by the
// elfcpp::Elf_file interface, and also called by the Object code
// itself.

void
Object::error(const char* format, ...) const
{
  va_list args;
  va_start(args, format);
  char* buf = NULL;
  if (vasprintf(&buf, format, args) < 0)
    gold_nomem();
  va_end(args);
  gold_error(_("%s: %s"), this->name().c_str(), buf);
  free(buf);
}

// Return a view of the contents of a section.

const unsigned char*
Object::section_contents(unsigned int shndx, section_size_type* plen,
			 bool cache)
{ return this->do_section_contents(shndx, plen, cache); }

// Read the section data into SD.  This is code common to Sized_relobj_file
// and Sized_dynobj, so we put it into Object.

template<int size, bool big_endian>
void
Object::read_section_data(elfcpp::Elf_file<size, big_endian, Object>* elf_file,
			  Read_symbols_data* sd)
{
  const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;

  // Read the section headers.
  const off_t shoff = elf_file->shoff();
  const unsigned int shnum = this->shnum();
  sd->section_headers = this->get_lasting_view(shoff, shnum * shdr_size,
					       true, true);

  // Read the section names.
  const unsigned char* pshdrs = sd->section_headers->data();
  const unsigned char* pshdrnames = pshdrs + elf_file->shstrndx() * shdr_size;
  typename elfcpp::Shdr<size, big_endian> shdrnames(pshdrnames);

  if (shdrnames.get_sh_type() != elfcpp::SHT_STRTAB)
    this->error(_("section name section has wrong type: %u"),
		static_cast<unsigned int>(shdrnames.get_sh_type()));

  sd->section_names_size =
    convert_to_section_size_type(shdrnames.get_sh_size());
  sd->section_names = this->get_lasting_view(shdrnames.get_sh_offset(),
					     sd->section_names_size, false,
					     false);
}

// If NAME is the name of a special .gnu.warning section, arrange for
// the warning to be issued.  SHNDX is the section index.  Return
// whether it is a warning section.

bool
Object::handle_gnu_warning_section(const char* name, unsigned int shndx,
				   Symbol_table* symtab)
{
  const char warn_prefix[] = ".gnu.warning.";
  const int warn_prefix_len = sizeof warn_prefix - 1;
  if (strncmp(name, warn_prefix, warn_prefix_len) == 0)
    {
      // Read the section contents to get the warning text.  It would
      // be nicer if we only did this if we have to actually issue a
      // warning.  Unfortunately, warnings are issued as we relocate
      // sections.  That means that we can not lock the object then,
      // as we might try to issue the same warning multiple times
      // simultaneously.
      section_size_type len;
      const unsigned char* contents = this->section_contents(shndx, &len,
							     false);
      if (len == 0)
	{
	  const char* warning = name + warn_prefix_len;
	  contents = reinterpret_cast<const unsigned char*>(warning);
	  len = strlen(warning);
	}
      std::string warning(reinterpret_cast<const char*>(contents), len);
      symtab->add_warning(name + warn_prefix_len, this, warning);
      return true;
    }
  return false;
}

// If NAME is the name of the special section which indicates that
// this object was compiled with -fsplit-stack, mark it accordingly.

bool
Object::handle_split_stack_section(const char* name)
{
  if (strcmp(name, ".note.GNU-split-stack") == 0)
    {
      this->uses_split_stack_ = true;
      return true;
    }
  if (strcmp(name, ".note.GNU-no-split-stack") == 0)
    {
      this->has_no_split_stack_ = true;
      return true;
    }
  return false;
}

// Class Relobj

// To copy the symbols data read from the file to a local data structure.
// This function is called from do_layout only while doing garbage
// collection.

void
Relobj::copy_symbols_data(Symbols_data* gc_sd, Read_symbols_data* sd,
			  unsigned int section_header_size)
{
  gc_sd->section_headers_data =
	 new unsigned char[(section_header_size)];
  memcpy(gc_sd->section_headers_data, sd->section_headers->data(),
	 section_header_size);
  gc_sd->section_names_data =
	 new unsigned char[sd->section_names_size];
  memcpy(gc_sd->section_names_data, sd->section_names->data(),
	 sd->section_names_size);
  gc_sd->section_names_size = sd->section_names_size;
  if (sd->symbols != NULL)
    {
      gc_sd->symbols_data =
	     new unsigned char[sd->symbols_size];
      memcpy(gc_sd->symbols_data, sd->symbols->data(),
	    sd->symbols_size);
    }
  else
    {
      gc_sd->symbols_data = NULL;
    }
  gc_sd->symbols_size = sd->symbols_size;
  gc_sd->external_symbols_offset = sd->external_symbols_offset;
  if (sd->symbol_names != NULL)
    {
      gc_sd->symbol_names_data =
	     new unsigned char[sd->symbol_names_size];
      memcpy(gc_sd->symbol_names_data, sd->symbol_names->data(),
	    sd->symbol_names_size);
    }
  else
    {
      gc_sd->symbol_names_data = NULL;
    }
  gc_sd->symbol_names_size = sd->symbol_names_size;
}

// This function determines if a particular section name must be included
// in the link.  This is used during garbage collection to determine the
// roots of the worklist.

bool
Relobj::is_section_name_included(const char* name)
{
  if (is_prefix_of(".ctors", name)
      || is_prefix_of(".dtors", name)
      || is_prefix_of(".note", name)
      || is_prefix_of(".init", name)
      || is_prefix_of(".fini", name)
      || is_prefix_of(".gcc_except_table", name)
      || is_prefix_of(".jcr", name)
      || is_prefix_of(".preinit_array", name)
      || (is_prefix_of(".text", name)
	  && strstr(name, "personality"))
      || (is_prefix_of(".data", name)
	  &&  strstr(name, "personality"))
      || (is_prefix_of(".gnu.linkonce.d", name)
	  && strstr(name, "personality")))
    {
      return true;
    }
  return false;
}

// Finalize the incremental relocation information.  Allocates a block
// of relocation entries for each symbol, and sets the reloc_bases_
// array to point to the first entry in each block.  If CLEAR_COUNTS
// is TRUE, also clear the per-symbol relocation counters.

void
Relobj::finalize_incremental_relocs(Layout* layout, bool clear_counts)
{
  unsigned int nsyms = this->get_global_symbols()->size();
  this->reloc_bases_ = new unsigned int[nsyms];

  gold_assert(this->reloc_bases_ != NULL);
  gold_assert(layout->incremental_inputs() != NULL);

  unsigned int rindex = layout->incremental_inputs()->get_reloc_count();
  for (unsigned int i = 0; i < nsyms; ++i)
    {
      this->reloc_bases_[i] = rindex;
      rindex += this->reloc_counts_[i];
      if (clear_counts)
	this->reloc_counts_[i] = 0;
    }
  layout->incremental_inputs()->set_reloc_count(rindex);
}

// Class Sized_relobj.

// Iterate over local symbols, calling a visitor class V for each GOT offset
// associated with a local symbol.

template<int size, bool big_endian>
void
Sized_relobj<size, big_endian>::do_for_all_local_got_entries(
    Got_offset_list::Visitor* v) const
{
  unsigned int nsyms = this->local_symbol_count();
  for (unsigned int i = 0; i < nsyms; i++)
    {
      Local_got_offsets::const_iterator p = this->local_got_offsets_.find(i);
      if (p != this->local_got_offsets_.end())
	{
	  const Got_offset_list* got_offsets = p->second;
	  got_offsets->for_all_got_offsets(v);
	}
    }
}

// Class Sized_relobj_file.

template<int size, bool big_endian>
Sized_relobj_file<size, big_endian>::Sized_relobj_file(
    const std::string& name,
    Input_file* input_file,
    off_t offset,
    const elfcpp::Ehdr<size, big_endian>& ehdr)
  : Sized_relobj<size, big_endian>(name, input_file, offset),
    elf_file_(this, ehdr),
    symtab_shndx_(-1U),
    local_symbol_count_(0),
    output_local_symbol_count_(0),
    output_local_dynsym_count_(0),
    symbols_(),
    defined_count_(0),
    local_symbol_offset_(0),
    local_dynsym_offset_(0),
    local_values_(),
    local_plt_offsets_(),
    kept_comdat_sections_(),
    has_eh_frame_(false),
    discarded_eh_frame_shndx_(-1U),
    deferred_layout_(),
    deferred_layout_relocs_(),
    compressed_sections_()
{
  this->e_type_ = ehdr.get_e_type();
}

template<int size, bool big_endian>
Sized_relobj_file<size, big_endian>::~Sized_relobj_file()
{
}

// Set up an object file based on the file header.  This sets up the
// section information.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_setup()
{
  const unsigned int shnum = this->elf_file_.shnum();
  this->set_shnum(shnum);
}

// Find the SHT_SYMTAB section, given the section headers.  The ELF
// standard says that maybe in the future there can be more than one
// SHT_SYMTAB section.  Until somebody figures out how that could
// work, we assume there is only one.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::find_symtab(const unsigned char* pshdrs)
{
  const unsigned int shnum = this->shnum();
  this->symtab_shndx_ = 0;
  if (shnum > 0)
    {
      // Look through the sections in reverse order, since gas tends
      // to put the symbol table at the end.
      const unsigned char* p = pshdrs + shnum * This::shdr_size;
      unsigned int i = shnum;
      unsigned int xindex_shndx = 0;
      unsigned int xindex_link = 0;
      while (i > 0)
	{
	  --i;
	  p -= This::shdr_size;
	  typename This::Shdr shdr(p);
	  if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
	    {
	      this->symtab_shndx_ = i;
	      if (xindex_shndx > 0 && xindex_link == i)
		{
		  Xindex* xindex =
		    new Xindex(this->elf_file_.large_shndx_offset());
		  xindex->read_symtab_xindex<size, big_endian>(this,
							       xindex_shndx,
							       pshdrs);
		  this->set_xindex(xindex);
		}
	      break;
	    }

	  // Try to pick up the SHT_SYMTAB_SHNDX section, if there is
	  // one.  This will work if it follows the SHT_SYMTAB
	  // section.
	  if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB_SHNDX)
	    {
	      xindex_shndx = i;
	      xindex_link = this->adjust_shndx(shdr.get_sh_link());
	    }
	}
    }
}

// Return the Xindex structure to use for object with lots of
// sections.

template<int size, bool big_endian>
Xindex*
Sized_relobj_file<size, big_endian>::do_initialize_xindex()
{
  gold_assert(this->symtab_shndx_ != -1U);
  Xindex* xindex = new Xindex(this->elf_file_.large_shndx_offset());
  xindex->initialize_symtab_xindex<size, big_endian>(this, this->symtab_shndx_);
  return xindex;
}

// Return whether SHDR has the right type and flags to be a GNU
// .eh_frame section.

template<int size, bool big_endian>
bool
Sized_relobj_file<size, big_endian>::check_eh_frame_flags(
    const elfcpp::Shdr<size, big_endian>* shdr) const
{
  elfcpp::Elf_Word sh_type = shdr->get_sh_type();
  return ((sh_type == elfcpp::SHT_PROGBITS
	   || sh_type == elfcpp::SHT_X86_64_UNWIND)
	  && (shdr->get_sh_flags() & elfcpp::SHF_ALLOC) != 0);
}

// Return whether there is a GNU .eh_frame section, given the section
// headers and the section names.

template<int size, bool big_endian>
bool
Sized_relobj_file<size, big_endian>::find_eh_frame(
    const unsigned char* pshdrs,
    const char* names,
    section_size_type names_size) const
{
  const unsigned int shnum = this->shnum();
  const unsigned char* p = pshdrs + This::shdr_size;
  for (unsigned int i = 1; i < shnum; ++i, p += This::shdr_size)
    {
      typename This::Shdr shdr(p);
      if (this->check_eh_frame_flags(&shdr))
	{
	  if (shdr.get_sh_name() >= names_size)
	    {
	      this->error(_("bad section name offset for section %u: %lu"),
			  i, static_cast<unsigned long>(shdr.get_sh_name()));
	      continue;
	    }

	  const char* name = names + shdr.get_sh_name();
	  if (strcmp(name, ".eh_frame") == 0)
	    return true;
	}
    }
  return false;
}

// Return TRUE if this is a section whose contents will be needed in the
// Add_symbols task.  This function is only called for sections that have
// already passed the test in is_compressed_debug_section(), so we know
// that the section name begins with ".zdebug".

static bool
need_decompressed_section(const char* name)
{
  // Skip over the ".zdebug" and a quick check for the "_".
  name += 7;
  if (*name++ != '_')
    return false;

#ifdef ENABLE_THREADS
  // Decompressing these sections now will help only if we're
  // multithreaded.
  if (parameters->options().threads())
    {
      // We will need .zdebug_str if this is not an incremental link
      // (i.e., we are processing string merge sections) or if we need
      // to build a gdb index.
      if ((!parameters->incremental() || parameters->options().gdb_index())
	  && strcmp(name, "str") == 0)
	return true;

      // We will need these other sections when building a gdb index.
      if (parameters->options().gdb_index()
	  && (strcmp(name, "info") == 0
	      || strcmp(name, "types") == 0
	      || strcmp(name, "pubnames") == 0
	      || strcmp(name, "pubtypes") == 0
	      || strcmp(name, "ranges") == 0
	      || strcmp(name, "abbrev") == 0))
	return true;
    }
#endif

  // Even when single-threaded, we will need .zdebug_str if this is
  // not an incremental link and we are building a gdb index.
  // Otherwise, we would decompress the section twice: once for
  // string merge processing, and once for building the gdb index.
  if (!parameters->incremental()
      && parameters->options().gdb_index()
      && strcmp(name, "str") == 0)
    return true;

  return false;
}

// Build a table for any compressed debug sections, mapping each section index
// to the uncompressed size and (if needed) the decompressed contents.

template<int size, bool big_endian>
Compressed_section_map*
build_compressed_section_map(
    const unsigned char* pshdrs,
    unsigned int shnum,
    const char* names,
    section_size_type names_size,
    Sized_relobj_file<size, big_endian>* obj)
{
  Compressed_section_map* uncompressed_map = new Compressed_section_map();
  const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  const unsigned char* p = pshdrs + shdr_size;

  for (unsigned int i = 1; i < shnum; ++i, p += shdr_size)
    {
      typename elfcpp::Shdr<size, big_endian> shdr(p);
      if (shdr.get_sh_type() == elfcpp::SHT_PROGBITS
	  && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
	{
	  if (shdr.get_sh_name() >= names_size)
	    {
	      obj->error(_("bad section name offset for section %u: %lu"),
			 i, static_cast<unsigned long>(shdr.get_sh_name()));
	      continue;
	    }

	  const char* name = names + shdr.get_sh_name();
	  if (is_compressed_debug_section(name))
	    {
	      section_size_type len;
	      const unsigned char* contents =
		  obj->section_contents(i, &len, false);
	      uint64_t uncompressed_size = get_uncompressed_size(contents, len);
	      Compressed_section_info info;
	      info.size = convert_to_section_size_type(uncompressed_size);
	      info.contents = NULL;
	      if (uncompressed_size != -1ULL)
		{
		  unsigned char* uncompressed_data = NULL;
		  if (need_decompressed_section(name))
		    {
		      uncompressed_data = new unsigned char[uncompressed_size];
		      if (decompress_input_section(contents, len,
						   uncompressed_data,
						   uncompressed_size))
			info.contents = uncompressed_data;
		      else
			delete[] uncompressed_data;
		    }
		  (*uncompressed_map)[i] = info;
		}
	    }
	}
    }
  return uncompressed_map;
}

// Read the sections and symbols from an object file.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
{
  bool need_local_symbols = false;

  this->read_section_data(&this->elf_file_, sd);

  const unsigned char* const pshdrs = sd->section_headers->data();

  this->find_symtab(pshdrs);

  const unsigned char* namesu = sd->section_names->data();
  const char* names = reinterpret_cast<const char*>(namesu);
  if (memmem(names, sd->section_names_size, ".eh_frame", 10) != NULL)
    {
      if (this->find_eh_frame(pshdrs, names, sd->section_names_size))
	this->has_eh_frame_ = true;
    }
  if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL)
    this->compressed_sections_ =
	build_compressed_section_map(pshdrs, this->shnum(), names,
				     sd->section_names_size, this);

  if (this->has_eh_frame_
      || (!parameters->options().relocatable()
	  && parameters->options().gdb_index()
	  && (memmem(names, sd->section_names_size, "debug_info", 12) == 0
	      || memmem(names, sd->section_names_size, "debug_types",
			13) == 0)))
    need_local_symbols = true;

  sd->symbols = NULL;
  sd->symbols_size = 0;
  sd->external_symbols_offset = 0;
  sd->symbol_names = NULL;
  sd->symbol_names_size = 0;

  if (this->symtab_shndx_ == 0)
    {
      // No symbol table.  Weird but legal.
      return;
    }

  // Get the symbol table section header.
  typename This::Shdr symtabshdr(pshdrs
				 + this->symtab_shndx_ * This::shdr_size);
  gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);

  // If this object has a .eh_frame section, or if building a .gdb_index
  // section and there is debug info, we need all the symbols.
  // Otherwise we only need the external symbols.  While it would be
  // simpler to just always read all the symbols, I've seen object
  // files with well over 2000 local symbols, which for a 64-bit
  // object file format is over 5 pages that we don't need to read
  // now.

  const int sym_size = This::sym_size;
  const unsigned int loccount = symtabshdr.get_sh_info();
  this->local_symbol_count_ = loccount;
  this->local_values_.resize(loccount);
  section_offset_type locsize = loccount * sym_size;
  off_t dataoff = symtabshdr.get_sh_offset();
  section_size_type datasize =
    convert_to_section_size_type(symtabshdr.get_sh_size());
  off_t extoff = dataoff + locsize;
  section_size_type extsize = datasize - locsize;

  off_t readoff = need_local_symbols ? dataoff : extoff;
  section_size_type readsize = need_local_symbols ? datasize : extsize;

  if (readsize == 0)
    {
      // No external symbols.  Also weird but also legal.
      return;
    }

  File_view* fvsymtab = this->get_lasting_view(readoff, readsize, true, false);

  // Read the section header for the symbol names.
  unsigned int strtab_shndx = this->adjust_shndx(symtabshdr.get_sh_link());
  if (strtab_shndx >= this->shnum())
    {
      this->error(_("invalid symbol table name index: %u"), strtab_shndx);
      return;
    }
  typename This::Shdr strtabshdr(pshdrs + strtab_shndx * This::shdr_size);
  if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB)
    {
      this->error(_("symbol table name section has wrong type: %u"),
		  static_cast<unsigned int>(strtabshdr.get_sh_type()));
      return;
    }

  // Read the symbol names.
  File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(),
					       strtabshdr.get_sh_size(),
					       false, true);

  sd->symbols = fvsymtab;
  sd->symbols_size = readsize;
  sd->external_symbols_offset = need_local_symbols ? locsize : 0;
  sd->symbol_names = fvstrtab;
  sd->symbol_names_size =
    convert_to_section_size_type(strtabshdr.get_sh_size());
}

// Return the section index of symbol SYM.  Set *VALUE to its value in
// the object file.  Set *IS_ORDINARY if this is an ordinary section
// index, not a special code between SHN_LORESERVE and SHN_HIRESERVE.
// Note that for a symbol which is not defined in this object file,
// this will set *VALUE to 0 and return SHN_UNDEF; it will not return
// the final value of the symbol in the link.

template<int size, bool big_endian>
unsigned int
Sized_relobj_file<size, big_endian>::symbol_section_and_value(unsigned int sym,
							      Address* value,
							      bool* is_ordinary)
{
  section_size_type symbols_size;
  const unsigned char* symbols = this->section_contents(this->symtab_shndx_,
							&symbols_size,
							false);

  const size_t count = symbols_size / This::sym_size;
  gold_assert(sym < count);

  elfcpp::Sym<size, big_endian> elfsym(symbols + sym * This::sym_size);
  *value = elfsym.get_st_value();

  return this->adjust_sym_shndx(sym, elfsym.get_st_shndx(), is_ordinary);
}

// Return whether to include a section group in the link.  LAYOUT is
// used to keep track of which section groups we have already seen.
// INDEX is the index of the section group and SHDR is the section
// header.  If we do not want to include this group, we set bits in
// OMIT for each section which should be discarded.

template<int size, bool big_endian>
bool
Sized_relobj_file<size, big_endian>::include_section_group(
    Symbol_table* symtab,
    Layout* layout,
    unsigned int index,
    const char* name,
    const unsigned char* shdrs,
    const char* section_names,
    section_size_type section_names_size,
    std::vector<bool>* omit)
{
  // Read the section contents.
  typename This::Shdr shdr(shdrs + index * This::shdr_size);
  const unsigned char* pcon = this->get_view(shdr.get_sh_offset(),
					     shdr.get_sh_size(), true, false);
  const elfcpp::Elf_Word* pword =
    reinterpret_cast<const elfcpp::Elf_Word*>(pcon);

  // The first word contains flags.  We only care about COMDAT section
  // groups.  Other section groups are always included in the link
  // just like ordinary sections.
  elfcpp::Elf_Word flags = elfcpp::Swap<32, big_endian>::readval(pword);

  // Look up the group signature, which is the name of a symbol.  ELF
  // uses a symbol name because some group signatures are long, and
  // the name is generally already in the symbol table, so it makes
  // sense to put the long string just once in .strtab rather than in
  // both .strtab and .shstrtab.

  // Get the appropriate symbol table header (this will normally be
  // the single SHT_SYMTAB section, but in principle it need not be).
  const unsigned int link = this->adjust_shndx(shdr.get_sh_link());
  typename This::Shdr symshdr(this, this->elf_file_.section_header(link));

  // Read the symbol table entry.
  unsigned int symndx = shdr.get_sh_info();
  if (symndx >= symshdr.get_sh_size() / This::sym_size)
    {
      this->error(_("section group %u info %u out of range"),
		  index, symndx);
      return false;
    }
  off_t symoff = symshdr.get_sh_offset() + symndx * This::sym_size;
  const unsigned char* psym = this->get_view(symoff, This::sym_size, true,
					     false);
  elfcpp::Sym<size, big_endian> sym(psym);

  // Read the symbol table names.
  section_size_type symnamelen;
  const unsigned char* psymnamesu;
  psymnamesu = this->section_contents(this->adjust_shndx(symshdr.get_sh_link()),
				      &symnamelen, true);
  const char* psymnames = reinterpret_cast<const char*>(psymnamesu);

  // Get the section group signature.
  if (sym.get_st_name() >= symnamelen)
    {
      this->error(_("symbol %u name offset %u out of range"),
		  symndx, sym.get_st_name());
      return false;
    }

  std::string signature(psymnames + sym.get_st_name());

  // It seems that some versions of gas will create a section group
  // associated with a section symbol, and then fail to give a name to
  // the section symbol.  In such a case, use the name of the section.
  if (signature[0] == '\0' && sym.get_st_type() == elfcpp::STT_SECTION)
    {
      bool is_ordinary;
      unsigned int sym_shndx = this->adjust_sym_shndx(symndx,
						      sym.get_st_shndx(),
						      &is_ordinary);
      if (!is_ordinary || sym_shndx >= this->shnum())
	{
	  this->error(_("symbol %u invalid section index %u"),
		      symndx, sym_shndx);
	  return false;
	}
      typename This::Shdr member_shdr(shdrs + sym_shndx * This::shdr_size);
      if (member_shdr.get_sh_name() < section_names_size)
	signature = section_names + member_shdr.get_sh_name();
    }

  // Record this section group in the layout, and see whether we've already
  // seen one with the same signature.
  bool include_group;
  bool is_comdat;
  Kept_section* kept_section = NULL;

  if ((flags & elfcpp::GRP_COMDAT) == 0)
    {
      include_group = true;
      is_comdat = false;
    }
  else
    {
      include_group = layout->find_or_add_kept_section(signature,
						       this, index, true,
						       true, &kept_section);
      is_comdat = true;
    }

  if (is_comdat && include_group)
    {
      Incremental_inputs* incremental_inputs = layout->incremental_inputs();
      if (incremental_inputs != NULL)
	incremental_inputs->report_comdat_group(this, signature.c_str());
    }

  size_t count = shdr.get_sh_size() / sizeof(elfcpp::Elf_Word);

  std::vector<unsigned int> shndxes;
  bool relocate_group = include_group && parameters->options().relocatable();
  if (relocate_group)
    shndxes.reserve(count - 1);

  for (size_t i = 1; i < count; ++i)
    {
      elfcpp::Elf_Word shndx =
	this->adjust_shndx(elfcpp::Swap<32, big_endian>::readval(pword + i));

      if (relocate_group)
	shndxes.push_back(shndx);

      if (shndx >= this->shnum())
	{
	  this->error(_("section %u in section group %u out of range"),
		      shndx, index);
	  continue;
	}

      // Check for an earlier section number, since we're going to get
      // it wrong--we may have already decided to include the section.
      if (shndx < index)
	this->error(_("invalid section group %u refers to earlier section %u"),
		    index, shndx);

      // Get the name of the member section.
      typename This::Shdr member_shdr(shdrs + shndx * This::shdr_size);
      if (member_shdr.get_sh_name() >= section_names_size)
	{
	  // This is an error, but it will be diagnosed eventually
	  // in do_layout, so we don't need to do anything here but
	  // ignore it.
	  continue;
	}
      std::string mname(section_names + member_shdr.get_sh_name());

      if (include_group)
	{
	  if (is_comdat)
	    kept_section->add_comdat_section(mname, shndx,
					     member_shdr.get_sh_size());
	}
      else
	{
	  (*omit)[shndx] = true;

	  if (is_comdat)
	    {
	      Relobj* kept_object = kept_section->object();
	      if (kept_section->is_comdat())
		{
		  // Find the corresponding kept section, and store
		  // that info in the discarded section table.
		  unsigned int kept_shndx;
		  uint64_t kept_size;
		  if (kept_section->find_comdat_section(mname, &kept_shndx,
							&kept_size))
		    {
		      // We don't keep a mapping for this section if
		      // it has a different size.  The mapping is only
		      // used for relocation processing, and we don't
		      // want to treat the sections as similar if the
		      // sizes are different.  Checking the section
		      // size is the approach used by the GNU linker.
		      if (kept_size == member_shdr.get_sh_size())
			this->set_kept_comdat_section(shndx, kept_object,
						      kept_shndx);
		    }
		}
	      else
		{
		  // The existing section is a linkonce section.  Add
		  // a mapping if there is exactly one section in the
		  // group (which is true when COUNT == 2) and if it
		  // is the same size.
		  if (count == 2
		      && (kept_section->linkonce_size()
			  == member_shdr.get_sh_size()))
		    this->set_kept_comdat_section(shndx, kept_object,
						  kept_section->shndx());
		}
	    }
	}
    }

  if (relocate_group)
    layout->layout_group(symtab, this, index, name, signature.c_str(),
			 shdr, flags, &shndxes);

  return include_group;
}

// Whether to include a linkonce section in the link.  NAME is the
// name of the section and SHDR is the section header.

// Linkonce sections are a GNU extension implemented in the original
// GNU linker before section groups were defined.  The semantics are
// that we only include one linkonce section with a given name.  The
// name of a linkonce section is normally .gnu.linkonce.T.SYMNAME,
// where T is the type of section and SYMNAME is the name of a symbol.
// In an attempt to make linkonce sections interact well with section
// groups, we try to identify SYMNAME and use it like a section group
// signature.  We want to block section groups with that signature,
// but not other linkonce sections with that signature.  We also use
// the full name of the linkonce section as a normal section group
// signature.

template<int size, bool big_endian>
bool
Sized_relobj_file<size, big_endian>::include_linkonce_section(
    Layout* layout,
    unsigned int index,
    const char* name,
    const elfcpp::Shdr<size, big_endian>& shdr)
{
  typename elfcpp::Elf_types<size>::Elf_WXword sh_size = shdr.get_sh_size();
  // In general the symbol name we want will be the string following
  // the last '.'.  However, we have to handle the case of
  // .gnu.linkonce.t.__i686.get_pc_thunk.bx, which was generated by
  // some versions of gcc.  So we use a heuristic: if the name starts
  // with ".gnu.linkonce.t.", we use everything after that.  Otherwise
  // we look for the last '.'.  We can't always simply skip
  // ".gnu.linkonce.X", because we have to deal with cases like
  // ".gnu.linkonce.d.rel.ro.local".
  const char* const linkonce_t = ".gnu.linkonce.t.";
  const char* symname;
  if (strncmp(name, linkonce_t, strlen(linkonce_t)) == 0)
    symname = name + strlen(linkonce_t);
  else
    symname = strrchr(name, '.') + 1;
  std::string sig1(symname);
  std::string sig2(name);
  Kept_section* kept1;
  Kept_section* kept2;
  bool include1 = layout->find_or_add_kept_section(sig1, this, index, false,
						   false, &kept1);
  bool include2 = layout->find_or_add_kept_section(sig2, this, index, false,
						   true, &kept2);

  if (!include2)
    {
      // We are not including this section because we already saw the
      // name of the section as a signature.  This normally implies
      // that the kept section is another linkonce section.  If it is
      // the same size, record it as the section which corresponds to
      // this one.
      if (kept2->object() != NULL
	  && !kept2->is_comdat()
	  && kept2->linkonce_size() == sh_size)
	this->set_kept_comdat_section(index, kept2->object(), kept2->shndx());
    }
  else if (!include1)
    {
      // The section is being discarded on the basis of its symbol
      // name.  This means that the corresponding kept section was
      // part of a comdat group, and it will be difficult to identify
      // the specific section within that group that corresponds to
      // this linkonce section.  We'll handle the simple case where
      // the group has only one member section.  Otherwise, it's not
      // worth the effort.
      unsigned int kept_shndx;
      uint64_t kept_size;
      if (kept1->object() != NULL
	  && kept1->is_comdat()
	  && kept1->find_single_comdat_section(&kept_shndx, &kept_size)
	  && kept_size == sh_size)
	this->set_kept_comdat_section(index, kept1->object(), kept_shndx);
    }
  else
    {
      kept1->set_linkonce_size(sh_size);
      kept2->set_linkonce_size(sh_size);
    }

  return include1 && include2;
}

// Layout an input section.

template<int size, bool big_endian>
inline void
Sized_relobj_file<size, big_endian>::layout_section(
    Layout* layout,
    unsigned int shndx,
    const char* name,
    const typename This::Shdr& shdr,
    unsigned int reloc_shndx,
    unsigned int reloc_type)
{
  off_t offset;
  Output_section* os = layout->layout(this, shndx, name, shdr,
					  reloc_shndx, reloc_type, &offset);

  this->output_sections()[shndx] = os;
  if (offset == -1)
    this->section_offsets()[shndx] = invalid_address;
  else
    this->section_offsets()[shndx] = convert_types<Address, off_t>(offset);

  // If this section requires special handling, and if there are
  // relocs that apply to it, then we must do the special handling
  // before we apply the relocs.
  if (offset == -1 && reloc_shndx != 0)
    this->set_relocs_must_follow_section_writes();
}

// Layout an input .eh_frame section.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::layout_eh_frame_section(
    Layout* layout,
    const unsigned char* symbols_data,
    section_size_type symbols_size,
    const unsigned char* symbol_names_data,
    section_size_type symbol_names_size,
    unsigned int shndx,
    const typename This::Shdr& shdr,
    unsigned int reloc_shndx,
    unsigned int reloc_type)
{
  gold_assert(this->has_eh_frame_);

  off_t offset;
  Output_section* os = layout->layout_eh_frame(this,
					       symbols_data,
					       symbols_size,
					       symbol_names_data,
					       symbol_names_size,
					       shndx,
					       shdr,
					       reloc_shndx,
					       reloc_type,
					       &offset);
  this->output_sections()[shndx] = os;
  if (os == NULL || offset == -1)
    {
      // An object can contain at most one section holding exception
      // frame information.
      gold_assert(this->discarded_eh_frame_shndx_ == -1U);
      this->discarded_eh_frame_shndx_ = shndx;
      this->section_offsets()[shndx] = invalid_address;
    }
  else
    this->section_offsets()[shndx] = convert_types<Address, off_t>(offset);

  // If this section requires special handling, and if there are
  // relocs that aply to it, then we must do the special handling
  // before we apply the relocs.
  if (os != NULL && offset == -1 && reloc_shndx != 0)
    this->set_relocs_must_follow_section_writes();
}

// Lay out the input sections.  We walk through the sections and check
// whether they should be included in the link.  If they should, we
// pass them to the Layout object, which will return an output section
// and an offset.
// During garbage collection (--gc-sections) and identical code folding
// (--icf), this function is called twice.  When it is called the first
// time, it is for setting up some sections as roots to a work-list for
// --gc-sections and to do comdat processing.  Actual layout happens the
// second time around after all the relevant sections have been determined.
// The first time, is_worklist_ready or is_icf_ready is false. It is then
// set to true after the garbage collection worklist or identical code
// folding is processed and the relevant sections to be kept are
// determined.  Then, this function is called again to layout the sections.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_layout(Symbol_table* symtab,
					       Layout* layout,
					       Read_symbols_data* sd)
{
  const unsigned int shnum = this->shnum();
  bool is_gc_pass_one = ((parameters->options().gc_sections()
			  && !symtab->gc()->is_worklist_ready())
			 || (parameters->options().icf_enabled()
			     && !symtab->icf()->is_icf_ready()));

  bool is_gc_pass_two = ((parameters->options().gc_sections()
			  && symtab->gc()->is_worklist_ready())
			 || (parameters->options().icf_enabled()
			     && symtab->icf()->is_icf_ready()));

  bool is_gc_or_icf = (parameters->options().gc_sections()
		       || parameters->options().icf_enabled());

  // Both is_gc_pass_one and is_gc_pass_two should not be true.
  gold_assert(!(is_gc_pass_one  && is_gc_pass_two));

  if (shnum == 0)
    return;
  Symbols_data* gc_sd = NULL;
  if (is_gc_pass_one)
    {
      // During garbage collection save the symbols data to use it when
      // re-entering this function.
      gc_sd = new Symbols_data;
      this->copy_symbols_data(gc_sd, sd, This::shdr_size * shnum);
      this->set_symbols_data(gc_sd);
    }
  else if (is_gc_pass_two)
    {
      gc_sd = this->get_symbols_data();
    }

  const unsigned char* section_headers_data = NULL;
  section_size_type section_names_size;
  const unsigned char* symbols_data = NULL;
  section_size_type symbols_size;
  const unsigned char* symbol_names_data = NULL;
  section_size_type symbol_names_size;

  if (is_gc_or_icf)
    {
      section_headers_data = gc_sd->section_headers_data;
      section_names_size = gc_sd->section_names_size;
      symbols_data = gc_sd->symbols_data;
      symbols_size = gc_sd->symbols_size;
      symbol_names_data = gc_sd->symbol_names_data;
      symbol_names_size = gc_sd->symbol_names_size;
    }
  else
    {
      section_headers_data = sd->section_headers->data();
      section_names_size = sd->section_names_size;
      if (sd->symbols != NULL)
	symbols_data = sd->symbols->data();
      symbols_size = sd->symbols_size;
      if (sd->symbol_names != NULL)
	symbol_names_data = sd->symbol_names->data();
      symbol_names_size = sd->symbol_names_size;
    }

  // Get the section headers.
  const unsigned char* shdrs = section_headers_data;
  const unsigned char* pshdrs;

  // Get the section names.
  const unsigned char* pnamesu = (is_gc_or_icf)
				 ? gc_sd->section_names_data
				 : sd->section_names->data();

  const char* pnames = reinterpret_cast<const char*>(pnamesu);

  // If any input files have been claimed by plugins, we need to defer
  // actual layout until the replacement files have arrived.
  const bool should_defer_layout =
      (parameters->options().has_plugins()
       && parameters->options().plugins()->should_defer_layout());
  unsigned int num_sections_to_defer = 0;

  // For each section, record the index of the reloc section if any.
  // Use 0 to mean that there is no reloc section, -1U to mean that
  // there is more than one.
  std::vector<unsigned int> reloc_shndx(shnum, 0);
  std::vector<unsigned int> reloc_type(shnum, elfcpp::SHT_NULL);
  // Skip the first, dummy, section.
  pshdrs = shdrs + This::shdr_size;
  for (unsigned int i = 1; i < shnum; ++i, pshdrs += This::shdr_size)
    {
      typename This::Shdr shdr(pshdrs);

      // Count the number of sections whose layout will be deferred.
      if (should_defer_layout && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC))
	++num_sections_to_defer;

      unsigned int sh_type = shdr.get_sh_type();
      if (sh_type == elfcpp::SHT_REL || sh_type == elfcpp::SHT_RELA)
	{
	  unsigned int target_shndx = this->adjust_shndx(shdr.get_sh_info());
	  if (target_shndx == 0 || target_shndx >= shnum)
	    {
	      this->error(_("relocation section %u has bad info %u"),
			  i, target_shndx);
	      continue;
	    }

	  if (reloc_shndx[target_shndx] != 0)
	    reloc_shndx[target_shndx] = -1U;
	  else
	    {
	      reloc_shndx[target_shndx] = i;
	      reloc_type[target_shndx] = sh_type;
	    }
	}
    }

  Output_sections& out_sections(this->output_sections());
  std::vector<Address>& out_section_offsets(this->section_offsets());

  if (!is_gc_pass_two)
    {
      out_sections.resize(shnum);
      out_section_offsets.resize(shnum);
    }

  // If we are only linking for symbols, then there is nothing else to
  // do here.
  if (this->input_file()->just_symbols())
    {
      if (!is_gc_pass_two)
	{
	  delete sd->section_headers;
	  sd->section_headers = NULL;
	  delete sd->section_names;
	  sd->section_names = NULL;
	}
      return;
    }

  if (num_sections_to_defer > 0)
    {
      parameters->options().plugins()->add_deferred_layout_object(this);
      this->deferred_layout_.reserve(num_sections_to_defer);
    }

  // Whether we've seen a .note.GNU-stack section.
  bool seen_gnu_stack = false;
  // The flags of a .note.GNU-stack section.
  uint64_t gnu_stack_flags = 0;

  // Keep track of which sections to omit.
  std::vector<bool> omit(shnum, false);

  // Keep track of reloc sections when emitting relocations.
  const bool relocatable = parameters->options().relocatable();
  const bool emit_relocs = (relocatable
			    || parameters->options().emit_relocs());
  std::vector<unsigned int> reloc_sections;

  // Keep track of .eh_frame sections.
  std::vector<unsigned int> eh_frame_sections;

  // Keep track of .debug_info and .debug_types sections.
  std::vector<unsigned int> debug_info_sections;
  std::vector<unsigned int> debug_types_sections;

  // Skip the first, dummy, section.
  pshdrs = shdrs + This::shdr_size;
  for (unsigned int i = 1; i < shnum; ++i, pshdrs += This::shdr_size)
    {
      typename This::Shdr shdr(pshdrs);

      if (shdr.get_sh_name() >= section_names_size)
	{
	  this->error(_("bad section name offset for section %u: %lu"),
		      i, static_cast<unsigned long>(shdr.get_sh_name()));
	  return;
	}

      const char* name = pnames + shdr.get_sh_name();

      if (!is_gc_pass_two)
	{
	  if (this->handle_gnu_warning_section(name, i, symtab))
	    {
	      if (!relocatable && !parameters->options().shared())
		omit[i] = true;
	    }

	  // The .note.GNU-stack section is special.  It gives the
	  // protection flags that this object file requires for the stack
	  // in memory.
	  if (strcmp(name, ".note.GNU-stack") == 0)
	    {
	      seen_gnu_stack = true;
	      gnu_stack_flags |= shdr.get_sh_flags();
	      omit[i] = true;
	    }

	  // The .note.GNU-split-stack section is also special.  It
	  // indicates that the object was compiled with
	  // -fsplit-stack.
	  if (this->handle_split_stack_section(name))
	    {
	      if (!relocatable && !parameters->options().shared())
		omit[i] = true;
	    }

	  // Skip attributes section.
	  if (parameters->target().is_attributes_section(name))
	    {
	      omit[i] = true;
	    }

	  bool discard = omit[i];
	  if (!discard)
	    {
	      if (shdr.get_sh_type() == elfcpp::SHT_GROUP)
		{
		  if (!this->include_section_group(symtab, layout, i, name,
						   shdrs, pnames,
						   section_names_size,
						   &omit))
		    discard = true;
		}
	      else if ((shdr.get_sh_flags() & elfcpp::SHF_GROUP) == 0
		       && Layout::is_linkonce(name))
		{
		  if (!this->include_linkonce_section(layout, i, name, shdr))
		    discard = true;
		}
	    }

	  // Add the section to the incremental inputs layout.
	  Incremental_inputs* incremental_inputs = layout->incremental_inputs();
	  if (incremental_inputs != NULL
	      && !discard
	      && can_incremental_update(shdr.get_sh_type()))
	    {
	      off_t sh_size = shdr.get_sh_size();
	      section_size_type uncompressed_size;
	      if (this->section_is_compressed(i, &uncompressed_size))
		sh_size = uncompressed_size;
	      incremental_inputs->report_input_section(this, i, name, sh_size);
	    }

	  if (discard)
	    {
	      // Do not include this section in the link.
	      out_sections[i] = NULL;
	      out_section_offsets[i] = invalid_address;
	      continue;
	    }
	}

      if (is_gc_pass_one && parameters->options().gc_sections())
	{
	  if (this->is_section_name_included(name)
	      || shdr.get_sh_type() == elfcpp::SHT_INIT_ARRAY
	      || shdr.get_sh_type() == elfcpp::SHT_FINI_ARRAY)
	    {
	      symtab->gc()->worklist().push(Section_id(this, i));
	    }
	  // If the section name XXX can be represented as a C identifier
	  // it cannot be discarded if there are references to
	  // __start_XXX and __stop_XXX symbols.  These need to be
	  // specially handled.
	  if (is_cident(name))
	    {
	      symtab->gc()->add_cident_section(name, Section_id(this, i));
	    }
	}

      // When doing a relocatable link we are going to copy input
      // reloc sections into the output.  We only want to copy the
      // ones associated with sections which are not being discarded.
      // However, we don't know that yet for all sections.  So save
      // reloc sections and process them later. Garbage collection is
      // not triggered when relocatable code is desired.
      if (emit_relocs
	  && (shdr.get_sh_type() == elfcpp::SHT_REL
	      || shdr.get_sh_type() == elfcpp::SHT_RELA))
	{
	  reloc_sections.push_back(i);
	  continue;
	}

      if (relocatable && shdr.get_sh_type() == elfcpp::SHT_GROUP)
	continue;

      // The .eh_frame section is special.  It holds exception frame
      // information that we need to read in order to generate the
      // exception frame header.  We process these after all the other
      // sections so that the exception frame reader can reliably
      // determine which sections are being discarded, and discard the
      // corresponding information.
      if (!relocatable
	  && strcmp(name, ".eh_frame") == 0
	  && this->check_eh_frame_flags(&shdr))
	{
	  if (is_gc_pass_one)
	    {
	      out_sections[i] = reinterpret_cast<Output_section*>(1);
	      out_section_offsets[i] = invalid_address;
	    }
	  else if (should_defer_layout)
	    this->deferred_layout_.push_back(Deferred_layout(i, name,
							     pshdrs,
							     reloc_shndx[i],
							     reloc_type[i]));
	  else
	    eh_frame_sections.push_back(i);
	  continue;
	}

      if (is_gc_pass_two && parameters->options().gc_sections())
	{
	  // This is executed during the second pass of garbage
	  // collection. do_layout has been called before and some
	  // sections have been already discarded. Simply ignore
	  // such sections this time around.
	  if (out_sections[i] == NULL)
	    {
	      gold_assert(out_section_offsets[i] == invalid_address);
	      continue;
	    }
	  if (((shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0)
	      && symtab->gc()->is_section_garbage(this, i))
	      {
		if (parameters->options().print_gc_sections())
		  gold_info(_("%s: removing unused section from '%s'"
			      " in file '%s'"),
			    program_name, this->section_name(i).c_str(),
			    this->name().c_str());
		out_sections[i] = NULL;
		out_section_offsets[i] = invalid_address;
		continue;
	      }
	}

      if (is_gc_pass_two && parameters->options().icf_enabled())
	{
	  if (out_sections[i] == NULL)
	    {
	      gold_assert(out_section_offsets[i] == invalid_address);
	      continue;
	    }
	  if (((shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0)
	      && symtab->icf()->is_section_folded(this, i))
	      {
		if (parameters->options().print_icf_sections())
		  {
		    Section_id folded =
				symtab->icf()->get_folded_section(this, i);
		    Relobj* folded_obj =
				reinterpret_cast<Relobj*>(folded.first);
		    gold_info(_("%s: ICF folding section '%s' in file '%s'"
				"into '%s' in file '%s'"),
			      program_name, this->section_name(i).c_str(),
			      this->name().c_str(),
			      folded_obj->section_name(folded.second).c_str(),
			      folded_obj->name().c_str());
		  }
		out_sections[i] = NULL;
		out_section_offsets[i] = invalid_address;
		continue;
	      }
	}

      // Defer layout here if input files are claimed by plugins.  When gc
      // is turned on this function is called twice.  For the second call
      // should_defer_layout should be false.
      if (should_defer_layout && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC))
	{
	  gold_assert(!is_gc_pass_two);
	  this->deferred_layout_.push_back(Deferred_layout(i, name,
							   pshdrs,
							   reloc_shndx[i],
							   reloc_type[i]));
	  // Put dummy values here; real values will be supplied by
	  // do_layout_deferred_sections.
	  out_sections[i] = reinterpret_cast<Output_section*>(2);
	  out_section_offsets[i] = invalid_address;
	  continue;
	}

      // During gc_pass_two if a section that was previously deferred is
      // found, do not layout the section as layout_deferred_sections will
      // do it later from gold.cc.
      if (is_gc_pass_two
	  && (out_sections[i] == reinterpret_cast<Output_section*>(2)))
	continue;

      if (is_gc_pass_one)
	{
	  // This is during garbage collection. The out_sections are
	  // assigned in the second call to this function.
	  out_sections[i] = reinterpret_cast<Output_section*>(1);
	  out_section_offsets[i] = invalid_address;
	}
      else
	{
	  // When garbage collection is switched on the actual layout
	  // only happens in the second call.
	  this->layout_section(layout, i, name, shdr, reloc_shndx[i],
			       reloc_type[i]);

	  // When generating a .gdb_index section, we do additional
	  // processing of .debug_info and .debug_types sections after all
	  // the other sections for the same reason as above.
	  if (!relocatable
	      && parameters->options().gdb_index()
	      && !(shdr.get_sh_flags() & elfcpp::SHF_ALLOC))
	    {
	      if (strcmp(name, ".debug_info") == 0
		  || strcmp(name, ".zdebug_info") == 0)
		debug_info_sections.push_back(i);
	      else if (strcmp(name, ".debug_types") == 0
		       || strcmp(name, ".zdebug_types") == 0)
		debug_types_sections.push_back(i);
	    }
	}
    }

  if (!is_gc_pass_two)
    layout->layout_gnu_stack(seen_gnu_stack, gnu_stack_flags, this);

  // When doing a relocatable link handle the reloc sections at the
  // end.  Garbage collection  and Identical Code Folding is not
  // turned on for relocatable code.
  if (emit_relocs)
    this->size_relocatable_relocs();

  gold_assert(!(is_gc_or_icf) || reloc_sections.empty());

  for (std::vector<unsigned int>::const_iterator p = reloc_sections.begin();
       p != reloc_sections.end();
       ++p)
    {
      unsigned int i = *p;
      const unsigned char* pshdr;
      pshdr = section_headers_data + i * This::shdr_size;
      typename This::Shdr shdr(pshdr);

      unsigned int data_shndx = this->adjust_shndx(shdr.get_sh_info());
      if (data_shndx >= shnum)
	{
	  // We already warned about this above.
	  continue;
	}

      Output_section* data_section = out_sections[data_shndx];
      if (data_section == reinterpret_cast<Output_section*>(2))
	{
	  // The layout for the data section was deferred, so we need
	  // to defer the relocation section, too.
	  const char* name = pnames + shdr.get_sh_name();
	  this->deferred_layout_relocs_.push_back(
	      Deferred_layout(i, name, pshdr, 0, elfcpp::SHT_NULL));
	  out_sections[i] = reinterpret_cast<Output_section*>(2);
	  out_section_offsets[i] = invalid_address;
	  continue;
	}
      if (data_section == NULL)
	{
	  out_sections[i] = NULL;
	  out_section_offsets[i] = invalid_address;
	  continue;
	}

      Relocatable_relocs* rr = new Relocatable_relocs();
      this->set_relocatable_relocs(i, rr);

      Output_section* os = layout->layout_reloc(this, i, shdr, data_section,
						rr);
      out_sections[i] = os;
      out_section_offsets[i] = invalid_address;
    }

  // Handle the .eh_frame sections at the end.
  gold_assert(!is_gc_pass_one || eh_frame_sections.empty());
  for (std::vector<unsigned int>::const_iterator p = eh_frame_sections.begin();
       p != eh_frame_sections.end();
       ++p)
    {
      unsigned int i = *p;
      const unsigned char* pshdr;
      pshdr = section_headers_data + i * This::shdr_size;
      typename This::Shdr shdr(pshdr);

      this->layout_eh_frame_section(layout,
				    symbols_data,
				    symbols_size,
				    symbol_names_data,
				    symbol_names_size,
				    i,
				    shdr,
				    reloc_shndx[i],
				    reloc_type[i]);
    }

  // When building a .gdb_index section, scan the .debug_info and
  // .debug_types sections.
  gold_assert(!is_gc_pass_one
	      || (debug_info_sections.empty() && debug_types_sections.empty()));
  for (std::vector<unsigned int>::const_iterator p
	   = debug_info_sections.begin();
       p != debug_info_sections.end();
       ++p)
    {
      unsigned int i = *p;
      layout->add_to_gdb_index(false, this, symbols_data, symbols_size,
			       i, reloc_shndx[i], reloc_type[i]);
    }
  for (std::vector<unsigned int>::const_iterator p
	   = debug_types_sections.begin();
       p != debug_types_sections.end();
       ++p)
    {
      unsigned int i = *p;
      layout->add_to_gdb_index(true, this, symbols_data, symbols_size,
			       i, reloc_shndx[i], reloc_type[i]);
    }

  if (is_gc_pass_two)
    {
      delete[] gc_sd->section_headers_data;
      delete[] gc_sd->section_names_data;
      delete[] gc_sd->symbols_data;
      delete[] gc_sd->symbol_names_data;
      this->set_symbols_data(NULL);
    }
  else
    {
      delete sd->section_headers;
      sd->section_headers = NULL;
      delete sd->section_names;
      sd->section_names = NULL;
    }
}

// Layout sections whose layout was deferred while waiting for
// input files from a plugin.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_layout_deferred_sections(Layout* layout)
{
  typename std::vector<Deferred_layout>::iterator deferred;

  for (deferred = this->deferred_layout_.begin();
       deferred != this->deferred_layout_.end();
       ++deferred)
    {
      typename This::Shdr shdr(deferred->shdr_data_);
      // If the section is not included, it is because the garbage collector
      // decided it is not needed.  Avoid reverting that decision.
      if (!this->is_section_included(deferred->shndx_))
	continue;

      if (parameters->options().relocatable()
	  || deferred->name_ != ".eh_frame"
	  || !this->check_eh_frame_flags(&shdr))
	this->layout_section(layout, deferred->shndx_, deferred->name_.c_str(),
			     shdr, deferred->reloc_shndx_,
			     deferred->reloc_type_);
      else
	{
	  // Reading the symbols again here may be slow.
	  Read_symbols_data sd;
	  this->read_symbols(&sd);
	  this->layout_eh_frame_section(layout,
					sd.symbols->data(),
					sd.symbols_size,
					sd.symbol_names->data(),
					sd.symbol_names_size,
					deferred->shndx_,
					shdr,
					deferred->reloc_shndx_,
					deferred->reloc_type_);
	}
    }

  this->deferred_layout_.clear();

  // Now handle the deferred relocation sections.

  Output_sections& out_sections(this->output_sections());
  std::vector<Address>& out_section_offsets(this->section_offsets());

  for (deferred = this->deferred_layout_relocs_.begin();
       deferred != this->deferred_layout_relocs_.end();
       ++deferred)
    {
      unsigned int shndx = deferred->shndx_;
      typename This::Shdr shdr(deferred->shdr_data_);
      unsigned int data_shndx = this->adjust_shndx(shdr.get_sh_info());

      Output_section* data_section = out_sections[data_shndx];
      if (data_section == NULL)
	{
	  out_sections[shndx] = NULL;
	  out_section_offsets[shndx] = invalid_address;
	  continue;
	}

      Relocatable_relocs* rr = new Relocatable_relocs();
      this->set_relocatable_relocs(shndx, rr);

      Output_section* os = layout->layout_reloc(this, shndx, shdr,
						data_section, rr);
      out_sections[shndx] = os;
      out_section_offsets[shndx] = invalid_address;
    }
}

// Add the symbols to the symbol table.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_add_symbols(Symbol_table* symtab,
						    Read_symbols_data* sd,
						    Layout*)
{
  if (sd->symbols == NULL)
    {
      gold_assert(sd->symbol_names == NULL);
      return;
    }

  const int sym_size = This::sym_size;
  size_t symcount = ((sd->symbols_size - sd->external_symbols_offset)
		     / sym_size);
  if (symcount * sym_size != sd->symbols_size - sd->external_symbols_offset)
    {
      this->error(_("size of symbols is not multiple of symbol size"));
      return;
    }

  this->symbols_.resize(symcount);

  const char* sym_names =
    reinterpret_cast<const char*>(sd->symbol_names->data());
  symtab->add_from_relobj(this,
			  sd->symbols->data() + sd->external_symbols_offset,
			  symcount, this->local_symbol_count_,
			  sym_names, sd->symbol_names_size,
			  &this->symbols_,
			  &this->defined_count_);

  delete sd->symbols;
  sd->symbols = NULL;
  delete sd->symbol_names;
  sd->symbol_names = NULL;
}

// Find out if this object, that is a member of a lib group, should be included
// in the link. We check every symbol defined by this object. If the symbol
// table has a strong undefined reference to that symbol, we have to include
// the object.

template<int size, bool big_endian>
Archive::Should_include
Sized_relobj_file<size, big_endian>::do_should_include_member(
    Symbol_table* symtab,
    Layout* layout,
    Read_symbols_data* sd,
    std::string* why)
{
  char* tmpbuf = NULL;
  size_t tmpbuflen = 0;
  const char* sym_names =
      reinterpret_cast<const char*>(sd->symbol_names->data());
  const unsigned char* syms =
      sd->symbols->data() + sd->external_symbols_offset;
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
  size_t symcount = ((sd->symbols_size - sd->external_symbols_offset)
			 / sym_size);

  const unsigned char* p = syms;

  for (size_t i = 0; i < symcount; ++i, p += sym_size)
    {
      elfcpp::Sym<size, big_endian> sym(p);
      unsigned int st_shndx = sym.get_st_shndx();
      if (st_shndx == elfcpp::SHN_UNDEF)
	continue;

      unsigned int st_name = sym.get_st_name();
      const char* name = sym_names + st_name;
      Symbol* symbol;
      Archive::Should_include t = Archive::should_include_member(symtab,
								 layout,
								 name,
								 &symbol, why,
								 &tmpbuf,
								 &tmpbuflen);
      if (t == Archive::SHOULD_INCLUDE_YES)
	{
	  if (tmpbuf != NULL)
	    free(tmpbuf);
	  return t;
	}
    }
  if (tmpbuf != NULL)
    free(tmpbuf);
  return Archive::SHOULD_INCLUDE_UNKNOWN;
}

// Iterate over global defined symbols, calling a visitor class V for each.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_for_all_global_symbols(
    Read_symbols_data* sd,
    Library_base::Symbol_visitor_base* v)
{
  const char* sym_names =
      reinterpret_cast<const char*>(sd->symbol_names->data());
  const unsigned char* syms =
      sd->symbols->data() + sd->external_symbols_offset;
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
  size_t symcount = ((sd->symbols_size - sd->external_symbols_offset)
		     / sym_size);
  const unsigned char* p = syms;

  for (size_t i = 0; i < symcount; ++i, p += sym_size)
    {
      elfcpp::Sym<size, big_endian> sym(p);
      if (sym.get_st_shndx() != elfcpp::SHN_UNDEF)
	v->visit(sym_names + sym.get_st_name());
    }
}

// Return whether the local symbol SYMNDX has a PLT offset.

template<int size, bool big_endian>
bool
Sized_relobj_file<size, big_endian>::local_has_plt_offset(
    unsigned int symndx) const
{
  typename Local_plt_offsets::const_iterator p =
    this->local_plt_offsets_.find(symndx);
  return p != this->local_plt_offsets_.end();
}

// Get the PLT offset of a local symbol.

template<int size, bool big_endian>
unsigned int
Sized_relobj_file<size, big_endian>::do_local_plt_offset(
    unsigned int symndx) const
{
  typename Local_plt_offsets::const_iterator p =
    this->local_plt_offsets_.find(symndx);
  gold_assert(p != this->local_plt_offsets_.end());
  return p->second;
}

// Set the PLT offset of a local symbol.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::set_local_plt_offset(
    unsigned int symndx, unsigned int plt_offset)
{
  std::pair<typename Local_plt_offsets::iterator, bool> ins =
    this->local_plt_offsets_.insert(std::make_pair(symndx, plt_offset));
  gold_assert(ins.second);
}

// First pass over the local symbols.  Here we add their names to
// *POOL and *DYNPOOL, and we store the symbol value in
// THIS->LOCAL_VALUES_.  This function is always called from a
// singleton thread.  This is followed by a call to
// finalize_local_symbols.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_count_local_symbols(Stringpool* pool,
							    Stringpool* dynpool)
{
  gold_assert(this->symtab_shndx_ != -1U);
  if (this->symtab_shndx_ == 0)
    {
      // This object has no symbols.  Weird but legal.
      return;
    }

  // Read the symbol table section header.
  const unsigned int symtab_shndx = this->symtab_shndx_;
  typename This::Shdr symtabshdr(this,
				 this->elf_file_.section_header(symtab_shndx));
  gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);

  // Read the local symbols.
  const int sym_size = This::sym_size;
  const unsigned int loccount = this->local_symbol_count_;
  gold_assert(loccount == symtabshdr.get_sh_info());
  off_t locsize = loccount * sym_size;
  const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
					      locsize, true, true);

  // Read the symbol names.
  const unsigned int strtab_shndx =
    this->adjust_shndx(symtabshdr.get_sh_link());
  section_size_type strtab_size;
  const unsigned char* pnamesu = this->section_contents(strtab_shndx,
							&strtab_size,
							true);
  const char* pnames = reinterpret_cast<const char*>(pnamesu);

  // Loop over the local symbols.

  const Output_sections& out_sections(this->output_sections());
  unsigned int shnum = this->shnum();
  unsigned int count = 0;
  unsigned int dyncount = 0;
  // Skip the first, dummy, symbol.
  psyms += sym_size;
  bool strip_all = parameters->options().strip_all();
  bool discard_all = parameters->options().discard_all();
  bool discard_locals = parameters->options().discard_locals();
  for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
    {
      elfcpp::Sym<size, big_endian> sym(psyms);

      Symbol_value<size>& lv(this->local_values_[i]);

      bool is_ordinary;
      unsigned int shndx = this->adjust_sym_shndx(i, sym.get_st_shndx(),
						  &is_ordinary);
      lv.set_input_shndx(shndx, is_ordinary);

      if (sym.get_st_type() == elfcpp::STT_SECTION)
	lv.set_is_section_symbol();
      else if (sym.get_st_type() == elfcpp::STT_TLS)
	lv.set_is_tls_symbol();
      else if (sym.get_st_type() == elfcpp::STT_GNU_IFUNC)
	lv.set_is_ifunc_symbol();

      // Save the input symbol value for use in do_finalize_local_symbols().
      lv.set_input_value(sym.get_st_value());

      // Decide whether this symbol should go into the output file.

      if ((shndx < shnum && out_sections[shndx] == NULL)
	  || shndx == this->discarded_eh_frame_shndx_)
	{
	  lv.set_no_output_symtab_entry();
	  gold_assert(!lv.needs_output_dynsym_entry());
	  continue;
	}

      if (sym.get_st_type() == elfcpp::STT_SECTION)
	{
	  lv.set_no_output_symtab_entry();
	  gold_assert(!lv.needs_output_dynsym_entry());
	  continue;
	}

      if (sym.get_st_name() >= strtab_size)
	{
	  this->error(_("local symbol %u section name out of range: %u >= %u"),
		      i, sym.get_st_name(),
		      static_cast<unsigned int>(strtab_size));
	  lv.set_no_output_symtab_entry();
	  continue;
	}

      const char* name = pnames + sym.get_st_name();

      // If needed, add the symbol to the dynamic symbol table string pool.
      if (lv.needs_output_dynsym_entry())
	{
	  dynpool->add(name, true, NULL);
	  ++dyncount;
	}

      if (strip_all
	  || (discard_all && lv.may_be_discarded_from_output_symtab()))
	{
	  lv.set_no_output_symtab_entry();
	  continue;
	}

      // If --discard-locals option is used, discard all temporary local
      // symbols.  These symbols start with system-specific local label
      // prefixes, typically .L for ELF system.  We want to be compatible
      // with GNU ld so here we essentially use the same check in
      // bfd_is_local_label().  The code is different because we already
      // know that:
      //
      //   - the symbol is local and thus cannot have global or weak binding.
      //   - the symbol is not a section symbol.
      //   - the symbol has a name.
      //
      // We do not discard a symbol if it needs a dynamic symbol entry.
      if (discard_locals
	  && sym.get_st_type() != elfcpp::STT_FILE
	  && !lv.needs_output_dynsym_entry()
	  && lv.may_be_discarded_from_output_symtab()
	  && parameters->target().is_local_label_name(name))
	{
	  lv.set_no_output_symtab_entry();
	  continue;
	}

      // Discard the local symbol if -retain_symbols_file is specified
      // and the local symbol is not in that file.
      if (!parameters->options().should_retain_symbol(name))
	{
	  lv.set_no_output_symtab_entry();
	  continue;
	}

      // Add the symbol to the symbol table string pool.
      pool->add(name, true, NULL);
      ++count;
    }

  this->output_local_symbol_count_ = count;
  this->output_local_dynsym_count_ = dyncount;
}

// Compute the final value of a local symbol.

template<int size, bool big_endian>
typename Sized_relobj_file<size, big_endian>::Compute_final_local_value_status
Sized_relobj_file<size, big_endian>::compute_final_local_value_internal(
    unsigned int r_sym,
    const Symbol_value<size>* lv_in,
    Symbol_value<size>* lv_out,
    bool relocatable,
    const Output_sections& out_sections,
    const std::vector<Address>& out_offsets,
    const Symbol_table* symtab)
{
  // We are going to overwrite *LV_OUT, if it has a merged symbol value,
  // we may have a memory leak.
  gold_assert(lv_out->has_output_value());

  bool is_ordinary;
  unsigned int shndx = lv_in->input_shndx(&is_ordinary);

  // Set the output symbol value.

  if (!is_ordinary)
    {
      if (shndx == elfcpp::SHN_ABS || Symbol::is_common_shndx(shndx))
	lv_out->set_output_value(lv_in->input_value());
      else
	{
	  this->error(_("unknown section index %u for local symbol %u"),
		      shndx, r_sym);
	  lv_out->set_output_value(0);
	  return This::CFLV_ERROR;
	}
    }
  else
    {
      if (shndx >= this->shnum())
	{
	  this->error(_("local symbol %u section index %u out of range"),
		      r_sym, shndx);
	  lv_out->set_output_value(0);
	  return This::CFLV_ERROR;
	}

      Output_section* os = out_sections[shndx];
      Address secoffset = out_offsets[shndx];
      if (symtab->is_section_folded(this, shndx))
	{
	  gold_assert(os == NULL && secoffset == invalid_address);
	  // Get the os of the section it is folded onto.
	  Section_id folded = symtab->icf()->get_folded_section(this,
								shndx);
	  gold_assert(folded.first != NULL);
	  Sized_relobj_file<size, big_endian>* folded_obj = reinterpret_cast
	    <Sized_relobj_file<size, big_endian>*>(folded.first);
	  os = folded_obj->output_section(folded.second);
	  gold_assert(os != NULL);
	  secoffset = folded_obj->get_output_section_offset(folded.second);

	  // This could be a relaxed input section.
	  if (secoffset == invalid_address)
	    {
	      const Output_relaxed_input_section* relaxed_section =
		os->find_relaxed_input_section(folded_obj, folded.second);
	      gold_assert(relaxed_section != NULL);
	      secoffset = relaxed_section->address() - os->address();
	    }
	}

      if (os == NULL)
	{
	  // This local symbol belongs to a section we are discarding.
	  // In some cases when applying relocations later, we will
	  // attempt to match it to the corresponding kept section,
	  // so we leave the input value unchanged here.
	  return This::CFLV_DISCARDED;
	}
      else if (secoffset == invalid_address)
	{
	  uint64_t start;

	  // This is a SHF_MERGE section or one which otherwise
	  // requires special handling.
	  if (shndx == this->discarded_eh_frame_shndx_)
	    {
	      // This local symbol belongs to a discarded .eh_frame
	      // section.  Just treat it like the case in which
	      // os == NULL above.
	      gold_assert(this->has_eh_frame_);
	      return This::CFLV_DISCARDED;
	    }
	  else if (!lv_in->is_section_symbol())
	    {
	      // This is not a section symbol.  We can determine
	      // the final value now.
	      lv_out->set_output_value(
		  os->output_address(this, shndx, lv_in->input_value()));
	    }
	  else if (!os->find_starting_output_address(this, shndx, &start))
	    {
	      // This is a section symbol, but apparently not one in a
	      // merged section.  First check to see if this is a relaxed
	      // input section.  If so, use its address.  Otherwise just
	      // use the start of the output section.  This happens with
	      // relocatable links when the input object has section
	      // symbols for arbitrary non-merge sections.
	      const Output_section_data* posd =
		os->find_relaxed_input_section(this, shndx);
	      if (posd != NULL)
		{
		  Address relocatable_link_adjustment =
		    relocatable ? os->address() : 0;
		  lv_out->set_output_value(posd->address()
					   - relocatable_link_adjustment);
		}
	      else
		lv_out->set_output_value(os->address());
	    }
	  else
	    {
	      // We have to consider the addend to determine the
	      // value to use in a relocation.  START is the start
	      // of this input section.  If we are doing a relocatable
	      // link, use offset from start output section instead of
	      // address.
	      Address adjusted_start =
		relocatable ? start - os->address() : start;
	      Merged_symbol_value<size>* msv =
		new Merged_symbol_value<size>(lv_in->input_value(),
					      adjusted_start);
	      lv_out->set_merged_symbol_value(msv);
	    }
	}
      else if (lv_in->is_tls_symbol())
	lv_out->set_output_value(os->tls_offset()
				 + secoffset
				 + lv_in->input_value());
      else
	lv_out->set_output_value((relocatable ? 0 : os->address())
				 + secoffset
				 + lv_in->input_value());
    }
  return This::CFLV_OK;
}

// Compute final local symbol value.  R_SYM is the index of a local
// symbol in symbol table.  LV points to a symbol value, which is
// expected to hold the input value and to be over-written by the
// final value.  SYMTAB points to a symbol table.  Some targets may want
// to know would-be-finalized local symbol values in relaxation.
// Hence we provide this method.  Since this method updates *LV, a
// callee should make a copy of the original local symbol value and
// use the copy instead of modifying an object's local symbols before
// everything is finalized.  The caller should also free up any allocated
// memory in the return value in *LV.
template<int size, bool big_endian>
typename Sized_relobj_file<size, big_endian>::Compute_final_local_value_status
Sized_relobj_file<size, big_endian>::compute_final_local_value(
    unsigned int r_sym,
    const Symbol_value<size>* lv_in,
    Symbol_value<size>* lv_out,
    const Symbol_table* symtab)
{
  // This is just a wrapper of compute_final_local_value_internal.
  const bool relocatable = parameters->options().relocatable();
  const Output_sections& out_sections(this->output_sections());
  const std::vector<Address>& out_offsets(this->section_offsets());
  return this->compute_final_local_value_internal(r_sym, lv_in, lv_out,
						  relocatable, out_sections,
						  out_offsets, symtab);
}

// Finalize the local symbols.  Here we set the final value in
// THIS->LOCAL_VALUES_ and set their output symbol table indexes.
// This function is always called from a singleton thread.  The actual
// output of the local symbols will occur in a separate task.

template<int size, bool big_endian>
unsigned int
Sized_relobj_file<size, big_endian>::do_finalize_local_symbols(
    unsigned int index,
    off_t off,
    Symbol_table* symtab)
{
  gold_assert(off == static_cast<off_t>(align_address(off, size >> 3)));

  const unsigned int loccount = this->local_symbol_count_;
  this->local_symbol_offset_ = off;

  const bool relocatable = parameters->options().relocatable();
  const Output_sections& out_sections(this->output_sections());
  const std::vector<Address>& out_offsets(this->section_offsets());

  for (unsigned int i = 1; i < loccount; ++i)
    {
      Symbol_value<size>* lv = &this->local_values_[i];

      Compute_final_local_value_status cflv_status =
	this->compute_final_local_value_internal(i, lv, lv, relocatable,
						 out_sections, out_offsets,
						 symtab);
      switch (cflv_status)
	{
	case CFLV_OK:
	  if (!lv->is_output_symtab_index_set())
	    {
	      lv->set_output_symtab_index(index);
	      ++index;
	    }
	  break;
	case CFLV_DISCARDED:
	case CFLV_ERROR:
	  // Do nothing.
	  break;
	default:
	  gold_unreachable();
	}
    }
  return index;
}

// Set the output dynamic symbol table indexes for the local variables.

template<int size, bool big_endian>
unsigned int
Sized_relobj_file<size, big_endian>::do_set_local_dynsym_indexes(
    unsigned int index)
{
  const unsigned int loccount = this->local_symbol_count_;
  for (unsigned int i = 1; i < loccount; ++i)
    {
      Symbol_value<size>& lv(this->local_values_[i]);
      if (lv.needs_output_dynsym_entry())
	{
	  lv.set_output_dynsym_index(index);
	  ++index;
	}
    }
  return index;
}

// Set the offset where local dynamic symbol information will be stored.
// Returns the count of local symbols contributed to the symbol table by
// this object.

template<int size, bool big_endian>
unsigned int
Sized_relobj_file<size, big_endian>::do_set_local_dynsym_offset(off_t off)
{
  gold_assert(off == static_cast<off_t>(align_address(off, size >> 3)));
  this->local_dynsym_offset_ = off;
  return this->output_local_dynsym_count_;
}

// If Symbols_data is not NULL get the section flags from here otherwise
// get it from the file.

template<int size, bool big_endian>
uint64_t
Sized_relobj_file<size, big_endian>::do_section_flags(unsigned int shndx)
{
  Symbols_data* sd = this->get_symbols_data();
  if (sd != NULL)
    {
      const unsigned char* pshdrs = sd->section_headers_data
				    + This::shdr_size * shndx;
      typename This::Shdr shdr(pshdrs);
      return shdr.get_sh_flags();
    }
  // If sd is NULL, read the section header from the file.
  return this->elf_file_.section_flags(shndx);
}

// Get the section's ent size from Symbols_data.  Called by get_section_contents
// in icf.cc

template<int size, bool big_endian>
uint64_t
Sized_relobj_file<size, big_endian>::do_section_entsize(unsigned int shndx)
{
  Symbols_data* sd = this->get_symbols_data();
  gold_assert(sd != NULL);

  const unsigned char* pshdrs = sd->section_headers_data
				+ This::shdr_size * shndx;
  typename This::Shdr shdr(pshdrs);
  return shdr.get_sh_entsize();
}

// Write out the local symbols.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::write_local_symbols(
    Output_file* of,
    const Stringpool* sympool,
    const Stringpool* dynpool,
    Output_symtab_xindex* symtab_xindex,
    Output_symtab_xindex* dynsym_xindex,
    off_t symtab_off)
{
  const bool strip_all = parameters->options().strip_all();
  if (strip_all)
    {
      if (this->output_local_dynsym_count_ == 0)
	return;
      this->output_local_symbol_count_ = 0;
    }

  gold_assert(this->symtab_shndx_ != -1U);
  if (this->symtab_shndx_ == 0)
    {
      // This object has no symbols.  Weird but legal.
      return;
    }

  // Read the symbol table section header.
  const unsigned int symtab_shndx = this->symtab_shndx_;
  typename This::Shdr symtabshdr(this,
				 this->elf_file_.section_header(symtab_shndx));
  gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
  const unsigned int loccount = this->local_symbol_count_;
  gold_assert(loccount == symtabshdr.get_sh_info());

  // Read the local symbols.
  const int sym_size = This::sym_size;
  off_t locsize = loccount * sym_size;
  const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
					      locsize, true, false);

  // Read the symbol names.
  const unsigned int strtab_shndx =
    this->adjust_shndx(symtabshdr.get_sh_link());
  section_size_type strtab_size;
  const unsigned char* pnamesu = this->section_contents(strtab_shndx,
							&strtab_size,
							false);
  const char* pnames = reinterpret_cast<const char*>(pnamesu);

  // Get views into the output file for the portions of the symbol table
  // and the dynamic symbol table that we will be writing.
  off_t output_size = this->output_local_symbol_count_ * sym_size;
  unsigned char* oview = NULL;
  if (output_size > 0)
    oview = of->get_output_view(symtab_off + this->local_symbol_offset_,
				output_size);

  off_t dyn_output_size = this->output_local_dynsym_count_ * sym_size;
  unsigned char* dyn_oview = NULL;
  if (dyn_output_size > 0)
    dyn_oview = of->get_output_view(this->local_dynsym_offset_,
				    dyn_output_size);

  const Output_sections out_sections(this->output_sections());

  gold_assert(this->local_values_.size() == loccount);

  unsigned char* ov = oview;
  unsigned char* dyn_ov = dyn_oview;
  psyms += sym_size;
  for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
    {
      elfcpp::Sym<size, big_endian> isym(psyms);

      Symbol_value<size>& lv(this->local_values_[i]);

      bool is_ordinary;
      unsigned int st_shndx = this->adjust_sym_shndx(i, isym.get_st_shndx(),
						     &is_ordinary);
      if (is_ordinary)
	{
	  gold_assert(st_shndx < out_sections.size());
	  if (out_sections[st_shndx] == NULL)
	    continue;
	  st_shndx = out_sections[st_shndx]->out_shndx();
	  if (st_shndx >= elfcpp::SHN_LORESERVE)
	    {
	      if (lv.has_output_symtab_entry())
		symtab_xindex->add(lv.output_symtab_index(), st_shndx);
	      if (lv.has_output_dynsym_entry())
		dynsym_xindex->add(lv.output_dynsym_index(), st_shndx);
	      st_shndx = elfcpp::SHN_XINDEX;
	    }
	}

      // Write the symbol to the output symbol table.
      if (lv.has_output_symtab_entry())
	{
	  elfcpp::Sym_write<size, big_endian> osym(ov);

	  gold_assert(isym.get_st_name() < strtab_size);
	  const char* name = pnames + isym.get_st_name();
	  osym.put_st_name(sympool->get_offset(name));
	  osym.put_st_value(this->local_values_[i].value(this, 0));
	  osym.put_st_size(isym.get_st_size());
	  osym.put_st_info(isym.get_st_info());
	  osym.put_st_other(isym.get_st_other());
	  osym.put_st_shndx(st_shndx);

	  ov += sym_size;
	}

      // Write the symbol to the output dynamic symbol table.
      if (lv.has_output_dynsym_entry())
	{
	  gold_assert(dyn_ov < dyn_oview + dyn_output_size);
	  elfcpp::Sym_write<size, big_endian> osym(dyn_ov);

	  gold_assert(isym.get_st_name() < strtab_size);
	  const char* name = pnames + isym.get_st_name();
	  osym.put_st_name(dynpool->get_offset(name));
	  osym.put_st_value(this->local_values_[i].value(this, 0));
	  osym.put_st_size(isym.get_st_size());
	  osym.put_st_info(isym.get_st_info());
	  osym.put_st_other(isym.get_st_other());
	  osym.put_st_shndx(st_shndx);

	  dyn_ov += sym_size;
	}
    }


  if (output_size > 0)
    {
      gold_assert(ov - oview == output_size);
      of->write_output_view(symtab_off + this->local_symbol_offset_,
			    output_size, oview);
    }

  if (dyn_output_size > 0)
    {
      gold_assert(dyn_ov - dyn_oview == dyn_output_size);
      of->write_output_view(this->local_dynsym_offset_, dyn_output_size,
			    dyn_oview);
    }
}

// Set *INFO to symbolic information about the offset OFFSET in the
// section SHNDX.  Return true if we found something, false if we
// found nothing.

template<int size, bool big_endian>
bool
Sized_relobj_file<size, big_endian>::get_symbol_location_info(
    unsigned int shndx,
    off_t offset,
    Symbol_location_info* info)
{
  if (this->symtab_shndx_ == 0)
    return false;

  section_size_type symbols_size;
  const unsigned char* symbols = this->section_contents(this->symtab_shndx_,
							&symbols_size,
							false);

  unsigned int symbol_names_shndx =
    this->adjust_shndx(this->section_link(this->symtab_shndx_));
  section_size_type names_size;
  const unsigned char* symbol_names_u =
    this->section_contents(symbol_names_shndx, &names_size, false);
  const char* symbol_names = reinterpret_cast<const char*>(symbol_names_u);

  const int sym_size = This::sym_size;
  const size_t count = symbols_size / sym_size;

  const unsigned char* p = symbols;
  for (size_t i = 0; i < count; ++i, p += sym_size)
    {
      elfcpp::Sym<size, big_endian> sym(p);

      if (sym.get_st_type() == elfcpp::STT_FILE)
	{
	  if (sym.get_st_name() >= names_size)
	    info->source_file = "(invalid)";
	  else
	    info->source_file = symbol_names + sym.get_st_name();
	  continue;
	}

      bool is_ordinary;
      unsigned int st_shndx = this->adjust_sym_shndx(i, sym.get_st_shndx(),
						     &is_ordinary);
      if (is_ordinary
	  && st_shndx == shndx
	  && static_cast<off_t>(sym.get_st_value()) <= offset
	  && (static_cast<off_t>(sym.get_st_value() + sym.get_st_size())
	      > offset))
	{
	  if (sym.get_st_name() > names_size)
	    info->enclosing_symbol_name = "(invalid)";
	  else
	    {
	      info->enclosing_symbol_name = symbol_names + sym.get_st_name();
	      if (parameters->options().do_demangle())
		{
		  char* demangled_name = cplus_demangle(
		      info->enclosing_symbol_name.c_str(),
		      DMGL_ANSI | DMGL_PARAMS);
		  if (demangled_name != NULL)
		    {
		      info->enclosing_symbol_name.assign(demangled_name);
		      free(demangled_name);
		    }
		}
	    }
	  return true;
	}
    }

  return false;
}

// Look for a kept section corresponding to the given discarded section,
// and return its output address.  This is used only for relocations in
// debugging sections.  If we can't find the kept section, return 0.

template<int size, bool big_endian>
typename Sized_relobj_file<size, big_endian>::Address
Sized_relobj_file<size, big_endian>::map_to_kept_section(
    unsigned int shndx,
    bool* found) const
{
  Relobj* kept_object;
  unsigned int kept_shndx;
  if (this->get_kept_comdat_section(shndx, &kept_object, &kept_shndx))
    {
      Sized_relobj_file<size, big_endian>* kept_relobj =
	static_cast<Sized_relobj_file<size, big_endian>*>(kept_object);
      Output_section* os = kept_relobj->output_section(kept_shndx);
      Address offset = kept_relobj->get_output_section_offset(kept_shndx);
      if (os != NULL && offset != invalid_address)
	{
	  *found = true;
	  return os->address() + offset;
	}
    }
  *found = false;
  return 0;
}

// Get symbol counts.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_get_global_symbol_counts(
    const Symbol_table*,
    size_t* defined,
    size_t* used) const
{
  *defined = this->defined_count_;
  size_t count = 0;
  for (typename Symbols::const_iterator p = this->symbols_.begin();
       p != this->symbols_.end();
       ++p)
    if (*p != NULL
	&& (*p)->source() == Symbol::FROM_OBJECT
	&& (*p)->object() == this
	&& (*p)->is_defined())
      ++count;
  *used = count;
}

// Return a view of the decompressed contents of a section.  Set *PLEN
// to the size.  Set *IS_NEW to true if the contents need to be freed
// by the caller.

template<int size, bool big_endian>
const unsigned char*
Sized_relobj_file<size, big_endian>::do_decompressed_section_contents(
    unsigned int shndx,
    section_size_type* plen,
    bool* is_new)
{
  section_size_type buffer_size;
  const unsigned char* buffer = this->do_section_contents(shndx, &buffer_size,
							  false);

  if (this->compressed_sections_ == NULL)
    {
      *plen = buffer_size;
      *is_new = false;
      return buffer;
    }

  Compressed_section_map::const_iterator p =
      this->compressed_sections_->find(shndx);
  if (p == this->compressed_sections_->end())
    {
      *plen = buffer_size;
      *is_new = false;
      return buffer;
    }

  section_size_type uncompressed_size = p->second.size;
  if (p->second.contents != NULL)
    {
      *plen = uncompressed_size;
      *is_new = false;
      return p->second.contents;
    }

  unsigned char* uncompressed_data = new unsigned char[uncompressed_size];
  if (!decompress_input_section(buffer,
				buffer_size,
				uncompressed_data,
				uncompressed_size))
    this->error(_("could not decompress section %s"),
		this->do_section_name(shndx).c_str());

  // We could cache the results in p->second.contents and store
  // false in *IS_NEW, but build_compressed_section_map() would
  // have done so if it had expected it to be profitable.  If
  // we reach this point, we expect to need the contents only
  // once in this pass.
  *plen = uncompressed_size;
  *is_new = true;
  return uncompressed_data;
}

// Discard any buffers of uncompressed sections.  This is done
// at the end of the Add_symbols task.

template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::do_discard_decompressed_sections()
{
  if (this->compressed_sections_ == NULL)
    return;

  for (Compressed_section_map::iterator p = this->compressed_sections_->begin();
       p != this->compressed_sections_->end();
       ++p)
    {
      if (p->second.contents != NULL)
	{
	  delete[] p->second.contents;
	  p->second.contents = NULL;
	}
    }
}

// Input_objects methods.

// Add a regular relocatable object to the list.  Return false if this
// object should be ignored.

bool
Input_objects::add_object(Object* obj)
{
  // Print the filename if the -t/--trace option is selected.
  if (parameters->options().trace())
    gold_info("%s", obj->name().c_str());

  if (!obj->is_dynamic())
    this->relobj_list_.push_back(static_cast<Relobj*>(obj));
  else
    {
      // See if this is a duplicate SONAME.
      Dynobj* dynobj = static_cast<Dynobj*>(obj);
      const char* soname = dynobj->soname();

      std::pair<Unordered_set<std::string>::iterator, bool> ins =
	this->sonames_.insert(soname);
      if (!ins.second)
	{
	  // We have already seen a dynamic object with this soname.
	  return false;
	}

      this->dynobj_list_.push_back(dynobj);
    }

  // Add this object to the cross-referencer if requested.
  if (parameters->options().user_set_print_symbol_counts()
      || parameters->options().cref())
    {
      if (this->cref_ == NULL)
	this->cref_ = new Cref();
      this->cref_->add_object(obj);
    }

  return true;
}

// For each dynamic object, record whether we've seen all of its
// explicit dependencies.

void
Input_objects::check_dynamic_dependencies() const
{
  bool issued_copy_dt_needed_error = false;
  for (Dynobj_list::const_iterator p = this->dynobj_list_.begin();
       p != this->dynobj_list_.end();
       ++p)
    {
      const Dynobj::Needed& needed((*p)->needed());
      bool found_all = true;
      Dynobj::Needed::const_iterator pneeded;
      for (pneeded = needed.begin(); pneeded != needed.end(); ++pneeded)
	{
	  if (this->sonames_.find(*pneeded) == this->sonames_.end())
	    {
	      found_all = false;
	      break;
	    }
	}
      (*p)->set_has_unknown_needed_entries(!found_all);

      // --copy-dt-needed-entries aka --add-needed is a GNU ld option
      // that gold does not support.  However, they cause no trouble
      // unless there is a DT_NEEDED entry that we don't know about;
      // warn only in that case.
      if (!found_all
	  && !issued_copy_dt_needed_error
	  && (parameters->options().copy_dt_needed_entries()
	      || parameters->options().add_needed()))
	{
	  const char* optname;
	  if (parameters->options().copy_dt_needed_entries())
	    optname = "--copy-dt-needed-entries";
	  else
	    optname = "--add-needed";
	  gold_error(_("%s is not supported but is required for %s in %s"),
		     optname, (*pneeded).c_str(), (*p)->name().c_str());
	  issued_copy_dt_needed_error = true;
	}
    }
}

// Start processing an archive.

void
Input_objects::archive_start(Archive* archive)
{
  if (parameters->options().user_set_print_symbol_counts()
      || parameters->options().cref())
    {
      if (this->cref_ == NULL)
	this->cref_ = new Cref();
      this->cref_->add_archive_start(archive);
    }
}

// Stop processing an archive.

void
Input_objects::archive_stop(Archive* archive)
{
  if (parameters->options().user_set_print_symbol_counts()
      || parameters->options().cref())
    this->cref_->add_archive_stop(archive);
}

// Print symbol counts

void
Input_objects::print_symbol_counts(const Symbol_table* symtab) const
{
  if (parameters->options().user_set_print_symbol_counts()
      && this->cref_ != NULL)
    this->cref_->print_symbol_counts(symtab);
}

// Print a cross reference table.

void
Input_objects::print_cref(const Symbol_table* symtab, FILE* f) const
{
  if (parameters->options().cref() && this->cref_ != NULL)
    this->cref_->print_cref(symtab, f);
}

// Relocate_info methods.

// Return a string describing the location of a relocation when file
// and lineno information is not available.  This is only used in
// error messages.

template<int size, bool big_endian>
std::string
Relocate_info<size, big_endian>::location(size_t, off_t offset) const
{
  Sized_dwarf_line_info<size, big_endian> line_info(this->object);
  std::string ret = line_info.addr2line(this->data_shndx, offset, NULL);
  if (!ret.empty())
    return ret;

  ret = this->object->name();

  Symbol_location_info info;
  if (this->object->get_symbol_location_info(this->data_shndx, offset, &info))
    {
      if (!info.source_file.empty())
	{
	  ret += ":";
	  ret += info.source_file;
	}
      size_t len = info.enclosing_symbol_name.length() + 100;
      char* buf = new char[len];
      snprintf(buf, len, _(":function %s"),
	       info.enclosing_symbol_name.c_str());
      ret += buf;
      delete[] buf;
      return ret;
    }

  ret += "(";
  ret += this->object->section_name(this->data_shndx);
  char buf[100];
  snprintf(buf, sizeof buf, "+0x%lx)", static_cast<long>(offset));
  ret += buf;
  return ret;
}

} // End namespace gold.

namespace
{

using namespace gold;

// Read an ELF file with the header and return the appropriate
// instance of Object.

template<int size, bool big_endian>
Object*
make_elf_sized_object(const std::string& name, Input_file* input_file,
		      off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr,
		      bool* punconfigured)
{
  Target* target = select_target(input_file, offset,
				 ehdr.get_e_machine(), size, big_endian,
				 ehdr.get_e_ident()[elfcpp::EI_OSABI],
				 ehdr.get_e_ident()[elfcpp::EI_ABIVERSION]);
  if (target == NULL)
    gold_fatal(_("%s: unsupported ELF machine number %d"),
	       name.c_str(), ehdr.get_e_machine());

  if (!parameters->target_valid())
    set_parameters_target(target);
  else if (target != &parameters->target())
    {
      if (punconfigured != NULL)
	*punconfigured = true;
      else
	gold_error(_("%s: incompatible target"), name.c_str());
      return NULL;
    }

  return target->make_elf_object<size, big_endian>(name, input_file, offset,
						   ehdr);
}

} // End anonymous namespace.

namespace gold
{

// Return whether INPUT_FILE is an ELF object.

bool
is_elf_object(Input_file* input_file, off_t offset,
	      const unsigned char** start, int* read_size)
{
  off_t filesize = input_file->file().filesize();
  int want = elfcpp::Elf_recognizer::max_header_size;
  if (filesize - offset < want)
    want = filesize - offset;

  const unsigned char* p = input_file->file().get_view(offset, 0, want,
						       true, false);
  *start = p;
  *read_size = want;

  return elfcpp::Elf_recognizer::is_elf_file(p, want);
}

// Read an ELF file and return the appropriate instance of Object.

Object*
make_elf_object(const std::string& name, Input_file* input_file, off_t offset,
		const unsigned char* p, section_offset_type bytes,
		bool* punconfigured)
{
  if (punconfigured != NULL)
    *punconfigured = false;

  std::string error;
  bool big_endian = false;
  int size = 0;
  if (!elfcpp::Elf_recognizer::is_valid_header(p, bytes, &size,
					       &big_endian, &error))
    {
      gold_error(_("%s: %s"), name.c_str(), error.c_str());
      return NULL;
    }

  if (size == 32)
    {
      if (big_endian)
	{
#ifdef HAVE_TARGET_32_BIG
	  elfcpp::Ehdr<32, true> ehdr(p);
	  return make_elf_sized_object<32, true>(name, input_file,
						 offset, ehdr, punconfigured);
#else
	  if (punconfigured != NULL)
	    *punconfigured = true;
	  else
	    gold_error(_("%s: not configured to support "
			 "32-bit big-endian object"),
		       name.c_str());
	  return NULL;
#endif
	}
      else
	{
#ifdef HAVE_TARGET_32_LITTLE
	  elfcpp::Ehdr<32, false> ehdr(p);
	  return make_elf_sized_object<32, false>(name, input_file,
						  offset, ehdr, punconfigured);
#else
	  if (punconfigured != NULL)
	    *punconfigured = true;
	  else
	    gold_error(_("%s: not configured to support "
			 "32-bit little-endian object"),
		       name.c_str());
	  return NULL;
#endif
	}
    }
  else if (size == 64)
    {
      if (big_endian)
	{
#ifdef HAVE_TARGET_64_BIG
	  elfcpp::Ehdr<64, true> ehdr(p);
	  return make_elf_sized_object<64, true>(name, input_file,
						 offset, ehdr, punconfigured);
#else
	  if (punconfigured != NULL)
	    *punconfigured = true;
	  else
	    gold_error(_("%s: not configured to support "
			 "64-bit big-endian object"),
		       name.c_str());
	  return NULL;
#endif
	}
      else
	{
#ifdef HAVE_TARGET_64_LITTLE
	  elfcpp::Ehdr<64, false> ehdr(p);
	  return make_elf_sized_object<64, false>(name, input_file,
						  offset, ehdr, punconfigured);
#else
	  if (punconfigured != NULL)
	    *punconfigured = true;
	  else
	    gold_error(_("%s: not configured to support "
			 "64-bit little-endian object"),
		       name.c_str());
	  return NULL;
#endif
	}
    }
  else
    gold_unreachable();
}

// Instantiate the templates we need.

#ifdef HAVE_TARGET_32_LITTLE
template
void
Object::read_section_data<32, false>(elfcpp::Elf_file<32, false, Object>*,
				     Read_symbols_data*);
#endif

#ifdef HAVE_TARGET_32_BIG
template
void
Object::read_section_data<32, true>(elfcpp::Elf_file<32, true, Object>*,
				    Read_symbols_data*);
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
void
Object::read_section_data<64, false>(elfcpp::Elf_file<64, false, Object>*,
				     Read_symbols_data*);
#endif

#ifdef HAVE_TARGET_64_BIG
template
void
Object::read_section_data<64, true>(elfcpp::Elf_file<64, true, Object>*,
				    Read_symbols_data*);
#endif

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

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

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

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

#ifdef HAVE_TARGET_32_LITTLE
template
struct Relocate_info<32, false>;
#endif

#ifdef HAVE_TARGET_32_BIG
template
struct Relocate_info<32, true>;
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
struct Relocate_info<64, false>;
#endif

#ifdef HAVE_TARGET_64_BIG
template
struct Relocate_info<64, true>;
#endif

#ifdef HAVE_TARGET_32_LITTLE
template
void
Xindex::initialize_symtab_xindex<32, false>(Object*, unsigned int);

template
void
Xindex::read_symtab_xindex<32, false>(Object*, unsigned int,
				      const unsigned char*);
#endif

#ifdef HAVE_TARGET_32_BIG
template
void
Xindex::initialize_symtab_xindex<32, true>(Object*, unsigned int);

template
void
Xindex::read_symtab_xindex<32, true>(Object*, unsigned int,
				     const unsigned char*);
#endif

#ifdef HAVE_TARGET_64_LITTLE
template
void
Xindex::initialize_symtab_xindex<64, false>(Object*, unsigned int);

template
void
Xindex::read_symtab_xindex<64, false>(Object*, unsigned int,
				      const unsigned char*);
#endif

#ifdef HAVE_TARGET_64_BIG
template
void
Xindex::initialize_symtab_xindex<64, true>(Object*, unsigned int);

template
void
Xindex::read_symtab_xindex<64, true>(Object*, unsigned int,
				     const unsigned char*);
#endif

} // End namespace gold.
