// target-reloc.h -- target specific relocation support  -*- C++ -*-

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

// This file is part of gold.

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

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

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

#ifndef GOLD_TARGET_RELOC_H
#define GOLD_TARGET_RELOC_H

#include "elfcpp.h"
#include "symtab.h"
#include "object.h"
#include "reloc.h"
#include "reloc-types.h"

namespace gold
{

// This function implements the generic part of reloc scanning.  The
// template parameter Scan must be a class type which provides two
// functions: local() and global().  Those functions implement the
// machine specific part of scanning.  We do it this way to
// avoid making a function call for each relocation, and to avoid
// repeating the generic code for each target.

template<int size, bool big_endian, typename Target_type, int sh_type,
	 typename Scan>
inline void
scan_relocs(
    Symbol_table* symtab,
    Layout* layout,
    Target_type* target,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    size_t local_count,
    const unsigned char* plocal_syms)
{
  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
  Scan scan;

  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
    {
      Reltype reloc(prelocs);

      if (needs_special_offset_handling
	  && !output_section->is_input_address_mapped(object, data_shndx,
						      reloc.get_r_offset()))
	continue;

      typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
      unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
      unsigned int r_type = elfcpp::elf_r_type<size>(r_info);

      if (r_sym < local_count)
	{
	  gold_assert(plocal_syms != NULL);
	  typename elfcpp::Sym<size, big_endian> lsym(plocal_syms
						      + r_sym * sym_size);
	  unsigned int shndx = lsym.get_st_shndx();
	  bool is_ordinary;
	  shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
	  // If RELOC is a relocation against a local symbol in a
	  // section we are discarding then we can ignore it.  It will
	  // eventually become a reloc against the value zero.
	  //
	  // FIXME: We should issue a warning if this is an
	  // allocated section; is this the best place to do it?
	  // 
	  // FIXME: The old GNU linker would in some cases look
	  // for the linkonce section which caused this section to
	  // be discarded, and, if the other section was the same
	  // size, change the reloc to refer to the other section.
	  // That seems risky and weird to me, and I don't know of
	  // any case where it is actually required.
	  bool is_discarded = (is_ordinary
			       && shndx != elfcpp::SHN_UNDEF
			       && !object->is_section_included(shndx)
			       && !symtab->is_section_folded(object, shndx));
	  scan.local(symtab, layout, target, object, data_shndx,
		     output_section, reloc, r_type, lsym, is_discarded);
	}
      else
	{
	  Symbol* gsym = object->global_symbol(r_sym);
	  gold_assert(gsym != NULL);
	  if (gsym->is_forwarder())
	    gsym = symtab->resolve_forwards(gsym);

	  scan.global(symtab, layout, target, object, data_shndx,
		      output_section, reloc, r_type, gsym);
	}
    }
}

// Behavior for relocations to discarded comdat sections.

enum Comdat_behavior
{
  CB_UNDETERMINED,   // Not yet determined -- need to look at section name.
  CB_PRETEND,        // Attempt to map to the corresponding kept section.
  CB_IGNORE,         // Ignore the relocation.
  CB_WARNING         // Print a warning.
};

// Decide what the linker should do for relocations that refer to discarded
// comdat sections.  This decision is based on the name of the section being
// relocated.

inline Comdat_behavior
get_comdat_behavior(const char* name)
{
  if (Layout::is_debug_info_section(name))
    return CB_PRETEND;
  if (strcmp(name, ".eh_frame") == 0
      || strcmp(name, ".gcc_except_table") == 0)
    return CB_IGNORE;
  return CB_WARNING;
}

// Give an error for a symbol with non-default visibility which is not
// defined locally.

inline void
visibility_error(const Symbol* sym)
{
  const char* v;
  switch (sym->visibility())
    {
    case elfcpp::STV_INTERNAL:
      v = _("internal");
      break;
    case elfcpp::STV_HIDDEN:
      v = _("hidden");
      break;
    case elfcpp::STV_PROTECTED:
      v = _("protected");
      break;
    default:
      gold_unreachable();
    }
  gold_error(_("%s symbol '%s' is not defined locally"),
	     v, sym->name());
}

// Return true if we are should issue an error saying that SYM is an
// undefined symbol.  This is called if there is a relocation against
// SYM.

inline bool
issue_undefined_symbol_error(const Symbol* sym)
{
  // We only report global symbols.
  if (sym == NULL)
    return false;

  // We only report undefined symbols.
  if (!sym->is_undefined() && !sym->is_placeholder())
    return false;

  // We don't report weak symbols.
  if (sym->binding() == elfcpp::STB_WEAK)
    return false;

  // We don't report symbols defined in discarded sections.
  if (sym->is_defined_in_discarded_section())
    return false;

  // If the target defines this symbol, don't report it here.
  if (parameters->target().is_defined_by_abi(sym))
    return false;

  // See if we've been told to ignore whether this symbol is
  // undefined.
  const char* const u = parameters->options().unresolved_symbols();
  if (u != NULL)
    {
      if (strcmp(u, "ignore-all") == 0)
	return false;
      if (strcmp(u, "report-all") == 0)
	return true;
      if (strcmp(u, "ignore-in-object-files") == 0 && !sym->in_dyn())
	return false;
      if (strcmp(u, "ignore-in-shared-libs") == 0 && !sym->in_reg())
	return false;
    }

  // When creating a shared library, only report unresolved symbols if
  // -z defs was used.
  if (parameters->options().shared() && !parameters->options().defs())
    return false;

  // Otherwise issue a warning.
  return true;
}

// This function implements the generic part of relocation processing.
// The template parameter Relocate must be a class type which provides
// a single function, relocate(), which implements the machine
// specific part of a relocation.

// SIZE is the ELF size: 32 or 64.  BIG_ENDIAN is the endianness of
// the data.  SH_TYPE is the section type: SHT_REL or SHT_RELA.
// RELOCATE implements operator() to do a relocation.

// PRELOCS points to the relocation data.  RELOC_COUNT is the number
// of relocs.  OUTPUT_SECTION is the output section.
// NEEDS_SPECIAL_OFFSET_HANDLING is true if input offsets need to be
// mapped to output offsets.

// VIEW is the section data, VIEW_ADDRESS is its memory address, and
// VIEW_SIZE is the size.  These refer to the input section, unless
// NEEDS_SPECIAL_OFFSET_HANDLING is true, in which case they refer to
// the output section.

// RELOC_SYMBOL_CHANGES is used for -fsplit-stack support.  If it is
// not NULL, it is a vector indexed by relocation index.  If that
// entry is not NULL, it points to a global symbol which used as the
// symbol for the relocation, ignoring the symbol index in the
// relocation.

template<int size, bool big_endian, typename Target_type, int sh_type,
	 typename Relocate>
inline void
relocate_section(
    const Relocate_info<size, big_endian>* relinfo,
    Target_type* target,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    unsigned char* view,
    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
    section_size_type view_size,
    const Reloc_symbol_changes* reloc_symbol_changes)
{
  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
  Relocate relocate;

  Sized_relobj_file<size, big_endian>* object = relinfo->object;
  unsigned int local_count = object->local_symbol_count();

  Comdat_behavior comdat_behavior = CB_UNDETERMINED;

  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
    {
      Reltype reloc(prelocs);

      section_offset_type offset =
	convert_to_section_size_type(reloc.get_r_offset());

      if (needs_special_offset_handling)
	{
	  offset = output_section->output_offset(relinfo->object,
						 relinfo->data_shndx,
						 offset);
	  if (offset == -1)
	    continue;
	}

      typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
      unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
      unsigned int r_type = elfcpp::elf_r_type<size>(r_info);

      const Sized_symbol<size>* sym;

      Symbol_value<size> symval;
      const Symbol_value<size> *psymval;
      bool is_defined_in_discarded_section;
      unsigned int shndx;
      if (r_sym < local_count
	  && (reloc_symbol_changes == NULL
	      || (*reloc_symbol_changes)[i] == NULL))
	{
	  sym = NULL;
	  psymval = object->local_symbol(r_sym);

          // If the local symbol belongs to a section we are discarding,
          // and that section is a debug section, try to find the
          // corresponding kept section and map this symbol to its
          // counterpart in the kept section.  The symbol must not 
          // correspond to a section we are folding.
	  bool is_ordinary;
	  shndx = psymval->input_shndx(&is_ordinary);
	  is_defined_in_discarded_section =
	    (is_ordinary
	     && shndx != elfcpp::SHN_UNDEF
	     && !object->is_section_included(shndx)
	     && !relinfo->symtab->is_section_folded(object, shndx));
	}
      else
	{
	  const Symbol* gsym;
	  if (reloc_symbol_changes != NULL
	      && (*reloc_symbol_changes)[i] != NULL)
	    gsym = (*reloc_symbol_changes)[i];
	  else
	    {
	      gsym = object->global_symbol(r_sym);
	      gold_assert(gsym != NULL);
	      if (gsym->is_forwarder())
		gsym = relinfo->symtab->resolve_forwards(gsym);
	    }

	  sym = static_cast<const Sized_symbol<size>*>(gsym);
	  if (sym->has_symtab_index() && sym->symtab_index() != -1U)
	    symval.set_output_symtab_index(sym->symtab_index());
	  else
	    symval.set_no_output_symtab_entry();
	  symval.set_output_value(sym->value());
	  if (gsym->type() == elfcpp::STT_TLS)
	    symval.set_is_tls_symbol();
	  else if (gsym->type() == elfcpp::STT_GNU_IFUNC)
	    symval.set_is_ifunc_symbol();
	  psymval = &symval;

	  is_defined_in_discarded_section =
	    (gsym->is_defined_in_discarded_section()
	     && gsym->is_undefined());
	  shndx = 0;
	}

      Symbol_value<size> symval2;
      if (is_defined_in_discarded_section)
	{
	  if (comdat_behavior == CB_UNDETERMINED)
	    {
	      std::string name = object->section_name(relinfo->data_shndx);
	      comdat_behavior = get_comdat_behavior(name.c_str());
	    }
	  if (comdat_behavior == CB_PRETEND)
	    {
	      // FIXME: This case does not work for global symbols.
	      // We have no place to store the original section index.
	      // Fortunately this does not matter for comdat sections,
	      // only for sections explicitly discarded by a linker
	      // script.
	      bool found;
	      typename elfcpp::Elf_types<size>::Elf_Addr value =
		object->map_to_kept_section(shndx, &found);
	      if (found)
		symval2.set_output_value(value + psymval->input_value());
	      else
		symval2.set_output_value(0);
	    }
	  else
	    {
	      if (comdat_behavior == CB_WARNING)
		gold_warning_at_location(relinfo, i, offset,
					 _("relocation refers to discarded "
					   "section"));
	      symval2.set_output_value(0);
	    }
	  symval2.set_no_output_symtab_entry();
	  psymval = &symval2;
	}

      if (!relocate.relocate(relinfo, target, output_section, i, reloc,
			     r_type, sym, psymval, view + offset,
			     view_address + offset, view_size))
	continue;

      if (offset < 0 || static_cast<section_size_type>(offset) >= view_size)
	{
	  gold_error_at_location(relinfo, i, offset,
				 _("reloc has bad offset %zu"),
				 static_cast<size_t>(offset));
	  continue;
	}

      if (issue_undefined_symbol_error(sym))
	gold_undefined_symbol_at_location(sym, relinfo, i, offset);
      else if (sym != NULL
	       && sym->visibility() != elfcpp::STV_DEFAULT
	       && (sym->is_undefined() || sym->is_from_dynobj()))
	visibility_error(sym);

      if (sym != NULL && sym->has_warning())
	relinfo->symtab->issue_warning(sym, relinfo, i, offset);
    }
}

// Apply an incremental relocation.

template<int size, bool big_endian, typename Target_type,
	 typename Relocate>
void
apply_relocation(const Relocate_info<size, big_endian>* relinfo,
		 Target_type* target,
		 typename elfcpp::Elf_types<size>::Elf_Addr r_offset,
		 unsigned int r_type,
		 typename elfcpp::Elf_types<size>::Elf_Swxword r_addend,
		 const Symbol* gsym,
		 unsigned char* view,
		 typename elfcpp::Elf_types<size>::Elf_Addr address,
		 section_size_type view_size)
{
  // Construct the ELF relocation in a temporary buffer.
  const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
  unsigned char relbuf[reloc_size];
  elfcpp::Rela<size, big_endian> rel(relbuf);
  elfcpp::Rela_write<size, big_endian> orel(relbuf);
  orel.put_r_offset(r_offset);
  orel.put_r_info(elfcpp::elf_r_info<size>(0, r_type));
  orel.put_r_addend(r_addend);

  // Setup a Symbol_value for the global symbol.
  const Sized_symbol<size>* sym = static_cast<const Sized_symbol<size>*>(gsym);
  Symbol_value<size> symval;
  gold_assert(sym->has_symtab_index() && sym->symtab_index() != -1U);
  symval.set_output_symtab_index(sym->symtab_index());
  symval.set_output_value(sym->value());
  if (gsym->type() == elfcpp::STT_TLS)
    symval.set_is_tls_symbol();
  else if (gsym->type() == elfcpp::STT_GNU_IFUNC)
    symval.set_is_ifunc_symbol();

  Relocate relocate;
  relocate.relocate(relinfo, target, NULL, -1U, rel, r_type, sym, &symval,
		    view + r_offset, address + r_offset, view_size);
}

// This class may be used as a typical class for the
// Scan_relocatable_reloc parameter to scan_relocatable_relocs.  The
// template parameter Classify_reloc must be a class type which
// provides a function get_size_for_reloc which returns the number of
// bytes to which a reloc applies.  This class is intended to capture
// the most typical target behaviour, while still permitting targets
// to define their own independent class for Scan_relocatable_reloc.

template<int sh_type, typename Classify_reloc>
class Default_scan_relocatable_relocs
{
 public:
  // Return the strategy to use for a local symbol which is not a
  // section symbol, given the relocation type.
  inline Relocatable_relocs::Reloc_strategy
  local_non_section_strategy(unsigned int r_type, Relobj*, unsigned int r_sym)
  {
    // We assume that relocation type 0 is NONE.  Targets which are
    // different must override.
    if (r_type == 0 && r_sym == 0)
      return Relocatable_relocs::RELOC_DISCARD;
    return Relocatable_relocs::RELOC_COPY;
  }

  // Return the strategy to use for a local symbol which is a section
  // symbol, given the relocation type.
  inline Relocatable_relocs::Reloc_strategy
  local_section_strategy(unsigned int r_type, Relobj* object)
  {
    if (sh_type == elfcpp::SHT_RELA)
      return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
    else
      {
	Classify_reloc classify;
	switch (classify.get_size_for_reloc(r_type, object))
	  {
	  case 0:
	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
	  case 1:
	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1;
	  case 2:
	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2;
	  case 4:
	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4;
	  case 8:
	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8;
	  default:
	    gold_unreachable();
	  }
      }
  }

  // Return the strategy to use for a global symbol, given the
  // relocation type, the object, and the symbol index.
  inline Relocatable_relocs::Reloc_strategy
  global_strategy(unsigned int, Relobj*, unsigned int)
  { return Relocatable_relocs::RELOC_COPY; }
};

// Scan relocs during a relocatable link.  This is a default
// definition which should work for most targets.
// Scan_relocatable_reloc must name a class type which provides three
// functions which return a Relocatable_relocs::Reloc_strategy code:
// global_strategy, local_non_section_strategy, and
// local_section_strategy.  Most targets should be able to use
// Default_scan_relocatable_relocs as this class.

template<int size, bool big_endian, int sh_type,
	 typename Scan_relocatable_reloc>
void
scan_relocatable_relocs(
    Symbol_table*,
    Layout*,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    size_t local_symbol_count,
    const unsigned char* plocal_syms,
    Relocatable_relocs* rr)
{
  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
  Scan_relocatable_reloc scan;

  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
    {
      Reltype reloc(prelocs);

      Relocatable_relocs::Reloc_strategy strategy;

      if (needs_special_offset_handling
	  && !output_section->is_input_address_mapped(object, data_shndx,
						      reloc.get_r_offset()))
	strategy = Relocatable_relocs::RELOC_DISCARD;
      else
	{
	  typename elfcpp::Elf_types<size>::Elf_WXword r_info =
	    reloc.get_r_info();
	  const unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
	  const unsigned int r_type = elfcpp::elf_r_type<size>(r_info);

	  if (r_sym >= local_symbol_count)
	    strategy = scan.global_strategy(r_type, object, r_sym);
	  else
	    {
	      gold_assert(plocal_syms != NULL);
	      typename elfcpp::Sym<size, big_endian> lsym(plocal_syms
							  + r_sym * sym_size);
	      unsigned int shndx = lsym.get_st_shndx();
	      bool is_ordinary;
	      shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
	      if (is_ordinary
		  && shndx != elfcpp::SHN_UNDEF
		  && !object->is_section_included(shndx))
		{
		  // RELOC is a relocation against a local symbol
		  // defined in a section we are discarding.  Discard
		  // the reloc.  FIXME: Should we issue a warning?
		  strategy = Relocatable_relocs::RELOC_DISCARD;
		}
	      else if (lsym.get_st_type() != elfcpp::STT_SECTION)
		strategy = scan.local_non_section_strategy(r_type, object,
							   r_sym);
	      else
		{
		  strategy = scan.local_section_strategy(r_type, object);
		  if (strategy != Relocatable_relocs::RELOC_DISCARD)
                    object->output_section(shndx)->set_needs_symtab_index();
		}

	      if (strategy == Relocatable_relocs::RELOC_COPY)
		object->set_must_have_output_symtab_entry(r_sym);
	    }
	}

      rr->set_next_reloc_strategy(strategy);
    }
}

// Relocate relocs.  Called for a relocatable link, and for --emit-relocs.
// This is a default definition which should work for most targets.

template<int size, bool big_endian, int sh_type>
void
relocate_relocs(
    const Relocate_info<size, big_endian>* relinfo,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
    const Relocatable_relocs* rr,
    unsigned char* view,
    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
    section_size_type view_size,
    unsigned char* reloc_view,
    section_size_type reloc_view_size)
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
  typedef typename Reloc_types<sh_type, size, big_endian>::Reloc_write
    Reltype_write;
  const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
  const Address invalid_address = static_cast<Address>(0) - 1;

  Sized_relobj_file<size, big_endian>* const object = relinfo->object;
  const unsigned int local_count = object->local_symbol_count();

  unsigned char* pwrite = reloc_view;

  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
    {
      Relocatable_relocs::Reloc_strategy strategy = rr->strategy(i);
      if (strategy == Relocatable_relocs::RELOC_DISCARD)
	continue;

      if (strategy == Relocatable_relocs::RELOC_SPECIAL)
	{
	  // Target wants to handle this relocation.
	  Sized_target<size, big_endian>* target =
	    parameters->sized_target<size, big_endian>();
	  target->relocate_special_relocatable(relinfo, sh_type, prelocs,
					       i, output_section,
					       offset_in_output_section,
					       view, view_address,
					       view_size, pwrite);
	  pwrite += reloc_size;
	  continue;
	}
      Reltype reloc(prelocs);
      Reltype_write reloc_write(pwrite);

      typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
      const unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
      const unsigned int r_type = elfcpp::elf_r_type<size>(r_info);

      // Get the new symbol index.

      unsigned int new_symndx;
      if (r_sym < local_count)
	{
	  switch (strategy)
	    {
	    case Relocatable_relocs::RELOC_COPY:
	      if (r_sym == 0)
		new_symndx = 0;
	      else
		{
		  new_symndx = object->symtab_index(r_sym);
		  gold_assert(new_symndx != -1U);
		}
	      break;

	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA:
	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0:
	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1:
	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2:
	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4:
	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8:
	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED:
	      {
		// We are adjusting a section symbol.  We need to find
		// the symbol table index of the section symbol for
		// the output section corresponding to input section
		// in which this symbol is defined.
		gold_assert(r_sym < local_count);
		bool is_ordinary;
		unsigned int shndx =
		  object->local_symbol_input_shndx(r_sym, &is_ordinary);
		gold_assert(is_ordinary);
		Output_section* os = object->output_section(shndx);
		gold_assert(os != NULL);
		gold_assert(os->needs_symtab_index());
		new_symndx = os->symtab_index();
	      }
	      break;

	    default:
	      gold_unreachable();
	    }
	}
      else
	{
	  const Symbol* gsym = object->global_symbol(r_sym);
	  gold_assert(gsym != NULL);
	  if (gsym->is_forwarder())
	    gsym = relinfo->symtab->resolve_forwards(gsym);

	  gold_assert(gsym->has_symtab_index());
	  new_symndx = gsym->symtab_index();
	}

      // Get the new offset--the location in the output section where
      // this relocation should be applied.

      Address offset = reloc.get_r_offset();
      Address new_offset;
      if (offset_in_output_section != invalid_address)
	new_offset = offset + offset_in_output_section;
      else
	{
          section_offset_type sot_offset =
              convert_types<section_offset_type, Address>(offset);
	  section_offset_type new_sot_offset =
              output_section->output_offset(object, relinfo->data_shndx,
                                            sot_offset);
	  gold_assert(new_sot_offset != -1);
          new_offset = new_sot_offset;
	}

      // In an object file, r_offset is an offset within the section.
      // In an executable or dynamic object, generated by
      // --emit-relocs, r_offset is an absolute address.
      if (!parameters->options().relocatable())
	{
	  new_offset += view_address;
	  if (offset_in_output_section != invalid_address)
	    new_offset -= offset_in_output_section;
	}

      reloc_write.put_r_offset(new_offset);
      reloc_write.put_r_info(elfcpp::elf_r_info<size>(new_symndx, r_type));

      // Handle the reloc addend based on the strategy.

      if (strategy == Relocatable_relocs::RELOC_COPY)
	{
	  if (sh_type == elfcpp::SHT_RELA)
	    Reloc_types<sh_type, size, big_endian>::
	      copy_reloc_addend(&reloc_write,
				&reloc);
	}
      else
	{
	  // The relocation uses a section symbol in the input file.
	  // We are adjusting it to use a section symbol in the output
	  // file.  The input section symbol refers to some address in
	  // the input section.  We need the relocation in the output
	  // file to refer to that same address.  This adjustment to
	  // the addend is the same calculation we use for a simple
	  // absolute relocation for the input section symbol.

	  const Symbol_value<size>* psymval = object->local_symbol(r_sym);

	  unsigned char* padd = view + offset;
	  switch (strategy)
	    {
	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA:
	      {
		typename elfcpp::Elf_types<size>::Elf_Swxword addend;
		addend = Reloc_types<sh_type, size, big_endian>::
			   get_reloc_addend(&reloc);
		addend = psymval->value(object, addend);
		Reloc_types<sh_type, size, big_endian>::
		  set_reloc_addend(&reloc_write, addend);
	      }
	      break;

	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0:
	      break;

	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_1:
	      Relocate_functions<size, big_endian>::rel8(padd, object,
							 psymval);
	      break;

	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_2:
	      Relocate_functions<size, big_endian>::rel16(padd, object,
							  psymval);
	      break;

	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4:
	      Relocate_functions<size, big_endian>::rel32(padd, object,
							  psymval);
	      break;

	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_8:
	      Relocate_functions<size, big_endian>::rel64(padd, object,
							  psymval);
	      break;

	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED:
	      Relocate_functions<size, big_endian>::rel32_unaligned(padd,
								    object,
								    psymval);
	      break;

	    default:
	      gold_unreachable();
	    }
	}

      pwrite += reloc_size;
    }

  gold_assert(static_cast<section_size_type>(pwrite - reloc_view)
	      == reloc_view_size);
}

} // End namespace gold.

#endif // !defined(GOLD_TARGET_RELOC_H)
