// powerpc.cc -- powerpc target support for gold.

// Copyright (C) 2008-2021 Free Software Foundation, Inc.
// Written by David S. Miller <davem@davemloft.net>
//        and David Edelsohn <edelsohn@gnu.org>

// 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 <set>
#include <algorithm>
#include "elfcpp.h"
#include "dwarf.h"
#include "parameters.h"
#include "reloc.h"
#include "powerpc.h"
#include "object.h"
#include "symtab.h"
#include "layout.h"
#include "output.h"
#include "copy-relocs.h"
#include "target.h"
#include "target-reloc.h"
#include "target-select.h"
#include "tls.h"
#include "errors.h"
#include "gc.h"
#include "attributes.h"

namespace
{

using namespace gold;

template<int size, bool big_endian>
class Output_data_plt_powerpc;

template<int size, bool big_endian>
class Output_data_brlt_powerpc;

template<int size, bool big_endian>
class Output_data_got_powerpc;

template<int size, bool big_endian>
class Output_data_glink;

template<int size, bool big_endian>
class Stub_table;

template<int size, bool big_endian>
class Output_data_save_res;

template<int size, bool big_endian>
class Target_powerpc;

struct Stub_table_owner
{
  Stub_table_owner()
    : output_section(NULL), owner(NULL)
  { }

  Output_section* output_section;
  const Output_section::Input_section* owner;
};

template<int size>
inline bool is_branch_reloc(unsigned int);

template<int size>
inline bool is_plt16_reloc(unsigned int);

// Counter incremented on every Powerpc_relobj constructed.
static uint32_t object_id = 0;

template<int size, bool big_endian>
class Powerpc_relobj : public Sized_relobj_file<size, big_endian>
{
public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef Unordered_set<Section_id, Section_id_hash> Section_refs;
  typedef Unordered_map<Address, Section_refs> Access_from;

  Powerpc_relobj(const std::string& name, Input_file* input_file, off_t offset,
		 const typename elfcpp::Ehdr<size, big_endian>& ehdr)
    : Sized_relobj_file<size, big_endian>(name, input_file, offset, ehdr),
      uniq_(object_id++), special_(0), relatoc_(0), toc_(0),
      has_small_toc_reloc_(false), opd_valid_(false),
      no_tls_marker_(false), tls_marker_(false), tls_opt_error_(false),
      e_flags_(ehdr.get_e_flags()), no_toc_opt_(), opd_ent_(),
      access_from_map_(), has14_(), stub_table_index_(), st_other_(),
      attributes_section_data_(NULL)
  {
    this->set_abiversion(0);
  }

  ~Powerpc_relobj()
  { delete this->attributes_section_data_; }

  // Read the symbols then set up st_other vector.
  void
  do_read_symbols(Read_symbols_data*);

  // Arrange to always relocate .toc first.
  virtual void
  do_relocate_sections(
      const Symbol_table* symtab, const Layout* layout,
      const unsigned char* pshdrs, Output_file* of,
      typename Sized_relobj_file<size, big_endian>::Views* pviews);

  // The .toc section index.
  unsigned int
  toc_shndx() const
  {
    return this->toc_;
  }

  // Mark .toc entry at OFF as not optimizable.
  void
  set_no_toc_opt(Address off)
  {
    if (this->no_toc_opt_.empty())
      this->no_toc_opt_.resize(this->section_size(this->toc_shndx())
			       / (size / 8));
    off /= size / 8;
    if (off < this->no_toc_opt_.size())
      this->no_toc_opt_[off] = true;
  }

  // Mark the entire .toc as not optimizable.
  void
  set_no_toc_opt()
  {
    this->no_toc_opt_.resize(1);
    this->no_toc_opt_[0] = true;
  }

  // Return true if code using the .toc entry at OFF should not be edited.
  bool
  no_toc_opt(Address off) const
  {
    if (this->no_toc_opt_.empty())
      return false;
    off /= size / 8;
    if (off >= this->no_toc_opt_.size())
      return true;
    return this->no_toc_opt_[off];
  }

  void
  set_no_tls_marker()
  {
    if (!this->no_tls_marker_ && this->tls_marker_)
      this->tls_opt_error_ = true;
    this->no_tls_marker_ = true;
  }

  bool
  no_tls_marker() const
  { return this->no_tls_marker_; }

  void
  set_tls_marker()
  { this->tls_marker_ = true; }

  bool
  tls_marker() const
  { return this->tls_marker_; }

  bool
  tls_opt_error() const
  { return this->tls_opt_error_; }

  // The .got2 section shndx.
  unsigned int
  got2_shndx() const
  {
    if (size == 32)
      return this->special_;
    else
      return 0;
  }

  // The .opd section shndx.
  unsigned int
  opd_shndx() const
  {
    if (size == 32)
      return 0;
    else
      return this->special_;
  }

  // Init OPD entry arrays.
  void
  init_opd(size_t opd_size)
  {
    size_t count = this->opd_ent_ndx(opd_size);
    this->opd_ent_.resize(count);
  }

  // Return section and offset of function entry for .opd + R_OFF.
  unsigned int
  get_opd_ent(Address r_off, Address* value = NULL) const
  {
    size_t ndx = this->opd_ent_ndx(r_off);
    gold_assert(ndx < this->opd_ent_.size());
    gold_assert(this->opd_ent_[ndx].shndx != 0);
    if (value != NULL)
      *value = this->opd_ent_[ndx].off;
    return this->opd_ent_[ndx].shndx;
  }

  // Set section and offset of function entry for .opd + R_OFF.
  void
  set_opd_ent(Address r_off, unsigned int shndx, Address value)
  {
    size_t ndx = this->opd_ent_ndx(r_off);
    gold_assert(ndx < this->opd_ent_.size());
    this->opd_ent_[ndx].shndx = shndx;
    this->opd_ent_[ndx].off = value;
  }

  // Return discard flag for .opd + R_OFF.
  bool
  get_opd_discard(Address r_off) const
  {
    size_t ndx = this->opd_ent_ndx(r_off);
    gold_assert(ndx < this->opd_ent_.size());
    return this->opd_ent_[ndx].discard;
  }

  // Set discard flag for .opd + R_OFF.
  void
  set_opd_discard(Address r_off)
  {
    size_t ndx = this->opd_ent_ndx(r_off);
    gold_assert(ndx < this->opd_ent_.size());
    this->opd_ent_[ndx].discard = true;
  }

  bool
  opd_valid() const
  { return this->opd_valid_; }

  void
  set_opd_valid()
  { this->opd_valid_ = true; }

  // Examine .rela.opd to build info about function entry points.
  void
  scan_opd_relocs(size_t reloc_count,
		  const unsigned char* prelocs,
		  const unsigned char* plocal_syms);

  // Returns true if a code sequence loading a TOC entry can be
  // converted into code calculating a TOC pointer relative offset.
  bool
  make_toc_relative(Target_powerpc<size, big_endian>* target,
		    Address* value);

  bool
  make_got_relative(Target_powerpc<size, big_endian>* target,
		    const Symbol_value<size>* psymval,
		    Address addend,
		    Address* value);

  // Perform the Sized_relobj_file method, then set up opd info from
  // .opd relocs.
  void
  do_read_relocs(Read_relocs_data*);

  bool
  do_find_special_sections(Read_symbols_data* sd);

  // Adjust this local symbol value.  Return false if the symbol
  // should be discarded from the output file.
  bool
  do_adjust_local_symbol(Symbol_value<size>* lv) const
  {
    if (size == 64 && this->opd_shndx() != 0)
      {
	bool is_ordinary;
	if (lv->input_shndx(&is_ordinary) != this->opd_shndx())
	  return true;
	if (this->get_opd_discard(lv->input_value()))
	  return false;
      }
    return true;
  }

  Access_from*
  access_from_map()
  { return &this->access_from_map_; }

  // Add a reference from SRC_OBJ, SRC_INDX to this object's .opd
  // section at DST_OFF.
  void
  add_reference(Relobj* src_obj,
		unsigned int src_indx,
		typename elfcpp::Elf_types<size>::Elf_Addr dst_off)
  {
    Section_id src_id(src_obj, src_indx);
    this->access_from_map_[dst_off].insert(src_id);
  }

  // Add a reference to the code section specified by the .opd entry
  // at DST_OFF
  void
  add_gc_mark(typename elfcpp::Elf_types<size>::Elf_Addr dst_off)
  {
    size_t ndx = this->opd_ent_ndx(dst_off);
    if (ndx >= this->opd_ent_.size())
      this->opd_ent_.resize(ndx + 1);
    this->opd_ent_[ndx].gc_mark = true;
  }

  void
  process_gc_mark(Symbol_table* symtab)
  {
    for (size_t i = 0; i < this->opd_ent_.size(); i++)
      if (this->opd_ent_[i].gc_mark)
	{
	  unsigned int shndx = this->opd_ent_[i].shndx;
	  symtab->gc()->worklist().push_back(Section_id(this, shndx));
	}
  }

  void
  set_has_small_toc_reloc()
  { has_small_toc_reloc_ = true; }

  bool
  has_small_toc_reloc() const
  { return has_small_toc_reloc_; }

  void
  set_has_14bit_branch(unsigned int shndx)
  {
    if (shndx >= this->has14_.size())
      this->has14_.resize(shndx + 1);
    this->has14_[shndx] = true;
  }

  bool
  has_14bit_branch(unsigned int shndx) const
  { return shndx < this->has14_.size() && this->has14_[shndx];  }

  void
  set_stub_table(unsigned int shndx, unsigned int stub_index)
  {
    if (shndx >= this->stub_table_index_.size())
      this->stub_table_index_.resize(shndx + 1, -1);
    this->stub_table_index_[shndx] = stub_index;
  }

  Stub_table<size, big_endian>*
  stub_table(unsigned int shndx)
  {
    if (shndx < this->stub_table_index_.size())
      {
	Target_powerpc<size, big_endian>* target
	  = static_cast<Target_powerpc<size, big_endian>*>(
	      parameters->sized_target<size, big_endian>());
	unsigned int indx = this->stub_table_index_[shndx];
	if (indx < target->stub_tables().size())
	  return target->stub_tables()[indx];
      }
    return NULL;
  }

  void
  clear_stub_table()
  {
    this->stub_table_index_.clear();
  }

  uint32_t
  uniq() const
  { return this->uniq_; }

  int
  abiversion() const
  { return this->e_flags_ & elfcpp::EF_PPC64_ABI; }

  // Set ABI version for input and output
  void
  set_abiversion(int ver);

  unsigned int
  st_other (unsigned int symndx) const
  {
    return this->st_other_[symndx];
  }

  unsigned int
  ppc64_local_entry_offset(const Symbol* sym) const
  { return elfcpp::ppc64_decode_local_entry(sym->nonvis() >> 3); }

  unsigned int
  ppc64_local_entry_offset(unsigned int symndx) const
  { return elfcpp::ppc64_decode_local_entry(this->st_other_[symndx] >> 5); }

  bool
  ppc64_needs_toc(const Symbol* sym) const
  { return sym->nonvis() > 1 << 3; }

  bool
  ppc64_needs_toc(unsigned int symndx) const
  { return this->st_other_[symndx] > 1 << 5; }

  // The contents of the .gnu.attributes section if there is one.
  const Attributes_section_data*
  attributes_section_data() const
  { return this->attributes_section_data_; }

private:
  struct Opd_ent
  {
    unsigned int shndx;
    bool discard : 1;
    bool gc_mark : 1;
    Address off;
  };

  // Return index into opd_ent_ array for .opd entry at OFF.
  // .opd entries are 24 bytes long, but they can be spaced 16 bytes
  // apart when the language doesn't use the last 8-byte word, the
  // environment pointer.  Thus dividing the entry section offset by
  // 16 will give an index into opd_ent_ that works for either layout
  // of .opd.  (It leaves some elements of the vector unused when .opd
  // entries are spaced 24 bytes apart, but we don't know the spacing
  // until relocations are processed, and in any case it is possible
  // for an object to have some entries spaced 16 bytes apart and
  // others 24 bytes apart.)
  size_t
  opd_ent_ndx(size_t off) const
  { return off >> 4;}

  // Per object unique identifier
  uint32_t uniq_;

  // For 32-bit the .got2 section shdnx, for 64-bit the .opd section shndx.
  unsigned int special_;

  // For 64-bit the .rela.toc and .toc section shdnx.
  unsigned int relatoc_;
  unsigned int toc_;

  // For 64-bit, whether this object uses small model relocs to access
  // the toc.
  bool has_small_toc_reloc_;

  // Set at the start of gc_process_relocs, when we know opd_ent_
  // vector is valid.  The flag could be made atomic and set in
  // do_read_relocs with memory_order_release and then tested with
  // memory_order_acquire, potentially resulting in fewer entries in
  // access_from_map_.
  bool opd_valid_;

  // Set when finding a __tls_get_addr call without marker relocs.
  // Such a call disables GD and LD tls optimisations for the object file.
  bool no_tls_marker_;

  // Set when finding a __tls_get_addr call with marker relocs, or
  // when finding a relocation that needs __tls_get_addr calls with
  // marker relocs.
  bool tls_marker_;

  // Set when seeing a __tls_get_addr call without marker relocs after
  // seeing some __tls_get_addr calls with marker relocs.
  bool tls_opt_error_;

  // Header e_flags
  elfcpp::Elf_Word e_flags_;

  // For 64-bit, an array with one entry per 64-bit word in the .toc
  // section, set if accesses using that word cannot be optimised.
  std::vector<bool> no_toc_opt_;

  // The first 8-byte word of an OPD entry gives the address of the
  // entry point of the function.  Relocatable object files have a
  // relocation on this word.  The following vector records the
  // section and offset specified by these relocations.
  std::vector<Opd_ent> opd_ent_;

  // References made to this object's .opd section when running
  // gc_process_relocs for another object, before the opd_ent_ vector
  // is valid for this object.
  Access_from access_from_map_;

  // Whether input section has a 14-bit branch reloc.
  std::vector<bool> has14_;

  // The stub table to use for a given input section.
  std::vector<unsigned int> stub_table_index_;

  // ELF st_other field for local symbols.
  std::vector<unsigned char> st_other_;

  // Object attributes if there is a .gnu.attributes section.
  Attributes_section_data* attributes_section_data_;
};

template<int size, bool big_endian>
class Powerpc_dynobj : public Sized_dynobj<size, big_endian>
{
public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;

  Powerpc_dynobj(const std::string& name, Input_file* input_file, off_t offset,
		 const typename elfcpp::Ehdr<size, big_endian>& ehdr)
    : Sized_dynobj<size, big_endian>(name, input_file, offset, ehdr),
      opd_shndx_(0), e_flags_(ehdr.get_e_flags()), opd_ent_(),
      attributes_section_data_(NULL)
  {
    this->set_abiversion(0);
  }

  ~Powerpc_dynobj()
  { delete this->attributes_section_data_; }

  // Call Sized_dynobj::do_read_symbols to read the symbols then
  // read .opd from a dynamic object, filling in opd_ent_ vector,
  void
  do_read_symbols(Read_symbols_data*);

  // The .opd section shndx.
  unsigned int
  opd_shndx() const
  {
    return this->opd_shndx_;
  }

  // The .opd section address.
  Address
  opd_address() const
  {
    return this->opd_address_;
  }

  // Init OPD entry arrays.
  void
  init_opd(size_t opd_size)
  {
    size_t count = this->opd_ent_ndx(opd_size);
    this->opd_ent_.resize(count);
  }

  // Return section and offset of function entry for .opd + R_OFF.
  unsigned int
  get_opd_ent(Address r_off, Address* value = NULL) const
  {
    size_t ndx = this->opd_ent_ndx(r_off);
    gold_assert(ndx < this->opd_ent_.size());
    gold_assert(this->opd_ent_[ndx].shndx != 0);
    if (value != NULL)
      *value = this->opd_ent_[ndx].off;
    return this->opd_ent_[ndx].shndx;
  }

  // Set section and offset of function entry for .opd + R_OFF.
  void
  set_opd_ent(Address r_off, unsigned int shndx, Address value)
  {
    size_t ndx = this->opd_ent_ndx(r_off);
    gold_assert(ndx < this->opd_ent_.size());
    this->opd_ent_[ndx].shndx = shndx;
    this->opd_ent_[ndx].off = value;
  }

  int
  abiversion() const
  { return this->e_flags_ & elfcpp::EF_PPC64_ABI; }

  // Set ABI version for input and output.
  void
  set_abiversion(int ver);

  // The contents of the .gnu.attributes section if there is one.
  const Attributes_section_data*
  attributes_section_data() const
  { return this->attributes_section_data_; }

private:
  // Used to specify extent of executable sections.
  struct Sec_info
  {
    Sec_info(Address start_, Address len_, unsigned int shndx_)
      : start(start_), len(len_), shndx(shndx_)
    { }

    bool
    operator<(const Sec_info& that) const
    { return this->start < that.start; }

    Address start;
    Address len;
    unsigned int shndx;
  };

  struct Opd_ent
  {
    unsigned int shndx;
    Address off;
  };

  // Return index into opd_ent_ array for .opd entry at OFF.
  size_t
  opd_ent_ndx(size_t off) const
  { return off >> 4;}

  // For 64-bit the .opd section shndx and address.
  unsigned int opd_shndx_;
  Address opd_address_;

  // Header e_flags
  elfcpp::Elf_Word e_flags_;

  // The first 8-byte word of an OPD entry gives the address of the
  // entry point of the function.  Records the section and offset
  // corresponding to the address.  Note that in dynamic objects,
  // offset is *not* relative to the section.
  std::vector<Opd_ent> opd_ent_;

  // Object attributes if there is a .gnu.attributes section.
  Attributes_section_data* attributes_section_data_;
};

// Powerpc_copy_relocs class.  Needed to peek at dynamic relocs the
// base class will emit.

template<int sh_type, int size, bool big_endian>
class Powerpc_copy_relocs : public Copy_relocs<sh_type, size, big_endian>
{
 public:
  Powerpc_copy_relocs()
    : Copy_relocs<sh_type, size, big_endian>(elfcpp::R_POWERPC_COPY)
  { }

  // Emit any saved relocations which turn out to be needed.  This is
  // called after all the relocs have been scanned.
  void
  emit(Output_data_reloc<sh_type, true, size, big_endian>*);
};

// The types of GOT entries needed for this platform.
// These values are exposed to the ABI in an incremental link, but
// powerpc does not support incremental linking as yet.
enum Got_type
  {
    GOT_TYPE_STANDARD = 0,
    GOT_TYPE_TLSGD = 1,		// double entry for @got@tlsgd
    GOT_TYPE_DTPREL = 2,	// entry for @got@dtprel
    GOT_TYPE_TPREL = 3,		// entry for @got@tprel
    GOT_TYPE_SMALL = 4,
    GOT_TYPE_SMALL_TLSGD = 5,
    GOT_TYPE_SMALL_DTPREL = 6,
    GOT_TYPE_SMALL_TPREL = 7
  };

template<int size, bool big_endian>
class Target_powerpc : public Sized_target<size, big_endian>
{
 public:
  typedef
    Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Reloc_section;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename elfcpp::Elf_types<size>::Elf_Swxword Signed_address;
  typedef Unordered_set<Symbol_location, Symbol_location_hash> Tocsave_loc;
  static const Address invalid_address = static_cast<Address>(0) - 1;
  // Offset of tp and dtp pointers from start of TLS block.
  static const Address tp_offset = 0x7000;
  static const Address dtp_offset = 0x8000;

  Target_powerpc()
    : Sized_target<size, big_endian>(&powerpc_info),
      got_(NULL), biggot_(NULL), plt_(NULL), iplt_(NULL), lplt_(NULL),
      brlt_section_(NULL), glink_(NULL), rela_dyn_(NULL), copy_relocs_(),
      tlsld_got_offset_(-1U),
      stub_tables_(), branch_lookup_table_(), branch_info_(), tocsave_loc_(),
      power10_relocs_(false), plt_thread_safe_(false), plt_localentry0_(false),
      plt_localentry0_init_(false), has_localentry0_(false),
      has_tls_get_addr_opt_(false), no_tprel_opt_(false),
      relax_failed_(false), relax_fail_count_(0),
      stub_group_size_(0), savres_section_(0),
      tls_get_addr_(NULL), tls_get_addr_opt_(NULL),
      attributes_section_data_(NULL),
      last_fp_(NULL), last_ld_(NULL), last_vec_(NULL), last_struct_(NULL)
  {
  }

  // Process the relocations to determine unreferenced sections for
  // garbage collection.
  void
  gc_process_relocs(Symbol_table* symtab,
		    Layout* layout,
		    Sized_relobj_file<size, big_endian>* object,
		    unsigned int data_shndx,
		    unsigned int sh_type,
		    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_symbols);

  // Scan the relocations to look for symbol adjustments.
  void
  scan_relocs(Symbol_table* symtab,
	      Layout* layout,
	      Sized_relobj_file<size, big_endian>* object,
	      unsigned int data_shndx,
	      unsigned int sh_type,
	      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_symbols);

  // Map input .toc section to output .got section.
  const char*
  do_output_section_name(const Relobj*, const char* name, size_t* plen) const
  {
    if (size == 64 && strcmp(name, ".toc") == 0)
      {
	*plen = 4;
	return ".got";
      }
    return NULL;
  }

  // Provide linker defined save/restore functions.
  void
  define_save_restore_funcs(Layout*, Symbol_table*);

  // No stubs unless a final link.
  bool
  do_may_relax() const
  { return !parameters->options().relocatable(); }

  bool
  do_relax(int, const Input_objects*, Symbol_table*, Layout*, const Task*);

  void
  do_plt_fde_location(const Output_data*, unsigned char*,
		      uint64_t*, off_t*) const;

  // Stash info about branches, for stub generation.
  void
  push_branch(Powerpc_relobj<size, big_endian>* ppc_object,
	      unsigned int data_shndx, Address r_offset,
	      unsigned int r_type, unsigned int r_sym, Address addend)
  {
    Branch_info info(ppc_object, data_shndx, r_offset, r_type, r_sym, addend);
    this->branch_info_.push_back(info);
    if (r_type == elfcpp::R_POWERPC_REL14
	|| r_type == elfcpp::R_POWERPC_REL14_BRTAKEN
	|| r_type == elfcpp::R_POWERPC_REL14_BRNTAKEN)
      ppc_object->set_has_14bit_branch(data_shndx);
  }

  // Return whether the last branch is a plt call, and if so, mark the
  // branch as having an R_PPC64_TOCSAVE.
  bool
  mark_pltcall(Powerpc_relobj<size, big_endian>* ppc_object,
	       unsigned int data_shndx, Address r_offset, Symbol_table* symtab)
  {
    return (size == 64
	    && !this->branch_info_.empty()
	    && this->branch_info_.back().mark_pltcall(ppc_object, data_shndx,
						      r_offset, this, symtab));
  }

  // Say the given location, that of a nop in a function prologue with
  // an R_PPC64_TOCSAVE reloc, will be used to save r2.
  // R_PPC64_TOCSAVE relocs on nops following calls point at this nop.
  void
  add_tocsave(Powerpc_relobj<size, big_endian>* ppc_object,
	      unsigned int shndx, Address offset)
  {
    Symbol_location loc;
    loc.object = ppc_object;
    loc.shndx = shndx;
    loc.offset = offset;
    this->tocsave_loc_.insert(loc);
  }

  // Accessor
  const Tocsave_loc*
  tocsave_loc() const
  {
    return &this->tocsave_loc_;
  }

  void
  do_define_standard_symbols(Symbol_table*, Layout*);

  // Finalize the sections.
  void
  do_finalize_sections(Layout*, const Input_objects*, Symbol_table*);

  // Return the value to use for a dynamic which requires special
  // treatment.
  uint64_t
  do_dynsym_value(const Symbol*) const;

  // Return the PLT address to use for a local symbol.
  uint64_t
  do_plt_address_for_local(const Relobj*, unsigned int) const;

  // Return the PLT address to use for a global symbol.
  uint64_t
  do_plt_address_for_global(const Symbol*) const;

  // Return the offset to use for the GOT_INDX'th got entry which is
  // for a local tls symbol specified by OBJECT, SYMNDX.
  int64_t
  do_tls_offset_for_local(const Relobj* object,
			  unsigned int symndx,
			  Output_data_got_base* got,
			  unsigned int got_indx,
			  uint64_t addend) const;

  // Return the offset to use for the GOT_INDX'th got entry which is
  // for global tls symbol GSYM.
  int64_t
  do_tls_offset_for_global(Symbol* gsym,
			   Output_data_got_base* got, unsigned int got_indx,
			   uint64_t addend) const;

  void
  do_function_location(Symbol_location*) const;

  bool
  do_can_check_for_function_pointers() const
  { return true; }

  // Adjust -fsplit-stack code which calls non-split-stack code.
  void
  do_calls_non_split(Relobj* object, unsigned int shndx,
		     section_offset_type fnoffset, section_size_type fnsize,
		     const unsigned char* prelocs, size_t reloc_count,
		     unsigned char* view, section_size_type view_size,
		     std::string* from, std::string* to) const;

  // Relocate a section.
  void
  relocate_section(const Relocate_info<size, big_endian>*,
		   unsigned int sh_type,
		   const unsigned char* prelocs,
		   size_t reloc_count,
		   Output_section* output_section,
		   bool needs_special_offset_handling,
		   unsigned char* view,
		   Address view_address,
		   section_size_type view_size,
		   const Reloc_symbol_changes*);

  // Scan the relocs during a relocatable link.
  void
  scan_relocatable_relocs(Symbol_table* symtab,
			  Layout* layout,
			  Sized_relobj_file<size, big_endian>* object,
			  unsigned int data_shndx,
			  unsigned int sh_type,
			  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_symbols,
			  Relocatable_relocs*);

  // Scan the relocs for --emit-relocs.
  void
  emit_relocs_scan(Symbol_table* symtab,
		   Layout* layout,
		   Sized_relobj_file<size, big_endian>* object,
		   unsigned int data_shndx,
		   unsigned int sh_type,
		   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);

  // Emit relocations for a section.
  void
  relocate_relocs(const Relocate_info<size, big_endian>*,
		  unsigned int sh_type,
		  const unsigned char* prelocs,
		  size_t reloc_count,
		  Output_section* output_section,
		  typename elfcpp::Elf_types<size>::Elf_Off
                    offset_in_output_section,
		  unsigned char*,
		  Address view_address,
		  section_size_type,
		  unsigned char* reloc_view,
		  section_size_type reloc_view_size);

  // Return whether SYM is defined by the ABI.
  bool
  do_is_defined_by_abi(const Symbol* sym) const
  {
    return strcmp(sym->name(), "__tls_get_addr") == 0;
  }

  // Return the size of the GOT section, for incremental linking
  section_size_type
  got_size() const
  {
    gold_assert(this->got_ != NULL);
    return this->got_->data_size() + (this->biggot_
				      ? this->biggot_->data_size() : 0);
  }

  // Get the PLT section.
  const Output_data_plt_powerpc<size, big_endian>*
  plt_section() const
  {
    gold_assert(this->plt_ != NULL);
    return this->plt_;
  }

  // Get the IPLT section.
  const Output_data_plt_powerpc<size, big_endian>*
  iplt_section() const
  {
    gold_assert(this->iplt_ != NULL);
    return this->iplt_;
  }

  // Get the LPLT section.
  const Output_data_plt_powerpc<size, big_endian>*
  lplt_section() const
  {
    return this->lplt_;
  }

  // Return the plt offset and section for the given global sym.
  Address
  plt_off(const Symbol* gsym,
	  const Output_data_plt_powerpc<size, big_endian>** sec) const
  {
    if (gsym->type() == elfcpp::STT_GNU_IFUNC
	&& gsym->can_use_relative_reloc(false))
      *sec = this->iplt_section();
    else
      *sec = this->plt_section();
    return gsym->plt_offset();
  }

  // Return the plt offset and section for the given local sym.
  Address
  plt_off(const Sized_relobj_file<size, big_endian>* relobj,
	  unsigned int local_sym_index,
	  const Output_data_plt_powerpc<size, big_endian>** sec) const
  {
    const Symbol_value<size>* lsym = relobj->local_symbol(local_sym_index);
    if (lsym->is_ifunc_symbol())
      *sec = this->iplt_section();
    else
      *sec = this->lplt_section();
    return relobj->local_plt_offset(local_sym_index);
  }

  // Get the .glink section.
  const Output_data_glink<size, big_endian>*
  glink_section() const
  {
    gold_assert(this->glink_ != NULL);
    return this->glink_;
  }

  Output_data_glink<size, big_endian>*
  glink_section()
  {
    gold_assert(this->glink_ != NULL);
    return this->glink_;
  }

  bool has_glink() const
  { return this->glink_ != NULL; }

  // Get the GOT section.
  const Output_data_got_powerpc<size, big_endian>*
  got_section(Got_type got_type) const
  {
    gold_assert(this->got_ != NULL);
    if (size == 32 || (got_type & GOT_TYPE_SMALL))
      return this->got_;
    gold_assert(this->biggot_ != NULL);
    return this->biggot_;
  }

  // Get the GOT section, creating it if necessary.
  Output_data_got_powerpc<size, big_endian>*
  got_section(Symbol_table*, Layout*, Got_type);

  // The toc/got pointer reg will be set to this value.
  Address
  toc_pointer() const
  {
    return this->got_->address() + this->got_->g_o_t();
  }

  // Offset of base used to access the GOT/TOC relative to the GOT section.
  Address
  got_base_offset(Got_type got_type) const
  {
    if (size == 32 || (got_type & GOT_TYPE_SMALL))
      return this->got_->g_o_t();
    return this->toc_pointer() - this->biggot_->address();
  }

  Object*
  do_make_elf_object(const std::string&, Input_file*, off_t,
		     const elfcpp::Ehdr<size, big_endian>&);

  // Return the number of entries in the GOT.
  unsigned int
  got_entry_count() const
  {
    if (this->got_ == NULL)
      return 0;
    return this->got_size() / (size / 8);
  }

  // Return the number of entries in the PLT.
  unsigned int
  plt_entry_count() const;

  // Return the offset of the first non-reserved PLT entry.
  unsigned int
  first_plt_entry_offset() const
  {
    if (size == 32)
      return 0;
    if (this->abiversion() >= 2)
      return 16;
    return 24;
  }

  // Return the size of each PLT entry.
  unsigned int
  plt_entry_size() const
  {
    if (size == 32)
      return 4;
    if (this->abiversion() >= 2)
      return 8;
    return 24;
  }

  Output_data_save_res<size, big_endian>*
  savres_section() const
  {
    return this->savres_section_;
  }

  // Add any special sections for this symbol to the gc work list.
  // For powerpc64, this adds the code section of a function
  // descriptor.
  void
  do_gc_mark_symbol(Symbol_table* symtab, Symbol* sym) const;

  // Handle target specific gc actions when adding a gc reference from
  // SRC_OBJ, SRC_SHNDX to a location specified by DST_OBJ, DST_SHNDX
  // and DST_OFF.  For powerpc64, this adds a referenc to the code
  // section of a function descriptor.
  void
  do_gc_add_reference(Symbol_table* symtab,
		      Relobj* src_obj,
		      unsigned int src_shndx,
		      Relobj* dst_obj,
		      unsigned int dst_shndx,
		      Address dst_off) const;

  typedef std::vector<Stub_table<size, big_endian>*> Stub_tables;
  const Stub_tables&
  stub_tables() const
  { return this->stub_tables_; }

  const Output_data_brlt_powerpc<size, big_endian>*
  brlt_section() const
  { return this->brlt_section_; }

  void
  add_branch_lookup_table(Address to)
  {
    unsigned int off = this->branch_lookup_table_.size() * (size / 8);
    this->branch_lookup_table_.insert(std::make_pair(to, off));
  }

  Address
  find_branch_lookup_table(Address to)
  {
    typename Branch_lookup_table::const_iterator p
      = this->branch_lookup_table_.find(to);
    return p == this->branch_lookup_table_.end() ? invalid_address : p->second;
  }

  void
  write_branch_lookup_table(unsigned char *oview)
  {
    for (typename Branch_lookup_table::const_iterator p
	   = this->branch_lookup_table_.begin();
	 p != this->branch_lookup_table_.end();
	 ++p)
      {
	elfcpp::Swap<size, big_endian>::writeval(oview + p->second, p->first);
      }
  }

  // Wrapper used after relax to define a local symbol in output data,
  // from the end if value < 0.
  void
  define_local(Symbol_table* symtab, const char* name,
	       Output_data* od, Address value, unsigned int symsize)
  {
    Symbol* sym
      = symtab->define_in_output_data(name, NULL, Symbol_table::PREDEFINED,
				      od, value, symsize, elfcpp::STT_NOTYPE,
				      elfcpp::STB_LOCAL, elfcpp::STV_HIDDEN, 0,
				      static_cast<Signed_address>(value) < 0,
				      false);
    // We are creating this symbol late, so need to fix up things
    // done early in Layout::finalize.
    sym->set_dynsym_index(-1U);
  }

  void
  set_power10_relocs()
  {
      this->power10_relocs_ = true;
  }

  bool
  power10_stubs() const
  {
    return (this->power10_relocs_
	    && (parameters->options().power10_stubs_enum()
		!= General_options::POWER10_STUBS_NO));
  }

  bool
  power10_stubs_auto() const
  {
    return (parameters->options().power10_stubs_enum()
	    == General_options::POWER10_STUBS_AUTO);
  }

  bool
  plt_thread_safe() const
  { return this->plt_thread_safe_; }

  bool
  plt_localentry0() const
  { return this->plt_localentry0_; }

  bool
  has_localentry0() const
  { return this->has_localentry0_; }

  void
  set_has_localentry0()
  {
    this->has_localentry0_ = true;
  }

  bool
  is_elfv2_localentry0(const Symbol* gsym) const
  {
    return (size == 64
	    && this->abiversion() >= 2
	    && this->plt_localentry0()
	    && gsym->type() == elfcpp::STT_FUNC
	    && gsym->is_defined()
	    && gsym->nonvis() >> 3 == 0
	    && !gsym->non_zero_localentry());
  }

  bool
  is_elfv2_localentry0(const Sized_relobj_file<size, big_endian>* object,
		       unsigned int r_sym) const
  {
    const Powerpc_relobj<size, big_endian>* ppc_object
      = static_cast<const Powerpc_relobj<size, big_endian>*>(object);

    if (size == 64
	&& this->abiversion() >= 2
	&& this->plt_localentry0()
	&& ppc_object->st_other(r_sym) >> 5 == 0)
      {
	const Symbol_value<size>* psymval = object->local_symbol(r_sym);
	bool is_ordinary;
	if (!psymval->is_ifunc_symbol()
	    && psymval->input_shndx(&is_ordinary) != elfcpp::SHN_UNDEF
	    && is_ordinary)
	  return true;
      }
    return false;
  }

  bool
  tprel_opt() const
  { return !this->no_tprel_opt_ && parameters->options().tls_optimize(); }

  void
  set_no_tprel_opt()
  { this->no_tprel_opt_ = true; }

  // Remember any symbols seen with non-zero localentry, even those
  // not providing a definition
  bool
  resolve(Symbol* to, const elfcpp::Sym<size, big_endian>& sym, Object*,
	  const char*)
  {
    if (size == 64)
      {
	unsigned char st_other = sym.get_st_other();
	if ((st_other & elfcpp::STO_PPC64_LOCAL_MASK) != 0)
	  to->set_non_zero_localentry();
      }
    // We haven't resolved anything, continue normal processing.
    return false;
  }

  int
  abiversion() const
  { return this->processor_specific_flags() & elfcpp::EF_PPC64_ABI; }

  void
  set_abiversion(int ver)
  {
    elfcpp::Elf_Word flags = this->processor_specific_flags();
    flags &= ~elfcpp::EF_PPC64_ABI;
    flags |= ver & elfcpp::EF_PPC64_ABI;
    this->set_processor_specific_flags(flags);
  }

  Symbol*
  tls_get_addr_opt() const
  { return this->tls_get_addr_opt_; }

  Symbol*
  tls_get_addr() const
  { return this->tls_get_addr_; }

  // If optimizing __tls_get_addr calls, whether this is the
  // "__tls_get_addr" symbol.
  bool
  is_tls_get_addr_opt(const Symbol* gsym) const
  {
    return this->tls_get_addr_opt_ && (gsym == this->tls_get_addr_
				       || gsym == this->tls_get_addr_opt_);
  }

  bool
  replace_tls_get_addr(const Symbol* gsym) const
  { return this->tls_get_addr_opt_ && gsym == this->tls_get_addr_; }

  void
  set_has_tls_get_addr_opt()
  { this->has_tls_get_addr_opt_ = true; }

  // Offset to toc save stack slot
  int
  stk_toc() const
  { return this->abiversion() < 2 ? 40 : 24; }

  // Offset to linker save stack slot.  ELFv2 doesn't have a linker word,
  // so use the CR save slot.  Used only by __tls_get_addr call stub,
  // relying on __tls_get_addr not saving CR itself.
  int
  stk_linker() const
  { return this->abiversion() < 2 ? 32 : 8; }

  // Merge object attributes from input object with those in the output.
  void
  merge_object_attributes(const Object*, const Attributes_section_data*);

 private:

  class Track_tls
  {
  public:
    enum Tls_get_addr
    {
      NOT_EXPECTED = 0,
      EXPECTED = 1,
      SKIP = 2,
      NORMAL = 3
    };

    Track_tls()
      : tls_get_addr_state_(NOT_EXPECTED),
	relinfo_(NULL), relnum_(0), r_offset_(0)
    { }

    ~Track_tls()
    {
      if (this->tls_get_addr_state_ != NOT_EXPECTED)
	this->missing();
    }

    void
    missing(void)
    {
      if (this->relinfo_ != NULL)
	gold_error_at_location(this->relinfo_, this->relnum_, this->r_offset_,
			       _("missing expected __tls_get_addr call"));
    }

    void
    expect_tls_get_addr_call(
	const Relocate_info<size, big_endian>* relinfo,
	size_t relnum,
	Address r_offset)
    {
      this->tls_get_addr_state_ = EXPECTED;
      this->relinfo_ = relinfo;
      this->relnum_ = relnum;
      this->r_offset_ = r_offset;
    }

    void
    expect_tls_get_addr_call()
    { this->tls_get_addr_state_ = EXPECTED; }

    void
    skip_next_tls_get_addr_call()
    {this->tls_get_addr_state_ = SKIP; }

    Tls_get_addr
    maybe_skip_tls_get_addr_call(Target_powerpc<size, big_endian>* target,
				 unsigned int r_type, const Symbol* gsym)
    {
      bool is_tls_call
	= ((r_type == elfcpp::R_POWERPC_REL24
	    || (size == 64 && r_type == elfcpp::R_PPC64_REL24_NOTOC)
	    || r_type == elfcpp::R_PPC_PLTREL24
	    || is_plt16_reloc<size>(r_type)
	    || r_type == elfcpp::R_PPC64_PLT_PCREL34
	    || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC
	    || r_type == elfcpp::R_POWERPC_PLTSEQ
	    || r_type == elfcpp::R_POWERPC_PLTCALL
	    || r_type == elfcpp::R_PPC64_PLTSEQ_NOTOC
	    || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC)
	   && gsym != NULL
	   && (gsym == target->tls_get_addr()
	       || gsym == target->tls_get_addr_opt()));
      Tls_get_addr last_tls = this->tls_get_addr_state_;
      this->tls_get_addr_state_ = NOT_EXPECTED;
      if (is_tls_call && last_tls != EXPECTED)
	return last_tls;
      else if (!is_tls_call && last_tls != NOT_EXPECTED)
	{
	  this->missing();
	  return EXPECTED;
	}
      return NORMAL;
    }

  private:
    // What we're up to regarding calls to __tls_get_addr.
    // On powerpc, the branch and link insn making a call to
    // __tls_get_addr is marked with a relocation, R_PPC64_TLSGD,
    // R_PPC64_TLSLD, R_PPC_TLSGD or R_PPC_TLSLD, in addition to the
    // usual R_POWERPC_REL24 or R_PPC_PLTREL24 relocation on a call.
    // The marker relocation always comes first, and has the same
    // symbol as the reloc on the insn setting up the __tls_get_addr
    // argument.  This ties the arg setup insn with the call insn,
    // allowing ld to safely optimize away the call.  We check that
    // every call to __tls_get_addr has a marker relocation, and that
    // every marker relocation is on a call to __tls_get_addr.
    Tls_get_addr tls_get_addr_state_;
    // Info about the last reloc for error message.
    const Relocate_info<size, big_endian>* relinfo_;
    size_t relnum_;
    Address r_offset_;
  };

  // The class which scans relocations.
  class Scan : protected Track_tls
  {
  public:
    typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;

    Scan()
      : Track_tls(), issued_non_pic_error_(false)
    { }

    static inline int
    get_reference_flags(unsigned int r_type, const Target_powerpc* target);

    inline void
    local(Symbol_table* symtab, Layout* layout, Target_powerpc* target,
	  Sized_relobj_file<size, big_endian>* object,
	  unsigned int data_shndx,
	  Output_section* output_section,
	  const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
	  const elfcpp::Sym<size, big_endian>& lsym,
	  bool is_discarded);

    inline void
    global(Symbol_table* symtab, Layout* layout, Target_powerpc* target,
	   Sized_relobj_file<size, big_endian>* object,
	   unsigned int data_shndx,
	   Output_section* output_section,
	   const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type,
	   Symbol* gsym);

    inline bool
    local_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
					Target_powerpc* ,
					Sized_relobj_file<size, big_endian>* relobj,
					unsigned int ,
					Output_section* ,
					const elfcpp::Rela<size, big_endian>& ,
					unsigned int r_type,
					const elfcpp::Sym<size, big_endian>&)
    {
      // PowerPC64 .opd is not folded, so any identical function text
      // may be folded and we'll still keep function addresses distinct.
      // That means no reloc is of concern here.
      if (size == 64)
	{
	  Powerpc_relobj<size, big_endian>* ppcobj = static_cast
	    <Powerpc_relobj<size, big_endian>*>(relobj);
	  if (ppcobj->abiversion() == 1)
	    return false;
	}
      // For 32-bit and ELFv2, conservatively assume anything but calls to
      // function code might be taking the address of the function.
      return !is_branch_reloc<size>(r_type);
    }

    inline bool
    global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
					 Target_powerpc* ,
					 Sized_relobj_file<size, big_endian>* relobj,
					 unsigned int ,
					 Output_section* ,
					 const elfcpp::Rela<size, big_endian>& ,
					 unsigned int r_type,
					 Symbol*)
    {
      // As above.
      if (size == 64)
	{
	  Powerpc_relobj<size, big_endian>* ppcobj = static_cast
	    <Powerpc_relobj<size, big_endian>*>(relobj);
	  if (ppcobj->abiversion() == 1)
	    return false;
	}
      return !is_branch_reloc<size>(r_type);
    }

    static bool
    reloc_needs_plt_for_ifunc(Target_powerpc<size, big_endian>* target,
			      Sized_relobj_file<size, big_endian>* object,
			      unsigned int r_type, bool report_err);

  private:
    static void
    unsupported_reloc_local(Sized_relobj_file<size, big_endian>*,
			    unsigned int r_type);

    static void
    unsupported_reloc_global(Sized_relobj_file<size, big_endian>*,
			     unsigned int r_type, Symbol*);

    static void
    generate_tls_call(Symbol_table* symtab, Layout* layout,
		      Target_powerpc* target);

    void
    check_non_pic(Relobj*, unsigned int r_type);

    // Whether we have issued an error about a non-PIC compilation.
    bool issued_non_pic_error_;
  };

  bool
  symval_for_branch(const Symbol_table* symtab,
		    const Sized_symbol<size>* gsym,
		    Powerpc_relobj<size, big_endian>* object,
		    Address *value, unsigned int *dest_shndx);

  // The class which implements relocation.
  class Relocate : protected Track_tls
  {
   public:
    // Use 'at' branch hints when true, 'y' when false.
    // FIXME maybe: set this with an option.
    static const bool is_isa_v2 = true;

    Relocate()
      : Track_tls()
    { }

    // Do a relocation.  Return false if the caller should not issue
    // any warnings about this relocation.
    inline bool
    relocate(const Relocate_info<size, big_endian>*, unsigned int,
	     Target_powerpc*, Output_section*, size_t, const unsigned char*,
	     const Sized_symbol<size>*, const Symbol_value<size>*,
	     unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr,
	     section_size_type);
  };

  class Relocate_comdat_behavior
  {
   public:
    // Decide what the linker should do for relocations that refer to
    // discarded comdat sections.
    inline Comdat_behavior
    get(const char* name)
    {
      gold::Default_comdat_behavior default_behavior;
      Comdat_behavior ret = default_behavior.get(name);
      if (ret == CB_ERROR)
	{
	  if (size == 32
	      && (strcmp(name, ".fixup") == 0
		  || strcmp(name, ".got2") == 0))
	    ret = CB_IGNORE;
	  if (size == 64
	      && (strcmp(name, ".opd") == 0
		  || strcmp(name, ".toc") == 0
		  || strcmp(name, ".toc1") == 0))
	    ret = CB_IGNORE;
	}
      return ret;
    }
  };

  // Optimize the TLS relocation type based on what we know about the
  // symbol.  IS_FINAL is true if the final address of this symbol is
  // known at link time.

  tls::Tls_optimization
  optimize_tls_gd(bool is_final)
  {
    // If we are generating a shared library, then we can't do anything
    // in the linker.
    if (parameters->options().shared()
	|| !parameters->options().tls_optimize())
      return tls::TLSOPT_NONE;

    if (!is_final)
      return tls::TLSOPT_TO_IE;
    return tls::TLSOPT_TO_LE;
  }

  tls::Tls_optimization
  optimize_tls_ld()
  {
    if (parameters->options().shared()
	|| !parameters->options().tls_optimize())
      return tls::TLSOPT_NONE;

    return tls::TLSOPT_TO_LE;
  }

  tls::Tls_optimization
  optimize_tls_ie(bool is_final)
  {
    if (!is_final
	|| parameters->options().shared()
	|| !parameters->options().tls_optimize())
      return tls::TLSOPT_NONE;

    return tls::TLSOPT_TO_LE;
  }

  // Create glink.
  void
  make_glink_section(Layout*);

  // Create the PLT section.
  void
  make_plt_section(Symbol_table*, Layout*);

  void
  make_iplt_section(Symbol_table*, Layout*);

  void
  make_lplt_section(Layout*);

  void
  make_brlt_section(Layout*);

  // Create a PLT entry for a global symbol.
  void
  make_plt_entry(Symbol_table*, Layout*, Symbol*);

  // Create a PLT entry for a local IFUNC symbol.
  void
  make_local_ifunc_plt_entry(Symbol_table*, Layout*,
			     Sized_relobj_file<size, big_endian>*,
			     unsigned int);

  // Create a PLT entry for a local non-IFUNC symbol.
  void
  make_local_plt_entry(Layout*,
		       Sized_relobj_file<size, big_endian>*,
		       unsigned int);


  // Create a GOT entry for local dynamic __tls_get_addr.
  unsigned int
  tlsld_got_offset(Symbol_table* symtab, Layout* layout,
		   Sized_relobj_file<size, big_endian>* object);

  unsigned int
  tlsld_got_offset() const
  {
    return this->tlsld_got_offset_;
  }

  // Get the dynamic reloc section, creating it if necessary.
  Reloc_section*
  rela_dyn_section(Layout*);

  // Similarly, but for ifunc symbols get the one for ifunc.
  Reloc_section*
  rela_dyn_section(Symbol_table*, Layout*, bool for_ifunc);

  // Copy a relocation against a global symbol.
  void
  copy_reloc(Symbol_table* symtab, Layout* layout,
	     Sized_relobj_file<size, big_endian>* object,
	     unsigned int shndx, Output_section* output_section,
	     Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
  {
    unsigned int r_type = elfcpp::elf_r_type<size>(reloc.get_r_info());
    this->copy_relocs_.copy_reloc(symtab, layout,
				  symtab->get_sized_symbol<size>(sym),
				  object, shndx, output_section,
				  r_type, reloc.get_r_offset(),
				  reloc.get_r_addend(),
				  this->rela_dyn_section(layout));
  }

  // Look over all the input sections, deciding where to place stubs.
  void
  group_sections(Layout*, const Task*, bool);

  // Sort output sections by address.
  struct Sort_sections
  {
    bool
    operator()(const Output_section* sec1, const Output_section* sec2)
    { return sec1->address() < sec2->address(); }
  };

  class Branch_info
  {
   public:
    Branch_info(Powerpc_relobj<size, big_endian>* ppc_object,
		unsigned int data_shndx,
		Address r_offset,
		unsigned int r_type,
		unsigned int r_sym,
		Address addend)
      : object_(ppc_object), shndx_(data_shndx), offset_(r_offset),
	r_type_(r_type), tocsave_ (0), r_sym_(r_sym), addend_(addend)
    { }

    ~Branch_info()
    { }

    // Return whether this branch is going via a plt call stub, and if
    // so, mark it as having an R_PPC64_TOCSAVE.
    bool
    mark_pltcall(Powerpc_relobj<size, big_endian>* ppc_object,
		 unsigned int shndx, Address offset,
		 Target_powerpc* target, Symbol_table* symtab);

    // If this branch needs a plt call stub, or a long branch stub, make one.
    bool
    make_stub(Stub_table<size, big_endian>*,
	      Stub_table<size, big_endian>*,
	      Symbol_table*) const;

   private:
    // The branch location..
    Powerpc_relobj<size, big_endian>* object_;
    unsigned int shndx_;
    Address offset_;
    // ..and the branch type and destination.
    unsigned int r_type_ : 31;
    unsigned int tocsave_ : 1;
    unsigned int r_sym_;
    Address addend_;
  };

  // Information about this specific target which we pass to the
  // general Target structure.
  static Target::Target_info powerpc_info;

  // The small GOT section used by ppc32, and by ppc64 for entries that
  // must be addresseed +/-32k from the got pointer.
  Output_data_got_powerpc<size, big_endian>* got_;
  // Another GOT section used for entries that can be addressed +/- 2G
  // from the got pointer.
  Output_data_got_powerpc<size, big_endian>* biggot_;

  // The PLT section.  This is a container for a table of addresses,
  // and their relocations.  Each address in the PLT has a dynamic
  // relocation (R_*_JMP_SLOT) and each address will have a
  // corresponding entry in .glink for lazy resolution of the PLT.
  // ppc32 initialises the PLT to point at the .glink entry, while
  // ppc64 leaves this to ld.so.  To make a call via the PLT, the
  // linker adds a stub that loads the PLT entry into ctr then
  // branches to ctr.  There may be more than one stub for each PLT
  // entry.  DT_JMPREL points at the first PLT dynamic relocation and
  // DT_PLTRELSZ gives the total size of PLT dynamic relocations.
  Output_data_plt_powerpc<size, big_endian>* plt_;
  // The IPLT section.  Like plt_, this is a container for a table of
  // addresses and their relocations, specifically for STT_GNU_IFUNC
  // functions that resolve locally (STT_GNU_IFUNC functions that
  // don't resolve locally go in PLT).  Unlike plt_, these have no
  // entry in .glink for lazy resolution, and the relocation section
  // does not have a 1-1 correspondence with IPLT addresses.  In fact,
  // the relocation section may contain relocations against
  // STT_GNU_IFUNC symbols at locations outside of IPLT.  The
  // relocation section will appear at the end of other dynamic
  // relocations, so that ld.so applies these relocations after other
  // dynamic relocations.  In a static executable, the relocation
  // section is emitted and marked with __rela_iplt_start and
  // __rela_iplt_end symbols.
  Output_data_plt_powerpc<size, big_endian>* iplt_;
  // A PLT style section for local, non-ifunc symbols
  Output_data_plt_powerpc<size, big_endian>* lplt_;
  // Section holding long branch destinations.
  Output_data_brlt_powerpc<size, big_endian>* brlt_section_;
  // The .glink section.
  Output_data_glink<size, big_endian>* glink_;
  // The dynamic reloc section.
  Reloc_section* rela_dyn_;
  // Relocs saved to avoid a COPY reloc.
  Powerpc_copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
  // Offset of the GOT entry for local dynamic __tls_get_addr calls.
  unsigned int tlsld_got_offset_;

  Stub_tables stub_tables_;
  typedef Unordered_map<Address, unsigned int> Branch_lookup_table;
  Branch_lookup_table branch_lookup_table_;

  typedef std::vector<Branch_info> Branches;
  Branches branch_info_;
  Tocsave_loc tocsave_loc_;

  bool power10_relocs_;
  bool plt_thread_safe_;
  bool plt_localentry0_;
  bool plt_localentry0_init_;
  bool has_localentry0_;
  bool has_tls_get_addr_opt_;
  bool no_tprel_opt_;

  bool relax_failed_;
  int relax_fail_count_;
  int32_t stub_group_size_;

  Output_data_save_res<size, big_endian> *savres_section_;

  // The "__tls_get_addr" symbol, if present
  Symbol* tls_get_addr_;
  // If optimizing __tls_get_addr calls, the "__tls_get_addr_opt" symbol.
  Symbol* tls_get_addr_opt_;

  // Attributes in output.
  Attributes_section_data* attributes_section_data_;

  // Last input file to change various attribute tags
  const char* last_fp_;
  const char* last_ld_;
  const char* last_vec_;
  const char* last_struct_;
};

template<>
Target::Target_info Target_powerpc<32, true>::powerpc_info =
{
  32,			// size
  true,			// is_big_endian
  elfcpp::EM_PPC,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  false,		// has_code_fill
  true,			// is_default_stack_executable
  false,		// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/usr/lib/ld.so.1",	// dynamic_linker
  0x10000000,		// default_text_segment_address
  64 * 1024,		// abi_pagesize (overridable by -z max-page-size)
  4 * 1024,		// common_pagesize (overridable by -z common-page-size)
  false,		// isolate_execinstr
  0,			// rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  32,			// hash_entry_size
  elfcpp::SHT_PROGBITS,	// unwind_section_type
};

template<>
Target::Target_info Target_powerpc<32, false>::powerpc_info =
{
  32,			// size
  false,		// is_big_endian
  elfcpp::EM_PPC,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  false,		// has_code_fill
  true,			// is_default_stack_executable
  false,		// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/usr/lib/ld.so.1",	// dynamic_linker
  0x10000000,		// default_text_segment_address
  64 * 1024,		// abi_pagesize (overridable by -z max-page-size)
  4 * 1024,		// common_pagesize (overridable by -z common-page-size)
  false,		// isolate_execinstr
  0,			// rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  32,			// hash_entry_size
  elfcpp::SHT_PROGBITS,	// unwind_section_type
};

template<>
Target::Target_info Target_powerpc<64, true>::powerpc_info =
{
  64,			// size
  true,			// is_big_endian
  elfcpp::EM_PPC64,	// machine_code
  false,		// has_make_symbol
  true,			// has_resolve
  false,		// has_code_fill
  false,		// is_default_stack_executable
  false,		// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/usr/lib/ld.so.1",	// dynamic_linker
  0x10000000,		// default_text_segment_address
  64 * 1024,		// abi_pagesize (overridable by -z max-page-size)
  4 * 1024,		// common_pagesize (overridable by -z common-page-size)
  false,		// isolate_execinstr
  0,			// rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  32,			// hash_entry_size
  elfcpp::SHT_PROGBITS,	// unwind_section_type
};

template<>
Target::Target_info Target_powerpc<64, false>::powerpc_info =
{
  64,			// size
  false,		// is_big_endian
  elfcpp::EM_PPC64,	// machine_code
  false,		// has_make_symbol
  true,			// has_resolve
  false,		// has_code_fill
  false,		// is_default_stack_executable
  false,		// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/usr/lib/ld.so.1",	// dynamic_linker
  0x10000000,		// default_text_segment_address
  64 * 1024,		// abi_pagesize (overridable by -z max-page-size)
  4 * 1024,		// common_pagesize (overridable by -z common-page-size)
  false,		// isolate_execinstr
  0,			// rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  NULL,			// attributes_section
  NULL,			// attributes_vendor
  "_start",		// entry_symbol_name
  32,			// hash_entry_size
  elfcpp::SHT_PROGBITS,	// unwind_section_type
};

template<int size>
inline bool
is_branch_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_POWERPC_REL24
	  || (size == 64 && r_type == elfcpp::R_PPC64_REL24_NOTOC)
	  || r_type == elfcpp::R_PPC_PLTREL24
	  || r_type == elfcpp::R_PPC_LOCAL24PC
	  || r_type == elfcpp::R_POWERPC_REL14
	  || r_type == elfcpp::R_POWERPC_REL14_BRTAKEN
	  || r_type == elfcpp::R_POWERPC_REL14_BRNTAKEN
	  || r_type == elfcpp::R_POWERPC_ADDR24
	  || r_type == elfcpp::R_POWERPC_ADDR14
	  || r_type == elfcpp::R_POWERPC_ADDR14_BRTAKEN
	  || r_type == elfcpp::R_POWERPC_ADDR14_BRNTAKEN);
}

// Reloc resolves to plt entry.
template<int size>
inline bool
is_plt16_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_POWERPC_PLT16_LO
	  || r_type == elfcpp::R_POWERPC_PLT16_HI
	  || r_type == elfcpp::R_POWERPC_PLT16_HA
	  || (size == 64 && r_type == elfcpp::R_PPC64_PLT16_LO_DS));
}

// GOT_TYPE_STANDARD or GOT_TYPE_SMALL (ie. not TLS) GOT relocs
inline bool
is_got_reloc(unsigned int r_type)
{
  return (r_type == elfcpp::R_POWERPC_GOT16
	  || r_type == elfcpp::R_POWERPC_GOT16_LO
	  || r_type == elfcpp::R_POWERPC_GOT16_HI
	  || r_type == elfcpp::R_POWERPC_GOT16_HA
	  || r_type == elfcpp::R_PPC64_GOT16_DS
	  || r_type == elfcpp::R_PPC64_GOT16_LO_DS
	  || r_type == elfcpp::R_PPC64_GOT_PCREL34);
}

// If INSN is an opcode that may be used with an @tls operand, return
// the transformed insn for TLS optimisation, otherwise return 0.  If
// REG is non-zero only match an insn with RB or RA equal to REG.
uint32_t
at_tls_transform(uint32_t insn, unsigned int reg)
{
  if ((insn & (0x3f << 26)) != 31 << 26)
    return 0;

  unsigned int rtra;
  if (reg == 0 || ((insn >> 11) & 0x1f) == reg)
    rtra = insn & ((1 << 26) - (1 << 16));
  else if (((insn >> 16) & 0x1f) == reg)
    rtra = (insn & (0x1f << 21)) | ((insn & (0x1f << 11)) << 5);
  else
    return 0;

  if ((insn & (0x3ff << 1)) == 266 << 1)
    // add -> addi
    insn = 14 << 26;
  else if ((insn & (0x1f << 1)) == 23 << 1
	   && ((insn & (0x1f << 6)) < 14 << 6
	       || ((insn & (0x1f << 6)) >= 16 << 6
		   && (insn & (0x1f << 6)) < 24 << 6)))
    // load and store indexed -> dform
    insn = (32 | ((insn >> 6) & 0x1f)) << 26;
  else if ((insn & (((0x1a << 5) | 0x1f) << 1)) == 21 << 1)
    // ldx, ldux, stdx, stdux -> ld, ldu, std, stdu
    insn = ((58 | ((insn >> 6) & 4)) << 26) | ((insn >> 6) & 1);
  else if ((insn & (((0x1f << 5) | 0x1f) << 1)) == 341 << 1)
    // lwax -> lwa
    insn = (58 << 26) | 2;
  else
    return 0;
  insn |= rtra;
  return insn;
}


template<int size, bool big_endian>
class Powerpc_relocate_functions
{
public:
  enum Overflow_check
  {
    CHECK_NONE,
    CHECK_SIGNED,
    CHECK_UNSIGNED,
    CHECK_BITFIELD,
    CHECK_LOW_INSN,
    CHECK_HIGH_INSN
  };

  enum Status
  {
    STATUS_OK,
    STATUS_OVERFLOW
  };

private:
  typedef Powerpc_relocate_functions<size, big_endian> This;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef typename elfcpp::Elf_types<size>::Elf_Swxword SignedAddress;

  template<int valsize>
  static inline bool
  has_overflow_signed(Address value)
  {
    // limit = 1 << (valsize - 1) without shift count exceeding size of type
    Address limit = static_cast<Address>(1) << ((valsize - 1) >> 1);
    limit <<= ((valsize - 1) >> 1);
    limit <<= ((valsize - 1) - 2 * ((valsize - 1) >> 1));
    return value + limit > (limit << 1) - 1;
  }

  template<int valsize>
  static inline bool
  has_overflow_unsigned(Address value)
  {
    Address limit = static_cast<Address>(1) << ((valsize - 1) >> 1);
    limit <<= ((valsize - 1) >> 1);
    limit <<= ((valsize - 1) - 2 * ((valsize - 1) >> 1));
    return value > (limit << 1) - 1;
  }

  template<int valsize>
  static inline bool
  has_overflow_bitfield(Address value)
  {
    return (has_overflow_unsigned<valsize>(value)
	    && has_overflow_signed<valsize>(value));
  }

  template<int valsize>
  static inline Status
  overflowed(Address value, Overflow_check overflow)
  {
    if (overflow == CHECK_SIGNED)
      {
	if (has_overflow_signed<valsize>(value))
	  return STATUS_OVERFLOW;
      }
    else if (overflow == CHECK_UNSIGNED)
      {
	if (has_overflow_unsigned<valsize>(value))
	  return STATUS_OVERFLOW;
      }
    else if (overflow == CHECK_BITFIELD)
      {
	if (has_overflow_bitfield<valsize>(value))
	  return STATUS_OVERFLOW;
      }
    return STATUS_OK;
  }

  // Do a simple RELA relocation
  template<int fieldsize, int valsize>
  static inline Status
  rela(unsigned char* view, Address value, Overflow_check overflow)
  {
    typedef typename elfcpp::Swap<fieldsize, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    elfcpp::Swap<fieldsize, big_endian>::writeval(wv, value);
    return overflowed<valsize>(value, overflow);
  }

  template<int fieldsize, int valsize>
  static inline Status
  rela(unsigned char* view,
       unsigned int right_shift,
       typename elfcpp::Valtype_base<fieldsize>::Valtype dst_mask,
       Address value,
       Overflow_check overflow)
  {
    typedef typename elfcpp::Swap<fieldsize, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<fieldsize, big_endian>::readval(wv);
    if (overflow == CHECK_SIGNED)
      value = static_cast<SignedAddress>(value) >> right_shift;
    else
      value = value >> right_shift;
    Valtype reloc = value;
    val &= ~dst_mask;
    reloc &= dst_mask;
    elfcpp::Swap<fieldsize, big_endian>::writeval(wv, val | reloc);
    return overflowed<valsize>(value, overflow);
  }

  // Do a simple RELA relocation, unaligned.
  template<int fieldsize, int valsize>
  static inline Status
  rela_ua(unsigned char* view, Address value, Overflow_check overflow)
  {
    elfcpp::Swap_unaligned<fieldsize, big_endian>::writeval(view, value);
    return overflowed<valsize>(value, overflow);
  }

  template<int fieldsize, int valsize>
  static inline Status
  rela_ua(unsigned char* view,
	  unsigned int right_shift,
	  typename elfcpp::Valtype_base<fieldsize>::Valtype dst_mask,
	  Address value,
	  Overflow_check overflow)
  {
    typedef typename elfcpp::Swap_unaligned<fieldsize, big_endian>::Valtype
      Valtype;
    Valtype val = elfcpp::Swap<fieldsize, big_endian>::readval(view);
    if (overflow == CHECK_SIGNED)
      value = static_cast<SignedAddress>(value) >> right_shift;
    else
      value = value >> right_shift;
    Valtype reloc = value;
    val &= ~dst_mask;
    reloc &= dst_mask;
    elfcpp::Swap_unaligned<fieldsize, big_endian>::writeval(view, val | reloc);
    return overflowed<valsize>(value, overflow);
  }

public:
  // R_PPC64_ADDR64: (Symbol + Addend)
  static inline void
  addr64(unsigned char* view, Address value)
  { This::template rela<64,64>(view, value, CHECK_NONE); }

  // R_PPC64_UADDR64: (Symbol + Addend) unaligned
  static inline void
  addr64_u(unsigned char* view, Address value)
  { This::template rela_ua<64,64>(view, value, CHECK_NONE); }

  // R_POWERPC_ADDR32: (Symbol + Addend)
  static inline Status
  addr32(unsigned char* view, Address value, Overflow_check overflow)
  { return This::template rela<32,32>(view, value, overflow); }

  // R_POWERPC_UADDR32: (Symbol + Addend) unaligned
  static inline Status
  addr32_u(unsigned char* view, Address value, Overflow_check overflow)
  { return This::template rela_ua<32,32>(view, value, overflow); }

  // R_POWERPC_ADDR24: (Symbol + Addend) & 0x3fffffc
  static inline Status
  addr24(unsigned char* view, Address value, Overflow_check overflow)
  {
    Status stat = This::template rela<32,26>(view, 0, 0x03fffffc,
					     value, overflow);
    if (overflow != CHECK_NONE && (value & 3) != 0)
      stat = STATUS_OVERFLOW;
    return stat;
  }

  // R_POWERPC_ADDR16: (Symbol + Addend) & 0xffff
  static inline Status
  addr16(unsigned char* view, Address value, Overflow_check overflow)
  { return This::template rela<16,16>(view, value, overflow); }

  // R_POWERPC_ADDR16: (Symbol + Addend) & 0xffff, unaligned
  static inline Status
  addr16_u(unsigned char* view, Address value, Overflow_check overflow)
  { return This::template rela_ua<16,16>(view, value, overflow); }

  // R_POWERPC_ADDR16_DS: (Symbol + Addend) & 0xfffc
  static inline Status
  addr16_ds(unsigned char* view, Address value, Overflow_check overflow)
  {
    Status stat = This::template rela<16,16>(view, 0, 0xfffc, value, overflow);
    if ((value & 3) != 0)
      stat = STATUS_OVERFLOW;
    return stat;
  }

  // R_POWERPC_ADDR16_DQ: (Symbol + Addend) & 0xfff0
  static inline Status
  addr16_dq(unsigned char* view, Address value, Overflow_check overflow)
  {
    Status stat = This::template rela<16,16>(view, 0, 0xfff0, value, overflow);
    if ((value & 15) != 0)
      stat = STATUS_OVERFLOW;
    return stat;
  }

  // R_POWERPC_ADDR16_HI: ((Symbol + Addend) >> 16) & 0xffff
  static inline void
  addr16_hi(unsigned char* view, Address value)
  { This::template rela<16,16>(view, 16, 0xffff, value, CHECK_NONE); }

  // R_POWERPC_ADDR16_HA: ((Symbol + Addend + 0x8000) >> 16) & 0xffff
  static inline void
  addr16_ha(unsigned char* view, Address value)
  { This::addr16_hi(view, value + 0x8000); }

  // R_POWERPC_ADDR16_HIGHER: ((Symbol + Addend) >> 32) & 0xffff
  static inline void
  addr16_hi2(unsigned char* view, Address value)
  { This::template rela<16,16>(view, 32, 0xffff, value, CHECK_NONE); }

  // R_POWERPC_ADDR16_HIGHERA: ((Symbol + Addend + 0x8000) >> 32) & 0xffff
  static inline void
  addr16_ha2(unsigned char* view, Address value)
  { This::addr16_hi2(view, value + 0x8000); }

  // R_POWERPC_ADDR16_HIGHEST: ((Symbol + Addend) >> 48) & 0xffff
  static inline void
  addr16_hi3(unsigned char* view, Address value)
  { This::template rela<16,16>(view, 48, 0xffff, value, CHECK_NONE); }

  // R_POWERPC_ADDR16_HIGHESTA: ((Symbol + Addend + 0x8000) >> 48) & 0xffff
  static inline void
  addr16_ha3(unsigned char* view, Address value)
  { This::addr16_hi3(view, value + 0x8000); }

  // R_POWERPC_ADDR14: (Symbol + Addend) & 0xfffc
  static inline Status
  addr14(unsigned char* view, Address value, Overflow_check overflow)
  {
    Status stat = This::template rela<32,16>(view, 0, 0xfffc, value, overflow);
    if (overflow != CHECK_NONE && (value & 3) != 0)
      stat = STATUS_OVERFLOW;
    return stat;
  }

  // R_POWERPC_REL16DX_HA
  static inline Status
  addr16dx_ha(unsigned char *view, Address value, Overflow_check overflow)
  {
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
    value += 0x8000;
    value = static_cast<SignedAddress>(value) >> 16;
    val |= (value & 0xffc1) | ((value & 0x3e) << 15);
    elfcpp::Swap<32, big_endian>::writeval(wv, val);
    return overflowed<16>(value, overflow);
  }

  // R_PPC64_D34
  static inline Status
  addr34(unsigned char *view, uint64_t value, Overflow_check overflow)
  {
    Status stat = This::template rela<32,18>(view, 16, 0x3ffff,
					     value, overflow);
    This::rela<32,16>(view + 4, 0, 0xffff, value, CHECK_NONE);
    return stat;
  }

  // R_PPC64_D34_HI30
  static inline void
  addr34_hi(unsigned char *view, uint64_t value)
  { This::addr34(view, value >> 34, CHECK_NONE);}

  // R_PPC64_D34_HA30
  static inline void
  addr34_ha(unsigned char *view, uint64_t value)
  { This::addr34_hi(view, value + (1ULL << 33));}

  // R_PPC64_D28
  static inline Status
  addr28(unsigned char *view, uint64_t value, Overflow_check overflow)
  {
    Status stat = This::template rela<32,12>(view, 16, 0xfff,
					     value, overflow);
    This::rela<32,16>(view + 4, 0, 0xffff, value, CHECK_NONE);
    return stat;
  }

  // R_PPC64_ADDR16_HIGHER34
  static inline void
  addr16_higher34(unsigned char* view, uint64_t value)
  { This::addr16(view, value >> 34, CHECK_NONE); }

  // R_PPC64_ADDR16_HIGHERA34
  static inline void
  addr16_highera34(unsigned char* view, uint64_t value)
  { This::addr16_higher34(view, value + (1ULL << 33)); }

  // R_PPC64_ADDR16_HIGHEST34
  static inline void
  addr16_highest34(unsigned char* view, uint64_t value)
  { This::addr16(view, value >> 50, CHECK_NONE); }

  // R_PPC64_ADDR16_HIGHESTA34
  static inline void
  addr16_highesta34(unsigned char* view, uint64_t value)
  { This::addr16_highest34(view, value + (1ULL << 33)); }
};

// Set ABI version for input and output.

template<int size, bool big_endian>
void
Powerpc_relobj<size, big_endian>::set_abiversion(int ver)
{
  this->e_flags_ |= ver;
  if (this->abiversion() != 0)
    {
      Target_powerpc<size, big_endian>* target =
	static_cast<Target_powerpc<size, big_endian>*>(
	   parameters->sized_target<size, big_endian>());
      if (target->abiversion() == 0)
	target->set_abiversion(this->abiversion());
      else if (target->abiversion() != this->abiversion())
	gold_error(_("%s: ABI version %d is not compatible "
		     "with ABI version %d output"),
		   this->name().c_str(),
		   this->abiversion(), target->abiversion());

    }
}

// Stash away the index of .got2, .opd, .rela.toc, and .toc in a
// relocatable object, if such sections exists.

template<int size, bool big_endian>
bool
Powerpc_relobj<size, big_endian>::do_find_special_sections(
    Read_symbols_data* sd)
{
  const unsigned char* const pshdrs = sd->section_headers->data();
  const unsigned char* namesu = sd->section_names->data();
  const char* names = reinterpret_cast<const char*>(namesu);
  section_size_type names_size = sd->section_names_size;
  const unsigned char* s;

  s = this->template find_shdr<size, big_endian>(pshdrs,
						 size == 32 ? ".got2" : ".opd",
						 names, names_size, NULL);
  if (s != NULL)
    {
      unsigned int ndx = (s - pshdrs) / elfcpp::Elf_sizes<size>::shdr_size;
      this->special_ = ndx;
      if (size == 64)
	{
	  if (this->abiversion() == 0)
	    this->set_abiversion(1);
	  else if (this->abiversion() > 1)
	    gold_error(_("%s: .opd invalid in abiv%d"),
		       this->name().c_str(), this->abiversion());
	}
    }
  if (size == 64)
    {
      s = this->template find_shdr<size, big_endian>(pshdrs, ".rela.toc",
						     names, names_size, NULL);
      if (s != NULL)
	{
	  unsigned int ndx = (s - pshdrs) / elfcpp::Elf_sizes<size>::shdr_size;
	  this->relatoc_ = ndx;
	  typename elfcpp::Shdr<size, big_endian> shdr(s);
	  this->toc_ = this->adjust_shndx(shdr.get_sh_info());
	}
    }
  return Sized_relobj_file<size, big_endian>::do_find_special_sections(sd);
}

// Examine .rela.opd to build info about function entry points.

template<int size, bool big_endian>
void
Powerpc_relobj<size, big_endian>::scan_opd_relocs(
    size_t reloc_count,
    const unsigned char* prelocs,
    const unsigned char* plocal_syms)
{
  if (size == 64)
    {
      typedef typename elfcpp::Rela<size, big_endian> Reltype;
      const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
      const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
      Address expected_off = 0;
      bool regular = true;
      unsigned int opd_ent_size = 0;

      for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
	{
	  Reltype reloc(prelocs);
	  typename elfcpp::Elf_types<size>::Elf_WXword r_info
	    = reloc.get_r_info();
	  unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
	  if (r_type == elfcpp::R_PPC64_ADDR64)
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
	      typename elfcpp::Elf_types<size>::Elf_Addr value;
	      bool is_ordinary;
	      unsigned int shndx;
	      if (r_sym < this->local_symbol_count())
		{
		  typename elfcpp::Sym<size, big_endian>
		    lsym(plocal_syms + r_sym * sym_size);
		  shndx = lsym.get_st_shndx();
		  shndx = this->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
		  value = lsym.get_st_value();
		}
	      else
		shndx = this->symbol_section_and_value(r_sym, &value,
						       &is_ordinary);
	      this->set_opd_ent(reloc.get_r_offset(), shndx,
				value + reloc.get_r_addend());
	      if (i == 2)
		{
		  expected_off = reloc.get_r_offset();
		  opd_ent_size = expected_off;
		}
	      else if (expected_off != reloc.get_r_offset())
		regular = false;
	      expected_off += opd_ent_size;
	    }
	  else if (r_type == elfcpp::R_PPC64_TOC)
	    {
	      if (expected_off - opd_ent_size + 8 != reloc.get_r_offset())
		regular = false;
	    }
	  else
	    {
	      gold_warning(_("%s: unexpected reloc type %u in .opd section"),
			   this->name().c_str(), r_type);
	      regular = false;
	    }
	}
      if (reloc_count <= 2)
	opd_ent_size = this->section_size(this->opd_shndx());
      if (opd_ent_size != 24 && opd_ent_size != 16)
	regular = false;
      if (!regular)
	{
	  gold_warning(_("%s: .opd is not a regular array of opd entries"),
		       this->name().c_str());
	  opd_ent_size = 0;
	}
    }
}

// Returns true if a code sequence loading the TOC entry at VALUE
// relative to the TOC pointer can be converted into code calculating
// a TOC pointer relative offset.
// If so, the TOC pointer relative offset is stored to VALUE.

template<int size, bool big_endian>
bool
Powerpc_relobj<size, big_endian>::make_toc_relative(
    Target_powerpc<size, big_endian>* target,
    Address* value)
{
  if (size != 64)
    return false;

  // With -mcmodel=medium code it is quite possible to have
  // toc-relative relocs referring to objects outside the TOC.
  // Don't try to look at a non-existent TOC.
  if (this->toc_shndx() == 0
      || this->output_section(this->toc_shndx()) == 0)
    return false;

  // Convert VALUE back to an address by adding got_base (see below),
  // then to an offset in the TOC by subtracting the TOC output
  // section address and the TOC output offset.
  Address off = (*value + target->toc_pointer()
		 - this->output_section(this->toc_shndx())->address()
		 - this->output_section_offset(this->toc_shndx()));
  // Is this offset in the TOC?  -mcmodel=medium code may be using
  // TOC relative access to variables outside the TOC.  Those of
  // course can't be optimized.  We also don't try to optimize code
  // that is using a different object's TOC.
  if (off >= this->section_size(this->toc_shndx()))
    return false;

  if (this->no_toc_opt(off))
    return false;

  section_size_type vlen;
  unsigned char* view = this->get_output_view(this->toc_shndx(), &vlen);
  Address addr = elfcpp::Swap<size, big_endian>::readval(view + off);
  // The TOC pointer
  Address got_base = target->toc_pointer();
  addr -= got_base;
  if (addr + (uint64_t) 0x80008000 >= (uint64_t) 1 << 32)
    return false;

  *value = addr;
  return true;
}

template<int size, bool big_endian>
bool
Powerpc_relobj<size, big_endian>::make_got_relative(
    Target_powerpc<size, big_endian>* target,
    const Symbol_value<size>* psymval,
    Address addend,
    Address* value)
{
  Address addr = psymval->value(this, addend);
  Address got_base = target->toc_pointer();
  addr -= got_base;
  if (addr + 0x80008000 > 0xffffffff)
    return false;

  *value = addr;
  return true;
}

// Perform the Sized_relobj_file method, then set up opd info from
// .opd relocs.

template<int size, bool big_endian>
void
Powerpc_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
{
  Sized_relobj_file<size, big_endian>::do_read_relocs(rd);
  if (size == 64)
    {
      for (Read_relocs_data::Relocs_list::iterator p = rd->relocs.begin();
	   p != rd->relocs.end();
	   ++p)
	{
	  if (p->data_shndx == this->opd_shndx())
	    {
	      uint64_t opd_size = this->section_size(this->opd_shndx());
	      gold_assert(opd_size == static_cast<size_t>(opd_size));
	      if (opd_size != 0)
		{
		  this->init_opd(opd_size);
		  this->scan_opd_relocs(p->reloc_count, p->contents->data(),
					rd->local_symbols->data());
		}
	      break;
	    }
	}
    }
}

// Read the symbols then set up st_other vector.

template<int size, bool big_endian>
void
Powerpc_relobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
{
  this->base_read_symbols(sd);
  if (this->input_file()->format() != Input_file::FORMAT_ELF)
    return;
  if (size == 64)
    {
      const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
      const unsigned char* const pshdrs = sd->section_headers->data();
      const unsigned int loccount = this->do_local_symbol_count();
      if (loccount != 0)
	{
	  this->st_other_.resize(loccount);
	  const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
	  off_t locsize = loccount * sym_size;
	  const unsigned int symtab_shndx = this->symtab_shndx();
	  const unsigned char *psymtab = pshdrs + symtab_shndx * shdr_size;
	  typename elfcpp::Shdr<size, big_endian> shdr(psymtab);
	  const unsigned char* psyms = this->get_view(shdr.get_sh_offset(),
						      locsize, true, false);
	  psyms += sym_size;
	  for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
	    {
	      elfcpp::Sym<size, big_endian> sym(psyms);
	      unsigned char st_other = sym.get_st_other();
	      this->st_other_[i] = st_other;
	      if ((st_other & elfcpp::STO_PPC64_LOCAL_MASK) != 0)
		{
		  if (this->abiversion() == 0)
		    this->set_abiversion(2);
		  else if (this->abiversion() < 2)
		    gold_error(_("%s: local symbol %d has invalid st_other"
				 " for ABI version 1"),
			       this->name().c_str(), i);
		}
	    }
	}
    }

  const size_t shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  const unsigned char* ps = sd->section_headers->data() + shdr_size;
  bool merge_attributes = false;
  for (unsigned int i = 1; i < this->shnum(); ++i, ps += shdr_size)
    {
      elfcpp::Shdr<size, big_endian> shdr(ps);
      switch (shdr.get_sh_type())
	{
	case elfcpp::SHT_GNU_ATTRIBUTES:
	  {
	    gold_assert(this->attributes_section_data_ == NULL);
	    section_offset_type section_offset = shdr.get_sh_offset();
	    section_size_type section_size =
	      convert_to_section_size_type(shdr.get_sh_size());
	    const unsigned char* view =
	      this->get_view(section_offset, section_size, true, false);
	    this->attributes_section_data_ =
	      new Attributes_section_data(view, section_size);
	  }
	  break;

	case elfcpp::SHT_SYMTAB:
	  {
	    // Sometimes an object has no contents except the section
	    // name string table and an empty symbol table with the
	    // undefined symbol.  We don't want to merge
	    // processor-specific flags from such an object.
	    const typename elfcpp::Elf_types<size>::Elf_WXword sym_size =
	      elfcpp::Elf_sizes<size>::sym_size;
	    if (shdr.get_sh_size() > sym_size)
	      merge_attributes = true;
	  }
	  break;

	case elfcpp::SHT_STRTAB:
	  break;

	default:
	  merge_attributes = true;
	  break;
	}
    }

  if (!merge_attributes)
    {
      // Should rarely happen.
      delete this->attributes_section_data_;
      this->attributes_section_data_ = NULL;
    }
}

template<int size, bool big_endian>
void
Powerpc_dynobj<size, big_endian>::set_abiversion(int ver)
{
  this->e_flags_ |= ver;
  if (this->abiversion() != 0)
    {
      Target_powerpc<size, big_endian>* target =
	static_cast<Target_powerpc<size, big_endian>*>(
	  parameters->sized_target<size, big_endian>());
      if (target->abiversion() == 0)
	target->set_abiversion(this->abiversion());
      else if (target->abiversion() != this->abiversion())
	gold_error(_("%s: ABI version %d is not compatible "
		     "with ABI version %d output"),
		   this->name().c_str(),
		   this->abiversion(), target->abiversion());

    }
}

// Call Sized_dynobj::base_read_symbols to read the symbols then
// read .opd from a dynamic object, filling in opd_ent_ vector,

template<int size, bool big_endian>
void
Powerpc_dynobj<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
{
  this->base_read_symbols(sd);
  const size_t shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  const unsigned char* ps =
    sd->section_headers->data() + shdr_size * (this->shnum() - 1);
  for (unsigned int i = this->shnum(); i > 0; --i, ps -= shdr_size)
    {
      elfcpp::Shdr<size, big_endian> shdr(ps);
      if (shdr.get_sh_type() == elfcpp::SHT_GNU_ATTRIBUTES)
	{
	  section_offset_type section_offset = shdr.get_sh_offset();
	  section_size_type section_size =
	    convert_to_section_size_type(shdr.get_sh_size());
	  const unsigned char* view =
	    this->get_view(section_offset, section_size, true, false);
	  this->attributes_section_data_ =
	    new Attributes_section_data(view, section_size);
	  break;
	}
    }
  if (size == 64)
    {
      const unsigned char* const pshdrs = sd->section_headers->data();
      const unsigned char* namesu = sd->section_names->data();
      const char* names = reinterpret_cast<const char*>(namesu);
      const unsigned char* s = NULL;
      const unsigned char* opd;
      section_size_type opd_size;

      // Find and read .opd section.
      while (1)
	{
	  s = this->template find_shdr<size, big_endian>(pshdrs, ".opd", names,
							 sd->section_names_size,
							 s);
	  if (s == NULL)
	    return;

	  typename elfcpp::Shdr<size, big_endian> shdr(s);
	  if (shdr.get_sh_type() == elfcpp::SHT_PROGBITS
	      && (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) != 0)
	    {
	      if (this->abiversion() == 0)
		this->set_abiversion(1);
	      else if (this->abiversion() > 1)
		gold_error(_("%s: .opd invalid in abiv%d"),
			   this->name().c_str(), this->abiversion());

	      this->opd_shndx_ = (s - pshdrs) / shdr_size;
	      this->opd_address_ = shdr.get_sh_addr();
	      opd_size = convert_to_section_size_type(shdr.get_sh_size());
	      opd = this->get_view(shdr.get_sh_offset(), opd_size,
				   true, false);
	      break;
	    }
	}

      // Build set of executable sections.
      // Using a set is probably overkill.  There is likely to be only
      // a few executable sections, typically .init, .text and .fini,
      // and they are generally grouped together.
      typedef std::set<Sec_info> Exec_sections;
      Exec_sections exec_sections;
      s = pshdrs;
      for (unsigned int i = 1; i < this->shnum(); ++i, s += shdr_size)
	{
	  typename elfcpp::Shdr<size, big_endian> shdr(s);
	  if (shdr.get_sh_type() == elfcpp::SHT_PROGBITS
	      && ((shdr.get_sh_flags()
		   & (elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR))
		  == (elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR))
	      && shdr.get_sh_size() != 0)
	    {
	      exec_sections.insert(Sec_info(shdr.get_sh_addr(),
					    shdr.get_sh_size(), i));
	    }
	}
      if (exec_sections.empty())
	return;

      // Look over the OPD entries.  This is complicated by the fact
      // that some binaries will use two-word entries while others
      // will use the standard three-word entries.  In most cases
      // the third word (the environment pointer for languages like
      // Pascal) is unused and will be zero.  If the third word is
      // used it should not be pointing into executable sections,
      // I think.
      this->init_opd(opd_size);
      for (const unsigned char* p = opd; p < opd + opd_size; p += 8)
	{
	  typedef typename elfcpp::Swap<64, big_endian>::Valtype Valtype;
	  const Valtype* valp = reinterpret_cast<const Valtype*>(p);
	  Valtype val = elfcpp::Swap<64, big_endian>::readval(valp);
	  if (val == 0)
	    // Chances are that this is the third word of an OPD entry.
	    continue;
	  typename Exec_sections::const_iterator e
	    = exec_sections.upper_bound(Sec_info(val, 0, 0));
	  if (e != exec_sections.begin())
	    {
	      --e;
	      if (e->start <= val && val < e->start + e->len)
		{
		  // We have an address in an executable section.
		  // VAL ought to be the function entry, set it up.
		  this->set_opd_ent(p - opd, e->shndx, val);
		  // Skip second word of OPD entry, the TOC pointer.
		  p += 8;
		}
	    }
	  // If we didn't match any executable sections, we likely
	  // have a non-zero third word in the OPD entry.
	}
    }
}

// Relocate sections.

template<int size, bool big_endian>
void
Powerpc_relobj<size, big_endian>::do_relocate_sections(
    const Symbol_table* symtab, const Layout* layout,
    const unsigned char* pshdrs, Output_file* of,
    typename Sized_relobj_file<size, big_endian>::Views* pviews)
{
  unsigned int start = 1;
  if (size == 64
      && this->relatoc_ != 0
      && !parameters->options().relocatable())
    {
      // Relocate .toc first.
      this->relocate_section_range(symtab, layout, pshdrs, of, pviews,
				   this->relatoc_, this->relatoc_);
      this->relocate_section_range(symtab, layout, pshdrs, of, pviews,
				   1, this->relatoc_ - 1);
      start = this->relatoc_ + 1;
    }
  this->relocate_section_range(symtab, layout, pshdrs, of, pviews,
			       start, this->shnum() - 1);

  if (!parameters->options().output_is_position_independent())
    {
      Target_powerpc<size, big_endian>* target
	= static_cast<Target_powerpc<size, big_endian>*>(
	    parameters->sized_target<size, big_endian>());
      if (target->lplt_section() && target->lplt_section()->data_size() != 0)
	{
	  const section_size_type offset = target->lplt_section()->offset();
	  const section_size_type oview_size
	    = convert_to_section_size_type(target->lplt_section()->data_size());
	  unsigned char* const oview = of->get_output_view(offset, oview_size);

	  bool modified = false;
	  unsigned int nsyms = this->local_symbol_count();
	  for (unsigned int i = 0; i < nsyms; i++)
	    if (this->local_has_plt_offset(i))
	      {
		Address value = this->local_symbol_value(i, 0);
		size_t off = this->local_plt_offset(i);
		elfcpp::Swap<size, big_endian>::writeval(oview + off, value);
		modified = true;
	      }
	  if (modified)
	    of->write_output_view(offset, oview_size, oview);
	}
    }
}

// Set up some symbols.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_define_standard_symbols(
    Symbol_table* symtab,
    Layout* layout)
{
  if (size == 32)
    {
      // Define _GLOBAL_OFFSET_TABLE_ to ensure it isn't seen as
      // undefined when scanning relocs (and thus requires
      // non-relative dynamic relocs).  The proper value will be
      // updated later.
      Symbol *gotsym = symtab->lookup("_GLOBAL_OFFSET_TABLE_", NULL);
      if (gotsym != NULL && gotsym->is_undefined())
	{
	  Target_powerpc<size, big_endian>* target =
	    static_cast<Target_powerpc<size, big_endian>*>(
		parameters->sized_target<size, big_endian>());
	  Output_data_got_powerpc<size, big_endian>* got
	    = target->got_section(symtab, layout, GOT_TYPE_SMALL);
	  symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
					Symbol_table::PREDEFINED,
					got, 0, 0,
					elfcpp::STT_OBJECT,
					elfcpp::STB_LOCAL,
					elfcpp::STV_HIDDEN, 0,
					false, false);
	}

      // Define _SDA_BASE_ at the start of the .sdata section + 32768.
      Symbol *sdasym = symtab->lookup("_SDA_BASE_", NULL);
      if (sdasym != NULL && sdasym->is_undefined())
	{
	  Output_data_space* sdata = new Output_data_space(4, "** sdata");
	  Output_section* os
	    = layout->add_output_section_data(".sdata", 0,
					      elfcpp::SHF_ALLOC
					      | elfcpp::SHF_WRITE,
					      sdata, ORDER_SMALL_DATA, false);
	  symtab->define_in_output_data("_SDA_BASE_", NULL,
					Symbol_table::PREDEFINED,
					os, 32768, 0, elfcpp::STT_OBJECT,
					elfcpp::STB_LOCAL, elfcpp::STV_HIDDEN,
					0, false, false);
	}
    }
  else
    {
      // Define .TOC. as for 32-bit _GLOBAL_OFFSET_TABLE_
      Symbol *gotsym = symtab->lookup(".TOC.", NULL);
      if (gotsym != NULL && gotsym->is_undefined())
	{
	  Target_powerpc<size, big_endian>* target =
	    static_cast<Target_powerpc<size, big_endian>*>(
		parameters->sized_target<size, big_endian>());
	  Output_data_got_powerpc<size, big_endian>* got
	    = target->got_section(symtab, layout, GOT_TYPE_SMALL);
	  symtab->define_in_output_data(".TOC.", NULL,
					Symbol_table::PREDEFINED,
					got, 0x8000, 0,
					elfcpp::STT_OBJECT,
					elfcpp::STB_LOCAL,
					elfcpp::STV_HIDDEN, 0,
					false, false);
	}
    }

  this->tls_get_addr_ = symtab->lookup("__tls_get_addr");
  if (parameters->options().tls_get_addr_optimize()
      && this->tls_get_addr_ != NULL
      && this->tls_get_addr_->in_reg())
    this->tls_get_addr_opt_ = symtab->lookup("__tls_get_addr_opt");
  if (this->tls_get_addr_opt_ != NULL)
    {
      if (this->tls_get_addr_->is_undefined()
	  || this->tls_get_addr_->is_from_dynobj())
	{
	  // Make it seem as if references to __tls_get_addr are
	  // really to __tls_get_addr_opt, so the latter symbol is
	  // made dynamic, not the former.
	  this->tls_get_addr_->clear_in_reg();
	  this->tls_get_addr_opt_->set_in_reg();
	}
      // We have a non-dynamic definition for __tls_get_addr.
      // Make __tls_get_addr_opt the same, if it does not already have
      // a non-dynamic definition.
      else if (this->tls_get_addr_opt_->is_undefined()
	       || this->tls_get_addr_opt_->is_from_dynobj())
	{
	  Sized_symbol<size>* from
	    = static_cast<Sized_symbol<size>*>(this->tls_get_addr_);
	  Sized_symbol<size>* to
	    = static_cast<Sized_symbol<size>*>(this->tls_get_addr_opt_);
	  symtab->clone<size>(to, from);
	}
    }
}

// Set up PowerPC target specific relobj.

template<int size, bool big_endian>
Object*
Target_powerpc<size, big_endian>::do_make_elf_object(
    const std::string& name,
    Input_file* input_file,
    off_t offset, const elfcpp::Ehdr<size, big_endian>& ehdr)
{
  int et = ehdr.get_e_type();
  // ET_EXEC files are valid input for --just-symbols/-R,
  // and we treat them as relocatable objects.
  if (et == elfcpp::ET_REL
      || (et == elfcpp::ET_EXEC && input_file->just_symbols()))
    {
      Powerpc_relobj<size, big_endian>* obj =
	new Powerpc_relobj<size, big_endian>(name, input_file, offset, ehdr);
      obj->setup();
      return obj;
    }
  else if (et == elfcpp::ET_DYN)
    {
      Powerpc_dynobj<size, big_endian>* obj =
	new Powerpc_dynobj<size, big_endian>(name, input_file, offset, ehdr);
      obj->setup();
      return obj;
    }
  else
    {
      gold_error(_("%s: unsupported ELF file type %d"), name.c_str(), et);
      return NULL;
    }
}

template<int size, bool big_endian>
class Output_data_got_powerpc : public Output_data_got<size, big_endian>
{
public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
  typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Rela_dyn;

  Output_data_got_powerpc(Symbol_table* symtab, Layout* layout,
			  Got_type got_type)
    : Output_data_got<size, big_endian>(),
      symtab_(symtab), layout_(layout),
      header_ent_cnt_(size == 32 ? 3 : 1),
      header_index_(size == 32 ? 0x2000 : -1u)
  {
    if (size == 64)
      this->set_addralign(256);
    if (size == 64 && (got_type & GOT_TYPE_SMALL))
      this->make_header();
  }

  // Override all the Output_data_got methods we use so as to first call
  // reserve_ent().
  bool
  add_global(Symbol* gsym, unsigned int got_type, uint64_t addend)
  {
    this->reserve_ent();
    return Output_data_got<size, big_endian>::add_global(gsym, got_type,
							 addend);
  }

  bool
  add_global_plt(Symbol* gsym, unsigned int got_type, uint64_t addend)
  {
    this->reserve_ent();
    return Output_data_got<size, big_endian>::add_global_plt(gsym, got_type,
							     addend);
  }

  bool
  add_global_tls(Symbol* gsym, unsigned int got_type, uint64_t addend)
  { return this->add_global_plt(gsym, got_type, addend); }

  void
  add_global_with_rel(Symbol* gsym, unsigned int got_type,
		      Output_data_reloc_generic* rel_dyn,
		      unsigned int r_type, uint64_t addend)
  {
    this->reserve_ent();
    Output_data_got<size, big_endian>::
      add_global_with_rel(gsym, got_type, rel_dyn, r_type, addend);
  }

  void
  add_global_pair_with_rel(Symbol* gsym, unsigned int got_type,
			   Output_data_reloc_generic* rel_dyn,
			   unsigned int r_type_1, unsigned int r_type_2,
			   uint64_t addend)
  {
    if (gsym->has_got_offset(got_type))
      return;

    this->reserve_ent(2);
    Output_data_got<size, big_endian>::
      add_global_pair_with_rel(gsym, got_type, rel_dyn, r_type_1, r_type_2,
			       addend);
  }

  bool
  add_local(Relobj* object, unsigned int sym_index, unsigned int got_type,
	    uint64_t addend)
  {
    this->reserve_ent();
    return Output_data_got<size, big_endian>::add_local(object, sym_index,
							got_type, addend);
  }

  bool
  add_local_plt(Relobj* object, unsigned int sym_index,
		unsigned int got_type, uint64_t addend)
  {
    this->reserve_ent();
    return Output_data_got<size, big_endian>::add_local_plt(object, sym_index,
							    got_type, addend);
  }

  bool
  add_local_tls(Relobj* object, unsigned int sym_index,
		unsigned int got_type, uint64_t addend)
  { return this->add_local_plt(object, sym_index, got_type, addend); }

  void
  add_local_tls_pair(Relobj* object, unsigned int sym_index,
		     unsigned int got_type,
		     Output_data_reloc_generic* rel_dyn,
		     unsigned int r_type, uint64_t addend)
  {
    if (object->local_has_got_offset(sym_index, got_type, addend))
      return;

    this->reserve_ent(2);
    Output_data_got<size, big_endian>::
      add_local_tls_pair(object, sym_index, got_type, rel_dyn, r_type, addend);
  }

  unsigned int
  add_constant(Valtype constant)
  {
    this->reserve_ent();
    return Output_data_got<size, big_endian>::add_constant(constant);
  }

  unsigned int
  add_constant_pair(Valtype c1, Valtype c2)
  {
    this->reserve_ent(2);
    return Output_data_got<size, big_endian>::add_constant_pair(c1, c2);
  }

  // Offset of _GLOBAL_OFFSET_TABLE_ and .TOC. in this section.
  unsigned int
  g_o_t() const
  {
    if (size == 32)
      return this->got_offset(this->header_index_);
    else if (this->header_index_ != -1u)
      return this->got_offset(this->header_index_) + 0x8000;
    else
      gold_unreachable();
  }

  // Ensure our GOT has a header.
  void
  set_final_data_size()
  {
    if (size == 32 && this->header_ent_cnt_ != 0)
      this->make_header();
    Output_data_got<size, big_endian>::set_final_data_size();
  }

  // First word of GOT header needs some values that are not
  // handled by Output_data_got so poke them in here.
  // For 32-bit, address of .dynamic, for 64-bit, address of TOCbase.
  void
  do_write(Output_file* of)
  {
    if (this->header_index_ != -1u)
      {
	Valtype val = 0;
	if (size == 32 && this->layout_->dynamic_data() != NULL)
	  val = this->layout_->dynamic_section()->address();
	if (size == 64)
	  val = this->address() + this->g_o_t();
	this->replace_constant(this->header_index_, val);
      }
    Output_data_got<size, big_endian>::do_write(of);
  }

private:
  void
  reserve_ent(unsigned int cnt = 1)
  {
    if (size != 32 || this->header_ent_cnt_ == 0)
      return;
    if (this->num_entries() + cnt > this->header_index_)
      this->make_header();
  }

  void
  make_header()
  {
    this->header_ent_cnt_ = 0;
    this->header_index_ = this->num_entries();
    if (size == 32)
      {
	Output_data_got<size, big_endian>::add_constant(0);
	Output_data_got<size, big_endian>::add_constant(0);
	Output_data_got<size, big_endian>::add_constant(0);

	// Define _GLOBAL_OFFSET_TABLE_ at the header
	Symbol *gotsym = this->symtab_->lookup("_GLOBAL_OFFSET_TABLE_", NULL);
	if (gotsym != NULL)
	  {
	    Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(gotsym);
	    sym->set_value(this->g_o_t());
	  }
	else
	  this->symtab_->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
					       Symbol_table::PREDEFINED,
					       this, this->g_o_t(), 0,
					       elfcpp::STT_OBJECT,
					       elfcpp::STB_LOCAL,
					       elfcpp::STV_HIDDEN, 0,
					       false, false);
      }
    else
      Output_data_got<size, big_endian>::add_constant(0);
  }

  // Stashed pointers.
  Symbol_table* symtab_;
  Layout* layout_;

  // GOT header size.
  unsigned int header_ent_cnt_;
  // GOT header index.
  unsigned int header_index_;
};

// Get the GOT section, creating it if necessary.

template<int size, bool big_endian>
Output_data_got_powerpc<size, big_endian>*
Target_powerpc<size, big_endian>::got_section(Symbol_table* symtab,
					      Layout* layout,
					      Got_type got_type)
{
  if (this->got_ == NULL)
    {
      gold_assert(symtab != NULL && layout != NULL);

      this->got_
	= new Output_data_got_powerpc<size, big_endian>(symtab, layout,
							GOT_TYPE_SMALL);

      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
				      this->got_, ORDER_DATA, false);
    }

  if (size == 32 || (got_type & GOT_TYPE_SMALL))
    return this->got_;

  if (this->biggot_ == NULL)
    {
      this->biggot_
	= new Output_data_got_powerpc<size, big_endian>(symtab, layout,
							GOT_TYPE_STANDARD);

      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
				      this->biggot_, ORDER_DATA, false);
    }

  return this->biggot_;
}

// Get the dynamic reloc section, creating it if necessary.

template<int size, bool big_endian>
typename Target_powerpc<size, big_endian>::Reloc_section*
Target_powerpc<size, big_endian>::rela_dyn_section(Layout* layout)
{
  if (this->rela_dyn_ == NULL)
    {
      gold_assert(layout != NULL);
      this->rela_dyn_ = new Reloc_section(parameters->options().combreloc());
      layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
				      elfcpp::SHF_ALLOC, this->rela_dyn_,
				      ORDER_DYNAMIC_RELOCS, false);
    }
  return this->rela_dyn_;
}

// Similarly, but for ifunc symbols get the one for ifunc.

template<int size, bool big_endian>
typename Target_powerpc<size, big_endian>::Reloc_section*
Target_powerpc<size, big_endian>::rela_dyn_section(Symbol_table* symtab,
						   Layout* layout,
						   bool for_ifunc)
{
  if (!for_ifunc)
    return this->rela_dyn_section(layout);

  if (this->iplt_ == NULL)
    this->make_iplt_section(symtab, layout);
  return this->iplt_->rel_plt();
}

class Stub_control
{
 public:
  // Determine the stub group size.  The group size is the absolute
  // value of the parameter --stub-group-size.  If --stub-group-size
  // is passed a negative value, we restrict stubs to be always after
  // the stubbed branches.
  Stub_control(int32_t size, bool no_size_errors, bool multi_os)
    : stub_group_size_(abs(size)), stubs_always_after_branch_(size < 0),
      suppress_size_errors_(no_size_errors), multi_os_(multi_os),
      state_(NO_GROUP), group_size_(0), group_start_addr_(0),
      owner_(NULL), output_section_(NULL)
  {
  }

  // Return true iff input section can be handled by current stub
  // group.
  bool
  can_add_to_stub_group(Output_section* o,
			const Output_section::Input_section* i,
			bool has14);

  const Output_section::Input_section*
  owner()
  { return owner_; }

  Output_section*
  output_section()
  { return output_section_; }

  void
  set_output_and_owner(Output_section* o,
		       const Output_section::Input_section* i)
  {
    this->output_section_ = o;
    this->owner_ = i;
  }

 private:
  typedef enum
  {
    // Initial state.
    NO_GROUP,
    // Adding group sections before the stubs.
    FINDING_STUB_SECTION,
    // Adding group sections after the stubs.
    HAS_STUB_SECTION
  } State;

  uint32_t stub_group_size_;
  bool stubs_always_after_branch_;
  bool suppress_size_errors_;
  // True if a stub group can serve multiple output sections.
  bool multi_os_;
  State state_;
  // Current max size of group.  Starts at stub_group_size_ but is
  // reduced to stub_group_size_/1024 on seeing a section with
  // external conditional branches.
  uint32_t group_size_;
  uint64_t group_start_addr_;
  // owner_ and output_section_ specify the section to which stubs are
  // attached.  The stubs are placed at the end of this section.
  const Output_section::Input_section* owner_;
  Output_section* output_section_;
};

// Return true iff input section can be handled by current stub
// group.  Sections are presented to this function in order,
// so the first section is the head of the group.

bool
Stub_control::can_add_to_stub_group(Output_section* o,
				    const Output_section::Input_section* i,
				    bool has14)
{
  bool whole_sec = o->order() == ORDER_INIT || o->order() == ORDER_FINI;
  uint64_t this_size;
  uint64_t start_addr = o->address();

  if (whole_sec)
    // .init and .fini sections are pasted together to form a single
    // function.  We can't be adding stubs in the middle of the function.
    this_size = o->data_size();
  else
    {
      start_addr += i->relobj()->output_section_offset(i->shndx());
      this_size = i->data_size();
    }

  uint64_t end_addr = start_addr + this_size;
  uint32_t group_size = this->stub_group_size_;
  if (has14)
    this->group_size_ = group_size = group_size >> 10;

  if (this_size > group_size && !this->suppress_size_errors_)
    gold_warning(_("%s:%s exceeds group size"),
		 i->relobj()->name().c_str(),
		 i->relobj()->section_name(i->shndx()).c_str());

  gold_debug(DEBUG_TARGET, "maybe add%s %s:%s size=%#llx total=%#llx",
	     has14 ? " 14bit" : "",
	     i->relobj()->name().c_str(),
	     i->relobj()->section_name(i->shndx()).c_str(),
	     (long long) this_size,
	     (this->state_ == NO_GROUP
	      ? this_size
	      : (long long) end_addr - this->group_start_addr_));

  if (this->state_ == NO_GROUP)
    {
      // Only here on very first use of Stub_control
      this->owner_ = i;
      this->output_section_ = o;
      this->state_ = FINDING_STUB_SECTION;
      this->group_size_ = group_size;
      this->group_start_addr_ = start_addr;
      return true;
    }
  else if (!this->multi_os_ && this->output_section_ != o)
    ;
  else if (this->state_ == HAS_STUB_SECTION)
    {
      // Can we add this section, which is after the stubs, to the
      // group?
      if (end_addr - this->group_start_addr_ <= this->group_size_)
	return true;
    }
  else if (this->state_ == FINDING_STUB_SECTION)
    {
      if ((whole_sec && this->output_section_ == o)
	  || end_addr - this->group_start_addr_ <= this->group_size_)
	{
	  // Stubs are added at the end of "owner_".
	  this->owner_ = i;
	  this->output_section_ = o;
	  return true;
	}
      // The group before the stubs has reached maximum size.
      // Now see about adding sections after the stubs to the
      // group.  If the current section has a 14-bit branch and
      // the group before the stubs exceeds group_size_ (because
      // they didn't have 14-bit branches), don't add sections
      // after the stubs:  The size of stubs for such a large
      // group may exceed the reach of a 14-bit branch.
      if (!this->stubs_always_after_branch_
	  && this_size <= this->group_size_
	  && start_addr - this->group_start_addr_ <= this->group_size_)
	{
	  gold_debug(DEBUG_TARGET, "adding after stubs");
	  this->state_ = HAS_STUB_SECTION;
	  this->group_start_addr_ = start_addr;
	  return true;
	}
    }
  else
    gold_unreachable();

  gold_debug(DEBUG_TARGET,
	     !this->multi_os_ && this->output_section_ != o
	     ? "nope, new output section\n"
	     : "nope, didn't fit\n");

  // The section fails to fit in the current group.  Set up a few
  // things for the next group.  owner_ and output_section_ will be
  // set later after we've retrieved those values for the current
  // group.
  this->state_ = FINDING_STUB_SECTION;
  this->group_size_ = group_size;
  this->group_start_addr_ = start_addr;
  return false;
}

// Look over all the input sections, deciding where to place stubs.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::group_sections(Layout* layout,
						 const Task*,
						 bool no_size_errors)
{
  Stub_control stub_control(this->stub_group_size_, no_size_errors,
			    parameters->options().stub_group_multi());

  // Group input sections and insert stub table
  Stub_table_owner* table_owner = NULL;
  std::vector<Stub_table_owner*> tables;
  Layout::Section_list section_list;
  layout->get_executable_sections(&section_list);
  std::stable_sort(section_list.begin(), section_list.end(), Sort_sections());
  for (Layout::Section_list::iterator o = section_list.begin();
       o != section_list.end();
       ++o)
    {
      typedef Output_section::Input_section_list Input_section_list;
      for (Input_section_list::const_iterator i
	     = (*o)->input_sections().begin();
	   i != (*o)->input_sections().end();
	   ++i)
	{
	  if (i->is_input_section()
	      || i->is_relaxed_input_section())
	    {
	      Powerpc_relobj<size, big_endian>* ppcobj = static_cast
		<Powerpc_relobj<size, big_endian>*>(i->relobj());
	      bool has14 = ppcobj->has_14bit_branch(i->shndx());
	      if (!stub_control.can_add_to_stub_group(*o, &*i, has14))
		{
		  table_owner->output_section = stub_control.output_section();
		  table_owner->owner = stub_control.owner();
		  stub_control.set_output_and_owner(*o, &*i);
		  table_owner = NULL;
		}
	      if (table_owner == NULL)
		{
		  table_owner = new Stub_table_owner;
		  tables.push_back(table_owner);
		}
	      ppcobj->set_stub_table(i->shndx(), tables.size() - 1);
	    }
	}
    }
  if (table_owner != NULL)
    {
      table_owner->output_section = stub_control.output_section();
      table_owner->owner = stub_control.owner();;
    }
  for (typename std::vector<Stub_table_owner*>::iterator t = tables.begin();
       t != tables.end();
       ++t)
    {
      Stub_table<size, big_endian>* stub_table;

      if ((*t)->owner->is_input_section())
	stub_table = new Stub_table<size, big_endian>(this,
						      (*t)->output_section,
						      (*t)->owner,
						      this->stub_tables_.size());
      else if ((*t)->owner->is_relaxed_input_section())
	stub_table = static_cast<Stub_table<size, big_endian>*>(
			(*t)->owner->relaxed_input_section());
      else
	gold_unreachable();
      this->stub_tables_.push_back(stub_table);
      delete *t;
    }
}

template<int size>
static unsigned long
max_branch_delta (unsigned int r_type)
{
  if (r_type == elfcpp::R_POWERPC_REL14
      || r_type == elfcpp::R_POWERPC_REL14_BRTAKEN
      || r_type == elfcpp::R_POWERPC_REL14_BRNTAKEN)
    return 1L << 15;
  if (r_type == elfcpp::R_POWERPC_REL24
      || (size == 64 && r_type == elfcpp::R_PPC64_REL24_NOTOC)
      || r_type == elfcpp::R_PPC_PLTREL24
      || r_type == elfcpp::R_PPC_LOCAL24PC)
    return 1L << 25;
  return 0;
}

// Return whether this branch is going via a plt call stub.

template<int size, bool big_endian>
bool
Target_powerpc<size, big_endian>::Branch_info::mark_pltcall(
    Powerpc_relobj<size, big_endian>* ppc_object,
    unsigned int shndx,
    Address offset,
    Target_powerpc* target,
    Symbol_table* symtab)
{
  if (this->object_ != ppc_object
      || this->shndx_ != shndx
      || this->offset_ != offset)
    return false;

  Symbol* sym = this->object_->global_symbol(this->r_sym_);
  if (sym != NULL && sym->is_forwarder())
    sym = symtab->resolve_forwards(sym);
  if (target->replace_tls_get_addr(sym))
    sym = target->tls_get_addr_opt();
  const Sized_symbol<size>* gsym = static_cast<const Sized_symbol<size>*>(sym);
  if (gsym != NULL
      ? (gsym->use_plt_offset(Scan::get_reference_flags(this->r_type_, target))
	 && !target->is_elfv2_localentry0(gsym))
      : (this->object_->local_has_plt_offset(this->r_sym_)
	 && !target->is_elfv2_localentry0(this->object_, this->r_sym_)))
    {
      this->tocsave_ = 1;
      return true;
    }
  return false;
}

// If this branch needs a plt call stub, or a long branch stub, make one.

template<int size, bool big_endian>
bool
Target_powerpc<size, big_endian>::Branch_info::make_stub(
    Stub_table<size, big_endian>* stub_table,
    Stub_table<size, big_endian>* ifunc_stub_table,
    Symbol_table* symtab) const
{
  Symbol* sym = this->object_->global_symbol(this->r_sym_);
  Target_powerpc<size, big_endian>* target =
    static_cast<Target_powerpc<size, big_endian>*>(
      parameters->sized_target<size, big_endian>());
  if (sym != NULL && sym->is_forwarder())
    sym = symtab->resolve_forwards(sym);
  if (target->replace_tls_get_addr(sym))
    sym = target->tls_get_addr_opt();
  const Sized_symbol<size>* gsym = static_cast<const Sized_symbol<size>*>(sym);
  bool ok = true;

  if (gsym != NULL
      ? gsym->use_plt_offset(Scan::get_reference_flags(this->r_type_, target))
      : this->object_->local_has_plt_offset(this->r_sym_))
    {
      if (size == 64
	  && gsym != NULL
	  && target->abiversion() >= 2
	  && !parameters->options().output_is_position_independent()
	  && !is_branch_reloc<size>(this->r_type_))
	target->glink_section()->add_global_entry(gsym);
      else
	{
	  if (stub_table == NULL
	      && !(size == 32
		   && gsym != NULL
		   && !parameters->options().output_is_position_independent()
		   && !is_branch_reloc<size>(this->r_type_)))
	    stub_table = this->object_->stub_table(this->shndx_);
	  if (stub_table == NULL)
	    {
	      // This is a ref from a data section to an ifunc symbol,
	      // or a non-branch reloc for which we always want to use
	      // one set of stubs for resolving function addresses.
	      stub_table = ifunc_stub_table;
	    }
	  gold_assert(stub_table != NULL);
	  Address from = this->object_->get_output_section_offset(this->shndx_);
	  if (from != invalid_address)
	    from += (this->object_->output_section(this->shndx_)->address()
		     + this->offset_);
	  if (gsym != NULL)
	    ok = stub_table->add_plt_call_entry(from,
						this->object_, gsym,
						this->r_type_, this->addend_,
						this->tocsave_);
	  else
	    ok = stub_table->add_plt_call_entry(from,
						this->object_, this->r_sym_,
						this->r_type_, this->addend_,
						this->tocsave_);
	}
    }
  else
    {
      Address max_branch_offset = max_branch_delta<size>(this->r_type_);
      if (max_branch_offset == 0)
	return true;
      Address from = this->object_->get_output_section_offset(this->shndx_);
      gold_assert(from != invalid_address);
      from += (this->object_->output_section(this->shndx_)->address()
	       + this->offset_);
      Address to;
      unsigned int other = 0;
      if (gsym != NULL)
	{
	  switch (gsym->source())
	    {
	    case Symbol::FROM_OBJECT:
	      {
		Object* symobj = gsym->object();
		if (symobj->is_dynamic()
		    || symobj->pluginobj() != NULL)
		  return true;
		bool is_ordinary;
		unsigned int shndx = gsym->shndx(&is_ordinary);
		if (shndx == elfcpp::SHN_UNDEF)
		  return true;
	      }
	      break;

	    case Symbol::IS_UNDEFINED:
	      return true;

	    default:
	      break;
	    }
	  Symbol_table::Compute_final_value_status status;
	  to = symtab->compute_final_value<size>(gsym, &status);
	  if (status != Symbol_table::CFVS_OK)
	    return true;
	  if (size == 64)
	    other = gsym->nonvis() >> 3;
	}
      else
	{
	  const Symbol_value<size>* psymval
	    = this->object_->local_symbol(this->r_sym_);
	  Symbol_value<size> symval;
	  if (psymval->is_section_symbol())
	    symval.set_is_section_symbol();
	  typedef Sized_relobj_file<size, big_endian> ObjType;
	  typename ObjType::Compute_final_local_value_status status
	    = this->object_->compute_final_local_value(this->r_sym_, psymval,
						       &symval, symtab);
	  if (status != ObjType::CFLV_OK
	      || !symval.has_output_value())
	    return true;
	  to = symval.value(this->object_, 0);
	  if (size == 64)
	    other = this->object_->st_other(this->r_sym_) >> 5;
	}
      if (!(size == 32 && this->r_type_ == elfcpp::R_PPC_PLTREL24))
	to += this->addend_;
      if (stub_table == NULL)
	stub_table = this->object_->stub_table(this->shndx_);
      if (size == 64 && target->abiversion() < 2)
	{
	  unsigned int dest_shndx;
	  if (!target->symval_for_branch(symtab, gsym, this->object_,
					 &to, &dest_shndx))
	    return true;
	}
      unsigned int local_ent = 0;
      if (size == 64
	  && this->r_type_ != elfcpp::R_PPC64_REL24_NOTOC)
	local_ent = elfcpp::ppc64_decode_local_entry(other);
      Address delta = to + local_ent - from;
      if (delta + max_branch_offset >= 2 * max_branch_offset
	  || (size == 64
	      && this->r_type_ == elfcpp::R_PPC64_REL24_NOTOC
	      && (gsym != NULL
		  ? this->object_->ppc64_needs_toc(gsym)
		  : this->object_->ppc64_needs_toc(this->r_sym_))))
	{
	  if (stub_table == NULL)
	    {
	      gold_warning(_("%s:%s: branch in non-executable section,"
			     " no long branch stub for you"),
			   this->object_->name().c_str(),
			   this->object_->section_name(this->shndx_).c_str());
	      return true;
	    }
	  bool save_res = (size == 64
			   && gsym != NULL
			   && gsym->source() == Symbol::IN_OUTPUT_DATA
			   && gsym->output_data() == target->savres_section());
	  ok = stub_table->add_long_branch_entry(this->r_type_,
						 from, to, other, save_res);
	}
    }
  if (!ok)
    gold_debug(DEBUG_TARGET,
	       "branch at %s:%s+%#lx\n"
	       "can't reach stub attached to %s:%s",
	       this->object_->name().c_str(),
	       this->object_->section_name(this->shndx_).c_str(),
	       (unsigned long) this->offset_,
	       stub_table->relobj()->name().c_str(),
	       stub_table->relobj()->section_name(stub_table->shndx()).c_str());

  return ok;
}

// Relaxation hook.  This is where we do stub generation.

template<int size, bool big_endian>
bool
Target_powerpc<size, big_endian>::do_relax(int pass,
					   const Input_objects*,
					   Symbol_table* symtab,
					   Layout* layout,
					   const Task* task)
{
  unsigned int prev_brlt_size = 0;
  if (pass == 1)
    {
      bool thread_safe
	= this->abiversion() < 2 && parameters->options().plt_thread_safe();
      if (size == 64
	  && this->abiversion() < 2
	  && !thread_safe
	  && !parameters->options().user_set_plt_thread_safe())
	{
	  static const char* const thread_starter[] =
	    {
	      "pthread_create",
	      /* libstdc++ */
	      "_ZNSt6thread15_M_start_threadESt10shared_ptrINS_10_Impl_baseEE",
	      /* librt */
	      "aio_init", "aio_read", "aio_write", "aio_fsync", "lio_listio",
	      "mq_notify", "create_timer",
	      /* libanl */
	      "getaddrinfo_a",
	      /* libgomp */
	      "GOMP_parallel",
	      "GOMP_parallel_start",
	      "GOMP_parallel_loop_static",
	      "GOMP_parallel_loop_static_start",
	      "GOMP_parallel_loop_dynamic",
	      "GOMP_parallel_loop_dynamic_start",
	      "GOMP_parallel_loop_guided",
	      "GOMP_parallel_loop_guided_start",
	      "GOMP_parallel_loop_runtime",
	      "GOMP_parallel_loop_runtime_start",
	      "GOMP_parallel_sections",
	      "GOMP_parallel_sections_start",
	      /* libgo */
	      "__go_go",
	    };

	  if (parameters->options().shared())
	    thread_safe = true;
	  else
	    {
	      for (unsigned int i = 0;
		   i < sizeof(thread_starter) / sizeof(thread_starter[0]);
		   i++)
		{
		  Symbol* sym = symtab->lookup(thread_starter[i], NULL);
		  thread_safe = (sym != NULL
				 && sym->in_reg()
				 && sym->in_real_elf());
		  if (thread_safe)
		    break;
		}
	    }
	}
      this->plt_thread_safe_ = thread_safe;
    }

  if (pass == 1)
    {
      this->stub_group_size_ = parameters->options().stub_group_size();
      bool no_size_errors = true;
      if (this->stub_group_size_ == 1)
	this->stub_group_size_ = 0x1c00000;
      else if (this->stub_group_size_ == -1)
	this->stub_group_size_ = -0x1e00000;
      else
	no_size_errors = false;
      this->group_sections(layout, task, no_size_errors);
    }
  else if (this->relax_failed_ && this->relax_fail_count_ < 3)
    {
      this->branch_lookup_table_.clear();
      for (typename Stub_tables::iterator p = this->stub_tables_.begin();
	   p != this->stub_tables_.end();
	   ++p)
	{
	  (*p)->clear_stubs(true);
	}
      this->stub_tables_.clear();
      this->stub_group_size_ = this->stub_group_size_ / 4 * 3;
      gold_info(_("%s: stub group size is too large; retrying with %#x"),
		program_name, this->stub_group_size_);
      this->group_sections(layout, task, true);
    }

  // We need address of stub tables valid for make_stub.
  for (typename Stub_tables::iterator p = this->stub_tables_.begin();
       p != this->stub_tables_.end();
       ++p)
    {
      const Powerpc_relobj<size, big_endian>* object
	= static_cast<const Powerpc_relobj<size, big_endian>*>((*p)->relobj());
      Address off = object->get_output_section_offset((*p)->shndx());
      gold_assert(off != invalid_address);
      Output_section* os = (*p)->output_section();
      (*p)->set_address_and_size(os, off);
    }

  if (pass != 1)
    {
      // Clear plt call stubs, long branch stubs and branch lookup table.
      prev_brlt_size = this->branch_lookup_table_.size();
      this->branch_lookup_table_.clear();
      for (typename Stub_tables::iterator p = this->stub_tables_.begin();
	   p != this->stub_tables_.end();
	   ++p)
	{
	  (*p)->clear_stubs(false);
	}
    }

  // Build all the stubs.
  this->relax_failed_ = false;
  Stub_table<size, big_endian>* ifunc_stub_table
    = this->stub_tables_.size() == 0 ? NULL : this->stub_tables_[0];
  Stub_table<size, big_endian>* one_stub_table
    = this->stub_tables_.size() != 1 ? NULL : ifunc_stub_table;
  for (typename Branches::const_iterator b = this->branch_info_.begin();
       b != this->branch_info_.end();
       b++)
    {
      if (!b->make_stub(one_stub_table, ifunc_stub_table, symtab)
	  && !this->relax_failed_)
	{
	  this->relax_failed_ = true;
	  this->relax_fail_count_++;
	  if (this->relax_fail_count_ < 3)
	    return true;
	}
    }
  bool do_resize = false;
  for (typename Stub_tables::iterator p = this->stub_tables_.begin();
       p != this->stub_tables_.end();
       ++p)
    if ((*p)->need_resize())
      {
	do_resize = true;
	break;
      }
  if (do_resize)
    {
      this->branch_lookup_table_.clear();
      for (typename Stub_tables::iterator p = this->stub_tables_.begin();
	   p != this->stub_tables_.end();
	   ++p)
	(*p)->set_resizing(true);
      for (typename Branches::const_iterator b = this->branch_info_.begin();
	   b != this->branch_info_.end();
	   b++)
	{
	  if (!b->make_stub(one_stub_table, ifunc_stub_table, symtab)
	      && !this->relax_failed_)
	    {
	      this->relax_failed_ = true;
	      this->relax_fail_count_++;
	      if (this->relax_fail_count_ < 3)
		return true;
	    }
	}
      for (typename Stub_tables::iterator p = this->stub_tables_.begin();
	   p != this->stub_tables_.end();
	   ++p)
	(*p)->set_resizing(false);
    }

  // Did anything change size?
  unsigned int num_huge_branches = this->branch_lookup_table_.size();
  bool again = num_huge_branches != prev_brlt_size;
  if (size == 64 && num_huge_branches != 0)
    this->make_brlt_section(layout);
  if (size == 64 && again)
    this->brlt_section_->set_current_size(num_huge_branches);

  for (typename Stub_tables::reverse_iterator p = this->stub_tables_.rbegin();
       p != this->stub_tables_.rend();
       ++p)
    (*p)->remove_eh_frame(layout);

  for (typename Stub_tables::iterator p = this->stub_tables_.begin();
       p != this->stub_tables_.end();
       ++p)
    (*p)->add_eh_frame(layout);

  typedef Unordered_set<Output_section*> Output_sections;
  Output_sections os_need_update;
  for (typename Stub_tables::iterator p = this->stub_tables_.begin();
       p != this->stub_tables_.end();
       ++p)
    {
      if ((*p)->size_update())
	{
	  again = true;
	  os_need_update.insert((*p)->output_section());
	}
    }

  // Set output section offsets for all input sections in an output
  // section that just changed size.  Anything past the stubs will
  // need updating.
  for (typename Output_sections::iterator p = os_need_update.begin();
       p != os_need_update.end();
       p++)
    {
      Output_section* os = *p;
      Address off = 0;
      typedef Output_section::Input_section_list Input_section_list;
      for (Input_section_list::const_iterator i = os->input_sections().begin();
	   i != os->input_sections().end();
	   ++i)
	{
	  off = align_address(off, i->addralign());
	  if (i->is_input_section() || i->is_relaxed_input_section())
	    i->relobj()->set_section_offset(i->shndx(), off);
	  if (i->is_relaxed_input_section())
	    {
	      Stub_table<size, big_endian>* stub_table
		= static_cast<Stub_table<size, big_endian>*>(
		    i->relaxed_input_section());
	      Address stub_table_size = stub_table->set_address_and_size(os, off);
	      off += stub_table_size;
	      // After a few iterations, set current stub table size
	      // as min size threshold, so later stub tables can only
	      // grow in size.
	      if (pass >= 4)
		stub_table->set_min_size_threshold(stub_table_size);
	    }
	  else
	    off += i->data_size();
	}
      // If .branch_lt is part of this output section, then we have
      // just done the offset adjustment.
      os->clear_section_offsets_need_adjustment();
    }

  if (size == 64
      && !again
      && num_huge_branches != 0
      && parameters->options().output_is_position_independent())
    {
      // Fill in the BRLT relocs.
      this->brlt_section_->reset_brlt_sizes();
      for (typename Branch_lookup_table::const_iterator p
	     = this->branch_lookup_table_.begin();
	   p != this->branch_lookup_table_.end();
	   ++p)
	{
	  this->brlt_section_->add_reloc(p->first, p->second);
	}
      this->brlt_section_->finalize_brlt_sizes();
    }

  if (!again
      && (parameters->options().user_set_emit_stub_syms()
	  ? parameters->options().emit_stub_syms()
	  : (size == 64
	     || parameters->options().output_is_position_independent()
	     || parameters->options().emit_relocs())))
    {
      for (typename Stub_tables::iterator p = this->stub_tables_.begin();
	   p != this->stub_tables_.end();
	   ++p)
	(*p)->define_stub_syms(symtab);

      if (this->glink_ != NULL)
	{
	  int stub_size = this->glink_->pltresolve_size();
	  Address value = -stub_size;
	  if (size == 64)
	    {
	      value = 8;
	      stub_size -= 8;
	    }
	  this->define_local(symtab, "__glink_PLTresolve",
			     this->glink_, value, stub_size);

	  if (size != 64)
	    this->define_local(symtab, "__glink", this->glink_, 0, 0);
	}
    }

  return again;
}

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_plt_fde_location(const Output_data* plt,
						      unsigned char* oview,
						      uint64_t* paddress,
						      off_t* plen) const
{
  uint64_t address = plt->address();
  off_t len = plt->data_size();

  if (plt == this->glink_)
    {
      // See Output_data_glink::do_write() for glink contents.
      if (len == 0)
	{
	  // Static linking may need stubs, to support ifunc and long
	  // branches.  We need to create an output section for
	  // .eh_frame early in the link process, to have a place to
	  // attach stub .eh_frame info.  We also need to have
	  // registered a CIE that matches the stub CIE.  Both of
	  // these requirements are satisfied by creating an FDE and
	  // CIE for .glink, even though static linking will leave
	  // .glink zero length.
	  // ??? Hopefully generating an FDE with a zero address range
	  // won't confuse anything that consumes .eh_frame info.
	}
      else if (size == 64)
	{
	  // There is one word before __glink_PLTresolve
	  address += 8;
	  len -= 8;
	}
      else if (parameters->options().output_is_position_independent())
	{
	  // There are two FDEs for a position independent glink.
	  // The first covers the branch table, the second
	  // __glink_PLTresolve at the end of glink.
	  off_t resolve_size = this->glink_->pltresolve_size();
	  if (oview[9] == elfcpp::DW_CFA_nop)
	    len -= resolve_size;
	  else
	    {
	      address += len - resolve_size;
	      len = resolve_size;
	    }
	}
    }
  else
    {
      // Must be a stub table.
      const Stub_table<size, big_endian>* stub_table
	= static_cast<const Stub_table<size, big_endian>*>(plt);
      uint64_t stub_address = stub_table->stub_address();
      len -= stub_address - address;
      address = stub_address;
    }

  *paddress = address;
  *plen = len;
}

// A class to handle the PLT data.

template<int size, bool big_endian>
class Output_data_plt_powerpc : public Output_section_data_build
{
 public:
  typedef Output_data_reloc<elfcpp::SHT_RELA, true,
			    size, big_endian> Reloc_section;

  Output_data_plt_powerpc(Target_powerpc<size, big_endian>* targ,
			  Reloc_section* plt_rel,
			  const char* name)
    : Output_section_data_build(size == 32 ? 4 : 8),
      rel_(plt_rel),
      targ_(targ),
      name_(name)
  { }

  // Add an entry to the PLT.
  void
  add_entry(Symbol*);

  void
  add_ifunc_entry(Symbol*);

  void
  add_local_entry(Sized_relobj_file<size, big_endian>*, unsigned int);

  void
  add_local_ifunc_entry(Sized_relobj_file<size, big_endian>*, unsigned int);

  // Return the .rela.plt section data.
  Reloc_section*
  rel_plt() const
  {
    return this->rel_;
  }

  // Return the number of PLT entries.
  unsigned int
  entry_count() const
  {
    if (this->current_data_size() == 0)
      return 0;
    return ((this->current_data_size() - this->first_plt_entry_offset())
	    / this->plt_entry_size());
  }

 protected:
  void
  do_adjust_output_section(Output_section* os)
  {
    os->set_entsize(0);
  }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, this->name_); }

 private:
  // Return the offset of the first non-reserved PLT entry.
  unsigned int
  first_plt_entry_offset() const
  {
    // IPLT and LPLT have no reserved entry.
    if (this->name_[3] == 'I' || this->name_[3] == 'L')
      return 0;
    return this->targ_->first_plt_entry_offset();
  }

  // Return the size of each PLT entry.
  unsigned int
  plt_entry_size() const
  {
    return this->targ_->plt_entry_size();
  }

  // Write out the PLT data.
  void
  do_write(Output_file*);

  // The reloc section.
  Reloc_section* rel_;
  // Allows access to .glink for do_write.
  Target_powerpc<size, big_endian>* targ_;
  // What to report in map file.
  const char *name_;
};

// Add an entry to the PLT.

template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::add_entry(Symbol* gsym)
{
  if (!gsym->has_plt_offset())
    {
      section_size_type off = this->current_data_size();
      if (off == 0)
	off += this->first_plt_entry_offset();
      gsym->set_plt_offset(off);
      gsym->set_needs_dynsym_entry();
      unsigned int dynrel = elfcpp::R_POWERPC_JMP_SLOT;
      this->rel_->add_global(gsym, dynrel, this, off, 0);
      off += this->plt_entry_size();
      this->set_current_data_size(off);
    }
}

// Add an entry for a global ifunc symbol that resolves locally, to the IPLT.

template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::add_ifunc_entry(Symbol* gsym)
{
  if (!gsym->has_plt_offset())
    {
      section_size_type off = this->current_data_size();
      gsym->set_plt_offset(off);
      unsigned int dynrel = elfcpp::R_POWERPC_IRELATIVE;
      if (size == 64 && this->targ_->abiversion() < 2)
	dynrel = elfcpp::R_PPC64_JMP_IREL;
      this->rel_->add_symbolless_global_addend(gsym, dynrel, this, off, 0);
      off += this->plt_entry_size();
      this->set_current_data_size(off);
    }
}

// Add an entry for a local symbol to the PLT.

template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::add_local_entry(
    Sized_relobj_file<size, big_endian>* relobj,
    unsigned int local_sym_index)
{
  if (!relobj->local_has_plt_offset(local_sym_index))
    {
      section_size_type off = this->current_data_size();
      relobj->set_local_plt_offset(local_sym_index, off);
      if (this->rel_)
	{
	  unsigned int dynrel = elfcpp::R_POWERPC_RELATIVE;
	  if (size == 64 && this->targ_->abiversion() < 2)
	    dynrel = elfcpp::R_POWERPC_JMP_SLOT;
	  this->rel_->add_symbolless_local_addend(relobj, local_sym_index,
						  dynrel, this, off, 0);
	}
      off += this->plt_entry_size();
      this->set_current_data_size(off);
    }
}

// Add an entry for a local ifunc symbol to the IPLT.

template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::add_local_ifunc_entry(
    Sized_relobj_file<size, big_endian>* relobj,
    unsigned int local_sym_index)
{
  if (!relobj->local_has_plt_offset(local_sym_index))
    {
      section_size_type off = this->current_data_size();
      relobj->set_local_plt_offset(local_sym_index, off);
      unsigned int dynrel = elfcpp::R_POWERPC_IRELATIVE;
      if (size == 64 && this->targ_->abiversion() < 2)
	dynrel = elfcpp::R_PPC64_JMP_IREL;
      this->rel_->add_symbolless_local_addend(relobj, local_sym_index, dynrel,
					      this, off, 0);
      off += this->plt_entry_size();
      this->set_current_data_size(off);
    }
}

static const uint32_t add_0_11_11	= 0x7c0b5a14;
static const uint32_t add_2_2_11	= 0x7c425a14;
static const uint32_t add_2_2_12	= 0x7c426214;
static const uint32_t add_3_3_2		= 0x7c631214;
static const uint32_t add_3_3_13	= 0x7c636a14;
static const uint32_t add_3_12_2	= 0x7c6c1214;
static const uint32_t add_3_12_13	= 0x7c6c6a14;
static const uint32_t add_11_0_11	= 0x7d605a14;
static const uint32_t add_11_2_11	= 0x7d625a14;
static const uint32_t add_11_11_2	= 0x7d6b1214;
static const uint32_t add_12_11_12	= 0x7d8b6214;
static const uint32_t addi_0_12		= 0x380c0000;
static const uint32_t addi_2_2		= 0x38420000;
static const uint32_t addi_3_3		= 0x38630000;
static const uint32_t addi_11_11	= 0x396b0000;
static const uint32_t addi_12_1		= 0x39810000;
static const uint32_t addi_12_11	= 0x398b0000;
static const uint32_t addi_12_12	= 0x398c0000;
static const uint32_t addis_0_2		= 0x3c020000;
static const uint32_t addis_0_13	= 0x3c0d0000;
static const uint32_t addis_2_12	= 0x3c4c0000;
static const uint32_t addis_11_2	= 0x3d620000;
static const uint32_t addis_11_11	= 0x3d6b0000;
static const uint32_t addis_11_30	= 0x3d7e0000;
static const uint32_t addis_12_1	= 0x3d810000;
static const uint32_t addis_12_2	= 0x3d820000;
static const uint32_t addis_12_11	= 0x3d8b0000;
static const uint32_t addis_12_12	= 0x3d8c0000;
static const uint32_t b			= 0x48000000;
static const uint32_t bcl_20_31		= 0x429f0005;
static const uint32_t bctr		= 0x4e800420;
static const uint32_t bctrl		= 0x4e800421;
static const uint32_t beqlr		= 0x4d820020;
static const uint32_t blr		= 0x4e800020;
static const uint32_t bnectr_p4		= 0x4ce20420;
static const uint32_t cmpld_7_12_0	= 0x7fac0040;
static const uint32_t cmpldi_2_0	= 0x28220000;
static const uint32_t cmpdi_11_0	= 0x2c2b0000;
static const uint32_t cmpwi_11_0	= 0x2c0b0000;
static const uint32_t cror_15_15_15	= 0x4def7b82;
static const uint32_t cror_31_31_31	= 0x4ffffb82;
static const uint32_t ld_0_1		= 0xe8010000;
static const uint32_t ld_0_11		= 0xe80b0000;
static const uint32_t ld_0_12		= 0xe80c0000;
static const uint32_t ld_2_1		= 0xe8410000;
static const uint32_t ld_2_2		= 0xe8420000;
static const uint32_t ld_2_11		= 0xe84b0000;
static const uint32_t ld_2_12		= 0xe84c0000;
static const uint32_t ld_11_1		= 0xe9610000;
static const uint32_t ld_11_2		= 0xe9620000;
static const uint32_t ld_11_3		= 0xe9630000;
static const uint32_t ld_11_11		= 0xe96b0000;
static const uint32_t ld_12_2		= 0xe9820000;
static const uint32_t ld_12_3		= 0xe9830000;
static const uint32_t ld_12_11		= 0xe98b0000;
static const uint32_t ld_12_12		= 0xe98c0000;
static const uint32_t ldx_12_11_12	= 0x7d8b602a;
static const uint32_t lfd_0_1		= 0xc8010000;
static const uint32_t li_0_0		= 0x38000000;
static const uint32_t li_11_0		= 0x39600000;
static const uint32_t li_12_0		= 0x39800000;
static const uint32_t lis_0		= 0x3c000000;
static const uint32_t lis_2		= 0x3c400000;
static const uint32_t lis_11		= 0x3d600000;
static const uint32_t lis_12		= 0x3d800000;
static const uint32_t lvx_0_12_0	= 0x7c0c00ce;
static const uint32_t lwz_0_12		= 0x800c0000;
static const uint32_t lwz_11_3		= 0x81630000;
static const uint32_t lwz_11_11		= 0x816b0000;
static const uint32_t lwz_11_30		= 0x817e0000;
static const uint32_t lwz_12_3		= 0x81830000;
static const uint32_t lwz_12_12		= 0x818c0000;
static const uint32_t lwzu_0_12		= 0x840c0000;
static const uint32_t mflr_0		= 0x7c0802a6;
static const uint32_t mflr_11		= 0x7d6802a6;
static const uint32_t mflr_12		= 0x7d8802a6;
static const uint32_t mr_0_3		= 0x7c601b78;
static const uint32_t mr_3_0		= 0x7c030378;
static const uint32_t mtctr_0		= 0x7c0903a6;
static const uint32_t mtctr_11		= 0x7d6903a6;
static const uint32_t mtctr_12		= 0x7d8903a6;
static const uint32_t mtlr_0		= 0x7c0803a6;
static const uint32_t mtlr_11		= 0x7d6803a6;
static const uint32_t mtlr_12		= 0x7d8803a6;
static const uint32_t nop		= 0x60000000;
static const uint32_t ori_0_0_0		= 0x60000000;
static const uint32_t ori_11_11_0	= 0x616b0000;
static const uint32_t ori_12_12_0	= 0x618c0000;
static const uint32_t oris_12_12_0	= 0x658c0000;
static const uint32_t sldi_11_11_34	= 0x796b1746;
static const uint32_t sldi_12_12_32	= 0x799c07c6;
static const uint32_t srdi_0_0_2	= 0x7800f082;
static const uint32_t std_0_1		= 0xf8010000;
static const uint32_t std_0_12		= 0xf80c0000;
static const uint32_t std_2_1		= 0xf8410000;
static const uint32_t std_11_1		= 0xf9610000;
static const uint32_t stfd_0_1		= 0xd8010000;
static const uint32_t stvx_0_12_0	= 0x7c0c01ce;
static const uint32_t sub_11_11_12	= 0x7d6c5850;
static const uint32_t sub_12_12_11	= 0x7d8b6050;
static const uint32_t xor_2_12_12	= 0x7d826278;
static const uint32_t xor_11_12_12	= 0x7d8b6278;

static const uint64_t paddi_12_pc	= 0x0610000039800000ULL;
static const uint64_t pld_12_pc		= 0x04100000e5800000ULL;
static const uint64_t pnop		= 0x0700000000000000ULL;

// Write out the PLT.

template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::do_write(Output_file* of)
{
  if (size == 32 && (this->name_[3] != 'I' && this->name_[3] != 'L'))
    {
      const section_size_type offset = this->offset();
      const section_size_type oview_size
	= convert_to_section_size_type(this->data_size());
      unsigned char* const oview = of->get_output_view(offset, oview_size);
      unsigned char* pov = oview;
      unsigned char* endpov = oview + oview_size;

      // The address of the .glink branch table
      const Output_data_glink<size, big_endian>* glink
	= this->targ_->glink_section();
      elfcpp::Elf_types<32>::Elf_Addr branch_tab = glink->address();

      while (pov < endpov)
	{
	  elfcpp::Swap<32, big_endian>::writeval(pov, branch_tab);
	  pov += 4;
	  branch_tab += 4;
	}

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

// Create the PLT section.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_plt_section(Symbol_table* symtab,
						   Layout* layout)
{
  if (this->plt_ == NULL)
    {
      if (this->got_ == NULL)
	this->got_section(symtab, layout, GOT_TYPE_SMALL);

      if (this->glink_ == NULL)
	make_glink_section(layout);

      // Ensure that .rela.dyn always appears before .rela.plt  This is
      // necessary due to how, on PowerPC and some other targets, .rela.dyn
      // needs to include .rela.plt in its range.
      this->rela_dyn_section(layout);

      Reloc_section* plt_rel = new Reloc_section(false);
      layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
				      elfcpp::SHF_ALLOC, plt_rel,
				      ORDER_DYNAMIC_PLT_RELOCS, false);
      this->plt_
	= new Output_data_plt_powerpc<size, big_endian>(this, plt_rel,
							"** PLT");
      layout->add_output_section_data(".plt",
				      (size == 32
				       ? elfcpp::SHT_PROGBITS
				       : elfcpp::SHT_NOBITS),
				      elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
				      this->plt_,
				      (size == 32
				       ? ORDER_SMALL_DATA
				       : ORDER_SMALL_BSS),
				      false);

      Output_section* rela_plt_os = plt_rel->output_section();
      rela_plt_os->set_info_section(this->plt_->output_section());
    }
}

// Create the IPLT section.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_iplt_section(Symbol_table* symtab,
						    Layout* layout)
{
  if (this->iplt_ == NULL)
    {
      this->make_plt_section(symtab, layout);
      this->make_lplt_section(layout);

      Reloc_section* iplt_rel = new Reloc_section(false);
      if (this->rela_dyn_->output_section())
	this->rela_dyn_->output_section()->add_output_section_data(iplt_rel);
      this->iplt_
	= new Output_data_plt_powerpc<size, big_endian>(this, iplt_rel,
							"** IPLT");
      if (this->plt_->output_section())
	this->plt_->output_section()->add_output_section_data(this->iplt_);
    }
}

// Create the LPLT section.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_lplt_section(Layout* layout)
{
  if (this->lplt_ == NULL)
    {
      Reloc_section* lplt_rel = NULL;
      if (parameters->options().output_is_position_independent())
	{
	  lplt_rel = new Reloc_section(false);
	  this->rela_dyn_section(layout);
	  if (this->rela_dyn_->output_section())
	    this->rela_dyn_->output_section()
	      ->add_output_section_data(lplt_rel);
	}
      this->lplt_
	= new Output_data_plt_powerpc<size, big_endian>(this, lplt_rel,
							"** LPLT");
      this->make_brlt_section(layout);
      if (this->brlt_section_ && this->brlt_section_->output_section())
	this->brlt_section_->output_section()
	  ->add_output_section_data(this->lplt_);
      else
	layout->add_output_section_data(".branch_lt",
					elfcpp::SHT_PROGBITS,
					elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
					this->lplt_,
					ORDER_RELRO,
					true);
    }
}

// A section for huge long branch addresses, similar to plt section.

template<int size, bool big_endian>
class Output_data_brlt_powerpc : public Output_section_data_build
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef Output_data_reloc<elfcpp::SHT_RELA, true,
			    size, big_endian> Reloc_section;

  Output_data_brlt_powerpc(Target_powerpc<size, big_endian>* targ,
			   Reloc_section* brlt_rel)
    : Output_section_data_build(size == 32 ? 4 : 8),
      rel_(brlt_rel),
      targ_(targ)
  { }

  void
  reset_brlt_sizes()
  {
    this->reset_data_size();
    this->rel_->reset_data_size();
  }

  void
  finalize_brlt_sizes()
  {
    this->finalize_data_size();
    this->rel_->finalize_data_size();
  }

  // Add a reloc for an entry in the BRLT.
  void
  add_reloc(Address to, unsigned int off)
  { this->rel_->add_relative(elfcpp::R_POWERPC_RELATIVE, this, off, to); }

  // Update section and reloc section size.
  void
  set_current_size(unsigned int num_branches)
  {
    this->reset_address_and_file_offset();
    this->set_current_data_size(num_branches * 16);
    this->finalize_data_size();
    Output_section* os = this->output_section();
    os->set_section_offsets_need_adjustment();
    if (this->rel_ != NULL)
      {
	const unsigned int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
	this->rel_->reset_address_and_file_offset();
	this->rel_->set_current_data_size(num_branches * reloc_size);
	this->rel_->finalize_data_size();
	Output_section* os = this->rel_->output_section();
	os->set_section_offsets_need_adjustment();
      }
  }

 protected:
  void
  do_adjust_output_section(Output_section* os)
  {
    os->set_entsize(0);
  }

  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, "** BRLT"); }

 private:
  // Write out the BRLT data.
  void
  do_write(Output_file*);

  // The reloc section.
  Reloc_section* rel_;
  Target_powerpc<size, big_endian>* targ_;
};

// Make the branch lookup table section.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_brlt_section(Layout* layout)
{
  if (size == 64 && this->brlt_section_ == NULL)
    {
      Reloc_section* brlt_rel = NULL;
      bool is_pic = parameters->options().output_is_position_independent();
      if (is_pic)
	{
	  // When PIC we can't fill in .branch_lt but must initialise at
	  // runtime via dynamic relocations.
	  this->rela_dyn_section(layout);
	  brlt_rel = new Reloc_section(false);
	  if (this->rela_dyn_->output_section())
	    this->rela_dyn_->output_section()
	      ->add_output_section_data(brlt_rel);
	}
      this->brlt_section_
	= new Output_data_brlt_powerpc<size, big_endian>(this, brlt_rel);
      if (this->plt_ && is_pic && this->plt_->output_section())
	this->plt_->output_section()
	  ->add_output_section_data(this->brlt_section_);
      else
	layout->add_output_section_data(".branch_lt",
					elfcpp::SHT_PROGBITS,
					elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE,
					this->brlt_section_,
					ORDER_RELRO,
					true);
    }
}

// Write out .branch_lt when non-PIC.

template<int size, bool big_endian>
void
Output_data_brlt_powerpc<size, big_endian>::do_write(Output_file* of)
{
  if (size == 64 && !parameters->options().output_is_position_independent())
    {
      const section_size_type offset = this->offset();
      const section_size_type oview_size
	= convert_to_section_size_type(this->data_size());
      unsigned char* const oview = of->get_output_view(offset, oview_size);

      this->targ_->write_branch_lookup_table(oview);
      of->write_output_view(offset, oview_size, oview);
    }
}

static inline uint32_t
l(uint32_t a)
{
  return a & 0xffff;
}

static inline uint32_t
hi(uint32_t a)
{
  return l(a >> 16);
}

static inline uint32_t
ha(uint32_t a)
{
  return hi(a + 0x8000);
}

static inline uint64_t
d34(uint64_t v)
{
  return ((v & 0x3ffff0000ULL) << 16) | (v & 0xffff);
}

static inline uint64_t
ha34(uint64_t v)
{
  return (v + (1ULL << 33)) >> 34;
}

template<int size>
struct Eh_cie
{
  static const unsigned char eh_frame_cie[12];
};

template<int size>
const unsigned char Eh_cie<size>::eh_frame_cie[] =
{
  1,					// CIE version.
  'z', 'R', 0,				// Augmentation string.
  4,					// Code alignment.
  0x80 - size / 8 ,			// Data alignment.
  65,					// RA reg.
  1,					// Augmentation size.
  (elfcpp::DW_EH_PE_pcrel
   | elfcpp::DW_EH_PE_sdata4),		// FDE encoding.
  elfcpp::DW_CFA_def_cfa, 1, 0		// def_cfa: r1 offset 0.
};

// Describe __glink_PLTresolve use of LR, 64-bit version ABIv1.
static const unsigned char glink_eh_frame_fde_64v1[] =
{
  0, 0, 0, 0,				// Replaced with offset to .glink.
  0, 0, 0, 0,				// Replaced with size of .glink.
  0,					// Augmentation size.
  elfcpp::DW_CFA_advance_loc + 2,
  elfcpp::DW_CFA_register, 65, 12,
  elfcpp::DW_CFA_advance_loc + 4,
  elfcpp::DW_CFA_restore_extended, 65
};

// Describe __glink_PLTresolve use of LR, 64-bit version ABIv2.
static const unsigned char glink_eh_frame_fde_64v2[] =
{
  0, 0, 0, 0,				// Replaced with offset to .glink.
  0, 0, 0, 0,				// Replaced with size of .glink.
  0,					// Augmentation size.
  elfcpp::DW_CFA_advance_loc + 2,
  elfcpp::DW_CFA_register, 65, 0,
  elfcpp::DW_CFA_advance_loc + 2,
  elfcpp::DW_CFA_restore_extended, 65
};

static const unsigned char glink_eh_frame_fde_64v2_localentry0[] =
{
  0, 0, 0, 0,				// Replaced with offset to .glink.
  0, 0, 0, 0,				// Replaced with size of .glink.
  0,					// Augmentation size.
  elfcpp::DW_CFA_advance_loc + 3,
  elfcpp::DW_CFA_register, 65, 0,
  elfcpp::DW_CFA_advance_loc + 2,
  elfcpp::DW_CFA_restore_extended, 65
};

// Describe __glink_PLTresolve use of LR, 32-bit version.
static const unsigned char glink_eh_frame_fde_32[] =
{
  0, 0, 0, 0,				// Replaced with offset to .glink.
  0, 0, 0, 0,				// Replaced with size of .glink.
  0,					// Augmentation size.
  elfcpp::DW_CFA_advance_loc + 2,
  elfcpp::DW_CFA_register, 65, 0,
  elfcpp::DW_CFA_advance_loc + 4,
  elfcpp::DW_CFA_restore_extended, 65
};

static const unsigned char default_fde[] =
{
  0, 0, 0, 0,				// Replaced with offset to stubs.
  0, 0, 0, 0,				// Replaced with size of stubs.
  0,					// Augmentation size.
  elfcpp::DW_CFA_nop,			// Pad.
  elfcpp::DW_CFA_nop,
  elfcpp::DW_CFA_nop
};

template<bool big_endian>
static inline void
write_insn(unsigned char* p, uint32_t v)
{
  elfcpp::Swap<32, big_endian>::writeval(p, v);
}

template<int size>
static inline unsigned int
param_plt_align()
{
  if (!parameters->options().user_set_plt_align())
    return size == 64 ? 32 : 8;
  return 1 << parameters->options().plt_align();
}

// Stub_table holds information about plt and long branch stubs.
// Stubs are built in an area following some input section determined
// by group_sections().  This input section is converted to a relaxed
// input section allowing it to be resized to accommodate the stubs

template<int size, bool big_endian>
class Stub_table : public Output_relaxed_input_section
{
 public:
  struct Plt_stub_ent
  {
    Plt_stub_ent(unsigned int off, unsigned int indx)
      : off_(off), indx_(indx), iter_(0), notoc_(0), toc_(0),
	r2save_(0), localentry0_(0), tocoff_(0)
    { }

    unsigned int off_;
    unsigned int indx_;
    unsigned int iter_ : 1;
    unsigned int notoc_ : 1;
    unsigned int toc_ : 1;
    unsigned int r2save_ : 1;
    unsigned int localentry0_ : 1;
    unsigned int tocoff_ : 8;
  };
  struct Branch_stub_ent
  {
    Branch_stub_ent(unsigned int off, bool notoc, bool save_res)
      : off_(off), iter_(0), notoc_(notoc), toc_(0), save_res_(save_res),
	other_(0), tocoff_(0)
    { }

    unsigned int off_;
    unsigned int iter_ : 1;
    unsigned int notoc_ : 1;
    unsigned int toc_ : 1;
    unsigned int save_res_ : 1;
    unsigned int other_ : 3;
    unsigned int tocoff_ : 8;
  };
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  static const Address invalid_address = static_cast<Address>(0) - 1;

  Stub_table(Target_powerpc<size, big_endian>* targ,
	     Output_section* output_section,
	     const Output_section::Input_section* owner,
	     uint32_t id)
    : Output_relaxed_input_section(owner->relobj(), owner->shndx(),
				   owner->relobj()
				   ->section_addralign(owner->shndx())),
      targ_(targ), plt_call_stubs_(), long_branch_stubs_(),
      orig_data_size_(owner->current_data_size()),
      plt_size_(0), last_plt_size_(0),
      branch_size_(0), last_branch_size_(0), min_size_threshold_(0),
      need_save_res_(false), need_resize_(false), resizing_(false),
      uniq_(id)
  {
    this->set_output_section(output_section);

    std::vector<Output_relaxed_input_section*> new_relaxed;
    new_relaxed.push_back(this);
    output_section->convert_input_sections_to_relaxed_sections(new_relaxed);
  }

  // Add a plt call stub.
  bool
  add_plt_call_entry(Address,
		     const Sized_relobj_file<size, big_endian>*,
		     const Symbol*,
		     unsigned int,
		     Address,
		     bool);

  bool
  add_plt_call_entry(Address,
		     const Sized_relobj_file<size, big_endian>*,
		     unsigned int,
		     unsigned int,
		     Address,
		     bool);

  // Find a given plt call stub.
  const Plt_stub_ent*
  find_plt_call_entry(const Symbol*) const;

  const Plt_stub_ent*
  find_plt_call_entry(const Sized_relobj_file<size, big_endian>*,
		      unsigned int) const;

  const Plt_stub_ent*
  find_plt_call_entry(const Sized_relobj_file<size, big_endian>*,
		      const Symbol*,
		      unsigned int,
		      Address) const;

  const Plt_stub_ent*
  find_plt_call_entry(const Sized_relobj_file<size, big_endian>*,
		      unsigned int,
		      unsigned int,
		      Address) const;

  // Add a long branch stub.
  bool
  add_long_branch_entry(unsigned int, Address, Address, unsigned int, bool);

  const Branch_stub_ent*
  find_long_branch_entry(Address) const;

  bool
  can_reach_stub(Address from, unsigned int off, unsigned int r_type)
  {
    Address max_branch_offset = max_branch_delta<size>(r_type);
    if (max_branch_offset == 0)
      return true;
    gold_assert(from != invalid_address);
    Address loc = off + this->stub_address();
    return loc - from + max_branch_offset < 2 * max_branch_offset;
  }

  void
  clear_stubs(bool all)
  {
    this->plt_call_stubs_.clear();
    this->plt_size_ = 0;
    this->long_branch_stubs_.clear();
    this->branch_size_ = 0;
    this->need_save_res_ = false;
    if (all)
      {
	this->last_plt_size_ = 0;
	this->last_branch_size_ = 0;
      }
  }

  bool
  need_resize() const
  { return need_resize_; }

  void
  set_resizing(bool val)
  {
    this->resizing_ = val;
    if (val)
      {
	this->need_resize_ = false;
	this->plt_size_ = 0;
	this->branch_size_ = 0;
	this->need_save_res_ = false;
      }
  }

  Address
  set_address_and_size(const Output_section* os, Address off)
  {
    Address start_off = off;
    off += this->orig_data_size_;
    Address my_size = this->plt_size_ + this->branch_size_;
    if (this->need_save_res_)
      my_size += this->targ_->savres_section()->data_size();
    if (my_size != 0)
      off = align_address(off, this->stub_align());
    // Include original section size and alignment padding in size
    my_size += off - start_off;
    // Ensure new size is always larger than min size
    // threshold. Alignment requirement is included in "my_size", so
    // increase "my_size" does not invalidate alignment.
    if (my_size < this->min_size_threshold_)
      my_size = this->min_size_threshold_;
    this->reset_address_and_file_offset();
    this->set_current_data_size(my_size);
    this->set_address_and_file_offset(os->address() + start_off,
				      os->offset() + start_off);
    return my_size;
  }

  Address
  stub_address() const
  {
    return align_address(this->address() + this->orig_data_size_,
			 this->stub_align());
  }

  Address
  stub_offset() const
  {
    return align_address(this->offset() + this->orig_data_size_,
			 this->stub_align());
  }

  section_size_type
  plt_size() const
  { return this->plt_size_; }

  section_size_type
  branch_size() const
  { return this->branch_size_; }

  void
  set_min_size_threshold(Address min_size)
  { this->min_size_threshold_ = min_size; }

  void
  define_stub_syms(Symbol_table*);

  bool
  size_update()
  {
    Output_section* os = this->output_section();
    if (os->addralign() < this->stub_align())
      {
	os->set_addralign(this->stub_align());
	// FIXME: get rid of the insane checkpointing.
	// We can't increase alignment of the input section to which
	// stubs are attached;  The input section may be .init which
	// is pasted together with other .init sections to form a
	// function.  Aligning might insert zero padding resulting in
	// sigill.  However we do need to increase alignment of the
	// output section so that the align_address() on offset in
	// set_address_and_size() adds the same padding as the
	// align_address() on address in stub_address().
	// What's more, we need this alignment for the layout done in
	// relaxation_loop_body() so that the output section starts at
	// a suitably aligned address.
	os->checkpoint_set_addralign(this->stub_align());
      }
    if (this->last_plt_size_ != this->plt_size_
	|| this->last_branch_size_ != this->branch_size_)
      {
	this->last_plt_size_ = this->plt_size_;
	this->last_branch_size_ = this->branch_size_;
	return true;
      }
    return false;
  }

  // Add .eh_frame info for this stub section.
  void
  add_eh_frame(Layout* layout);

  // Remove .eh_frame info for this stub section.
  void
  remove_eh_frame(Layout* layout);

  Target_powerpc<size, big_endian>*
  targ() const
  { return targ_; }

 private:
  class Plt_stub_key;
  class Plt_stub_key_hash;
  typedef Unordered_map<Plt_stub_key, Plt_stub_ent,
			Plt_stub_key_hash> Plt_stub_entries;
  class Branch_stub_key;
  class Branch_stub_key_hash;
  typedef Unordered_map<Branch_stub_key, Branch_stub_ent,
			Branch_stub_key_hash> Branch_stub_entries;

  // Alignment of stub section.
  unsigned int
  stub_align() const
  {
    unsigned int min_align = size == 64 ? 32 : 16;
    unsigned int user_align = 1 << parameters->options().plt_align();
    return std::max(user_align, min_align);
  }

  // Return the plt offset for the given call stub.
  Address
  plt_off(typename Plt_stub_entries::const_iterator p,
	  const Output_data_plt_powerpc<size, big_endian>** sec) const
  {
    const Symbol* gsym = p->first.sym_;
    if (gsym != NULL)
      return this->targ_->plt_off(gsym, sec);
    else
      {
	const Sized_relobj_file<size, big_endian>* relobj = p->first.object_;
	unsigned int local_sym_index = p->first.locsym_;
	return this->targ_->plt_off(relobj, local_sym_index, sec);
      }
  }

  // Size of a given plt call stub.
  unsigned int
  plt_call_size(typename Plt_stub_entries::iterator p) const;

  unsigned int
  plt_call_align(unsigned int bytes) const
  {
    unsigned int align = param_plt_align<size>();
    return (bytes + align - 1) & -align;
  }

  // Return long branch stub size.
  unsigned int
  branch_stub_size(typename Branch_stub_entries::iterator p,
		   bool* need_lt);

  void
  build_tls_opt_head(unsigned char** pp,  bool save_lr);

  void
  build_tls_opt_tail(unsigned char* p);

  void
  plt_error(const Plt_stub_key& p);

  // Write out stubs.
  void
  do_write(Output_file*);

  // Plt call stub keys.
  class Plt_stub_key
  {
  public:
    Plt_stub_key(const Symbol* sym)
      : sym_(sym), object_(0), addend_(0), locsym_(0)
    { }

    Plt_stub_key(const Sized_relobj_file<size, big_endian>* object,
		 unsigned int locsym_index)
      : sym_(NULL), object_(object), addend_(0), locsym_(locsym_index)
    { }

    Plt_stub_key(const Sized_relobj_file<size, big_endian>* object,
		 const Symbol* sym,
		 unsigned int r_type,
		 Address addend)
      : sym_(sym), object_(0), addend_(0), locsym_(0)
    {
      if (size != 32)
	this->addend_ = addend;
      else if (parameters->options().output_is_position_independent()
	       && (r_type == elfcpp::R_PPC_PLTREL24
		   || r_type == elfcpp::R_POWERPC_PLTCALL))
	{
	  this->addend_ = addend;
	  if (this->addend_ >= 32768)
	    this->object_ = object;
	}
    }

    Plt_stub_key(const Sized_relobj_file<size, big_endian>* object,
		 unsigned int locsym_index,
		 unsigned int r_type,
		 Address addend)
      : sym_(NULL), object_(object), addend_(0), locsym_(locsym_index)
    {
      if (size != 32)
	this->addend_ = addend;
      else if (parameters->options().output_is_position_independent()
	       && (r_type == elfcpp::R_PPC_PLTREL24
		   || r_type == elfcpp::R_POWERPC_PLTCALL))
	this->addend_ = addend;
    }

    bool operator==(const Plt_stub_key& that) const
    {
      return (this->sym_ == that.sym_
	      && this->object_ == that.object_
	      && this->addend_ == that.addend_
	      && this->locsym_ == that.locsym_);
    }

    const Symbol* sym_;
    const Sized_relobj_file<size, big_endian>* object_;
    typename elfcpp::Elf_types<size>::Elf_Addr addend_;
    unsigned int locsym_;
  };

  class Plt_stub_key_hash
  {
  public:
    size_t operator()(const Plt_stub_key& ent) const
    {
      return (reinterpret_cast<uintptr_t>(ent.sym_)
	      ^ reinterpret_cast<uintptr_t>(ent.object_)
	      ^ ent.addend_
	      ^ ent.locsym_);
    }
  };

  // Long branch stub keys.
  class Branch_stub_key
  {
  public:
    Branch_stub_key(Address to)
      : dest_(to)
    { }

    bool operator==(const Branch_stub_key& that) const
    {
      return this->dest_ == that.dest_;
    }

    Address dest_;
  };

  class Branch_stub_key_hash
  {
  public:
    size_t operator()(const Branch_stub_key& key) const
    { return key.dest_; }
  };

  // In a sane world this would be a global.
  Target_powerpc<size, big_endian>* targ_;
  // Map sym/object/addend to stub offset.
  Plt_stub_entries plt_call_stubs_;
  // Map destination address to stub offset.
  Branch_stub_entries long_branch_stubs_;
  // size of input section
  section_size_type orig_data_size_;
  // size of stubs
  section_size_type plt_size_, last_plt_size_, branch_size_, last_branch_size_;
  // Some rare cases cause (PR/20529) fluctuation in stub table
  // size, which leads to an endless relax loop. This is to be fixed
  // by, after the first few iterations, allowing only increase of
  // stub table size. This variable sets the minimal possible size of
  // a stub table, it is zero for the first few iterations, then
  // increases monotonically.
  Address min_size_threshold_;
  // Set if this stub group needs a copy of out-of-line register
  // save/restore functions.
  bool need_save_res_;
  // Set when notoc_/r2save_ changes after sizing a stub
  bool need_resize_;
  // Set when resizing stubs
  bool resizing_;
  // Per stub table unique identifier.
  uint32_t uniq_;
};

// Add a plt call stub, if we do not already have one for this
// sym/object/addend combo.

template<int size, bool big_endian>
bool
Stub_table<size, big_endian>::add_plt_call_entry(
    Address from,
    const Sized_relobj_file<size, big_endian>* object,
    const Symbol* gsym,
    unsigned int r_type,
    Address addend,
    bool tocsave)
{
  Plt_stub_key key(object, gsym, r_type, addend);
  Plt_stub_ent ent(this->plt_size_, this->plt_call_stubs_.size());
  std::pair<typename Plt_stub_entries::iterator, bool> p
    = this->plt_call_stubs_.insert(std::make_pair(key, ent));
  if (size == 64)
    {
      if (p.second
	  && this->targ_->is_elfv2_localentry0(gsym))
	{
	  p.first->second.localentry0_ = 1;
	  this->targ_->set_has_localentry0();
	}
      if (r_type == elfcpp::R_PPC64_REL24_NOTOC)
	{
	  if (!p.second && !p.first->second.notoc_
	      && (!this->targ_->power10_stubs()
		  || this->targ_->power10_stubs_auto()))
	    this->need_resize_ = true;
	  p.first->second.notoc_ = 1;
	}
      else
	{
	  if (!p.second && !p.first->second.toc_)
	    this->need_resize_ = true;
	  p.first->second.toc_ = 1;
	  if (!tocsave && !p.first->second.localentry0_)
	    {
	      if (!p.second && !p.first->second.r2save_)
		this->need_resize_ = true;
	      p.first->second.r2save_ = 1;
	    }
	}
    }
  if (p.second || (this->resizing_ && !p.first->second.iter_))
    {
      if (this->resizing_)
	{
	  p.first->second.iter_ = 1;
	  p.first->second.off_ = this->plt_size_;
	}
      this->plt_size_ += this->plt_call_size(p.first);
      if (this->targ_->is_tls_get_addr_opt(gsym))
	this->targ_->set_has_tls_get_addr_opt();
      this->plt_size_ = this->plt_call_align(this->plt_size_);
    }
  return this->can_reach_stub(from, p.first->second.off_, r_type);
}

template<int size, bool big_endian>
bool
Stub_table<size, big_endian>::add_plt_call_entry(
    Address from,
    const Sized_relobj_file<size, big_endian>* object,
    unsigned int locsym_index,
    unsigned int r_type,
    Address addend,
    bool tocsave)
{
  Plt_stub_key key(object, locsym_index, r_type, addend);
  Plt_stub_ent ent(this->plt_size_, this->plt_call_stubs_.size());
  std::pair<typename Plt_stub_entries::iterator, bool> p
    = this->plt_call_stubs_.insert(std::make_pair(key, ent));
  if (size == 64)
    {
      if (p.second
	  && this->targ_->is_elfv2_localentry0(object, locsym_index))
	{
	  p.first->second.localentry0_ = 1;
	  this->targ_->set_has_localentry0();
	}
      if (r_type == elfcpp::R_PPC64_REL24_NOTOC)
	{
	  if (!p.second && !p.first->second.notoc_
	      && (!this->targ_->power10_stubs()
		  || this->targ_->power10_stubs_auto()))
	    this->need_resize_ = true;
	  p.first->second.notoc_ = 1;
	}
      else
	{
	  if (!p.second && !p.first->second.toc_)
	    this->need_resize_ = true;
	  p.first->second.toc_ = 1;
	  if (!tocsave && !p.first->second.localentry0_)
	    {
	      if (!p.second && !p.first->second.r2save_)
		this->need_resize_ = true;
	      p.first->second.r2save_ = 1;
	    }
	}
    }
  if (p.second || (this->resizing_ && !p.first->second.iter_))
    {
      if (this->resizing_)
	{
	  p.first->second.iter_ = 1;
	  p.first->second.off_ = this->plt_size_;
	}
      this->plt_size_ += this->plt_call_size(p.first);
      this->plt_size_ = this->plt_call_align(this->plt_size_);
    }
  return this->can_reach_stub(from, p.first->second.off_, r_type);
}

// Find a plt call stub.

template<int size, bool big_endian>
const typename Stub_table<size, big_endian>::Plt_stub_ent*
Stub_table<size, big_endian>::find_plt_call_entry(
    const Sized_relobj_file<size, big_endian>* object,
    const Symbol* gsym,
    unsigned int r_type,
    Address addend) const
{
  Plt_stub_key key(object, gsym, r_type, addend);
  typename Plt_stub_entries::const_iterator p = this->plt_call_stubs_.find(key);
  if (p == this->plt_call_stubs_.end())
    return NULL;
  return &p->second;
}

template<int size, bool big_endian>
const typename Stub_table<size, big_endian>::Plt_stub_ent*
Stub_table<size, big_endian>::find_plt_call_entry(const Symbol* gsym) const
{
  Plt_stub_key key(gsym);
  typename Plt_stub_entries::const_iterator p = this->plt_call_stubs_.find(key);
  if (p == this->plt_call_stubs_.end())
    return NULL;
  return &p->second;
}

template<int size, bool big_endian>
const typename Stub_table<size, big_endian>::Plt_stub_ent*
Stub_table<size, big_endian>::find_plt_call_entry(
    const Sized_relobj_file<size, big_endian>* object,
    unsigned int locsym_index,
    unsigned int r_type,
    Address addend) const
{
  Plt_stub_key key(object, locsym_index, r_type, addend);
  typename Plt_stub_entries::const_iterator p = this->plt_call_stubs_.find(key);
  if (p == this->plt_call_stubs_.end())
    return NULL;
  return &p->second;
}

template<int size, bool big_endian>
const typename Stub_table<size, big_endian>::Plt_stub_ent*
Stub_table<size, big_endian>::find_plt_call_entry(
    const Sized_relobj_file<size, big_endian>* object,
    unsigned int locsym_index) const
{
  Plt_stub_key key(object, locsym_index);
  typename Plt_stub_entries::const_iterator p = this->plt_call_stubs_.find(key);
  if (p == this->plt_call_stubs_.end())
    return NULL;
  return &p->second;
}

// Add a long branch stub if we don't already have one to given
// destination.

template<int size, bool big_endian>
bool
Stub_table<size, big_endian>::add_long_branch_entry(
    unsigned int r_type,
    Address from,
    Address to,
    unsigned int other,
    bool save_res)
{
  Branch_stub_key key(to);
  bool notoc = (size == 64 && r_type == elfcpp::R_PPC64_REL24_NOTOC);
  Branch_stub_ent ent(this->branch_size_, notoc, save_res);
  std::pair<typename Branch_stub_entries::iterator, bool> p
    = this->long_branch_stubs_.insert(std::make_pair(key, ent));
  if (notoc)
    {
      if (!p.second && !p.first->second.notoc_)
	this->need_resize_ = true;
      p.first->second.notoc_ = true;
    }
  else
    {
      if (!p.second && !p.first->second.toc_)
	this->need_resize_ = true;
      p.first->second.toc_ = true;
    }
  if (size == 64 && p.first->second.other_ == 0)
    p.first->second.other_ = other;
  gold_assert(save_res == p.first->second.save_res_);
  if (p.second || (this->resizing_ && !p.first->second.iter_))
    {
      if (this->resizing_)
	{
	  p.first->second.iter_ = 1;
	  p.first->second.off_ = this->branch_size_;
	}
      if (save_res)
	this->need_save_res_ = true;
      else
	{
	  bool need_lt = false;
	  unsigned int stub_size = this->branch_stub_size(p.first, &need_lt);
	  this->branch_size_ += stub_size;
	  if (size == 64 && need_lt)
	    this->targ_->add_branch_lookup_table(to);
	}
    }
  return this->can_reach_stub(from, p.first->second.off_, r_type);
}

// Find long branch stub offset.

template<int size, bool big_endian>
const typename Stub_table<size, big_endian>::Branch_stub_ent*
Stub_table<size, big_endian>::find_long_branch_entry(Address to) const
{
  Branch_stub_key key(to);
  typename Branch_stub_entries::const_iterator p
    = this->long_branch_stubs_.find(key);
  if (p == this->long_branch_stubs_.end())
    return NULL;
  return &p->second;
}

template<bool big_endian>
static void
eh_advance (std::vector<unsigned char>& fde, unsigned int delta)
{
  delta /= 4;
  if (delta < 64)
    fde.push_back(elfcpp::DW_CFA_advance_loc + delta);
  else if (delta < 256)
    {
      fde.push_back(elfcpp::DW_CFA_advance_loc1);
      fde.push_back(delta);
    }
  else if (delta < 65536)
    {
      fde.resize(fde.size() + 3);
      unsigned char *p = &*fde.end() - 3;
      *p++ = elfcpp::DW_CFA_advance_loc2;
      elfcpp::Swap<16, big_endian>::writeval(p, delta);
    }
  else
    {
      fde.resize(fde.size() + 5);
      unsigned char *p = &*fde.end() - 5;
      *p++ = elfcpp::DW_CFA_advance_loc4;
      elfcpp::Swap<32, big_endian>::writeval(p, delta);
    }
}

template<typename T>
static bool
stub_sort(T s1, T s2)
{
  return s1->second.off_ < s2->second.off_;
}

// Add .eh_frame info for this stub section.  Unlike other linker
// generated .eh_frame this is added late in the link, because we
// only want the .eh_frame info if this particular stub section is
// non-empty.

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::add_eh_frame(Layout* layout)
{
  if (size != 64
      || !parameters->options().ld_generated_unwind_info())
    return;

  // Since we add stub .eh_frame info late, it must be placed
  // after all other linker generated .eh_frame info so that
  // merge mapping need not be updated for input sections.
  // There is no provision to use a different CIE to that used
  // by .glink.
  if (!this->targ_->has_glink())
    return;

  typedef typename Plt_stub_entries::iterator plt_iter;
  std::vector<plt_iter> calls;
  if (!this->plt_call_stubs_.empty())
    for (plt_iter cs = this->plt_call_stubs_.begin();
	 cs != this->plt_call_stubs_.end();
	 ++cs)
      if ((this->targ_->is_tls_get_addr_opt(cs->first.sym_)
	   && cs->second.r2save_
	   && !cs->second.localentry0_)
	  || (cs->second.notoc_
	      && !this->targ_->power10_stubs()))
	calls.push_back(cs);
  if (calls.size() > 1)
    std::stable_sort(calls.begin(), calls.end(),
		     stub_sort<plt_iter>);

  typedef typename Branch_stub_entries::const_iterator branch_iter;
  std::vector<branch_iter> branches;
  if (!this->long_branch_stubs_.empty()
      && !this->targ_->power10_stubs())
    for (branch_iter bs = this->long_branch_stubs_.begin();
	 bs != this->long_branch_stubs_.end();
	 ++bs)
      if (bs->second.notoc_)
	branches.push_back(bs);
  if (branches.size() > 1)
    std::stable_sort(branches.begin(), branches.end(),
		     stub_sort<branch_iter>);

  if (calls.empty() && branches.empty())
    return;

  unsigned int last_eh_loc = 0;
  // offset pcrel sdata4, size udata4, and augmentation size byte.
  std::vector<unsigned char> fde(9, 0);

  for (unsigned int i = 0; i < calls.size(); i++)
    {
      plt_iter cs = calls[i];
      unsigned int off = cs->second.off_;
      // The __tls_get_addr_opt call stub needs to describe where
      // it saves LR, to support exceptions that might be thrown
      // from __tls_get_addr, and to support asynchronous exceptions.
      if (this->targ_->is_tls_get_addr_opt(cs->first.sym_))
	{
	  off += 7 * 4;
	  if (cs->second.r2save_
	      && !cs->second.localentry0_)
	    {
	      off += 2 * 4;
	      eh_advance<big_endian>(fde, off - last_eh_loc);
	      fde.resize(fde.size() + 6);
	      unsigned char* p = &*fde.end() - 6;
	      *p++ = elfcpp::DW_CFA_offset_extended_sf;
	      *p++ = 65;
	      *p++ = -(this->targ_->stk_linker() / 8) & 0x7f;
	      unsigned int delta = this->plt_call_size(cs) - 4 - 9 * 4;
	      *p++ = elfcpp::DW_CFA_advance_loc + delta / 4;
	      *p++ = elfcpp::DW_CFA_restore_extended;
	      *p++ = 65;
	      last_eh_loc = off + delta;
	      continue;
	    }
	}
      // notoc stubs also should describe LR changes, to support
      // asynchronous exceptions.
      off += (cs->second.r2save_ ? 4 : 0) + 8;
      eh_advance<big_endian>(fde, off - last_eh_loc);
      fde.resize(fde.size() + 6);
      unsigned char* p = &*fde.end() - 6;
      *p++ = elfcpp::DW_CFA_register;
      *p++ = 65;
      *p++ = 12;
      *p++ = elfcpp::DW_CFA_advance_loc + 8 / 4;
      *p++ = elfcpp::DW_CFA_restore_extended;
      *p++ = 65;
      last_eh_loc = off + 8;
    }

  for (unsigned int i = 0; i < branches.size(); i++)
    {
      branch_iter bs = branches[i];
      unsigned int off = bs->second.off_ + 8;
      eh_advance<big_endian>(fde, off - last_eh_loc);
      fde.resize(fde.size() + 6);
      unsigned char* p = &*fde.end() - 6;
      *p++ = elfcpp::DW_CFA_register;
      *p++ = 65;
      *p++ = 12;
      *p++ = elfcpp::DW_CFA_advance_loc + 8 / 4;
      *p++ = elfcpp::DW_CFA_restore_extended;
      *p++ = 65;
      last_eh_loc = off + 8;
    }

  layout->add_eh_frame_for_plt(this,
			       Eh_cie<size>::eh_frame_cie,
			       sizeof (Eh_cie<size>::eh_frame_cie),
			       &*fde.begin(), fde.size());
}

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::remove_eh_frame(Layout* layout)
{
  if (size == 64
      && parameters->options().ld_generated_unwind_info()
      && this->targ_->has_glink())
    layout->remove_eh_frame_for_plt(this,
				    Eh_cie<size>::eh_frame_cie,
				    sizeof (Eh_cie<size>::eh_frame_cie));
}

// A class to handle .glink.

template<int size, bool big_endian>
class Output_data_glink : public Output_section_data
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  static const Address invalid_address = static_cast<Address>(0) - 1;

  Output_data_glink(Target_powerpc<size, big_endian>* targ)
    : Output_section_data(16), targ_(targ), global_entry_stubs_(),
      end_branch_table_(), ge_size_(0)
  { }

  void
  add_eh_frame(Layout* layout);

  void
  add_global_entry(const Symbol*);

  Address
  find_global_entry(const Symbol*) const;

  unsigned int
  global_entry_align(unsigned int off) const
  {
    unsigned int align = param_plt_align<size>();
    return (off + align - 1) & -align;
  }

  unsigned int
  global_entry_off() const
  {
    return this->global_entry_align(this->end_branch_table_);
  }

  Address
  global_entry_address() const
  {
    gold_assert(this->is_data_size_valid());
    return this->address() + this->global_entry_off();
  }

  int
  pltresolve_size() const
  {
    if (size == 64)
      return (8
	      + (this->targ_->abiversion() < 2 ? 11 * 4
		 : this->targ_->has_localentry0() ? 14 * 4 : 13 * 4));
    return 16 * 4;
  }

 protected:
  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** glink")); }

 private:
  void
  set_final_data_size();

  // Write out .glink
  void
  do_write(Output_file*);

  // Allows access to .got and .plt for do_write.
  Target_powerpc<size, big_endian>* targ_;

  // Map sym to stub offset.
  typedef Unordered_map<const Symbol*, unsigned int> Global_entry_stub_entries;
  Global_entry_stub_entries global_entry_stubs_;

  unsigned int end_branch_table_, ge_size_;
};

template<int size, bool big_endian>
void
Output_data_glink<size, big_endian>::add_eh_frame(Layout* layout)
{
  if (!parameters->options().ld_generated_unwind_info())
    return;

  if (size == 64)
    {
      if (this->targ_->abiversion() < 2)
	layout->add_eh_frame_for_plt(this,
				     Eh_cie<64>::eh_frame_cie,
				     sizeof (Eh_cie<64>::eh_frame_cie),
				     glink_eh_frame_fde_64v1,
				     sizeof (glink_eh_frame_fde_64v1));
      else if (this->targ_->has_localentry0())
	layout->add_eh_frame_for_plt(this,
				     Eh_cie<64>::eh_frame_cie,
				     sizeof (Eh_cie<64>::eh_frame_cie),
				     glink_eh_frame_fde_64v2_localentry0,
				     sizeof (glink_eh_frame_fde_64v2));
      else
	layout->add_eh_frame_for_plt(this,
				     Eh_cie<64>::eh_frame_cie,
				     sizeof (Eh_cie<64>::eh_frame_cie),
				     glink_eh_frame_fde_64v2,
				     sizeof (glink_eh_frame_fde_64v2));
    }
  else
    {
      // 32-bit .glink can use the default since the CIE return
      // address reg, LR, is valid.
      layout->add_eh_frame_for_plt(this,
				   Eh_cie<32>::eh_frame_cie,
				   sizeof (Eh_cie<32>::eh_frame_cie),
				   default_fde,
				   sizeof (default_fde));
      // Except where LR is used in a PIC __glink_PLTresolve.
      if (parameters->options().output_is_position_independent())
	layout->add_eh_frame_for_plt(this,
				     Eh_cie<32>::eh_frame_cie,
				     sizeof (Eh_cie<32>::eh_frame_cie),
				     glink_eh_frame_fde_32,
				     sizeof (glink_eh_frame_fde_32));
    }
}

template<int size, bool big_endian>
void
Output_data_glink<size, big_endian>::add_global_entry(const Symbol* gsym)
{
  unsigned int off = this->global_entry_align(this->ge_size_);
  std::pair<typename Global_entry_stub_entries::iterator, bool> p
    = this->global_entry_stubs_.insert(std::make_pair(gsym, off));
  if (p.second)
    this->ge_size_ = off + 16;
}

template<int size, bool big_endian>
typename Output_data_glink<size, big_endian>::Address
Output_data_glink<size, big_endian>::find_global_entry(const Symbol* gsym) const
{
  typename Global_entry_stub_entries::const_iterator p
    = this->global_entry_stubs_.find(gsym);
  return p == this->global_entry_stubs_.end() ? invalid_address : p->second;
}

template<int size, bool big_endian>
void
Output_data_glink<size, big_endian>::set_final_data_size()
{
  unsigned int count = this->targ_->plt_entry_count();
  section_size_type total = 0;

  if (count != 0)
    {
      if (size == 32)
	{
	  // space for branch table
	  total += 4 * (count - 1);

	  total += -total & 15;
	  total += this->pltresolve_size();
	}
      else
	{
	  total += this->pltresolve_size();

	  // space for branch table
	  total += 4 * count;
	  if (this->targ_->abiversion() < 2)
	    {
	      total += 4 * count;
	      if (count > 0x8000)
		total += 4 * (count - 0x8000);
	    }
	}
    }
  this->end_branch_table_ = total;
  total = this->global_entry_align(total);
  total += this->ge_size_;

  this->set_data_size(total);
}

// Define symbols on stubs, identifying the stub.

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::define_stub_syms(Symbol_table* symtab)
{
  if (!this->plt_call_stubs_.empty())
    {
      // The key for the plt call stub hash table includes addresses,
      // therefore traversal order depends on those addresses, which
      // can change between runs if gold is a PIE.  Unfortunately the
      // output .symtab ordering depends on the order in which symbols
      // are added to the linker symtab.  We want reproducible output
      // so must sort the call stub symbols.
      typedef typename Plt_stub_entries::iterator plt_iter;
      std::vector<plt_iter> sorted;
      sorted.resize(this->plt_call_stubs_.size());

      for (plt_iter cs = this->plt_call_stubs_.begin();
	   cs != this->plt_call_stubs_.end();
	   ++cs)
	sorted[cs->second.indx_] = cs;

      for (unsigned int i = 0; i < this->plt_call_stubs_.size(); ++i)
	{
	  plt_iter cs = sorted[i];
	  char add[10];
	  add[0] = 0;
	  if (cs->first.addend_ != 0)
	    sprintf(add, "+%x", static_cast<uint32_t>(cs->first.addend_));
	  char obj[10];
	  obj[0] = 0;
	  if (cs->first.object_)
	    {
	      const Powerpc_relobj<size, big_endian>* ppcobj = static_cast
		<const Powerpc_relobj<size, big_endian>*>(cs->first.object_);
	      sprintf(obj, "%x:", ppcobj->uniq());
	    }
	  char localname[9];
	  const char *symname;
	  if (cs->first.sym_ == NULL)
	    {
	      sprintf(localname, "%x", cs->first.locsym_);
	      symname = localname;
	    }
	  else if (this->targ_->is_tls_get_addr_opt(cs->first.sym_))
	    symname = this->targ_->tls_get_addr_opt()->name();
	  else
	    symname = cs->first.sym_->name();
	  char* name = new char[8 + 10 + strlen(obj) + strlen(symname) + strlen(add) + 1];
	  sprintf(name, "%08x.plt_call.%s%s%s", this->uniq_, obj, symname, add);
	  Address value
	    = this->stub_address() - this->address() + cs->second.off_;
	  unsigned int stub_size = this->plt_call_align(this->plt_call_size(cs));
	  this->targ_->define_local(symtab, name, this, value, stub_size);
	}
    }

  typedef typename Branch_stub_entries::iterator branch_iter;
  for (branch_iter bs = this->long_branch_stubs_.begin();
       bs != this->long_branch_stubs_.end();
       ++bs)
    {
      if (bs->second.save_res_)
	continue;

      char* name = new char[8 + 13 + 16 + 1];
      sprintf(name, "%08x.long_branch.%llx", this->uniq_,
	      static_cast<unsigned long long>(bs->first.dest_));
      Address value = (this->stub_address() - this->address()
		       + this->plt_size_ + bs->second.off_);
      bool need_lt = false;
      unsigned int stub_size = this->branch_stub_size(bs, &need_lt);
      this->targ_->define_local(symtab, name, this, value, stub_size);
    }
}

// Emit the start of a __tls_get_addr_opt plt call stub.

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::build_tls_opt_head(unsigned char** pp,
						 bool save_lr)
{
  unsigned char* p = *pp;
  if (size == 64)
    {
      write_insn<big_endian>(p, ld_11_3 + 0);
      p += 4;
      write_insn<big_endian>(p, ld_12_3 + 8);
      p += 4;
      write_insn<big_endian>(p, mr_0_3);
      p += 4;
      write_insn<big_endian>(p, cmpdi_11_0);
      p += 4;
      write_insn<big_endian>(p, add_3_12_13);
      p += 4;
      write_insn<big_endian>(p, beqlr);
      p += 4;
      write_insn<big_endian>(p, mr_3_0);
      p += 4;
      if (save_lr)
	{
	  write_insn<big_endian>(p, mflr_11);
	  p += 4;
	  write_insn<big_endian>(p, (std_11_1 + this->targ_->stk_linker()));
	  p += 4;
	}
    }
  else
    {
      write_insn<big_endian>(p, lwz_11_3 + 0);
      p += 4;
      write_insn<big_endian>(p, lwz_12_3 + 4);
      p += 4;
      write_insn<big_endian>(p, mr_0_3);
      p += 4;
      write_insn<big_endian>(p, cmpwi_11_0);
      p += 4;
      write_insn<big_endian>(p, add_3_12_2);
      p += 4;
      write_insn<big_endian>(p, beqlr);
      p += 4;
      write_insn<big_endian>(p, mr_3_0);
      p += 4;
      write_insn<big_endian>(p, nop);
      p += 4;
    }
  *pp = p;
}

// Emit the tail of a __tls_get_addr_opt plt call stub.

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::build_tls_opt_tail(unsigned char* p)
{
  write_insn<big_endian>(p, bctrl);
  p += 4;
  write_insn<big_endian>(p, ld_2_1 + this->targ_->stk_toc());
  p += 4;
  write_insn<big_endian>(p, ld_11_1 + this->targ_->stk_linker());
  p += 4;
  write_insn<big_endian>(p, mtlr_11);
  p += 4;
  write_insn<big_endian>(p, blr);
}

// Emit pc-relative plt call stub code.

template<bool big_endian>
static unsigned char*
build_power10_offset(unsigned char* p, uint64_t off, uint64_t odd, bool load)
{
  uint64_t insn;
  if (off - odd + (1ULL << 33) < 1ULL << 34)
    {
      off -= odd;
      if (odd)
	{
	  write_insn<big_endian>(p, nop);
	  p += 4;
	}
      if (load)
	insn = pld_12_pc;
      else
	insn = paddi_12_pc;
      insn |= d34(off);
      write_insn<big_endian>(p, insn >> 32);
      p += 4;
      write_insn<big_endian>(p, insn & 0xffffffff);
    }
  else if (off - (8 - odd) + (0x20002ULL << 32) < 0x40004ULL << 32)
    {
      off -= 8 - odd;
      write_insn<big_endian>(p, li_11_0 | (ha34(off) & 0xffff));
      p += 4;
      if (!odd)
	{
	  write_insn<big_endian>(p, sldi_11_11_34);
	  p += 4;
	}
      insn = paddi_12_pc | d34(off);
      write_insn<big_endian>(p, insn >> 32);
      p += 4;
      write_insn<big_endian>(p, insn & 0xffffffff);
      p += 4;
      if (odd)
	{
	  write_insn<big_endian>(p, sldi_11_11_34);
	  p += 4;
	}
      if (load)
	write_insn<big_endian>(p, ldx_12_11_12);
      else
	write_insn<big_endian>(p, add_12_11_12);
    }
  else
    {
      off -= odd + 8;
      write_insn<big_endian>(p, lis_11 | ((ha34(off) >> 16) & 0x3fff));
      p += 4;
      write_insn<big_endian>(p, ori_11_11_0 | (ha34(off) & 0xffff));
      p += 4;
      if (odd)
	{
	  write_insn<big_endian>(p, sldi_11_11_34);
	  p += 4;
	}
      insn = paddi_12_pc | d34(off);
      write_insn<big_endian>(p, insn >> 32);
      p += 4;
      write_insn<big_endian>(p, insn & 0xffffffff);
      p += 4;
      if (!odd)
	{
	  write_insn<big_endian>(p, sldi_11_11_34);
	  p += 4;
	}
      if (load)
	write_insn<big_endian>(p, ldx_12_11_12);
      else
	write_insn<big_endian>(p, add_12_11_12);
    }
  p += 4;
  return p;
}

// Gets the address of a label (1:) in r11 and builds an offset in r12,
// then adds it to r11 (LOAD false) or loads r12 from r11+r12 (LOAD true).
//	mflr	%r12
//	bcl	20,31,1f
// 1:	mflr	%r11
//	mtlr	%r12
//	lis	%r12,xxx-1b@highest
//	ori	%r12,%r12,xxx-1b@higher
//	sldi	%r12,%r12,32
//	oris	%r12,%r12,xxx-1b@high
//	ori	%r12,%r12,xxx-1b@l
//	add/ldx	%r12,%r11,%r12

template<bool big_endian>
static unsigned char*
build_notoc_offset(unsigned char* p, uint64_t off, bool load)
{
  write_insn<big_endian>(p, mflr_12);
  p += 4;
  write_insn<big_endian>(p, bcl_20_31);
  p += 4;
  write_insn<big_endian>(p, mflr_11);
  p += 4;
  write_insn<big_endian>(p, mtlr_12);
  p += 4;
  if (off + 0x8000 < 0x10000)
    {
      if (load)
	write_insn<big_endian>(p, ld_12_11 + l(off));
      else
	write_insn<big_endian>(p, addi_12_11 + l(off));
    }
  else if (off + 0x80008000ULL < 0x100000000ULL)
    {
      write_insn<big_endian>(p, addis_12_11 + ha(off));
      p += 4;
      if (load)
	write_insn<big_endian>(p, ld_12_12 + l(off));
      else
	write_insn<big_endian>(p, addi_12_12 + l(off));
    }
  else
    {
      if (off + 0x800000000000ULL < 0x1000000000000ULL)
	{
	  write_insn<big_endian>(p, li_12_0 + ((off >> 32) & 0xffff));
	  p += 4;
	}
      else
	{
	  write_insn<big_endian>(p, lis_12 + ((off >> 48) & 0xffff));
	  p += 4;
	  if (((off >> 32) & 0xffff) != 0)
	    {
	      write_insn<big_endian>(p, ori_12_12_0 + ((off >> 32) & 0xffff));
	      p += 4;
	    }
	}
      if (((off >> 32) & 0xffffffffULL) != 0)
	{
	  write_insn<big_endian>(p, sldi_12_12_32);
	  p += 4;
	}
      if (hi(off) != 0)
	{
	  write_insn<big_endian>(p, oris_12_12_0 + hi(off));
	  p += 4;
	}
      if (l(off) != 0)
	{
	  write_insn<big_endian>(p, ori_12_12_0 + l(off));
	  p += 4;
	}
      if (load)
	write_insn<big_endian>(p, ldx_12_11_12);
      else
	write_insn<big_endian>(p, add_12_11_12);
    }
  p += 4;
  return p;
}

// Size of a given plt call stub.

template<int size, bool big_endian>
unsigned int
Stub_table<size, big_endian>::plt_call_size(
    typename Plt_stub_entries::iterator p) const
{
  if (size == 32)
    {
      const Symbol* gsym = p->first.sym_;
      return (4 * 4
	      + (this->targ_->is_tls_get_addr_opt(gsym) ? 8 * 4 : 0));
    }

  const Output_data_plt_powerpc<size, big_endian>* plt;
  uint64_t plt_addr = this->plt_off(p, &plt);
  plt_addr += plt->address();
  if (this->targ_->power10_stubs()
      && this->targ_->power10_stubs_auto())
    {
      unsigned int bytes = 0;
      if (p->second.notoc_)
	{
	  if (this->targ_->is_tls_get_addr_opt(p->first.sym_))
	    bytes = 7 * 4;
	  uint64_t from = this->stub_address() + p->second.off_ + bytes;
	  uint64_t odd = from & 4;
	  uint64_t off = plt_addr - from;
	  if (off - odd + (1ULL << 33) < 1ULL << 34)
	    bytes += odd + 4 * 4;
	  else if (off - (8 - odd) + (0x20002ULL << 32) < 0x40004ULL << 32)
	    bytes += 7 * 4;
	  else
	    bytes += 8 * 4;
	  bytes = this->plt_call_align(bytes);
	}
      unsigned int tail = 0;
      if (p->second.toc_)
	{
	  p->second.tocoff_ = bytes;
	  if (this->targ_->is_tls_get_addr_opt(p->first.sym_))
	    {
	      bytes += 7 * 4;
	      if (p->second.r2save_ && !p->second.localentry0_)
		{
		  bytes += 2 * 4;
		  tail = 4 * 4;
		}
	    }
	  if (p->second.r2save_)
	    bytes += 4;
	  uint64_t got_addr = this->targ_->toc_pointer();
	  uint64_t off = plt_addr - got_addr;
	  bytes += 3 * 4 + 4 * (ha(off) != 0);
	}
      return bytes + tail;
    }
  else
    {
      unsigned int bytes = 0;
      unsigned int tail = 0;
      if (this->targ_->is_tls_get_addr_opt(p->first.sym_))
	{
	  bytes = 7 * 4;
	  if (p->second.r2save_ && !p->second.localentry0_)
	    {
	      bytes = 9 * 4;
	      tail = 4 * 4;
	    }
	}

      if (p->second.r2save_)
	bytes += 4;

      if (this->targ_->power10_stubs())
	{
	  uint64_t from = this->stub_address() + p->second.off_ + bytes;
	  uint64_t odd = from & 4;
	  uint64_t off = plt_addr - from;
	  if (off - odd + (1ULL << 33) < 1ULL << 34)
	    bytes += odd + 4 * 4;
	  else if (off - (8 - odd) + (0x20002ULL << 32) < 0x40004ULL << 32)
	    bytes += 7 * 4;
	  else
	    bytes += 8 * 4;
	  return bytes + tail;
	}

      if (p->second.notoc_)
	{
	  uint64_t from = this->stub_address() + p->second.off_ + bytes + 2 * 4;
	  uint64_t off = plt_addr - from;
	  if (off + 0x8000 < 0x10000)
	    bytes += 7 * 4;
	  else if (off + 0x80008000ULL < 0x100000000ULL)
	    bytes += 8 * 4;
	  else
	    {
	      bytes += 8 * 4;
	      if (off + 0x800000000000ULL >= 0x1000000000000ULL
		  && ((off >> 32) & 0xffff) != 0)
		bytes += 4;
	      if (((off >> 32) & 0xffffffffULL) != 0)
		bytes += 4;
	      if (hi(off) != 0)
		bytes += 4;
	      if (l(off) != 0)
		bytes += 4;
	    }
	  return bytes + tail;
	}

      uint64_t got_addr = this->targ_->toc_pointer();
      uint64_t off = plt_addr - got_addr;
      bytes += 3 * 4 + 4 * (ha(off) != 0);
      if (this->targ_->abiversion() < 2)
	{
	  bool static_chain = parameters->options().plt_static_chain();
	  bool thread_safe = this->targ_->plt_thread_safe();
	  bytes += (4
		    + 4 * static_chain
		    + 8 * thread_safe
		    + 4 * (ha(off + 8 + 8 * static_chain) != ha(off)));
	}
      return bytes + tail;
    }
}

// Return long branch stub size.

template<int size, bool big_endian>
unsigned int
Stub_table<size, big_endian>::branch_stub_size(
     typename Branch_stub_entries::iterator p,
     bool* need_lt)
{
  Address loc = this->stub_address() + this->last_plt_size_ + p->second.off_;
  if (size == 32)
    {
      if (p->first.dest_ - loc + (1 << 25) < 2 << 25)
	return 4;
      if (parameters->options().output_is_position_independent())
	return 32;
      return 16;
    }

  uint64_t off = p->first.dest_ - loc;
  unsigned int bytes = 0;
  if (p->second.notoc_)
    {
      if (this->targ_->power10_stubs())
	{
	  Address odd = loc & 4;
	  if (off + (1 << 25) < 2 << 25)
	    bytes = odd + 12;
	  else if (off - odd + (1ULL << 33) < 1ULL << 34)
	    bytes = odd + 16;
	  else if (off - (8 - odd) + (0x20002ULL << 32) < 0x40004ULL << 32)
	    bytes = 28;
	  else
	    bytes = 32;
	  if (!(p->second.toc_ && this->targ_->power10_stubs_auto()))
	    return bytes;
	  p->second.tocoff_ = bytes;
	}
      else
	{
	  off -= 8;
	  if (off + 0x8000 < 0x10000)
	    return 24;
	  if (off + 0x80008000ULL < 0x100000000ULL)
	    {
	      if (off + 24 + (1 << 25) < 2 << 25)
		return 28;
	      return 32;
	    }

	  bytes = 32;
	  if (off + 0x800000000000ULL >= 0x1000000000000ULL
	      && ((off >> 32) & 0xffff) != 0)
	    bytes += 4;
	  if (((off >> 32) & 0xffffffffULL) != 0)
	    bytes += 4;
	  if (hi(off) != 0)
	    bytes += 4;
	  if (l(off) != 0)
	    bytes += 4;
	  return bytes;
	}
    }

  off += elfcpp::ppc64_decode_local_entry(p->second.other_);
  if (off + (1 << 25) < 2 << 25)
    return bytes + 4;
  if (!this->targ_->power10_stubs()
      || (p->second.toc_ && this->targ_->power10_stubs_auto()))
    *need_lt = true;
  return bytes + 16;
}

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::plt_error(const Plt_stub_key& p)
{
  if (p.sym_)
    gold_error(_("linkage table error against `%s'"),
	       p.sym_->demangled_name().c_str());
  else
    gold_error(_("linkage table error against `%s:[local %u]'"),
	       p.object_->name().c_str(),
	       p.locsym_);
}

// Write out plt and long branch stub code.

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::do_write(Output_file* of)
{
  if (this->plt_call_stubs_.empty()
      && this->long_branch_stubs_.empty())
    return;

  const section_size_type start_off = this->offset();
  const section_size_type off = this->stub_offset();
  const section_size_type oview_size =
    convert_to_section_size_type(this->data_size() - (off - start_off));
  unsigned char* const oview = of->get_output_view(off, oview_size);
  unsigned char* p;

  if (size == 64
      && this->targ_->power10_stubs())
    {
      if (!this->plt_call_stubs_.empty())
	{
	  // Write out plt call stubs.
	  typename Plt_stub_entries::const_iterator cs;
	  for (cs = this->plt_call_stubs_.begin();
	       cs != this->plt_call_stubs_.end();
	       ++cs)
	    {
	      p = oview + cs->second.off_;
	      const Output_data_plt_powerpc<size, big_endian>* plt;
	      Address pltoff = this->plt_off(cs, &plt);
	      Address plt_addr = pltoff + plt->address();
	      if (this->targ_->power10_stubs_auto())
		{
		  if (cs->second.notoc_)
		    {
		      if (this->targ_->is_tls_get_addr_opt(cs->first.sym_))
			this->build_tls_opt_head(&p, false);
		      Address from = this->stub_address() + (p - oview);
		      Address delta = plt_addr - from;
		      p = build_power10_offset<big_endian>(p, delta, from & 4,
							   true);
		      write_insn<big_endian>(p, mtctr_12);
		      p += 4;
		      write_insn<big_endian>(p, bctr);
		      p += 4;
		      p = oview + this->plt_call_align(p - oview);
		    }
		  if (cs->second.toc_)
		    {
		      if (this->targ_->is_tls_get_addr_opt(cs->first.sym_))
			{
			  bool save_lr
			    = cs->second.r2save_ && !cs->second.localentry0_;
			  this->build_tls_opt_head(&p, save_lr);
			}
		      Address got_addr = this->targ_->toc_pointer();
		      Address off = plt_addr - got_addr;

		      if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
			this->plt_error(cs->first);

		      if (cs->second.r2save_)
			{
			  write_insn<big_endian>(p, std_2_1 + this->targ_->stk_toc());
			  p += 4;
			}
		      if (ha(off) != 0)
			{
			  write_insn<big_endian>(p, addis_12_2 + ha(off));
			  p += 4;
			  write_insn<big_endian>(p, ld_12_12 + l(off));
			  p += 4;
			}
		      else
			{
			  write_insn<big_endian>(p, ld_12_2 + l(off));
			  p += 4;
			}
		      write_insn<big_endian>(p, mtctr_12);
		      p += 4;
		      if (cs->second.r2save_
			  && !cs->second.localentry0_
			  && this->targ_->is_tls_get_addr_opt(cs->first.sym_))
			this->build_tls_opt_tail(p);
		      else
			write_insn<big_endian>(p, bctr);
		    }
		}
	      else
		{
		  if (this->targ_->is_tls_get_addr_opt(cs->first.sym_))
		    {
		      bool save_lr
			= cs->second.r2save_ && !cs->second.localentry0_;
		      this->build_tls_opt_head(&p, save_lr);
		    }
		  if (cs->second.r2save_)
		    {
		      write_insn<big_endian>(p, std_2_1 + this->targ_->stk_toc());
		      p += 4;
		    }
		  Address from = this->stub_address() + (p - oview);
		  Address delta = plt_addr - from;
		  p = build_power10_offset<big_endian>(p, delta, from & 4, true);
		  write_insn<big_endian>(p, mtctr_12);
		  p += 4;
		  if (cs->second.r2save_
		      && !cs->second.localentry0_
		      && this->targ_->is_tls_get_addr_opt(cs->first.sym_))
		    this->build_tls_opt_tail(p);
		  else
		    write_insn<big_endian>(p, bctr);
		}
	    }
	}

      // Write out long branch stubs.
      typename Branch_stub_entries::const_iterator bs;
      for (bs = this->long_branch_stubs_.begin();
	   bs != this->long_branch_stubs_.end();
	   ++bs)
	{
	  if (bs->second.save_res_)
	    continue;
	  Address off = this->plt_size_ + bs->second.off_;
	  p = oview + off;
	  Address loc = this->stub_address() + off;
	  Address delta = bs->first.dest_ - loc;
	  if (this->targ_->power10_stubs_auto())
	    {
	      if (bs->second.notoc_)
		{
		  unsigned char* startp = p;
		  p = build_power10_offset<big_endian>(p, delta,
						       loc & 4, false);
		  delta -= p - startp;
		  startp = p;
		  if (delta + (1 << 25) < 2 << 25)
		    write_insn<big_endian>(p, b | (delta & 0x3fffffc));
		  else
		    {
		      write_insn<big_endian>(p, mtctr_12);
		      p += 4;
		      write_insn<big_endian>(p, bctr);
		    }
		  p += 4;
		  delta -= p - startp;
		}
	      if (bs->second.toc_)
		{
		  delta += elfcpp::ppc64_decode_local_entry(bs->second.other_);
		  if (delta + (1 << 25) >= 2 << 25)
		    {
		      Address brlt_addr
			= this->targ_->find_branch_lookup_table(bs->first.dest_);
		      gold_assert(brlt_addr != invalid_address);
		      brlt_addr += this->targ_->brlt_section()->address();
		      Address got_addr = this->targ_->toc_pointer();
		      Address brltoff = brlt_addr - got_addr;
		      if (ha(brltoff) == 0)
			{
			  write_insn<big_endian>(p, ld_12_2 + l(brltoff));
			  p += 4;
			}
		      else
			{
			  write_insn<big_endian>(p, addis_12_2 + ha(brltoff));
			  p += 4;
			  write_insn<big_endian>(p, ld_12_12 + l(brltoff));
			  p += 4;
			}
		    }
		  if (delta + (1 << 25) < 2 << 25)
		    write_insn<big_endian>(p, b | (delta & 0x3fffffc));
		  else
		    {
		      write_insn<big_endian>(p, mtctr_12);
		      p += 4;
		      write_insn<big_endian>(p, bctr);
		    }
		}
	    }
	  else
	    {
	      if (!bs->second.notoc_)
		delta += elfcpp::ppc64_decode_local_entry(bs->second.other_);
	      if (bs->second.notoc_ || delta + (1 << 25) >= 2 << 25)
		{
		  unsigned char* startp = p;
		  p = build_power10_offset<big_endian>(p, delta,
						       loc & 4, false);
		  delta -= p - startp;
		}
	      if (delta + (1 << 25) < 2 << 25)
		write_insn<big_endian>(p, b | (delta & 0x3fffffc));
	      else
		{
		  write_insn<big_endian>(p, mtctr_12);
		  p += 4;
		  write_insn<big_endian>(p, bctr);
		}
	    }
	}
    }
  else if (size == 64)
    {

      if (!this->plt_call_stubs_.empty()
	  && this->targ_->abiversion() >= 2)
	{
	  // Write out plt call stubs for ELFv2.
	  typename Plt_stub_entries::const_iterator cs;
	  for (cs = this->plt_call_stubs_.begin();
	       cs != this->plt_call_stubs_.end();
	       ++cs)
	    {
	      const Output_data_plt_powerpc<size, big_endian>* plt;
	      Address pltoff = this->plt_off(cs, &plt);
	      Address plt_addr = pltoff + plt->address();

	      p = oview + cs->second.off_;
	      if (this->targ_->is_tls_get_addr_opt(cs->first.sym_))
		{
		  bool save_lr = cs->second.r2save_ && !cs->second.localentry0_;
		  this->build_tls_opt_head(&p, save_lr);
		}
	      if (cs->second.r2save_)
		{
		  write_insn<big_endian>(p, std_2_1 + this->targ_->stk_toc());
		  p += 4;
		}
	      if (cs->second.notoc_)
		{
		  Address from = this->stub_address() + (p - oview) + 8;
		  Address off = plt_addr - from;
		  p = build_notoc_offset<big_endian>(p, off, true);
		}
	      else
		{
		  Address got_addr = this->targ_->toc_pointer();
		  Address off = plt_addr - got_addr;

		  if (off + 0x80008000 > 0xffffffff || (off & 7) != 0)
		    this->plt_error(cs->first);

		  if (ha(off) != 0)
		    {
		      write_insn<big_endian>(p, addis_12_2 + ha(off));
		      p += 4;
		      write_insn<big_endian>(p, ld_12_12 + l(off));
		      p += 4;
		    }
		  else
		    {
		      write_insn<big_endian>(p, ld_12_2 + l(off));
		      p += 4;
		    }
		}
	      write_insn<big_endian>(p, mtctr_12);
	      p += 4;
	      if (cs->second.r2save_
		  && !cs->second.localentry0_
		  && this->targ_->is_tls_get_addr_opt(cs->first.sym_))
		this->build_tls_opt_tail(p);
	      else
		write_insn<big_endian>(p, bctr);
	    }
	}
      else if (!this->plt_call_stubs_.empty())
	{
	  // Write out plt call stubs for ELFv1.
	  typename Plt_stub_entries::const_iterator cs;
	  for (cs = this->plt_call_stubs_.begin();
	       cs != this->plt_call_stubs_.end();
	       ++cs)
	    {
	      const Output_data_plt_powerpc<size, big_endian>* plt;
	      Address pltoff = this->plt_off(cs, &plt);
	      Address plt_addr = pltoff + plt->address();
	      Address got_addr = this->targ_->toc_pointer();
	      Address off = plt_addr - got_addr;

	      if (off + 0x80008000 > 0xffffffff || (off & 7) != 0
		  || cs->second.notoc_)
		this->plt_error(cs->first);

	      bool static_chain = parameters->options().plt_static_chain();
	      bool thread_safe = this->targ_->plt_thread_safe();
	      bool use_fake_dep = false;
	      Address cmp_branch_off = 0;
	      if (thread_safe)
		{
		  unsigned int pltindex
		    = ((pltoff - this->targ_->first_plt_entry_offset())
		       / this->targ_->plt_entry_size());
		  Address glinkoff
		    = (this->targ_->glink_section()->pltresolve_size()
		       + pltindex * 8);
		  if (pltindex > 32768)
		    glinkoff += (pltindex - 32768) * 4;
		  Address to
		    = this->targ_->glink_section()->address() + glinkoff;
		  Address from
		    = (this->stub_address() + cs->second.off_ + 20
		       + 4 * cs->second.r2save_
		       + 4 * (ha(off) != 0)
		       + 4 * (ha(off + 8 + 8 * static_chain) != ha(off))
		       + 4 * static_chain);
		  cmp_branch_off = to - from;
		  use_fake_dep = cmp_branch_off + (1 << 25) >= (1 << 26);
		}

	      p = oview + cs->second.off_;
	      if (this->targ_->is_tls_get_addr_opt(cs->first.sym_))
		{
		  bool save_lr = cs->second.r2save_ && !cs->second.localentry0_;
		  this->build_tls_opt_head(&p, save_lr);
		  use_fake_dep = thread_safe;
		}
	      if (cs->second.r2save_)
		{
		  write_insn<big_endian>(p, std_2_1 + this->targ_->stk_toc());
		  p += 4;
		}
	      if (ha(off) != 0)
		{
		  write_insn<big_endian>(p, addis_11_2 + ha(off));
		  p += 4;
		  write_insn<big_endian>(p, ld_12_11 + l(off));
		  p += 4;
		  if (ha(off + 8 + 8 * static_chain) != ha(off))
		    {
		      write_insn<big_endian>(p, addi_11_11 + l(off));
		      p += 4;
		      off = 0;
		    }
		  write_insn<big_endian>(p, mtctr_12);
		  p += 4;
		  if (use_fake_dep)
		    {
		      write_insn<big_endian>(p, xor_2_12_12);
		      p += 4;
		      write_insn<big_endian>(p, add_11_11_2);
		      p += 4;
		    }
		  write_insn<big_endian>(p, ld_2_11 + l(off + 8));
		  p += 4;
		  if (static_chain)
		    {
		      write_insn<big_endian>(p, ld_11_11 + l(off + 16));
		      p += 4;
		    }
		}
	      else
		{
		  write_insn<big_endian>(p, ld_12_2 + l(off));
		  p += 4;
		  if (ha(off + 8 + 8 * static_chain) != ha(off))
		    {
		      write_insn<big_endian>(p, addi_2_2 + l(off));
		      p += 4;
		      off = 0;
		    }
		  write_insn<big_endian>(p, mtctr_12);
		  p += 4;
		  if (use_fake_dep)
		    {
		      write_insn<big_endian>(p, xor_11_12_12);
		      p += 4;
		      write_insn<big_endian>(p, add_2_2_11);
		      p += 4;
		    }
		  if (static_chain)
		    {
		      write_insn<big_endian>(p, ld_11_2 + l(off + 16));
		      p += 4;
		    }
		  write_insn<big_endian>(p, ld_2_2 + l(off + 8));
		  p += 4;
		}
	      if (cs->second.r2save_
		  && !cs->second.localentry0_
		  && this->targ_->is_tls_get_addr_opt(cs->first.sym_))
		this->build_tls_opt_tail(p);
	      else if (thread_safe && !use_fake_dep)
		{
		  write_insn<big_endian>(p, cmpldi_2_0);
		  p += 4;
		  write_insn<big_endian>(p, bnectr_p4);
		  p += 4;
		  write_insn<big_endian>(p, b | (cmp_branch_off & 0x3fffffc));
		}
	      else
		write_insn<big_endian>(p, bctr);
	    }
	}

      // Write out long branch stubs.
      typename Branch_stub_entries::const_iterator bs;
      for (bs = this->long_branch_stubs_.begin();
	   bs != this->long_branch_stubs_.end();
	   ++bs)
	{
	  if (bs->second.save_res_)
	    continue;
	  Address off = this->plt_size_ + bs->second.off_;
	  p = oview + off;
	  Address loc = this->stub_address() + off;
	  Address delta = bs->first.dest_ - loc;
	  if (!bs->second.notoc_)
	    delta += elfcpp::ppc64_decode_local_entry(bs->second.other_);
	  if (bs->second.notoc_)
	    {
	      unsigned char* startp = p;
	      p = build_notoc_offset<big_endian>(p, off, false);
	      delta -= p - startp;
	    }
	  else if (delta + (1 << 25) >= 2 << 25)
	    {
	      Address brlt_addr
		= this->targ_->find_branch_lookup_table(bs->first.dest_);
	      gold_assert(brlt_addr != invalid_address);
	      brlt_addr += this->targ_->brlt_section()->address();
	      Address got_addr = this->targ_->toc_pointer();
	      Address brltoff = brlt_addr - got_addr;
	      if (ha(brltoff) == 0)
		{
		  write_insn<big_endian>(p, ld_12_2 + l(brltoff));
		  p += 4;
		}
	      else
		{
		  write_insn<big_endian>(p, addis_12_2 + ha(brltoff));
		  p += 4;
		  write_insn<big_endian>(p, ld_12_12 + l(brltoff));
		  p += 4;
		}
	    }
	  if (delta + (1 << 25) < 2 << 25)
	    write_insn<big_endian>(p, b | (delta & 0x3fffffc));
	  else
	    {
	      write_insn<big_endian>(p, mtctr_12);
	      p += 4;
	      write_insn<big_endian>(p, bctr);
	    }
	}
    }
  else // size == 32
    {
      if (!this->plt_call_stubs_.empty())
	{
	  // The address of _GLOBAL_OFFSET_TABLE_.
	  Address g_o_t = invalid_address;

	  // Write out plt call stubs.
	  typename Plt_stub_entries::const_iterator cs;
	  for (cs = this->plt_call_stubs_.begin();
	       cs != this->plt_call_stubs_.end();
	       ++cs)
	    {
	      const Output_data_plt_powerpc<size, big_endian>* plt;
	      Address plt_addr = this->plt_off(cs, &plt);
	      plt_addr += plt->address();

	      p = oview + cs->second.off_;
	      if (this->targ_->is_tls_get_addr_opt(cs->first.sym_))
		this->build_tls_opt_head(&p, false);
	      if (parameters->options().output_is_position_independent())
		{
		  Address got_addr;
		  const Powerpc_relobj<size, big_endian>* ppcobj
		    = (static_cast<const Powerpc_relobj<size, big_endian>*>
		       (cs->first.object_));
		  if (ppcobj != NULL && cs->first.addend_ >= 32768)
		    {
		      unsigned int got2 = ppcobj->got2_shndx();
		      got_addr = ppcobj->get_output_section_offset(got2);
		      gold_assert(got_addr != invalid_address);
		      got_addr += (ppcobj->output_section(got2)->address()
				   + cs->first.addend_);
		    }
		  else
		    {
		      if (g_o_t == invalid_address)
			g_o_t = this->targ_->toc_pointer();
		      got_addr = g_o_t;
		    }

		  Address off = plt_addr - got_addr;
		  if (ha(off) == 0)
		    write_insn<big_endian>(p, lwz_11_30 + l(off));
		  else
		    {
		      write_insn<big_endian>(p, addis_11_30 + ha(off));
		      p += 4;
		      write_insn<big_endian>(p, lwz_11_11 + l(off));
		    }
		}
	      else
		{
		  write_insn<big_endian>(p, lis_11 + ha(plt_addr));
		  p += 4;
		  write_insn<big_endian>(p, lwz_11_11 + l(plt_addr));
		}
	      p += 4;
	      write_insn<big_endian>(p, mtctr_11);
	      p += 4;
	      write_insn<big_endian>(p, bctr);
	    }
	}

      // Write out long branch stubs.
      typename Branch_stub_entries::const_iterator bs;
      for (bs = this->long_branch_stubs_.begin();
	   bs != this->long_branch_stubs_.end();
	   ++bs)
	{
	  if (bs->second.save_res_)
	    continue;
	  Address off = this->plt_size_ + bs->second.off_;
	  p = oview + off;
	  Address loc = this->stub_address() + off;
	  Address delta = bs->first.dest_ - loc;
	  if (delta + (1 << 25) < 2 << 25)
	    write_insn<big_endian>(p, b | (delta & 0x3fffffc));
	  else if (!parameters->options().output_is_position_independent())
	    {
	      write_insn<big_endian>(p, lis_12 + ha(bs->first.dest_));
	      p += 4;
	      write_insn<big_endian>(p, addi_12_12 + l(bs->first.dest_));
	    }
	  else
	    {
	      delta -= 8;
	      write_insn<big_endian>(p, mflr_0);
	      p += 4;
	      write_insn<big_endian>(p, bcl_20_31);
	      p += 4;
	      write_insn<big_endian>(p, mflr_12);
	      p += 4;
	      write_insn<big_endian>(p, addis_12_12 + ha(delta));
	      p += 4;
	      write_insn<big_endian>(p, addi_12_12 + l(delta));
	      p += 4;
	      write_insn<big_endian>(p, mtlr_0);
	    }
	  p += 4;
	  write_insn<big_endian>(p, mtctr_12);
	  p += 4;
	  write_insn<big_endian>(p, bctr);
	}
    }
  if (this->need_save_res_)
    {
      p = oview + this->plt_size_ + this->branch_size_;
      memcpy (p, this->targ_->savres_section()->contents(),
	      this->targ_->savres_section()->data_size());
    }
}

// Write out .glink.

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

  // The base address of the .plt section.
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  Address plt_base = this->targ_->plt_section()->address();

  if (size == 64)
    {
      if (this->end_branch_table_ != 0)
	{
	  // Write pltresolve stub.
	  p = oview;
	  Address after_bcl = this->address() + 16;
	  Address pltoff = plt_base - after_bcl;

	  elfcpp::Swap<64, big_endian>::writeval(p, pltoff),	p += 8;

	  if (this->targ_->abiversion() < 2)
	    {
	      write_insn<big_endian>(p, mflr_12),		p += 4;
	      write_insn<big_endian>(p, bcl_20_31),		p += 4;
	      write_insn<big_endian>(p, mflr_11),		p += 4;
	      write_insn<big_endian>(p, ld_2_11 + l(-16)),	p += 4;
	      write_insn<big_endian>(p, mtlr_12),		p += 4;
	      write_insn<big_endian>(p, add_11_2_11),		p += 4;
	      write_insn<big_endian>(p, ld_12_11 + 0),		p += 4;
	      write_insn<big_endian>(p, ld_2_11 + 8),		p += 4;
	      write_insn<big_endian>(p, mtctr_12),		p += 4;
	      write_insn<big_endian>(p, ld_11_11 + 16),		p += 4;
	    }
	  else
	    {
	      if (this->targ_->has_localentry0())
		{
		  write_insn<big_endian>(p, std_2_1 + 24),	p += 4;
		}
	      write_insn<big_endian>(p, mflr_0),		p += 4;
	      write_insn<big_endian>(p, bcl_20_31),		p += 4;
	      write_insn<big_endian>(p, mflr_11),		p += 4;
	      write_insn<big_endian>(p, mtlr_0),		p += 4;
	      if (this->targ_->has_localentry0())
		{
		  write_insn<big_endian>(p, ld_0_11 + l(-20)),	p += 4;
		}
	      else
		{
		  write_insn<big_endian>(p, ld_0_11 + l(-16)),	p += 4;
		}
	      write_insn<big_endian>(p, sub_12_12_11),		p += 4;
	      write_insn<big_endian>(p, add_11_0_11),		p += 4;
	      write_insn<big_endian>(p, addi_0_12 + l(-44)),	p += 4;
	      write_insn<big_endian>(p, ld_12_11 + 0),		p += 4;
	      write_insn<big_endian>(p, srdi_0_0_2),		p += 4;
	      write_insn<big_endian>(p, mtctr_12),		p += 4;
	      write_insn<big_endian>(p, ld_11_11 + 8),		p += 4;
	    }
	  write_insn<big_endian>(p, bctr),			p += 4;
	  gold_assert(p == oview + this->pltresolve_size());

	  // Write lazy link call stubs.
	  uint32_t indx = 0;
	  while (p < oview + this->end_branch_table_)
	    {
	      if (this->targ_->abiversion() < 2)
		{
		  if (indx < 0x8000)
		    {
		      write_insn<big_endian>(p, li_0_0 + indx),		p += 4;
		    }
		  else
		    {
		      write_insn<big_endian>(p, lis_0 + hi(indx)),	p += 4;
		      write_insn<big_endian>(p, ori_0_0_0 + l(indx)),	p += 4;
		    }
		}
	      uint32_t branch_off = 8 - (p - oview);
	      write_insn<big_endian>(p, b + (branch_off & 0x3fffffc)),	p += 4;
	      indx++;
	    }
	}

      Address plt_base = this->targ_->plt_section()->address();
      Address iplt_base = invalid_address;
      unsigned int global_entry_off = this->global_entry_off();
      Address global_entry_base = this->address() + global_entry_off;
      typename Global_entry_stub_entries::const_iterator ge;
      for (ge = this->global_entry_stubs_.begin();
	   ge != this->global_entry_stubs_.end();
	   ++ge)
	{
	  p = oview + global_entry_off + ge->second;
	  Address plt_addr = ge->first->plt_offset();
	  if (ge->first->type() == elfcpp::STT_GNU_IFUNC
	      && ge->first->can_use_relative_reloc(false))
	    {
	      if (iplt_base == invalid_address)
		iplt_base = this->targ_->iplt_section()->address();
	      plt_addr += iplt_base;
	    }
	  else
	    plt_addr += plt_base;
	  Address my_addr = global_entry_base + ge->second;
	  Address off = plt_addr - my_addr;

	  if (off + 0x80008000 > 0xffffffff || (off & 3) != 0)
	    gold_error(_("linkage table error against `%s'"),
		       ge->first->demangled_name().c_str());

	  write_insn<big_endian>(p, addis_12_12 + ha(off)),	p += 4;
	  write_insn<big_endian>(p, ld_12_12 + l(off)),		p += 4;
	  write_insn<big_endian>(p, mtctr_12),			p += 4;
	  write_insn<big_endian>(p, bctr);
	}
    }
  else
    {
      // The address of _GLOBAL_OFFSET_TABLE_.
      Address g_o_t = this->targ_->toc_pointer();

      // Write out pltresolve branch table.
      p = oview;
      unsigned int the_end = oview_size - this->pltresolve_size();
      unsigned char* end_p = oview + the_end;
      while (p < end_p - 8 * 4)
	write_insn<big_endian>(p, b + end_p - p), p += 4;
      while (p < end_p)
	write_insn<big_endian>(p, nop), p += 4;

      // Write out pltresolve call stub.
      end_p = oview + oview_size;
      if (parameters->options().output_is_position_independent())
	{
	  Address res0_off = 0;
	  Address after_bcl_off = the_end + 12;
	  Address bcl_res0 = after_bcl_off - res0_off;

	  write_insn<big_endian>(p, addis_11_11 + ha(bcl_res0));
	  p += 4;
	  write_insn<big_endian>(p, mflr_0);
	  p += 4;
	  write_insn<big_endian>(p, bcl_20_31);
	  p += 4;
	  write_insn<big_endian>(p, addi_11_11 + l(bcl_res0));
	  p += 4;
	  write_insn<big_endian>(p, mflr_12);
	  p += 4;
	  write_insn<big_endian>(p, mtlr_0);
	  p += 4;
	  write_insn<big_endian>(p, sub_11_11_12);
	  p += 4;

	  Address got_bcl = g_o_t + 4 - (after_bcl_off + this->address());

	  write_insn<big_endian>(p, addis_12_12 + ha(got_bcl));
	  p += 4;
	  if (ha(got_bcl) == ha(got_bcl + 4))
	    {
	      write_insn<big_endian>(p, lwz_0_12 + l(got_bcl));
	      p += 4;
	      write_insn<big_endian>(p, lwz_12_12 + l(got_bcl + 4));
	    }
	  else
	    {
	      write_insn<big_endian>(p, lwzu_0_12 + l(got_bcl));
	      p += 4;
	      write_insn<big_endian>(p, lwz_12_12 + 4);
	    }
	  p += 4;
	  write_insn<big_endian>(p, mtctr_0);
	  p += 4;
	  write_insn<big_endian>(p, add_0_11_11);
	  p += 4;
	  write_insn<big_endian>(p, add_11_0_11);
	}
      else
	{
	  Address res0 = this->address();

	  write_insn<big_endian>(p, lis_12 + ha(g_o_t + 4));
	  p += 4;
	  write_insn<big_endian>(p, addis_11_11 + ha(-res0));
	  p += 4;
	  if (ha(g_o_t + 4) == ha(g_o_t + 8))
	    write_insn<big_endian>(p, lwz_0_12 + l(g_o_t + 4));
	  else
	    write_insn<big_endian>(p, lwzu_0_12 + l(g_o_t + 4));
	  p += 4;
	  write_insn<big_endian>(p, addi_11_11 + l(-res0));
	  p += 4;
	  write_insn<big_endian>(p, mtctr_0);
	  p += 4;
	  write_insn<big_endian>(p, add_0_11_11);
	  p += 4;
	  if (ha(g_o_t + 4) == ha(g_o_t + 8))
	    write_insn<big_endian>(p, lwz_12_12 + l(g_o_t + 8));
	  else
	    write_insn<big_endian>(p, lwz_12_12 + 4);
	  p += 4;
	  write_insn<big_endian>(p, add_11_0_11);
	}
      p += 4;
      write_insn<big_endian>(p, bctr);
      p += 4;
      while (p < end_p)
	{
	  write_insn<big_endian>(p, nop);
	  p += 4;
	}
    }

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


// A class to handle linker generated save/restore functions.

template<int size, bool big_endian>
class Output_data_save_res : public Output_section_data_build
{
 public:
  Output_data_save_res(Symbol_table* symtab);

  const unsigned char*
  contents() const
  {
    return contents_;
  }

 protected:
  // Write to a map file.
  void
  do_print_to_mapfile(Mapfile* mapfile) const
  { mapfile->print_output_data(this, _("** save/restore")); }

  void
  do_write(Output_file*);

 private:
  // The maximum size of save/restore contents.
  static const unsigned int savres_max = 218*4;

  void
  savres_define(Symbol_table* symtab,
		const char *name,
		unsigned int lo, unsigned int hi,
		unsigned char* write_ent(unsigned char*, int),
		unsigned char* write_tail(unsigned char*, int));

  unsigned char *contents_;
};

template<bool big_endian>
static unsigned char*
savegpr0(unsigned char* p, int r)
{
  uint32_t insn = std_0_1 + (r << 21) + (1 << 16) - (32 - r) * 8;
  write_insn<big_endian>(p, insn);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
savegpr0_tail(unsigned char* p, int r)
{
  p = savegpr0<big_endian>(p, r);
  uint32_t insn = std_0_1 + 16;
  write_insn<big_endian>(p, insn);
  p = p + 4;
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restgpr0(unsigned char* p, int r)
{
  uint32_t insn = ld_0_1 + (r << 21) + (1 << 16) - (32 - r) * 8;
  write_insn<big_endian>(p, insn);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restgpr0_tail(unsigned char* p, int r)
{
  uint32_t insn = ld_0_1 + 16;
  write_insn<big_endian>(p, insn);
  p = p + 4;
  p = restgpr0<big_endian>(p, r);
  write_insn<big_endian>(p, mtlr_0);
  p = p + 4;
  if (r == 29)
    {
      p = restgpr0<big_endian>(p, 30);
      p = restgpr0<big_endian>(p, 31);
    }
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
savegpr1(unsigned char* p, int r)
{
  uint32_t insn = std_0_12 + (r << 21) + (1 << 16) - (32 - r) * 8;
  write_insn<big_endian>(p, insn);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
savegpr1_tail(unsigned char* p, int r)
{
  p = savegpr1<big_endian>(p, r);
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restgpr1(unsigned char* p, int r)
{
  uint32_t insn = ld_0_12 + (r << 21) + (1 << 16) - (32 - r) * 8;
  write_insn<big_endian>(p, insn);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restgpr1_tail(unsigned char* p, int r)
{
  p = restgpr1<big_endian>(p, r);
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
savefpr(unsigned char* p, int r)
{
  uint32_t insn = stfd_0_1 + (r << 21) + (1 << 16) - (32 - r) * 8;
  write_insn<big_endian>(p, insn);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
savefpr0_tail(unsigned char* p, int r)
{
  p = savefpr<big_endian>(p, r);
  write_insn<big_endian>(p, std_0_1 + 16);
  p = p + 4;
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restfpr(unsigned char* p, int r)
{
  uint32_t insn = lfd_0_1 + (r << 21) + (1 << 16) - (32 - r) * 8;
  write_insn<big_endian>(p, insn);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restfpr0_tail(unsigned char* p, int r)
{
  write_insn<big_endian>(p, ld_0_1 + 16);
  p = p + 4;
  p = restfpr<big_endian>(p, r);
  write_insn<big_endian>(p, mtlr_0);
  p = p + 4;
  if (r == 29)
    {
      p = restfpr<big_endian>(p, 30);
      p = restfpr<big_endian>(p, 31);
    }
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
savefpr1_tail(unsigned char* p, int r)
{
  p = savefpr<big_endian>(p, r);
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restfpr1_tail(unsigned char* p, int r)
{
  p = restfpr<big_endian>(p, r);
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
savevr(unsigned char* p, int r)
{
  uint32_t insn = li_12_0 + (1 << 16) - (32 - r) * 16;
  write_insn<big_endian>(p, insn);
  p = p + 4;
  insn = stvx_0_12_0 + (r << 21);
  write_insn<big_endian>(p, insn);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
savevr_tail(unsigned char* p, int r)
{
  p = savevr<big_endian>(p, r);
  write_insn<big_endian>(p, blr);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restvr(unsigned char* p, int r)
{
  uint32_t insn = li_12_0 + (1 << 16) - (32 - r) * 16;
  write_insn<big_endian>(p, insn);
  p = p + 4;
  insn = lvx_0_12_0 + (r << 21);
  write_insn<big_endian>(p, insn);
  return p + 4;
}

template<bool big_endian>
static unsigned char*
restvr_tail(unsigned char* p, int r)
{
  p = restvr<big_endian>(p, r);
  write_insn<big_endian>(p, blr);
  return p + 4;
}


template<int size, bool big_endian>
Output_data_save_res<size, big_endian>::Output_data_save_res(
    Symbol_table* symtab)
  : Output_section_data_build(4),
    contents_(NULL)
{
  this->savres_define(symtab,
		      "_savegpr0_", 14, 31,
		      savegpr0<big_endian>, savegpr0_tail<big_endian>);
  this->savres_define(symtab,
		      "_restgpr0_", 14, 29,
		      restgpr0<big_endian>, restgpr0_tail<big_endian>);
  this->savres_define(symtab,
		      "_restgpr0_", 30, 31,
		      restgpr0<big_endian>, restgpr0_tail<big_endian>);
  this->savres_define(symtab,
		      "_savegpr1_", 14, 31,
		      savegpr1<big_endian>, savegpr1_tail<big_endian>);
  this->savres_define(symtab,
		      "_restgpr1_", 14, 31,
		      restgpr1<big_endian>, restgpr1_tail<big_endian>);
  this->savres_define(symtab,
		      "_savefpr_", 14, 31,
		      savefpr<big_endian>, savefpr0_tail<big_endian>);
  this->savres_define(symtab,
		      "_restfpr_", 14, 29,
		      restfpr<big_endian>, restfpr0_tail<big_endian>);
  this->savres_define(symtab,
		      "_restfpr_", 30, 31,
		      restfpr<big_endian>, restfpr0_tail<big_endian>);
  this->savres_define(symtab,
		      "._savef", 14, 31,
		      savefpr<big_endian>, savefpr1_tail<big_endian>);
  this->savres_define(symtab,
		      "._restf", 14, 31,
		      restfpr<big_endian>, restfpr1_tail<big_endian>);
  this->savres_define(symtab,
		      "_savevr_", 20, 31,
		      savevr<big_endian>, savevr_tail<big_endian>);
  this->savres_define(symtab,
		      "_restvr_", 20, 31,
		      restvr<big_endian>, restvr_tail<big_endian>);
}

template<int size, bool big_endian>
void
Output_data_save_res<size, big_endian>::savres_define(
    Symbol_table* symtab,
    const char *name,
    unsigned int lo, unsigned int hi,
    unsigned char* write_ent(unsigned char*, int),
    unsigned char* write_tail(unsigned char*, int))
{
  size_t len = strlen(name);
  bool writing = false;
  char sym[16];

  memcpy(sym, name, len);
  sym[len + 2] = 0;

  for (unsigned int i = lo; i <= hi; i++)
    {
      sym[len + 0] = i / 10 + '0';
      sym[len + 1] = i % 10 + '0';
      Symbol* gsym = symtab->lookup(sym);
      bool refd = gsym != NULL && gsym->is_undefined();
      writing = writing || refd;
      if (writing)
	{
	  if (this->contents_ == NULL)
	    this->contents_ = new unsigned char[this->savres_max];

	  section_size_type value = this->current_data_size();
	  unsigned char* p = this->contents_ + value;
	  if (i != hi)
	    p = write_ent(p, i);
	  else
	    p = write_tail(p, i);
	  section_size_type cur_size = p - this->contents_;
	  this->set_current_data_size(cur_size);
	  if (refd)
	    symtab->define_in_output_data(sym, NULL, Symbol_table::PREDEFINED,
					  this, value, cur_size - value,
					  elfcpp::STT_FUNC, elfcpp::STB_GLOBAL,
					  elfcpp::STV_HIDDEN, 0, false, false);
	}
    }
}

// Write out save/restore.

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


// Create the glink section.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_glink_section(Layout* layout)
{
  if (this->glink_ == NULL)
    {
      this->glink_ = new Output_data_glink<size, big_endian>(this);
      this->glink_->add_eh_frame(layout);
      layout->add_output_section_data(".text", elfcpp::SHT_PROGBITS,
				      elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR,
				      this->glink_, ORDER_TEXT, false);
    }
}

// Create a PLT entry for a global symbol.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_plt_entry(Symbol_table* symtab,
						 Layout* layout,
						 Symbol* gsym)
{
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    {
      if (this->iplt_ == NULL)
	this->make_iplt_section(symtab, layout);
      this->iplt_->add_ifunc_entry(gsym);
    }
  else
    {
      if (this->plt_ == NULL)
	this->make_plt_section(symtab, layout);
      this->plt_->add_entry(gsym);
    }
}

// Make a PLT entry for a local symbol.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_local_plt_entry(
    Layout* layout,
    Sized_relobj_file<size, big_endian>* relobj,
    unsigned int r_sym)
{
  if (this->lplt_ == NULL)
    this->make_lplt_section(layout);
  this->lplt_->add_local_entry(relobj, r_sym);
}

// Make a PLT entry for a local STT_GNU_IFUNC symbol.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_local_ifunc_plt_entry(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* relobj,
    unsigned int r_sym)
{
  if (this->iplt_ == NULL)
    this->make_iplt_section(symtab, layout);
  this->iplt_->add_local_ifunc_entry(relobj, r_sym);
}

// Return the number of entries in the PLT.

template<int size, bool big_endian>
unsigned int
Target_powerpc<size, big_endian>::plt_entry_count() const
{
  if (this->plt_ == NULL)
    return 0;
  return this->plt_->entry_count();
}

// Create a GOT entry for local dynamic __tls_get_addr calls.

template<int size, bool big_endian>
unsigned int
Target_powerpc<size, big_endian>::tlsld_got_offset(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* object)
{
  if (this->tlsld_got_offset_ == -1U)
    {
      gold_assert(symtab != NULL && layout != NULL && object != NULL);
      Reloc_section* rela_dyn = this->rela_dyn_section(layout);
      Output_data_got_powerpc<size, big_endian>* got
	= this->got_section(symtab, layout, GOT_TYPE_SMALL);
      unsigned int got_offset = got->add_constant_pair(0, 0);
      rela_dyn->add_local(object, 0, elfcpp::R_POWERPC_DTPMOD, got,
			  got_offset, 0);
      this->tlsld_got_offset_ = got_offset;
    }
  return this->tlsld_got_offset_;
}

// Get the Reference_flags for a particular relocation.

template<int size, bool big_endian>
int
Target_powerpc<size, big_endian>::Scan::get_reference_flags(
    unsigned int r_type,
    const Target_powerpc* target)
{
  int ref = 0;

  switch (r_type)
    {
    case elfcpp::R_POWERPC_NONE:
    case elfcpp::R_POWERPC_GNU_VTINHERIT:
    case elfcpp::R_POWERPC_GNU_VTENTRY:
    case elfcpp::R_PPC64_TOC:
      // No symbol reference.
      break;

    case elfcpp::R_PPC64_ADDR64:
    case elfcpp::R_PPC64_UADDR64:
    case elfcpp::R_POWERPC_ADDR32:
    case elfcpp::R_POWERPC_UADDR32:
    case elfcpp::R_POWERPC_ADDR16:
    case elfcpp::R_POWERPC_UADDR16:
    case elfcpp::R_POWERPC_ADDR16_LO:
    case elfcpp::R_POWERPC_ADDR16_HI:
    case elfcpp::R_POWERPC_ADDR16_HA:
    case elfcpp::R_PPC64_ADDR16_HIGHER34:
    case elfcpp::R_PPC64_ADDR16_HIGHERA34:
    case elfcpp::R_PPC64_ADDR16_HIGHEST34:
    case elfcpp::R_PPC64_ADDR16_HIGHESTA34:
    case elfcpp::R_PPC64_D34:
    case elfcpp::R_PPC64_D34_LO:
    case elfcpp::R_PPC64_D34_HI30:
    case elfcpp::R_PPC64_D34_HA30:
    case elfcpp::R_PPC64_D28:
      ref = Symbol::ABSOLUTE_REF;
      break;

    case elfcpp::R_POWERPC_ADDR24:
    case elfcpp::R_POWERPC_ADDR14:
    case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
    case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
      ref = Symbol::FUNCTION_CALL | Symbol::ABSOLUTE_REF;
      break;

    case elfcpp::R_PPC64_REL64:
    case elfcpp::R_POWERPC_REL32:
    case elfcpp::R_PPC_LOCAL24PC:
    case elfcpp::R_POWERPC_REL16:
    case elfcpp::R_POWERPC_REL16_LO:
    case elfcpp::R_POWERPC_REL16_HI:
    case elfcpp::R_POWERPC_REL16_HA:
    case elfcpp::R_PPC64_REL16_HIGH:
    case elfcpp::R_PPC64_REL16_HIGHA:
    case elfcpp::R_PPC64_REL16_HIGHER:
    case elfcpp::R_PPC64_REL16_HIGHERA:
    case elfcpp::R_PPC64_REL16_HIGHEST:
    case elfcpp::R_PPC64_REL16_HIGHESTA:
    case elfcpp::R_PPC64_PCREL34:
    case elfcpp::R_PPC64_REL16_HIGHER34:
    case elfcpp::R_PPC64_REL16_HIGHERA34:
    case elfcpp::R_PPC64_REL16_HIGHEST34:
    case elfcpp::R_PPC64_REL16_HIGHESTA34:
    case elfcpp::R_PPC64_PCREL28:
      ref = Symbol::RELATIVE_REF;
      break;

    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_REL24:
    case elfcpp::R_PPC_PLTREL24:
    case elfcpp::R_POWERPC_REL14:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
      ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
      break;

    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_POWERPC_GOT16_LO:
    case elfcpp::R_POWERPC_GOT16_HI:
    case elfcpp::R_POWERPC_GOT16_HA:
    case elfcpp::R_PPC64_GOT16_DS:
    case elfcpp::R_PPC64_GOT16_LO_DS:
    case elfcpp::R_PPC64_GOT_PCREL34:
    case elfcpp::R_PPC64_TOC16:
    case elfcpp::R_PPC64_TOC16_LO:
    case elfcpp::R_PPC64_TOC16_HI:
    case elfcpp::R_PPC64_TOC16_HA:
    case elfcpp::R_PPC64_TOC16_DS:
    case elfcpp::R_PPC64_TOC16_LO_DS:
    case elfcpp::R_POWERPC_PLT16_LO:
    case elfcpp::R_POWERPC_PLT16_HI:
    case elfcpp::R_POWERPC_PLT16_HA:
    case elfcpp::R_PPC64_PLT16_LO_DS:
    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
      ref = Symbol::RELATIVE_REF;
      break;

    case elfcpp::R_POWERPC_GOT_TPREL16:
    case elfcpp::R_POWERPC_TLS:
    case elfcpp::R_PPC64_TLSGD:
    case elfcpp::R_PPC64_TLSLD:
    case elfcpp::R_PPC64_TPREL34:
    case elfcpp::R_PPC64_DTPREL34:
    case elfcpp::R_PPC64_GOT_TLSGD_PCREL34:
    case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
    case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
    case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
      ref = Symbol::TLS_REF;
      break;

    case elfcpp::R_POWERPC_COPY:
    case elfcpp::R_POWERPC_GLOB_DAT:
    case elfcpp::R_POWERPC_JMP_SLOT:
    case elfcpp::R_POWERPC_RELATIVE:
    case elfcpp::R_POWERPC_DTPMOD:
    default:
      // Not expected.  We will give an error later.
      break;
    }

  if (size == 64 && target->abiversion() < 2)
    ref |= Symbol::FUNC_DESC_ABI;
  return ref;
}

// Report an unsupported relocation against a local symbol.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::Scan::unsupported_reloc_local(
    Sized_relobj_file<size, big_endian>* object,
    unsigned int r_type)
{
  gold_error(_("%s: unsupported reloc %u against local symbol"),
	     object->name().c_str(), r_type);
}

// We are about to emit a dynamic relocation of type R_TYPE.  If the
// dynamic linker does not support it, issue an error.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::Scan::check_non_pic(Relobj* object,
						      unsigned int r_type)
{
  gold_assert(r_type != elfcpp::R_POWERPC_NONE);

  // These are the relocation types supported by glibc for both 32-bit
  // and 64-bit powerpc.
  switch (r_type)
    {
    case elfcpp::R_POWERPC_NONE:
    case elfcpp::R_POWERPC_RELATIVE:
    case elfcpp::R_POWERPC_GLOB_DAT:
    case elfcpp::R_POWERPC_DTPMOD:
    case elfcpp::R_POWERPC_DTPREL:
    case elfcpp::R_POWERPC_TPREL:
    case elfcpp::R_POWERPC_JMP_SLOT:
    case elfcpp::R_POWERPC_COPY:
    case elfcpp::R_POWERPC_IRELATIVE:
    case elfcpp::R_POWERPC_ADDR32:
    case elfcpp::R_POWERPC_UADDR32:
    case elfcpp::R_POWERPC_ADDR24:
    case elfcpp::R_POWERPC_ADDR16:
    case elfcpp::R_POWERPC_UADDR16:
    case elfcpp::R_POWERPC_ADDR16_LO:
    case elfcpp::R_POWERPC_ADDR16_HI:
    case elfcpp::R_POWERPC_ADDR16_HA:
    case elfcpp::R_POWERPC_ADDR14:
    case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
    case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
    case elfcpp::R_POWERPC_REL32:
    case elfcpp::R_POWERPC_TPREL16:
    case elfcpp::R_POWERPC_TPREL16_LO:
    case elfcpp::R_POWERPC_TPREL16_HI:
    case elfcpp::R_POWERPC_TPREL16_HA:
      return;

    default:
      break;
    }

  if (size == 64)
    {
      switch (r_type)
	{
	  // These are the relocation types supported only on 64-bit.
	case elfcpp::R_PPC64_ADDR64:
	case elfcpp::R_PPC64_UADDR64:
	case elfcpp::R_PPC64_JMP_IREL:
	case elfcpp::R_PPC64_ADDR16_DS:
	case elfcpp::R_PPC64_ADDR16_LO_DS:
	case elfcpp::R_PPC64_ADDR16_HIGH:
	case elfcpp::R_PPC64_ADDR16_HIGHA:
	case elfcpp::R_PPC64_ADDR16_HIGHER:
	case elfcpp::R_PPC64_ADDR16_HIGHEST:
	case elfcpp::R_PPC64_ADDR16_HIGHERA:
	case elfcpp::R_PPC64_ADDR16_HIGHESTA:
	case elfcpp::R_PPC64_REL64:
	case elfcpp::R_POWERPC_ADDR30:
	case elfcpp::R_PPC64_TPREL16_DS:
	case elfcpp::R_PPC64_TPREL16_LO_DS:
	case elfcpp::R_PPC64_TPREL16_HIGH:
	case elfcpp::R_PPC64_TPREL16_HIGHA:
	case elfcpp::R_PPC64_TPREL16_HIGHER:
	case elfcpp::R_PPC64_TPREL16_HIGHEST:
	case elfcpp::R_PPC64_TPREL16_HIGHERA:
	case elfcpp::R_PPC64_TPREL16_HIGHESTA:
	  return;

	default:
	  break;
	}
    }
  else
    {
      switch (r_type)
	{
	  // These are the relocation types supported only on 32-bit.
	  // ??? glibc ld.so doesn't need to support these.
	case elfcpp::R_POWERPC_REL24:
	case elfcpp::R_POWERPC_DTPREL16:
	case elfcpp::R_POWERPC_DTPREL16_LO:
	case elfcpp::R_POWERPC_DTPREL16_HI:
	case elfcpp::R_POWERPC_DTPREL16_HA:
	  return;

	default:
	  break;
	}
    }

  // This prevents us from issuing more than one error per reloc
  // section.  But we can still wind up issuing more than one
  // error per object file.
  if (this->issued_non_pic_error_)
    return;
  gold_assert(parameters->options().output_is_position_independent());
  object->error(_("requires unsupported dynamic reloc; "
		  "recompile with -fPIC"));
  this->issued_non_pic_error_ = true;
  return;
}

// Return whether we need to make a PLT entry for a relocation of the
// given type against a STT_GNU_IFUNC symbol.

template<int size, bool big_endian>
bool
Target_powerpc<size, big_endian>::Scan::reloc_needs_plt_for_ifunc(
     Target_powerpc<size, big_endian>* target,
     Sized_relobj_file<size, big_endian>* object,
     unsigned int r_type,
     bool report_err)
{
  // In non-pic code any reference will resolve to the plt call stub
  // for the ifunc symbol.
  if ((size == 32 || target->abiversion() >= 2)
      && !parameters->options().output_is_position_independent())
    return true;

  switch (r_type)
    {
    // Word size refs from data sections are OK, but don't need a PLT entry.
    case elfcpp::R_POWERPC_ADDR32:
    case elfcpp::R_POWERPC_UADDR32:
      if (size == 32)
	return false;
      break;

    case elfcpp::R_PPC64_ADDR64:
    case elfcpp::R_PPC64_UADDR64:
      if (size == 64)
	return false;
      break;

    // GOT refs are good, but also don't need a PLT entry.
    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_POWERPC_GOT16_LO:
    case elfcpp::R_POWERPC_GOT16_HI:
    case elfcpp::R_POWERPC_GOT16_HA:
    case elfcpp::R_PPC64_GOT16_DS:
    case elfcpp::R_PPC64_GOT16_LO_DS:
    case elfcpp::R_PPC64_GOT_PCREL34:
      return false;

    // PLT relocs are OK and need a PLT entry.
    case elfcpp::R_POWERPC_PLT16_LO:
    case elfcpp::R_POWERPC_PLT16_HI:
    case elfcpp::R_POWERPC_PLT16_HA:
    case elfcpp::R_PPC64_PLT16_LO_DS:
    case elfcpp::R_POWERPC_PLTSEQ:
    case elfcpp::R_POWERPC_PLTCALL:
    case elfcpp::R_PPC64_PLTSEQ_NOTOC:
    case elfcpp::R_PPC64_PLTCALL_NOTOC:
    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
      return true;
      break;

    // Function calls are good, and these do need a PLT entry.
    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_ADDR24:
    case elfcpp::R_POWERPC_ADDR14:
    case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
    case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
    case elfcpp::R_POWERPC_REL24:
    case elfcpp::R_PPC_PLTREL24:
    case elfcpp::R_POWERPC_REL14:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
      return true;

    default:
      break;
    }

  // Anything else is a problem.
  // If we are building a static executable, the libc startup function
  // responsible for applying indirect function relocations is going
  // to complain about the reloc type.
  // If we are building a dynamic executable, we will have a text
  // relocation.  The dynamic loader will set the text segment
  // writable and non-executable to apply text relocations.  So we'll
  // segfault when trying to run the indirection function to resolve
  // the reloc.
  if (report_err)
    gold_error(_("%s: unsupported reloc %u for IFUNC symbol"),
	       object->name().c_str(), r_type);
  return false;
}

// Return TRUE iff INSN is one we expect on a _LO variety toc/got
// reloc.

static bool
ok_lo_toc_insn(uint32_t insn, unsigned int r_type)
{
  return ((insn & (0x3f << 26)) == 12u << 26 /* addic */
	  || (insn & (0x3f << 26)) == 14u << 26 /* addi */
	  || (insn & (0x3f << 26)) == 32u << 26 /* lwz */
	  || (insn & (0x3f << 26)) == 34u << 26 /* lbz */
	  || (insn & (0x3f << 26)) == 36u << 26 /* stw */
	  || (insn & (0x3f << 26)) == 38u << 26 /* stb */
	  || (insn & (0x3f << 26)) == 40u << 26 /* lhz */
	  || (insn & (0x3f << 26)) == 42u << 26 /* lha */
	  || (insn & (0x3f << 26)) == 44u << 26 /* sth */
	  || (insn & (0x3f << 26)) == 46u << 26 /* lmw */
	  || (insn & (0x3f << 26)) == 47u << 26 /* stmw */
	  || (insn & (0x3f << 26)) == 48u << 26 /* lfs */
	  || (insn & (0x3f << 26)) == 50u << 26 /* lfd */
	  || (insn & (0x3f << 26)) == 52u << 26 /* stfs */
	  || (insn & (0x3f << 26)) == 54u << 26 /* stfd */
	  || (insn & (0x3f << 26)) == 56u << 26 /* lq,lfq */
	  || ((insn & (0x3f << 26)) == 57u << 26 /* lxsd,lxssp,lfdp */
	      /* Exclude lfqu by testing reloc.  If relocs are ever
		 defined for the reduced D field in psq_lu then those
		 will need testing too.  */
	      && r_type != elfcpp::R_PPC64_TOC16_LO
	      && r_type != elfcpp::R_POWERPC_GOT16_LO)
	  || ((insn & (0x3f << 26)) == 58u << 26 /* ld,lwa */
	      && (insn & 1) == 0)
	  || (insn & (0x3f << 26)) == 60u << 26 /* stfq */
	  || ((insn & (0x3f << 26)) == 61u << 26 /* lxv,stx{v,sd,ssp},stfdp */
	      /* Exclude stfqu.  psq_stu as above for psq_lu.  */
	      && r_type != elfcpp::R_PPC64_TOC16_LO
	      && r_type != elfcpp::R_POWERPC_GOT16_LO)
	  || ((insn & (0x3f << 26)) == 62u << 26 /* std,stq */
	      && (insn & 1) == 0));
}

// Scan a relocation for a local symbol.

template<int size, bool big_endian>
inline void
Target_powerpc<size, big_endian>::Scan::local(
    Symbol_table* symtab,
    Layout* layout,
    Target_powerpc<size, big_endian>* target,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    Output_section* output_section,
    const elfcpp::Rela<size, big_endian>& reloc,
    unsigned int r_type,
    const elfcpp::Sym<size, big_endian>& lsym,
    bool is_discarded)
{
  Powerpc_relobj<size, big_endian>* ppc_object
    = static_cast<Powerpc_relobj<size, big_endian>*>(object);

  switch (this->maybe_skip_tls_get_addr_call(target, r_type, NULL))
    {
    case Track_tls::NOT_EXPECTED:
      ppc_object->set_no_tls_marker();
      break;
    default:
      break;
    }

  if ((size == 64 && r_type == elfcpp::R_PPC64_TLSGD)
      || (size == 32 && r_type == elfcpp::R_PPC_TLSGD))
    {
      this->expect_tls_get_addr_call();
      if (!ppc_object->no_tls_marker())
	{
	  tls::Tls_optimization tls_type = target->optimize_tls_gd(true);
	  if (tls_type != tls::TLSOPT_NONE)
	    {
	      this->skip_next_tls_get_addr_call();
	      ppc_object->set_tls_marker();
	    }
	}
    }
  else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSLD)
	   || (size == 32 && r_type == elfcpp::R_PPC_TLSLD))
    {
      this->expect_tls_get_addr_call();
      if (!ppc_object->no_tls_marker())
	{
	  tls::Tls_optimization tls_type = target->optimize_tls_ld();
	  if (tls_type != tls::TLSOPT_NONE)
	    {
	      this->skip_next_tls_get_addr_call();
	      ppc_object->set_tls_marker();
	    }
	}
    }

  if (is_discarded)
    {
      if (size == 64
	  && data_shndx == ppc_object->opd_shndx()
	  && r_type == elfcpp::R_PPC64_ADDR64)
	ppc_object->set_opd_discard(reloc.get_r_offset());
      return;
    }

  // A local STT_GNU_IFUNC symbol may require a PLT entry.
  bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC;
  if (is_ifunc && this->reloc_needs_plt_for_ifunc(target, object, r_type, true))
    {
      unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
      target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
			  r_type, r_sym, reloc.get_r_addend());
      target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);
    }

  switch (r_type)
    {
    case elfcpp::R_POWERPC_NONE:
    case elfcpp::R_POWERPC_GNU_VTINHERIT:
    case elfcpp::R_POWERPC_GNU_VTENTRY:
    case elfcpp::R_POWERPC_TLS:
    case elfcpp::R_PPC64_ENTRY:
    case elfcpp::R_POWERPC_PLTSEQ:
    case elfcpp::R_POWERPC_PLTCALL:
    case elfcpp::R_PPC64_PLTSEQ_NOTOC:
    case elfcpp::R_PPC64_PLTCALL_NOTOC:
    case elfcpp::R_PPC64_PCREL_OPT:
    case elfcpp::R_PPC64_ADDR16_HIGHER34:
    case elfcpp::R_PPC64_ADDR16_HIGHERA34:
    case elfcpp::R_PPC64_ADDR16_HIGHEST34:
    case elfcpp::R_PPC64_ADDR16_HIGHESTA34:
    case elfcpp::R_PPC64_REL16_HIGHER34:
    case elfcpp::R_PPC64_REL16_HIGHERA34:
    case elfcpp::R_PPC64_REL16_HIGHEST34:
    case elfcpp::R_PPC64_REL16_HIGHESTA34:
    case elfcpp::R_PPC64_D34:
    case elfcpp::R_PPC64_D34_LO:
    case elfcpp::R_PPC64_D34_HI30:
    case elfcpp::R_PPC64_D34_HA30:
    case elfcpp::R_PPC64_D28:
    case elfcpp::R_PPC64_PCREL34:
    case elfcpp::R_PPC64_PCREL28:
    case elfcpp::R_PPC64_TPREL34:
    case elfcpp::R_PPC64_DTPREL34:
      break;

    case elfcpp::R_PPC64_TOC:
      {
	Output_data_got_powerpc<size, big_endian>* got
	  = target->got_section(symtab, layout, GOT_TYPE_SMALL);
	if (parameters->options().output_is_position_independent())
	  {
	    Address off = reloc.get_r_offset();
	    if (size == 64
		&& target->abiversion() < 2
		&& data_shndx == ppc_object->opd_shndx()
		&& ppc_object->get_opd_discard(off - 8))
	      break;

	    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
	    Address got_off = (target->toc_pointer()
			       - got->output_section()->address());
	    rela_dyn->add_output_section_relative(got->output_section(),
						  elfcpp::R_POWERPC_RELATIVE,
						  output_section,
						  object, data_shndx, off,
						  got_off);
	  }
      }
      break;

    case elfcpp::R_PPC64_ADDR64:
    case elfcpp::R_PPC64_UADDR64:
    case elfcpp::R_POWERPC_ADDR32:
    case elfcpp::R_POWERPC_UADDR32:
    case elfcpp::R_POWERPC_ADDR24:
    case elfcpp::R_POWERPC_ADDR16:
    case elfcpp::R_POWERPC_ADDR16_LO:
    case elfcpp::R_POWERPC_ADDR16_HI:
    case elfcpp::R_POWERPC_ADDR16_HA:
    case elfcpp::R_POWERPC_UADDR16:
    case elfcpp::R_PPC64_ADDR16_HIGH:
    case elfcpp::R_PPC64_ADDR16_HIGHA:
    case elfcpp::R_PPC64_ADDR16_HIGHER:
    case elfcpp::R_PPC64_ADDR16_HIGHERA:
    case elfcpp::R_PPC64_ADDR16_HIGHEST:
    case elfcpp::R_PPC64_ADDR16_HIGHESTA:
    case elfcpp::R_PPC64_ADDR16_DS:
    case elfcpp::R_PPC64_ADDR16_LO_DS:
    case elfcpp::R_POWERPC_ADDR14:
    case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
    case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
      // If building a shared library (or a position-independent
      // executable), we need to create a dynamic relocation for
      // this location.
      if (parameters->options().output_is_position_independent()
	  || (size == 64 && is_ifunc && target->abiversion() < 2))
	{
	  Reloc_section* rela_dyn = target->rela_dyn_section(symtab, layout,
							     is_ifunc);
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  if ((size == 32 && r_type == elfcpp::R_POWERPC_ADDR32)
	      || (size == 64 && r_type == elfcpp::R_PPC64_ADDR64))
	    {
	      unsigned int dynrel = (is_ifunc ? elfcpp::R_POWERPC_IRELATIVE
				     : elfcpp::R_POWERPC_RELATIVE);
	      rela_dyn->add_local_relative(object, r_sym, dynrel,
					   output_section, data_shndx,
					   reloc.get_r_offset(),
					   reloc.get_r_addend(), false);
	    }
	  else if (lsym.get_st_type() != elfcpp::STT_SECTION)
	    {
	      check_non_pic(object, r_type);
	      rela_dyn->add_local(object, r_sym, r_type, output_section,
				  data_shndx, reloc.get_r_offset(),
				  reloc.get_r_addend());
	    }
	  else
	    {
	      gold_assert(lsym.get_st_value() == 0);
	      unsigned int shndx = lsym.get_st_shndx();
	      bool is_ordinary;
	      shndx = object->adjust_sym_shndx(r_sym, shndx,
					       &is_ordinary);
	      if (!is_ordinary)
		object->error(_("section symbol %u has bad shndx %u"),
			      r_sym, shndx);
	      else
		rela_dyn->add_local_section(object, shndx, r_type,
					    output_section, data_shndx,
					    reloc.get_r_offset());
	    }
	}
      break;

    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
    case elfcpp::R_POWERPC_PLT16_LO:
    case elfcpp::R_POWERPC_PLT16_HI:
    case elfcpp::R_POWERPC_PLT16_HA:
    case elfcpp::R_PPC64_PLT16_LO_DS:
      if (!is_ifunc)
	{
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  target->make_local_plt_entry(layout, object, r_sym);
	}
      break;

    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_REL24:
    case elfcpp::R_PPC_PLTREL24:
    case elfcpp::R_PPC_LOCAL24PC:
    case elfcpp::R_POWERPC_REL14:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
      if (!is_ifunc)
	{
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
			      r_type, r_sym, reloc.get_r_addend());
	}
      break;

    case elfcpp::R_PPC64_TOCSAVE:
      // R_PPC64_TOCSAVE follows a call instruction to indicate the
      // caller has already saved r2 and thus a plt call stub need not
      // save r2.
      if (size == 64
	  && target->mark_pltcall(ppc_object, data_shndx,
				  reloc.get_r_offset() - 4, symtab))
	{
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  unsigned int shndx = lsym.get_st_shndx();
	  bool is_ordinary;
	  shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
	  if (!is_ordinary)
	    object->error(_("tocsave symbol %u has bad shndx %u"),
			  r_sym, shndx);
	  else
	    target->add_tocsave(ppc_object, shndx,
				lsym.get_st_value() + reloc.get_r_addend());
	}
      break;

    case elfcpp::R_PPC64_REL64:
    case elfcpp::R_POWERPC_REL32:
    case elfcpp::R_POWERPC_REL16:
    case elfcpp::R_POWERPC_REL16_LO:
    case elfcpp::R_POWERPC_REL16_HI:
    case elfcpp::R_POWERPC_REL16_HA:
    case elfcpp::R_POWERPC_REL16DX_HA:
    case elfcpp::R_PPC64_REL16_HIGH:
    case elfcpp::R_PPC64_REL16_HIGHA:
    case elfcpp::R_PPC64_REL16_HIGHER:
    case elfcpp::R_PPC64_REL16_HIGHERA:
    case elfcpp::R_PPC64_REL16_HIGHEST:
    case elfcpp::R_PPC64_REL16_HIGHESTA:
    case elfcpp::R_POWERPC_SECTOFF:
    case elfcpp::R_POWERPC_SECTOFF_LO:
    case elfcpp::R_POWERPC_SECTOFF_HI:
    case elfcpp::R_POWERPC_SECTOFF_HA:
    case elfcpp::R_PPC64_SECTOFF_DS:
    case elfcpp::R_PPC64_SECTOFF_LO_DS:
    case elfcpp::R_POWERPC_TPREL16:
    case elfcpp::R_POWERPC_TPREL16_LO:
    case elfcpp::R_POWERPC_TPREL16_HI:
    case elfcpp::R_POWERPC_TPREL16_HA:
    case elfcpp::R_PPC64_TPREL16_DS:
    case elfcpp::R_PPC64_TPREL16_LO_DS:
    case elfcpp::R_PPC64_TPREL16_HIGH:
    case elfcpp::R_PPC64_TPREL16_HIGHA:
    case elfcpp::R_PPC64_TPREL16_HIGHER:
    case elfcpp::R_PPC64_TPREL16_HIGHERA:
    case elfcpp::R_PPC64_TPREL16_HIGHEST:
    case elfcpp::R_PPC64_TPREL16_HIGHESTA:
    case elfcpp::R_POWERPC_DTPREL16:
    case elfcpp::R_POWERPC_DTPREL16_LO:
    case elfcpp::R_POWERPC_DTPREL16_HI:
    case elfcpp::R_POWERPC_DTPREL16_HA:
    case elfcpp::R_PPC64_DTPREL16_DS:
    case elfcpp::R_PPC64_DTPREL16_LO_DS:
    case elfcpp::R_PPC64_DTPREL16_HIGH:
    case elfcpp::R_PPC64_DTPREL16_HIGHA:
    case elfcpp::R_PPC64_DTPREL16_HIGHER:
    case elfcpp::R_PPC64_DTPREL16_HIGHERA:
    case elfcpp::R_PPC64_DTPREL16_HIGHEST:
    case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
    case elfcpp::R_PPC64_TLSGD:
    case elfcpp::R_PPC64_TLSLD:
    case elfcpp::R_PPC64_ADDR64_LOCAL:
      break;

    case elfcpp::R_PPC64_GOT_PCREL34:
    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_POWERPC_GOT16_LO:
    case elfcpp::R_POWERPC_GOT16_HI:
    case elfcpp::R_POWERPC_GOT16_HA:
    case elfcpp::R_PPC64_GOT16_DS:
    case elfcpp::R_PPC64_GOT16_LO_DS:
      {
	// The symbol requires a GOT entry.
	Got_type got_type = ((size == 32
			      || r_type == elfcpp::R_POWERPC_GOT16
			      || r_type == elfcpp::R_PPC64_GOT16_DS)
			     ? GOT_TYPE_SMALL : GOT_TYPE_STANDARD);
	Output_data_got_powerpc<size, big_endian>* got
	  = target->got_section(symtab, layout, got_type);
	unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();

	if (!parameters->options().output_is_position_independent())
	  {
	    if (is_ifunc
		&& (size == 32 || target->abiversion() >= 2))
	      got->add_local_plt(object, r_sym, got_type, addend);
	    else
	      got->add_local(object, r_sym, got_type, addend);
	  }
	else if (!object->local_has_got_offset(r_sym, got_type, addend))
	  {
	    // If we are generating a shared object or a pie, this
	    // symbol's GOT entry will be set by a dynamic relocation.
	    unsigned int off;
	    off = got->add_constant(0);
	    object->set_local_got_offset(r_sym, got_type, off, addend);

	    Reloc_section* rela_dyn = target->rela_dyn_section(symtab, layout,
							       is_ifunc);
	    unsigned int dynrel = (is_ifunc ? elfcpp::R_POWERPC_IRELATIVE
				   : elfcpp::R_POWERPC_RELATIVE);
	    rela_dyn->add_local_relative(object, r_sym, dynrel,
					 got, off, addend, false);
	  }
      }
      break;

    case elfcpp::R_PPC64_TOC16:
    case elfcpp::R_PPC64_TOC16_LO:
    case elfcpp::R_PPC64_TOC16_HI:
    case elfcpp::R_PPC64_TOC16_HA:
    case elfcpp::R_PPC64_TOC16_DS:
    case elfcpp::R_PPC64_TOC16_LO_DS:
      // We need a GOT section.
      target->got_section(symtab, layout, GOT_TYPE_SMALL);
      break;

    case elfcpp::R_PPC64_GOT_TLSGD_PCREL34:
    case elfcpp::R_POWERPC_GOT_TLSGD16:
    case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
    case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
    case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
      {
	tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
	if (!ppc_object->no_tls_marker())
	  tls_type = target->optimize_tls_gd(true);
	if (tls_type == tls::TLSOPT_NONE)
	  {
	    Got_type got_type = ((size == 32
				  || r_type == elfcpp::R_POWERPC_GOT_TLSGD16)
				 ? GOT_TYPE_SMALL_TLSGD : GOT_TYPE_TLSGD);
	    Output_data_got_powerpc<size, big_endian>* got
	      = target->got_section(symtab, layout, got_type);
	    unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	    uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();
	    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
	    got->add_local_tls_pair(object, r_sym, got_type,
				    rela_dyn, elfcpp::R_POWERPC_DTPMOD,
				    addend);
	  }
	else if (tls_type == tls::TLSOPT_TO_LE)
	  {
	    // no GOT relocs needed for Local Exec.
	    ppc_object->set_tls_marker();
	  }
	else
	  gold_unreachable();
      }
      break;

    case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
    case elfcpp::R_POWERPC_GOT_TLSLD16:
    case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
    case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
    case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
      {
	tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
	if (!ppc_object->no_tls_marker())
	  tls_type = target->optimize_tls_ld();
	if (tls_type == tls::TLSOPT_NONE)
	  target->tlsld_got_offset(symtab, layout, object);
	else if (tls_type == tls::TLSOPT_TO_LE)
	  {
	    // no GOT relocs needed for Local Exec.
	    if (parameters->options().emit_relocs())
	      {
		Output_section* os = layout->tls_segment()->first_section();
		gold_assert(os != NULL);
		os->set_needs_symtab_index();
	      }
	    ppc_object->set_tls_marker();
	  }
	else
	  gold_unreachable();
      }
      break;

    case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
    case elfcpp::R_POWERPC_GOT_DTPREL16:
    case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
    case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
    case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
      {
	Got_type got_type = ((size == 32
			      || r_type == elfcpp::R_POWERPC_GOT_DTPREL16)
			     ? GOT_TYPE_SMALL_DTPREL : GOT_TYPE_DTPREL);
	Output_data_got_powerpc<size, big_endian>* got
	  = target->got_section(symtab, layout, got_type);
	unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();
	got->add_local_tls(object, r_sym, got_type, addend);
      }
      break;

    case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
    case elfcpp::R_POWERPC_GOT_TPREL16:
    case elfcpp::R_POWERPC_GOT_TPREL16_LO:
    case elfcpp::R_POWERPC_GOT_TPREL16_HI:
    case elfcpp::R_POWERPC_GOT_TPREL16_HA:
      {
	tls::Tls_optimization tls_type = target->optimize_tls_ie(true);
	if (tls_type == tls::TLSOPT_NONE)
	  {
	    unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	    uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();
	    Got_type got_type = ((size == 32
				  || r_type == elfcpp::R_POWERPC_GOT_TPREL16)
				 ? GOT_TYPE_SMALL_TPREL : GOT_TYPE_TPREL);
	    if (!object->local_has_got_offset(r_sym, got_type, addend))
	      {
		Output_data_got_powerpc<size, big_endian>* got
		  = target->got_section(symtab, layout, got_type);
		unsigned int off = got->add_constant(0);
		object->set_local_got_offset(r_sym, got_type, off, addend);

		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		rela_dyn->add_symbolless_local_addend(object, r_sym,
						      elfcpp::R_POWERPC_TPREL,
						      got, off, addend);
	      }
	  }
	else if (tls_type == tls::TLSOPT_TO_LE)
	  {
	    // no GOT relocs needed for Local Exec.
	  }
	else
	  gold_unreachable();
      }
      break;

    default:
      unsupported_reloc_local(object, r_type);
      break;
    }

  if (size == 64
      && parameters->options().toc_optimize())
    {
      if (data_shndx == ppc_object->toc_shndx())
	{
	  bool ok = true;
	  if (r_type != elfcpp::R_PPC64_ADDR64
	      || (is_ifunc && target->abiversion() < 2))
	    ok = false;
	  else if (parameters->options().output_is_position_independent())
	    {
	      if (is_ifunc)
		ok = false;
	      else
		{
		  unsigned int shndx = lsym.get_st_shndx();
		  if (shndx >= elfcpp::SHN_LORESERVE
		      && shndx != elfcpp::SHN_XINDEX)
		    ok = false;
		}
	    }
	  if (!ok)
	    ppc_object->set_no_toc_opt(reloc.get_r_offset());
	}

      enum {no_check, check_lo, check_ha} insn_check;
      switch (r_type)
	{
	default:
	  insn_check = no_check;
	  break;

	case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
	case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
	case elfcpp::R_POWERPC_GOT_TPREL16_HA:
	case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
	case elfcpp::R_POWERPC_GOT16_HA:
	case elfcpp::R_PPC64_TOC16_HA:
	  insn_check = check_ha;
	  break;

	case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
	case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
	case elfcpp::R_POWERPC_GOT_TPREL16_LO:
	case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
	case elfcpp::R_POWERPC_GOT16_LO:
	case elfcpp::R_PPC64_GOT16_LO_DS:
	case elfcpp::R_PPC64_TOC16_LO:
	case elfcpp::R_PPC64_TOC16_LO_DS:
	  insn_check = check_lo;
	  break;
	}

      section_size_type slen;
      const unsigned char* view = NULL;
      if (insn_check != no_check)
	{
	  view = ppc_object->section_contents(data_shndx, &slen, false);
	  section_size_type off =
	    convert_to_section_size_type(reloc.get_r_offset()) & -4;
	  if (off < slen)
	    {
	      uint32_t insn = elfcpp::Swap<32, big_endian>::readval(view + off);
	      if (insn_check == check_lo
		  ? !ok_lo_toc_insn(insn, r_type)
		  : ((insn & ((0x3f << 26) | 0x1f << 16))
		     != ((15u << 26) | (2 << 16)) /* addis rt,2,imm */))
		{
		  ppc_object->set_no_toc_opt();
		  gold_warning(_("%s: toc optimization is not supported "
				 "for %#08x instruction"),
			       ppc_object->name().c_str(), insn);
		}
	    }
	}

      switch (r_type)
	{
	default:
	  break;
	case elfcpp::R_PPC64_TOC16:
	case elfcpp::R_PPC64_TOC16_LO:
	case elfcpp::R_PPC64_TOC16_HI:
	case elfcpp::R_PPC64_TOC16_HA:
	case elfcpp::R_PPC64_TOC16_DS:
	case elfcpp::R_PPC64_TOC16_LO_DS:
	  unsigned int shndx = lsym.get_st_shndx();
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  bool is_ordinary;
	  shndx = ppc_object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
	  if (is_ordinary && shndx == ppc_object->toc_shndx())
	    {
	      Address dst_off = lsym.get_st_value() + reloc.get_r_addend();
	      if (dst_off < ppc_object->section_size(shndx))
		{
		  bool ok = false;
		  if (r_type == elfcpp::R_PPC64_TOC16_HA)
		    ok = true;
		  else if (r_type == elfcpp::R_PPC64_TOC16_LO_DS)
		    {
		      // Need to check that the insn is a ld
		      if (!view)
			view = ppc_object->section_contents(data_shndx,
							    &slen,
							    false);
		      section_size_type off =
			(convert_to_section_size_type(reloc.get_r_offset())
			 + (big_endian ? -2 : 3));
		      if (off < slen
			  && (view[off] & (0x3f << 2)) == 58u << 2)
			ok = true;
		    }
		  if (!ok)
		    ppc_object->set_no_toc_opt(dst_off);
		}
	    }
	  break;
	}
    }

  if (size == 32)
    {
      switch (r_type)
	{
	case elfcpp::R_POWERPC_REL32:
	  if (ppc_object->got2_shndx() != 0
	      && parameters->options().output_is_position_independent())
	    {
	      unsigned int shndx = lsym.get_st_shndx();
	      unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	      bool is_ordinary;
	      shndx = ppc_object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
	      if (is_ordinary && shndx == ppc_object->got2_shndx()
		  && (ppc_object->section_flags(data_shndx)
		      & elfcpp::SHF_EXECINSTR) != 0)
		gold_error(_("%s: unsupported -mbss-plt code"),
			   ppc_object->name().c_str());
	    }
	  break;
	default:
	  break;
	}
    }

  switch (r_type)
    {
    case elfcpp::R_POWERPC_GOT_TLSLD16:
    case elfcpp::R_POWERPC_GOT_TLSGD16:
    case elfcpp::R_POWERPC_GOT_TPREL16:
    case elfcpp::R_POWERPC_GOT_DTPREL16:
    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_PPC64_GOT16_DS:
    case elfcpp::R_PPC64_TOC16:
    case elfcpp::R_PPC64_TOC16_DS:
      ppc_object->set_has_small_toc_reloc();
      break;
    default:
      break;
    }

  switch (r_type)
    {
    case elfcpp::R_PPC64_TPREL16_DS:
    case elfcpp::R_PPC64_TPREL16_LO_DS:
    case elfcpp::R_PPC64_TPREL16_HIGH:
    case elfcpp::R_PPC64_TPREL16_HIGHA:
    case elfcpp::R_PPC64_TPREL16_HIGHER:
    case elfcpp::R_PPC64_TPREL16_HIGHERA:
    case elfcpp::R_PPC64_TPREL16_HIGHEST:
    case elfcpp::R_PPC64_TPREL16_HIGHESTA:
    case elfcpp::R_PPC64_TPREL34:
      if (size != 64)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_TPREL16:
    case elfcpp::R_POWERPC_TPREL16_LO:
    case elfcpp::R_POWERPC_TPREL16_HI:
    case elfcpp::R_POWERPC_TPREL16_HA:
      layout->set_has_static_tls();
      break;
    default:
      break;
    }

  switch (r_type)
    {
    case elfcpp::R_POWERPC_TPREL16_HA:
      if (target->tprel_opt())
	{
	  section_size_type slen;
	  const unsigned char* view = NULL;
	  view = ppc_object->section_contents(data_shndx, &slen, false);
	  section_size_type off
	    = convert_to_section_size_type(reloc.get_r_offset()) & -4;
	  if (off < slen)
	    {
	      uint32_t insn = elfcpp::Swap<32, big_endian>::readval(view + off);
	      if ((insn & ((0x3fu << 26) | 0x1f << 16))
		  != ((15u << 26) | ((size == 32 ? 2 : 13) << 16)))
		target->set_no_tprel_opt();
	    }
	}
      break;

    case elfcpp::R_PPC64_TPREL16_HIGH:
    case elfcpp::R_PPC64_TPREL16_HIGHA:
    case elfcpp::R_PPC64_TPREL16_HIGHER:
    case elfcpp::R_PPC64_TPREL16_HIGHERA:
    case elfcpp::R_PPC64_TPREL16_HIGHEST:
    case elfcpp::R_PPC64_TPREL16_HIGHESTA:
      if (size != 64)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_TPREL16_HI:
      target->set_no_tprel_opt();
      break;
    default:
      break;
    }

  switch (r_type)
    {
    case elfcpp::R_PPC64_D34:
    case elfcpp::R_PPC64_D34_LO:
    case elfcpp::R_PPC64_D34_HI30:
    case elfcpp::R_PPC64_D34_HA30:
    case elfcpp::R_PPC64_D28:
    case elfcpp::R_PPC64_PCREL34:
    case elfcpp::R_PPC64_PCREL28:
    case elfcpp::R_PPC64_TPREL34:
    case elfcpp::R_PPC64_DTPREL34:
    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
    case elfcpp::R_PPC64_GOT_PCREL34:
    case elfcpp::R_PPC64_GOT_TLSGD_PCREL34:
    case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
    case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
    case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
      target->set_power10_relocs();
      break;
    default:
      break;
    }
}

// Report an unsupported relocation against a global symbol.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::Scan::unsupported_reloc_global(
    Sized_relobj_file<size, big_endian>* object,
    unsigned int r_type,
    Symbol* gsym)
{
  gold_error(_("%s: unsupported reloc %u against global symbol %s"),
	     object->name().c_str(), r_type, gsym->demangled_name().c_str());
}

// Scan a relocation for a global symbol.

template<int size, bool big_endian>
inline void
Target_powerpc<size, big_endian>::Scan::global(
    Symbol_table* symtab,
    Layout* layout,
    Target_powerpc<size, big_endian>* target,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    Output_section* output_section,
    const elfcpp::Rela<size, big_endian>& reloc,
    unsigned int r_type,
    Symbol* gsym)
{
  Powerpc_relobj<size, big_endian>* ppc_object
    = static_cast<Powerpc_relobj<size, big_endian>*>(object);

  switch (this->maybe_skip_tls_get_addr_call(target, r_type, gsym))
    {
    case Track_tls::NOT_EXPECTED:
      ppc_object->set_no_tls_marker();
      break;
    case Track_tls::SKIP:
      return;
    default:
      break;
    }

  if (target->replace_tls_get_addr(gsym))
    // Change a __tls_get_addr reference to __tls_get_addr_opt
    // so dynamic relocs are emitted against the latter symbol.
    gsym = target->tls_get_addr_opt();

  if ((size == 64 && r_type == elfcpp::R_PPC64_TLSGD)
      || (size == 32 && r_type == elfcpp::R_PPC_TLSGD))
    {
      this->expect_tls_get_addr_call();
      if (!ppc_object->no_tls_marker())
	{
	  bool final = gsym->final_value_is_known();
	  tls::Tls_optimization tls_type = target->optimize_tls_gd(final);
	  if (tls_type != tls::TLSOPT_NONE)
	    {
	      this->skip_next_tls_get_addr_call();
	      ppc_object->set_tls_marker();
	    }
	}
    }
  else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSLD)
	   || (size == 32 && r_type == elfcpp::R_PPC_TLSLD))
    {
      this->expect_tls_get_addr_call();
      if (!ppc_object->no_tls_marker())
	{
	  tls::Tls_optimization tls_type = target->optimize_tls_ld();
	  if (tls_type != tls::TLSOPT_NONE)
	    {
	      this->skip_next_tls_get_addr_call();
	      ppc_object->set_tls_marker();
	    }
	}
    }

  // A STT_GNU_IFUNC symbol may require a PLT entry.
  bool is_ifunc = gsym->type() == elfcpp::STT_GNU_IFUNC;
  bool pushed_ifunc = false;
  if (is_ifunc && this->reloc_needs_plt_for_ifunc(target, object, r_type, true))
    {
      unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
      target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
			  r_type, r_sym, reloc.get_r_addend());
      target->make_plt_entry(symtab, layout, gsym);
      pushed_ifunc = true;
    }

  switch (r_type)
    {
    case elfcpp::R_POWERPC_NONE:
    case elfcpp::R_POWERPC_GNU_VTINHERIT:
    case elfcpp::R_POWERPC_GNU_VTENTRY:
    case elfcpp::R_PPC_LOCAL24PC:
    case elfcpp::R_POWERPC_TLS:
    case elfcpp::R_PPC64_ENTRY:
    case elfcpp::R_POWERPC_PLTSEQ:
    case elfcpp::R_POWERPC_PLTCALL:
    case elfcpp::R_PPC64_PLTSEQ_NOTOC:
    case elfcpp::R_PPC64_PLTCALL_NOTOC:
    case elfcpp::R_PPC64_PCREL_OPT:
    case elfcpp::R_PPC64_ADDR16_HIGHER34:
    case elfcpp::R_PPC64_ADDR16_HIGHERA34:
    case elfcpp::R_PPC64_ADDR16_HIGHEST34:
    case elfcpp::R_PPC64_ADDR16_HIGHESTA34:
    case elfcpp::R_PPC64_REL16_HIGHER34:
    case elfcpp::R_PPC64_REL16_HIGHERA34:
    case elfcpp::R_PPC64_REL16_HIGHEST34:
    case elfcpp::R_PPC64_REL16_HIGHESTA34:
    case elfcpp::R_PPC64_D34:
    case elfcpp::R_PPC64_D34_LO:
    case elfcpp::R_PPC64_D34_HI30:
    case elfcpp::R_PPC64_D34_HA30:
    case elfcpp::R_PPC64_D28:
    case elfcpp::R_PPC64_PCREL34:
    case elfcpp::R_PPC64_PCREL28:
    case elfcpp::R_PPC64_TPREL34:
    case elfcpp::R_PPC64_DTPREL34:
      break;

    case elfcpp::R_PPC64_TOC:
      {
	Output_data_got_powerpc<size, big_endian>* got
	  = target->got_section(symtab, layout, GOT_TYPE_SMALL);
	if (parameters->options().output_is_position_independent())
	  {
	    Address off = reloc.get_r_offset();
	    if (size == 64
		&& data_shndx == ppc_object->opd_shndx()
		&& ppc_object->get_opd_discard(off - 8))
	      break;

	    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
	    Address got_off = (target->toc_pointer()
			       - got->output_section()->address());
	    rela_dyn->add_output_section_relative(got->output_section(),
						  elfcpp::R_POWERPC_RELATIVE,
						  output_section,
						  object, data_shndx, off,
						  got_off);
	  }
      }
      break;

    case elfcpp::R_PPC64_ADDR64:
      if (size == 64
	  && target->abiversion() < 2
	  && data_shndx == ppc_object->opd_shndx()
	  && (gsym->is_defined_in_discarded_section()
	      || gsym->object() != object))
	{
	  ppc_object->set_opd_discard(reloc.get_r_offset());
	  break;
	}
      // Fall through.
    case elfcpp::R_PPC64_UADDR64:
    case elfcpp::R_POWERPC_ADDR32:
    case elfcpp::R_POWERPC_UADDR32:
    case elfcpp::R_POWERPC_ADDR24:
    case elfcpp::R_POWERPC_ADDR16:
    case elfcpp::R_POWERPC_ADDR16_LO:
    case elfcpp::R_POWERPC_ADDR16_HI:
    case elfcpp::R_POWERPC_ADDR16_HA:
    case elfcpp::R_POWERPC_UADDR16:
    case elfcpp::R_PPC64_ADDR16_HIGH:
    case elfcpp::R_PPC64_ADDR16_HIGHA:
    case elfcpp::R_PPC64_ADDR16_HIGHER:
    case elfcpp::R_PPC64_ADDR16_HIGHERA:
    case elfcpp::R_PPC64_ADDR16_HIGHEST:
    case elfcpp::R_PPC64_ADDR16_HIGHESTA:
    case elfcpp::R_PPC64_ADDR16_DS:
    case elfcpp::R_PPC64_ADDR16_LO_DS:
    case elfcpp::R_POWERPC_ADDR14:
    case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
    case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
      {
	// Make a PLT entry if necessary.
	if (gsym->needs_plt_entry())
	  {
	    // Since this is not a PC-relative relocation, we may be
	    // taking the address of a function. In that case we need to
	    // set the entry in the dynamic symbol table to the address of
	    // the PLT call stub.
	    bool need_ifunc_plt = false;
	    if ((size == 32 || target->abiversion() >= 2)
		&& gsym->is_from_dynobj()
		&& !parameters->options().output_is_position_independent())
	      {
		gsym->set_needs_dynsym_value();
		need_ifunc_plt = true;
	      }
	    if (!is_ifunc || (!pushed_ifunc && need_ifunc_plt))
	      {
		unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
		target->push_branch(ppc_object, data_shndx,
				    reloc.get_r_offset(), r_type, r_sym,
				    reloc.get_r_addend());
		target->make_plt_entry(symtab, layout, gsym);
	      }
	  }
	// Make a dynamic relocation if necessary.
	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type, target))
	    || (size == 64 && is_ifunc && target->abiversion() < 2))
	  {
	    if (!parameters->options().output_is_position_independent()
		&& gsym->may_need_copy_reloc())
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, reloc);
	      }
	    else if ((((size == 32
			&& r_type == elfcpp::R_POWERPC_ADDR32)
		       || (size == 64
			   && r_type == elfcpp::R_PPC64_ADDR64
			   && target->abiversion() >= 2))
		      && gsym->can_use_relative_reloc(false)
		      && !(gsym->visibility() == elfcpp::STV_PROTECTED
			   && parameters->options().shared()))
		     || (size == 64
			 && r_type == elfcpp::R_PPC64_ADDR64
			 && target->abiversion() < 2
			 && (gsym->can_use_relative_reloc(false)
			     || data_shndx == ppc_object->opd_shndx())))
	      {
		Reloc_section* rela_dyn
		  = target->rela_dyn_section(symtab, layout, is_ifunc);
		unsigned int dynrel = (is_ifunc ? elfcpp::R_POWERPC_IRELATIVE
				       : elfcpp::R_POWERPC_RELATIVE);
		rela_dyn->add_symbolless_global_addend(
		    gsym, dynrel, output_section, object, data_shndx,
		    reloc.get_r_offset(), reloc.get_r_addend());
	      }
	    else
	      {
		Reloc_section* rela_dyn
		  = target->rela_dyn_section(symtab, layout, is_ifunc);
		check_non_pic(object, r_type);
		rela_dyn->add_global(gsym, r_type, output_section,
				     object, data_shndx,
				     reloc.get_r_offset(),
				     reloc.get_r_addend());

		if (size == 64
		    && parameters->options().toc_optimize()
		    && data_shndx == ppc_object->toc_shndx())
		  ppc_object->set_no_toc_opt(reloc.get_r_offset());
	      }
	  }
      }
      break;

    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
    case elfcpp::R_POWERPC_PLT16_LO:
    case elfcpp::R_POWERPC_PLT16_HI:
    case elfcpp::R_POWERPC_PLT16_HA:
    case elfcpp::R_PPC64_PLT16_LO_DS:
      if (!pushed_ifunc)
	target->make_plt_entry(symtab, layout, gsym);
      break;

    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	break;
      // Fall through.
    case elfcpp::R_PPC_PLTREL24:
    case elfcpp::R_POWERPC_REL24:
      if (!is_ifunc)
	{
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
			      r_type, r_sym, reloc.get_r_addend());
	  if (gsym->needs_plt_entry()
	      || (!gsym->final_value_is_known()
		  && (gsym->is_undefined()
		      || gsym->is_from_dynobj()
		      || gsym->is_preemptible())))
	    target->make_plt_entry(symtab, layout, gsym);
	}
      // Fall through.

    case elfcpp::R_PPC64_REL64:
    case elfcpp::R_POWERPC_REL32:
      // Make a dynamic relocation if necessary.
      if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type, target)))
	{
	  if (!parameters->options().output_is_position_independent()
	      && gsym->may_need_copy_reloc())
	    {
	      target->copy_reloc(symtab, layout, object,
				 data_shndx, output_section, gsym,
				 reloc);
	    }
	  else
	    {
	      Reloc_section* rela_dyn
		= target->rela_dyn_section(symtab, layout, is_ifunc);
	      check_non_pic(object, r_type);
	      rela_dyn->add_global(gsym, r_type, output_section, object,
				   data_shndx, reloc.get_r_offset(),
				   reloc.get_r_addend());
	    }
	}
      break;

    case elfcpp::R_POWERPC_REL14:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
      if (!is_ifunc)
	{
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  target->push_branch(ppc_object, data_shndx, reloc.get_r_offset(),
			      r_type, r_sym, reloc.get_r_addend());
	}
      break;

    case elfcpp::R_PPC64_TOCSAVE:
      // R_PPC64_TOCSAVE follows a call instruction to indicate the
      // caller has already saved r2 and thus a plt call stub need not
      // save r2.
      if (size == 64
	  && target->mark_pltcall(ppc_object, data_shndx,
				  reloc.get_r_offset() - 4, symtab))
	{
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info());
	  bool is_ordinary;
	  unsigned int shndx = gsym->shndx(&is_ordinary);
	  if (!is_ordinary)
	    object->error(_("tocsave symbol %u has bad shndx %u"),
			  r_sym, shndx);
	  else
	    {
	      Sized_symbol<size>* sym = symtab->get_sized_symbol<size>(gsym);
	      target->add_tocsave(ppc_object, shndx,
				  sym->value() + reloc.get_r_addend());
	    }
	}
      break;

    case elfcpp::R_POWERPC_REL16:
    case elfcpp::R_POWERPC_REL16_LO:
    case elfcpp::R_POWERPC_REL16_HI:
    case elfcpp::R_POWERPC_REL16_HA:
    case elfcpp::R_POWERPC_REL16DX_HA:
    case elfcpp::R_PPC64_REL16_HIGH:
    case elfcpp::R_PPC64_REL16_HIGHA:
    case elfcpp::R_PPC64_REL16_HIGHER:
    case elfcpp::R_PPC64_REL16_HIGHERA:
    case elfcpp::R_PPC64_REL16_HIGHEST:
    case elfcpp::R_PPC64_REL16_HIGHESTA:
    case elfcpp::R_POWERPC_SECTOFF:
    case elfcpp::R_POWERPC_SECTOFF_LO:
    case elfcpp::R_POWERPC_SECTOFF_HI:
    case elfcpp::R_POWERPC_SECTOFF_HA:
    case elfcpp::R_PPC64_SECTOFF_DS:
    case elfcpp::R_PPC64_SECTOFF_LO_DS:
    case elfcpp::R_POWERPC_TPREL16:
    case elfcpp::R_POWERPC_TPREL16_LO:
    case elfcpp::R_POWERPC_TPREL16_HI:
    case elfcpp::R_POWERPC_TPREL16_HA:
    case elfcpp::R_PPC64_TPREL16_DS:
    case elfcpp::R_PPC64_TPREL16_LO_DS:
    case elfcpp::R_PPC64_TPREL16_HIGH:
    case elfcpp::R_PPC64_TPREL16_HIGHA:
    case elfcpp::R_PPC64_TPREL16_HIGHER:
    case elfcpp::R_PPC64_TPREL16_HIGHERA:
    case elfcpp::R_PPC64_TPREL16_HIGHEST:
    case elfcpp::R_PPC64_TPREL16_HIGHESTA:
    case elfcpp::R_POWERPC_DTPREL16:
    case elfcpp::R_POWERPC_DTPREL16_LO:
    case elfcpp::R_POWERPC_DTPREL16_HI:
    case elfcpp::R_POWERPC_DTPREL16_HA:
    case elfcpp::R_PPC64_DTPREL16_DS:
    case elfcpp::R_PPC64_DTPREL16_LO_DS:
    case elfcpp::R_PPC64_DTPREL16_HIGH:
    case elfcpp::R_PPC64_DTPREL16_HIGHA:
    case elfcpp::R_PPC64_DTPREL16_HIGHER:
    case elfcpp::R_PPC64_DTPREL16_HIGHERA:
    case elfcpp::R_PPC64_DTPREL16_HIGHEST:
    case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
    case elfcpp::R_PPC64_TLSGD:
    case elfcpp::R_PPC64_TLSLD:
    case elfcpp::R_PPC64_ADDR64_LOCAL:
      break;

    case elfcpp::R_PPC64_GOT_PCREL34:
    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_POWERPC_GOT16_LO:
    case elfcpp::R_POWERPC_GOT16_HI:
    case elfcpp::R_POWERPC_GOT16_HA:
    case elfcpp::R_PPC64_GOT16_DS:
    case elfcpp::R_PPC64_GOT16_LO_DS:
      {
	// The symbol requires a GOT entry.
	Output_data_got_powerpc<size, big_endian>* got;
	uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();
	Got_type got_type = ((size == 32
			      || r_type == elfcpp::R_POWERPC_GOT16
			      || r_type == elfcpp::R_PPC64_GOT16_DS)
			     ? GOT_TYPE_SMALL : GOT_TYPE_STANDARD);

	got = target->got_section(symtab, layout, got_type);
	if (gsym->final_value_is_known())
	  {
	    if (is_ifunc
		&& (size == 32 || target->abiversion() >= 2))
	      got->add_global_plt(gsym, got_type, addend);
	    else
	      got->add_global(gsym, got_type, addend);
	  }
	else if (!gsym->has_got_offset(got_type, addend))
	  {
	    // If we are generating a shared object or a pie, this
	    // symbol's GOT entry will be set by a dynamic relocation.
	    unsigned int off = got->add_constant(0);
	    gsym->set_got_offset(got_type, off, addend);

	    Reloc_section* rela_dyn
	      = target->rela_dyn_section(symtab, layout, is_ifunc);

	    if (gsym->can_use_relative_reloc(false)
		&& !((size == 32
		      || target->abiversion() >= 2)
		     && gsym->visibility() == elfcpp::STV_PROTECTED
		     && parameters->options().shared()))
	      {
		unsigned int dynrel = (is_ifunc ? elfcpp::R_POWERPC_IRELATIVE
				       : elfcpp::R_POWERPC_RELATIVE);
		rela_dyn->add_global_relative(gsym, dynrel, got, off,
					      addend, false);
	      }
	    else
	      {
		unsigned int dynrel = elfcpp::R_POWERPC_GLOB_DAT;
		rela_dyn->add_global(gsym, dynrel, got, off, addend);
	      }
	  }
      }
      break;

    case elfcpp::R_PPC64_TOC16:
    case elfcpp::R_PPC64_TOC16_LO:
    case elfcpp::R_PPC64_TOC16_HI:
    case elfcpp::R_PPC64_TOC16_HA:
    case elfcpp::R_PPC64_TOC16_DS:
    case elfcpp::R_PPC64_TOC16_LO_DS:
      // We need a GOT section.
      target->got_section(symtab, layout, GOT_TYPE_SMALL);
      break;

    case elfcpp::R_PPC64_GOT_TLSGD_PCREL34:
    case elfcpp::R_POWERPC_GOT_TLSGD16:
    case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
    case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
    case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
      {
	tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
	if (!ppc_object->no_tls_marker())
	  {
	    bool final = gsym->final_value_is_known();
	    tls_type = target->optimize_tls_gd(final);
	  }
	if (tls_type == tls::TLSOPT_NONE)
	  {
	    Got_type got_type = ((size == 32
				  || r_type == elfcpp::R_POWERPC_GOT_TLSGD16)
				 ? GOT_TYPE_SMALL_TLSGD : GOT_TYPE_TLSGD);
	    Output_data_got_powerpc<size, big_endian>* got
	      = target->got_section(symtab, layout, got_type);
	    Reloc_section* rela_dyn = target->rela_dyn_section(layout);
	    uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();
	    got->add_global_pair_with_rel(gsym, got_type, rela_dyn,
					  elfcpp::R_POWERPC_DTPMOD,
					  elfcpp::R_POWERPC_DTPREL,
					  addend);
	  }
	else if (tls_type == tls::TLSOPT_TO_IE)
	  {
	    Got_type got_type = ((size == 32
				  || r_type == elfcpp::R_POWERPC_GOT_TLSGD16)
				 ? GOT_TYPE_SMALL_TPREL : GOT_TYPE_TPREL);
	    if (!gsym->has_got_offset(got_type))
	      {
		Output_data_got_powerpc<size, big_endian>* got
		  = target->got_section(symtab, layout, got_type);
		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();
		if (gsym->is_undefined()
		    || gsym->is_from_dynobj())
		  {
		    got->add_global_with_rel(gsym, got_type, rela_dyn,
					     elfcpp::R_POWERPC_TPREL, addend);
		  }
		else
		  {
		    unsigned int off = got->add_constant(0);
		    gsym->set_got_offset(got_type, off);
		    unsigned int dynrel = elfcpp::R_POWERPC_TPREL;
		    rela_dyn->add_symbolless_global_addend(gsym, dynrel,
							   got, off, addend);
		  }
	      }
	    ppc_object->set_tls_marker();
	  }
	else if (tls_type == tls::TLSOPT_TO_LE)
	  {
	    // no GOT relocs needed for Local Exec.
	    ppc_object->set_tls_marker();
	  }
	else
	  gold_unreachable();
      }
      break;

    case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
    case elfcpp::R_POWERPC_GOT_TLSLD16:
    case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
    case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
    case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
      {
	tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
	if (!ppc_object->no_tls_marker())
	  tls_type = target->optimize_tls_ld();
	if (tls_type == tls::TLSOPT_NONE)
	  target->tlsld_got_offset(symtab, layout, object);
	else if (tls_type == tls::TLSOPT_TO_LE)
	  {
	    // no GOT relocs needed for Local Exec.
	    if (parameters->options().emit_relocs())
	      {
		Output_section* os = layout->tls_segment()->first_section();
		gold_assert(os != NULL);
		os->set_needs_symtab_index();
	      }
	    ppc_object->set_tls_marker();
	  }
	else
	  gold_unreachable();
      }
      break;

    case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
    case elfcpp::R_POWERPC_GOT_DTPREL16:
    case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
    case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
    case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
      {
	Got_type got_type = ((size == 32
			      || r_type == elfcpp::R_POWERPC_GOT_DTPREL16)
			     ? GOT_TYPE_SMALL_DTPREL : GOT_TYPE_DTPREL);
	Output_data_got_powerpc<size, big_endian>* got
	  = target->got_section(symtab, layout, got_type);
	uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();
	if (!gsym->final_value_is_known()
	    && (gsym->is_from_dynobj()
		|| gsym->is_undefined()
		|| gsym->is_preemptible()))
	  got->add_global_with_rel(gsym, got_type,
				   target->rela_dyn_section(layout),
				   elfcpp::R_POWERPC_DTPREL, addend);
	else
	  got->add_global_tls(gsym, got_type, addend);
      }
      break;

    case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
    case elfcpp::R_POWERPC_GOT_TPREL16:
    case elfcpp::R_POWERPC_GOT_TPREL16_LO:
    case elfcpp::R_POWERPC_GOT_TPREL16_HI:
    case elfcpp::R_POWERPC_GOT_TPREL16_HA:
      {
	bool final = gsym->final_value_is_known();
	tls::Tls_optimization tls_type = target->optimize_tls_ie(final);
	if (tls_type == tls::TLSOPT_NONE)
	  {
	    Got_type got_type = ((size == 32
				  || r_type == elfcpp::R_POWERPC_GOT_TPREL16)
				 ? GOT_TYPE_SMALL_TPREL : GOT_TYPE_TPREL);
	    if (!gsym->has_got_offset(got_type))
	      {
		Output_data_got_powerpc<size, big_endian>* got
		  = target->got_section(symtab, layout, got_type);
		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		uint64_t addend = size == 32 ? 0 : reloc.get_r_addend();
		if (gsym->is_undefined()
		    || gsym->is_from_dynobj())
		  {
		    got->add_global_with_rel(gsym, got_type, rela_dyn,
					     elfcpp::R_POWERPC_TPREL, addend);
		  }
		else
		  {
		    unsigned int off = got->add_constant(0);
		    gsym->set_got_offset(got_type, off);
		    unsigned int dynrel = elfcpp::R_POWERPC_TPREL;
		    rela_dyn->add_symbolless_global_addend(gsym, dynrel,
							   got, off, addend);
		  }
	      }
	  }
	else if (tls_type == tls::TLSOPT_TO_LE)
	  {
	    // no GOT relocs needed for Local Exec.
	  }
	else
	  gold_unreachable();
      }
      break;

    default:
      unsupported_reloc_global(object, r_type, gsym);
      break;
    }

  if (size == 64
      && parameters->options().toc_optimize())
    {
      if (data_shndx == ppc_object->toc_shndx())
	{
	  bool ok = true;
	  if (r_type != elfcpp::R_PPC64_ADDR64
	      || (is_ifunc && target->abiversion() < 2))
	    ok = false;
	  else if (parameters->options().output_is_position_independent()
		   && (is_ifunc || gsym->is_absolute() || gsym->is_undefined()))
	    ok = false;
	  if (!ok)
	    ppc_object->set_no_toc_opt(reloc.get_r_offset());
	}

      enum {no_check, check_lo, check_ha} insn_check;
      switch (r_type)
	{
	default:
	  insn_check = no_check;
	  break;

	case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
	case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
	case elfcpp::R_POWERPC_GOT_TPREL16_HA:
	case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
	case elfcpp::R_POWERPC_GOT16_HA:
	case elfcpp::R_PPC64_TOC16_HA:
	  insn_check = check_ha;
	  break;

	case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
	case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
	case elfcpp::R_POWERPC_GOT_TPREL16_LO:
	case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
	case elfcpp::R_POWERPC_GOT16_LO:
	case elfcpp::R_PPC64_GOT16_LO_DS:
	case elfcpp::R_PPC64_TOC16_LO:
	case elfcpp::R_PPC64_TOC16_LO_DS:
	  insn_check = check_lo;
	  break;
	}

      section_size_type slen;
      const unsigned char* view = NULL;
      if (insn_check != no_check)
	{
	  view = ppc_object->section_contents(data_shndx, &slen, false);
	  section_size_type off =
	    convert_to_section_size_type(reloc.get_r_offset()) & -4;
	  if (off < slen)
	    {
	      uint32_t insn = elfcpp::Swap<32, big_endian>::readval(view + off);
	      if (insn_check == check_lo
		  ? !ok_lo_toc_insn(insn, r_type)
		  : ((insn & ((0x3f << 26) | 0x1f << 16))
		     != ((15u << 26) | (2 << 16)) /* addis rt,2,imm */))
		{
		  ppc_object->set_no_toc_opt();
		  gold_warning(_("%s: toc optimization is not supported "
				 "for %#08x instruction"),
			       ppc_object->name().c_str(), insn);
		}
	    }
	}

      switch (r_type)
	{
	default:
	  break;
	case elfcpp::R_PPC64_TOC16:
	case elfcpp::R_PPC64_TOC16_LO:
	case elfcpp::R_PPC64_TOC16_HI:
	case elfcpp::R_PPC64_TOC16_HA:
	case elfcpp::R_PPC64_TOC16_DS:
	case elfcpp::R_PPC64_TOC16_LO_DS:
	  if (gsym->source() == Symbol::FROM_OBJECT
	      && !gsym->object()->is_dynamic())
	    {
	      Powerpc_relobj<size, big_endian>* sym_object
		= static_cast<Powerpc_relobj<size, big_endian>*>(gsym->object());
	      bool is_ordinary;
	      unsigned int shndx = gsym->shndx(&is_ordinary);
	      if (shndx == sym_object->toc_shndx())
		{
		  Sized_symbol<size>* sym = symtab->get_sized_symbol<size>(gsym);
		  Address dst_off = sym->value() + reloc.get_r_addend();
		  if (dst_off < sym_object->section_size(shndx))
		    {
		      bool ok = false;
		      if (r_type == elfcpp::R_PPC64_TOC16_HA)
			ok = true;
		      else if (r_type == elfcpp::R_PPC64_TOC16_LO_DS)
			{
			  // Need to check that the insn is a ld
			  if (!view)
			    view = ppc_object->section_contents(data_shndx,
								&slen,
								false);
			  section_size_type off =
			    (convert_to_section_size_type(reloc.get_r_offset())
			     + (big_endian ? -2 : 3));
			  if (off < slen
			      && (view[off] & (0x3f << 2)) == (58u << 2))
			    ok = true;
			}
		      if (!ok)
			sym_object->set_no_toc_opt(dst_off);
		    }
		}
	    }
	  break;
	}
    }

  if (size == 32)
    {
      switch (r_type)
	{
	case elfcpp::R_PPC_LOCAL24PC:
	  if (strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
	    gold_error(_("%s: unsupported -mbss-plt code"),
		       ppc_object->name().c_str());
	  break;
	default:
	  break;
	}
    }

  switch (r_type)
    {
    case elfcpp::R_POWERPC_GOT_TLSLD16:
    case elfcpp::R_POWERPC_GOT_TLSGD16:
    case elfcpp::R_POWERPC_GOT_TPREL16:
    case elfcpp::R_POWERPC_GOT_DTPREL16:
    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_PPC64_GOT16_DS:
    case elfcpp::R_PPC64_TOC16:
    case elfcpp::R_PPC64_TOC16_DS:
      ppc_object->set_has_small_toc_reloc();
      break;
    default:
      break;
    }

  switch (r_type)
    {
    case elfcpp::R_PPC64_TPREL16_DS:
    case elfcpp::R_PPC64_TPREL16_LO_DS:
    case elfcpp::R_PPC64_TPREL16_HIGH:
    case elfcpp::R_PPC64_TPREL16_HIGHA:
    case elfcpp::R_PPC64_TPREL16_HIGHER:
    case elfcpp::R_PPC64_TPREL16_HIGHERA:
    case elfcpp::R_PPC64_TPREL16_HIGHEST:
    case elfcpp::R_PPC64_TPREL16_HIGHESTA:
    case elfcpp::R_PPC64_TPREL34:
      if (size != 64)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_TPREL16:
    case elfcpp::R_POWERPC_TPREL16_LO:
    case elfcpp::R_POWERPC_TPREL16_HI:
    case elfcpp::R_POWERPC_TPREL16_HA:
      layout->set_has_static_tls();
      break;
    default:
      break;
    }

  switch (r_type)
    {
    case elfcpp::R_POWERPC_TPREL16_HA:
      if (target->tprel_opt())
	{
	  section_size_type slen;
	  const unsigned char* view = NULL;
	  view = ppc_object->section_contents(data_shndx, &slen, false);
	  section_size_type off
	    = convert_to_section_size_type(reloc.get_r_offset()) & -4;
	  if (off < slen)
	    {
	      uint32_t insn = elfcpp::Swap<32, big_endian>::readval(view + off);
	      if ((insn & ((0x3fu << 26) | 0x1f << 16))
		  != ((15u << 26) | ((size == 32 ? 2 : 13) << 16)))
		target->set_no_tprel_opt();
	    }
	}
      break;

    case elfcpp::R_PPC64_TPREL16_HIGH:
    case elfcpp::R_PPC64_TPREL16_HIGHA:
    case elfcpp::R_PPC64_TPREL16_HIGHER:
    case elfcpp::R_PPC64_TPREL16_HIGHERA:
    case elfcpp::R_PPC64_TPREL16_HIGHEST:
    case elfcpp::R_PPC64_TPREL16_HIGHESTA:
      if (size != 64)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_TPREL16_HI:
      target->set_no_tprel_opt();
      break;
    default:
      break;
    }

  switch (r_type)
    {
    case elfcpp::R_PPC64_D34:
    case elfcpp::R_PPC64_D34_LO:
    case elfcpp::R_PPC64_D34_HI30:
    case elfcpp::R_PPC64_D34_HA30:
    case elfcpp::R_PPC64_D28:
    case elfcpp::R_PPC64_PCREL34:
    case elfcpp::R_PPC64_PCREL28:
    case elfcpp::R_PPC64_TPREL34:
    case elfcpp::R_PPC64_DTPREL34:
    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
    case elfcpp::R_PPC64_GOT_PCREL34:
    case elfcpp::R_PPC64_GOT_TLSGD_PCREL34:
    case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
    case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
    case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
      target->set_power10_relocs();
      break;
    default:
      break;
    }
}

// Process relocations for gc.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::gc_process_relocs(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    unsigned int,
    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_symbols)
{
  typedef Target_powerpc<size, big_endian> Powerpc;
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
      Classify_reloc;

  Powerpc_relobj<size, big_endian>* ppc_object
    = static_cast<Powerpc_relobj<size, big_endian>*>(object);
  if (size == 64)
    ppc_object->set_opd_valid();
  if (size == 64 && data_shndx == ppc_object->opd_shndx())
    {
      typename Powerpc_relobj<size, big_endian>::Access_from::iterator p;
      for (p = ppc_object->access_from_map()->begin();
	   p != ppc_object->access_from_map()->end();
	   ++p)
	{
	  Address dst_off = p->first;
	  unsigned int dst_indx = ppc_object->get_opd_ent(dst_off);
	  typename Powerpc_relobj<size, big_endian>::Section_refs::iterator s;
	  for (s = p->second.begin(); s != p->second.end(); ++s)
	    {
	      Relobj* src_obj = s->first;
	      unsigned int src_indx = s->second;
	      symtab->gc()->add_reference(src_obj, src_indx,
					  ppc_object, dst_indx);
	    }
	  p->second.clear();
	}
      ppc_object->access_from_map()->clear();
      ppc_object->process_gc_mark(symtab);
      // Don't look at .opd relocs as .opd will reference everything.
      return;
    }

  gold::gc_process_relocs<size, big_endian, Powerpc, Scan, Classify_reloc>(
    symtab,
    layout,
    this,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols);
}

// Handle target specific gc actions when adding a gc reference from
// SRC_OBJ, SRC_SHNDX to a location specified by DST_OBJ, DST_SHNDX
// and DST_OFF.  For powerpc64, this adds a referenc to the code
// section of a function descriptor.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_gc_add_reference(
    Symbol_table* symtab,
    Relobj* src_obj,
    unsigned int src_shndx,
    Relobj* dst_obj,
    unsigned int dst_shndx,
    Address dst_off) const
{
  if (size != 64 || dst_obj->is_dynamic())
    return;

  Powerpc_relobj<size, big_endian>* ppc_object
    = static_cast<Powerpc_relobj<size, big_endian>*>(dst_obj);
  if (dst_shndx != 0 && dst_shndx == ppc_object->opd_shndx())
    {
      if (ppc_object->opd_valid())
	{
	  dst_shndx = ppc_object->get_opd_ent(dst_off);
	  symtab->gc()->add_reference(src_obj, src_shndx, dst_obj, dst_shndx);
	}
      else
	{
	  // If we haven't run scan_opd_relocs, we must delay
	  // processing this function descriptor reference.
	  ppc_object->add_reference(src_obj, src_shndx, dst_off);
	}
    }
}

// Add any special sections for this symbol to the gc work list.
// For powerpc64, this adds the code section of a function
// descriptor.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_gc_mark_symbol(
    Symbol_table* symtab,
    Symbol* sym) const
{
  if (size == 64 && sym->object()->pluginobj() == NULL)
    {
      Powerpc_relobj<size, big_endian>* ppc_object
	= static_cast<Powerpc_relobj<size, big_endian>*>(sym->object());
      bool is_ordinary;
      unsigned int shndx = sym->shndx(&is_ordinary);
      if (is_ordinary && shndx != 0 && shndx == ppc_object->opd_shndx())
	{
	  Sized_symbol<size>* gsym = symtab->get_sized_symbol<size>(sym);
	  Address dst_off = gsym->value();
	  if (ppc_object->opd_valid())
	    {
	      unsigned int dst_indx = ppc_object->get_opd_ent(dst_off);
	      symtab->gc()->worklist().push_back(Section_id(ppc_object,
                                                            dst_indx));
	    }
	  else
	    ppc_object->add_gc_mark(dst_off);
	}
    }
}

// For a symbol location in .opd, set LOC to the location of the
// function entry.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_function_location(
    Symbol_location* loc) const
{
  if (size == 64 && loc->shndx != 0)
    {
      if (loc->object->is_dynamic())
	{
	  Powerpc_dynobj<size, big_endian>* ppc_object
	    = static_cast<Powerpc_dynobj<size, big_endian>*>(loc->object);
	  if (loc->shndx == ppc_object->opd_shndx())
	    {
	      Address dest_off;
	      Address off = loc->offset - ppc_object->opd_address();
	      loc->shndx = ppc_object->get_opd_ent(off, &dest_off);
	      loc->offset = dest_off;
	    }
	}
      else
	{
	  const Powerpc_relobj<size, big_endian>* ppc_object
	    = static_cast<const Powerpc_relobj<size, big_endian>*>(loc->object);
	  if (loc->shndx == ppc_object->opd_shndx())
	    {
	      Address dest_off;
	      loc->shndx = ppc_object->get_opd_ent(loc->offset, &dest_off);
	      loc->offset = dest_off;
	    }
	}
    }
}

// FNOFFSET in section SHNDX in OBJECT is the start of a function
// compiled with -fsplit-stack.  The function calls non-split-stack
// code.  Change the function to ensure it has enough stack space to
// call some random function.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_calls_non_split(
    Relobj* object,
    unsigned int shndx,
    section_offset_type fnoffset,
    section_size_type fnsize,
    const unsigned char* prelocs,
    size_t reloc_count,
    unsigned char* view,
    section_size_type view_size,
    std::string* from,
    std::string* to) const
{
  // 32-bit not supported.
  if (size == 32)
    {
      // warn
      Target::do_calls_non_split(object, shndx, fnoffset, fnsize,
				 prelocs, reloc_count, view, view_size,
				 from, to);
      return;
    }

  // The function always starts with
  //	ld %r0,-0x7000-64(%r13)  # tcbhead_t.__private_ss
  //	addis %r12,%r1,-allocate@ha
  //	addi %r12,%r12,-allocate@l
  //	cmpld %r12,%r0
  // but note that the addis or addi may be replaced with a nop

  unsigned char *entry = view + fnoffset;
  uint32_t insn = elfcpp::Swap<32, big_endian>::readval(entry);

  if ((insn & 0xffff0000) == addis_2_12)
    {
      /* Skip ELFv2 global entry code.  */
      entry += 8;
      insn = elfcpp::Swap<32, big_endian>::readval(entry);
    }

  unsigned char *pinsn = entry;
  bool ok = false;
  const uint32_t ld_private_ss = 0xe80d8fc0;
  if (insn == ld_private_ss)
    {
      int32_t allocate = 0;
      while (1)
	{
	  pinsn += 4;
	  insn = elfcpp::Swap<32, big_endian>::readval(pinsn);
	  if ((insn & 0xffff0000) == addis_12_1)
	    allocate += (insn & 0xffff) << 16;
	  else if ((insn & 0xffff0000) == addi_12_1
		   || (insn & 0xffff0000) == addi_12_12)
	    allocate += ((insn & 0xffff) ^ 0x8000) - 0x8000;
	  else if (insn != nop)
	    break;
	}
      if (insn == cmpld_7_12_0 && pinsn == entry + 12)
	{
	  int extra = parameters->options().split_stack_adjust_size();
	  allocate -= extra;
	  if (allocate >= 0 || extra < 0)
	    {
	      object->error(_("split-stack stack size overflow at "
			      "section %u offset %0zx"),
			    shndx, static_cast<size_t>(fnoffset));
	      return;
	    }
	  pinsn = entry + 4;
	  insn = addis_12_1 | (((allocate + 0x8000) >> 16) & 0xffff);
	  if (insn != addis_12_1)
	    {
	      elfcpp::Swap<32, big_endian>::writeval(pinsn, insn);
	      pinsn += 4;
	      insn = addi_12_12 | (allocate & 0xffff);
	      if (insn != addi_12_12)
		{
		  elfcpp::Swap<32, big_endian>::writeval(pinsn, insn);
		  pinsn += 4;
		}
	    }
	  else
	    {
	      insn = addi_12_1 | (allocate & 0xffff);
	      elfcpp::Swap<32, big_endian>::writeval(pinsn, insn);
	      pinsn += 4;
	    }
	  if (pinsn != entry + 12)
	    elfcpp::Swap<32, big_endian>::writeval(pinsn, nop);

	  ok = true;
	}
    }

  if (!ok)
    {
      if (!object->has_no_split_stack())
	object->error(_("failed to match split-stack sequence at "
			"section %u offset %0zx"),
		      shndx, static_cast<size_t>(fnoffset));
    }
}

// Scan relocations for a section.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::scan_relocs(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    unsigned int sh_type,
    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_symbols)
{
  typedef Target_powerpc<size, big_endian> Powerpc;
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
      Classify_reloc;

  if (!this->plt_localentry0_init_)
    {
      bool plt_localentry0 = false;
      if (size == 64
	  && this->abiversion() >= 2)
	{
	  if (parameters->options().user_set_plt_localentry())
	    plt_localentry0 = parameters->options().plt_localentry();
	  if (plt_localentry0
	      && symtab->lookup("GLIBC_2.26", NULL) == NULL)
	    gold_warning(_("--plt-localentry is especially dangerous without "
			   "ld.so support to detect ABI violations"));
	}
      this->plt_localentry0_ = plt_localentry0;
      this->plt_localentry0_init_ = true;
    }

  if (sh_type == elfcpp::SHT_REL)
    {
      gold_error(_("%s: unsupported REL reloc section"),
		 object->name().c_str());
      return;
    }

  gold::scan_relocs<size, big_endian, Powerpc, Scan, Classify_reloc>(
    symtab,
    layout,
    this,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols);

  if (this->plt_localentry0_ && this->power10_relocs_)
    {
      gold_warning(_("--plt-localentry is incompatible with "
		     "power10 pc-relative code"));
      this->plt_localentry0_ = false;
    }
}

// Functor class for processing the global symbol table.
// Removes symbols defined on discarded opd entries.

template<bool big_endian>
class Global_symbol_visitor_opd
{
 public:
  Global_symbol_visitor_opd()
  { }

  void
  operator()(Sized_symbol<64>* sym)
  {
    if (sym->has_symtab_index()
	|| sym->source() != Symbol::FROM_OBJECT
	|| !sym->in_real_elf())
      return;

    if (sym->object()->is_dynamic())
      return;

    Powerpc_relobj<64, big_endian>* symobj
      = static_cast<Powerpc_relobj<64, big_endian>*>(sym->object());
    if (symobj->opd_shndx() == 0)
      return;

    bool is_ordinary;
    unsigned int shndx = sym->shndx(&is_ordinary);
    if (shndx == symobj->opd_shndx()
	&& symobj->get_opd_discard(sym->value()))
      {
	sym->set_undefined();
	sym->set_visibility(elfcpp::STV_DEFAULT);
	sym->set_is_defined_in_discarded_section();
	sym->set_symtab_index(-1U);
      }
  }
};

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::define_save_restore_funcs(
    Layout* layout,
    Symbol_table* symtab)
{
  if (size == 64)
    {
      Output_data_save_res<size, big_endian>* savres
	= new Output_data_save_res<size, big_endian>(symtab);
      this->savres_section_ = savres;
      layout->add_output_section_data(".text", elfcpp::SHT_PROGBITS,
				      elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR,
				      savres, ORDER_TEXT, false);
    }
}

// Sort linker created .got section first (for the header), then input
// sections belonging to files using small model code.

template<bool big_endian>
class Sort_toc_sections
{
  const Output_section_data*
  small_got_section() const
  {
    return (static_cast<Target_powerpc<64, big_endian>*>(
		parameters->sized_target<64, big_endian>())
	    ->got_section(GOT_TYPE_SMALL));
  }

  int
  rank(const Output_section::Input_section& isec) const
  {
    if (!isec.is_input_section())
      {
	if (isec.output_section_data() == this->small_got_section())
	  return 0;
	return 2;
      }
    if (static_cast<const Powerpc_relobj<64, big_endian>*>(isec.relobj())
	->has_small_toc_reloc())
      return 1;
    return 3;
  }

 public:
  bool
  operator()(const Output_section::Input_section& is1,
	     const Output_section::Input_section& is2) const
  {
    return rank(is1) < rank(is2);
  }
};

// Finalize the sections.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::do_finalize_sections(
    Layout* layout,
    const Input_objects* input_objects,
    Symbol_table* symtab)
{
  if (parameters->doing_static_link())
    {
      // At least some versions of glibc elf-init.o have a strong
      // reference to __rela_iplt marker syms.  A weak ref would be
      // better..
      if (this->iplt_ != NULL)
	{
	  Reloc_section* rel = this->iplt_->rel_plt();
	  symtab->define_in_output_data("__rela_iplt_start", NULL,
					Symbol_table::PREDEFINED, rel, 0, 0,
					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
					elfcpp::STV_HIDDEN, 0, false, true);
	  symtab->define_in_output_data("__rela_iplt_end", NULL,
					Symbol_table::PREDEFINED, rel, 0, 0,
					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
					elfcpp::STV_HIDDEN, 0, true, true);
	}
      else
	{
	  symtab->define_as_constant("__rela_iplt_start", NULL,
				     Symbol_table::PREDEFINED, 0, 0,
				     elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
				     elfcpp::STV_HIDDEN, 0, true, false);
	  symtab->define_as_constant("__rela_iplt_end", NULL,
				     Symbol_table::PREDEFINED, 0, 0,
				     elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
				     elfcpp::STV_HIDDEN, 0, true, false);
	}
    }

  if (size == 64)
    {
      typedef Global_symbol_visitor_opd<big_endian> Symbol_visitor;
      symtab->for_all_symbols<64, Symbol_visitor>(Symbol_visitor());

      if (!parameters->options().relocatable())
	{
	  this->define_save_restore_funcs(layout, symtab);

	  // Annoyingly, we need to make these sections now whether or
	  // not we need them.  If we delay until do_relax then we
	  // need to mess with the relaxation machinery checkpointing.
	  this->got_section(symtab, layout, GOT_TYPE_STANDARD);
	  this->make_brlt_section(layout);

	  // FIXME, maybe.  Here we could run through all the got
	  // entries in the small got section, removing any duplicates
	  // found in the big got section and renumbering offsets.

	  if (parameters->options().toc_sort())
	    {
	      Output_section* os = this->got_->output_section();
	      if (os != NULL && os->input_sections().size() > 1)
		std::stable_sort(os->input_sections().begin(),
				 os->input_sections().end(),
				 Sort_toc_sections<big_endian>());
	    }
	}
    }

  // Fill in some more dynamic tags.
  Output_data_dynamic* odyn = layout->dynamic_data();
  if (odyn != NULL)
    {
      const Reloc_section* rel_plt = (this->plt_ == NULL
				      ? NULL
				      : this->plt_->rel_plt());
      layout->add_target_dynamic_tags(false, this->plt_, rel_plt,
				      this->rela_dyn_, true, size == 32);

      if (size == 32)
	{
	  if (this->got_ != NULL)
	    {
	      this->got_->finalize_data_size();
	      odyn->add_section_plus_offset(elfcpp::DT_PPC_GOT,
					    this->got_, this->got_->g_o_t());
	    }
	  if (this->has_tls_get_addr_opt_)
	    odyn->add_constant(elfcpp::DT_PPC_OPT, elfcpp::PPC_OPT_TLS);
	}
      else
	{
	  if (this->glink_ != NULL)
	    {
	      this->glink_->finalize_data_size();
	      odyn->add_section_plus_offset(elfcpp::DT_PPC64_GLINK,
					    this->glink_,
					    (this->glink_->pltresolve_size()
					     - 32));
	    }
	  if (this->has_localentry0_ || this->has_tls_get_addr_opt_)
	    odyn->add_constant(elfcpp::DT_PPC64_OPT,
			       ((this->has_localentry0_
				 ? elfcpp::PPC64_OPT_LOCALENTRY : 0)
				| (this->has_tls_get_addr_opt_
				   ? elfcpp::PPC64_OPT_TLS : 0)));
	}
    }

  // Emit any relocs we saved in an attempt to avoid generating COPY
  // relocs.
  if (this->copy_relocs_.any_saved_relocs())
    this->copy_relocs_.emit(this->rela_dyn_section(layout));

  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      Powerpc_relobj<size, big_endian>* ppc_relobj
	= static_cast<Powerpc_relobj<size, big_endian>*>(*p);
      if (ppc_relobj->attributes_section_data())
	this->merge_object_attributes(ppc_relobj,
				      ppc_relobj->attributes_section_data());
    }
  for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
       p != input_objects->dynobj_end();
       ++p)
    {
      Powerpc_dynobj<size, big_endian>* ppc_dynobj
	= static_cast<Powerpc_dynobj<size, big_endian>*>(*p);
      if (ppc_dynobj->attributes_section_data())
	this->merge_object_attributes(ppc_dynobj,
				      ppc_dynobj->attributes_section_data());
    }

  // Create a .gnu.attributes section if we have merged any attributes
  // from inputs.
  if (this->attributes_section_data_ != NULL
      && this->attributes_section_data_->size() != 0)
    {
      Output_attributes_section_data* attributes_section
	= new Output_attributes_section_data(*this->attributes_section_data_);
      layout->add_output_section_data(".gnu.attributes",
				      elfcpp::SHT_GNU_ATTRIBUTES, 0,
				      attributes_section, ORDER_INVALID, false);
    }
}

// Merge object attributes from input file called NAME with those of the
// output.  The input object attributes are in the object pointed by PASD.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::merge_object_attributes(
    const Object* obj,
    const Attributes_section_data* pasd)
{
  // Return if there is no attributes section data.
  if (pasd == NULL)
    return;

  // Create output object attributes.
  if (this->attributes_section_data_ == NULL)
    this->attributes_section_data_ = new Attributes_section_data(NULL, 0);

  const int vendor = Object_attribute::OBJ_ATTR_GNU;
  const Object_attribute* in_attr = pasd->known_attributes(vendor);
  Object_attribute* out_attr
    = this->attributes_section_data_->known_attributes(vendor);

  const char* name = obj->name().c_str();
  const char* err;
  const char* first;
  const char* second;
  int tag = elfcpp::Tag_GNU_Power_ABI_FP;
  int in_fp = in_attr[tag].int_value() & 0xf;
  int out_fp = out_attr[tag].int_value() & 0xf;
  bool warn_only = obj->is_dynamic();
  if (in_fp != out_fp)
    {
      err = NULL;
      if ((in_fp & 3) == 0)
	;
      else if ((out_fp & 3) == 0)
	{
	  if (!warn_only)
	    {
	      out_fp |= in_fp & 3;
	      out_attr[tag].set_int_value(out_fp);
	      out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
	      this->last_fp_ = name;
	    }
	}
      else if ((out_fp & 3) != 2 && (in_fp & 3) == 2)
	{
	  err = N_("%s uses hard float, %s uses soft float");
	  first = this->last_fp_;
	  second = name;
	}
      else if ((out_fp & 3) == 2 && (in_fp & 3) != 2)
	{
	  err = N_("%s uses hard float, %s uses soft float");
	  first = name;
	  second = this->last_fp_;
	}
      else if ((out_fp & 3) == 1 && (in_fp & 3) == 3)
	{
	  err = N_("%s uses double-precision hard float, "
		   "%s uses single-precision hard float");
	  first = this->last_fp_;
	  second = name;
	}
      else if ((out_fp & 3) == 3 && (in_fp & 3) == 1)
	{
	  err = N_("%s uses double-precision hard float, "
		   "%s uses single-precision hard float");
	  first = name;
	  second = this->last_fp_;
	}

      if (err || (in_fp & 0xc) == 0)
	;
      else if ((out_fp & 0xc) == 0)
	{
	  if (!warn_only)
	    {
	      out_fp |= in_fp & 0xc;
	      out_attr[tag].set_int_value(out_fp);
	      out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
	      this->last_ld_ = name;
	    }
	}
      else if ((out_fp & 0xc) != 2 * 4 && (in_fp & 0xc) == 2 * 4)
	{
	  err = N_("%s uses 64-bit long double, %s uses 128-bit long double");
	  first = name;
	  second = this->last_ld_;
	}
      else if ((in_fp & 0xc) != 2 * 4 && (out_fp & 0xc) == 2 * 4)
	{
	  err = N_("%s uses 64-bit long double, %s uses 128-bit long double");
	  first = this->last_ld_;
	  second = name;
	}
      else if ((out_fp & 0xc) == 1 * 4 && (in_fp & 0xc) == 3 * 4)
	{
	  err = N_("%s uses IBM long double, %s uses IEEE long double");
	  first = this->last_ld_;
	  second = name;
	}
      else if ((out_fp & 0xc) == 3 * 4 && (in_fp & 0xc) == 1 * 4)
	{
	  err = N_("%s uses IBM long double, %s uses IEEE long double");
	  first = name;
	  second = this->last_ld_;
	}

      if (err)
	{
	  if (parameters->options().warn_mismatch())
	    {
	      if (warn_only)
		gold_warning(_(err), first, second);
	      else
		gold_error(_(err), first, second);
	    }
	  // Arrange for this attribute to be deleted.  It's better to
	  // say "don't know" about a file than to wrongly claim compliance.
	  if (!warn_only)
	    out_attr[tag].set_type(0);
	}
    }

  if (size == 32)
    {
      tag = elfcpp::Tag_GNU_Power_ABI_Vector;
      int in_vec = in_attr[tag].int_value() & 3;
      int out_vec = out_attr[tag].int_value() & 3;
      if (in_vec != out_vec)
	{
	  err = NULL;
	  if (in_vec == 0)
	    ;
	  else if (out_vec == 0)
	    {
	      out_vec = in_vec;
	      out_attr[tag].set_int_value(out_vec);
	      out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
	      this->last_vec_ = name;
	    }
	  // For now, allow generic to transition to AltiVec or SPE
	  // without a warning.  If GCC marked files with their stack
	  // alignment and used don't-care markings for files which are
	  // not affected by the vector ABI, we could warn about this
	  // case too.  */
	  else if (in_vec == 1)
	    ;
	  else if (out_vec == 1)
	    {
	      out_vec = in_vec;
	      out_attr[tag].set_int_value(out_vec);
	      out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
	      this->last_vec_ = name;
	    }
	  else if (out_vec < in_vec)
	    {
	      err = N_("%s uses AltiVec vector ABI, %s uses SPE vector ABI");
	      first = this->last_vec_;
	      second = name;
	    }
	  else if (out_vec > in_vec)
	    {
	      err = N_("%s uses AltiVec vector ABI, %s uses SPE vector ABI");
	      first = name;
	      second = this->last_vec_;
	    }
	  if (err)
	    {
	      if (parameters->options().warn_mismatch())
		gold_error(_(err), first, second);
	      out_attr[tag].set_type(0);
	    }
	}

      tag = elfcpp::Tag_GNU_Power_ABI_Struct_Return;
      int in_struct = in_attr[tag].int_value() & 3;
      int out_struct = out_attr[tag].int_value() & 3;
      if (in_struct != out_struct)
	{
	  err = NULL;
	  if (in_struct == 0 || in_struct == 3)
	    ;
	  else if (out_struct == 0)
	    {
	      out_struct = in_struct;
	      out_attr[tag].set_int_value(out_struct);
	      out_attr[tag].set_type(Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
	      this->last_struct_ = name;
	    }
	  else if (out_struct < in_struct)
	    {
	      err = N_("%s uses r3/r4 for small structure returns, "
		       "%s uses memory");
	      first = this->last_struct_;
	      second = name;
	    }
	  else if (out_struct > in_struct)
	    {
	      err = N_("%s uses r3/r4 for small structure returns, "
		       "%s uses memory");
	      first = name;
	      second = this->last_struct_;
	    }
	  if (err)
	    {
	      if (parameters->options().warn_mismatch())
		gold_error(_(err), first, second);
	      out_attr[tag].set_type(0);
	    }
	}
    }

  // Merge Tag_compatibility attributes and any common GNU ones.
  this->attributes_section_data_->merge(name, pasd);
}

// Emit any saved relocs, and mark toc entries using any of these
// relocs as not optimizable.

template<int sh_type, int size, bool big_endian>
void
Powerpc_copy_relocs<sh_type, size, big_endian>::emit(
    Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
{
  if (size == 64
      && parameters->options().toc_optimize())
    {
      for (typename Copy_relocs<sh_type, size, big_endian>::
	     Copy_reloc_entries::iterator p = this->entries_.begin();
	   p != this->entries_.end();
	   ++p)
	{
	  typename Copy_relocs<sh_type, size, big_endian>::Copy_reloc_entry&
	    entry = *p;

	  // If the symbol is no longer defined in a dynamic object,
	  // then we emitted a COPY relocation.  If it is still
	  // dynamic then we'll need dynamic relocations and thus
	  // can't optimize toc entries.
	  if (entry.sym_->is_from_dynobj())
	    {
	      Powerpc_relobj<size, big_endian>* ppc_object
		= static_cast<Powerpc_relobj<size, big_endian>*>(entry.relobj_);
	      if (entry.shndx_ == ppc_object->toc_shndx())
		ppc_object->set_no_toc_opt(entry.address_);
	    }
	}
    }

  Copy_relocs<sh_type, size, big_endian>::emit(reloc_section);
}

// Return the value to use for a branch relocation.

template<int size, bool big_endian>
bool
Target_powerpc<size, big_endian>::symval_for_branch(
    const Symbol_table* symtab,
    const Sized_symbol<size>* gsym,
    Powerpc_relobj<size, big_endian>* object,
    Address *value,
    unsigned int *dest_shndx)
{
  if (size == 32 || this->abiversion() >= 2)
    gold_unreachable();
  *dest_shndx = 0;

  // If the symbol is defined in an opd section, ie. is a function
  // descriptor, use the function descriptor code entry address
  Powerpc_relobj<size, big_endian>* symobj = object;
  if (gsym != NULL
      && (gsym->source() != Symbol::FROM_OBJECT
	  || gsym->object()->is_dynamic()))
    return true;
  if (gsym != NULL)
    symobj = static_cast<Powerpc_relobj<size, big_endian>*>(gsym->object());
  unsigned int shndx = symobj->opd_shndx();
  if (shndx == 0)
    return true;
  Address opd_addr = symobj->get_output_section_offset(shndx);
  if (opd_addr == invalid_address)
    return true;
  opd_addr += symobj->output_section_address(shndx);
  if (*value >= opd_addr && *value < opd_addr + symobj->section_size(shndx))
    {
      Address sec_off;
      *dest_shndx = symobj->get_opd_ent(*value - opd_addr, &sec_off);
      if (symtab->is_section_folded(symobj, *dest_shndx))
	{
	  Section_id folded
	    = symtab->icf()->get_folded_section(symobj, *dest_shndx);
	  symobj = static_cast<Powerpc_relobj<size, big_endian>*>(folded.first);
	  *dest_shndx = folded.second;
	}
      Address sec_addr = symobj->get_output_section_offset(*dest_shndx);
      if (sec_addr == invalid_address)
	return false;

      sec_addr += symobj->output_section(*dest_shndx)->address();
      *value = sec_addr + sec_off;
    }
  return true;
}

template<int size>
static bool
relative_value_is_known(const Sized_symbol<size>* gsym)
{
  if (gsym->type() == elfcpp::STT_GNU_IFUNC)
    return false;

  if (gsym->is_from_dynobj()
      || gsym->is_undefined()
      || gsym->is_preemptible())
    return false;

  if (gsym->is_absolute())
    return !parameters->options().output_is_position_independent();

  return true;
}

template<int size>
static bool
relative_value_is_known(const Symbol_value<size>* psymval)
{
  if (psymval->is_ifunc_symbol())
    return false;

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

  return is_ordinary && shndx != elfcpp::SHN_UNDEF;
}

// PCREL_OPT in one instance flags to the linker that a pair of insns:
//   pld ra,symbol@got@pcrel
//   load/store rt,0(ra)
// or
//   pla ra,symbol@pcrel
//   load/store rt,0(ra)
// may be translated to
//   pload/pstore rt,symbol@pcrel
//   nop.
// This function returns true if the optimization is possible, placing
// the prefix insn in *PINSN1 and a NOP in *PINSN2.
//
// On entry to this function, the linker has already determined that
// the pld can be replaced with pla: *PINSN1 is that pla insn,
// while *PINSN2 is the second instruction.

inline bool
xlate_pcrel_opt(uint64_t *pinsn1, uint64_t *pinsn2)
{
  uint32_t insn2 = *pinsn2 >> 32;
  uint64_t i1new;

  // Check that regs match.
  if (((insn2 >> 16) & 31) != ((*pinsn1 >> 21) & 31))
    return false;

  switch ((insn2 >> 26) & 63)
    {
    default:
      return false;

    case 32: // lwz
    case 34: // lbz
    case 36: // stw
    case 38: // stb
    case 40: // lhz
    case 42: // lha
    case 44: // sth
    case 48: // lfs
    case 50: // lfd
    case 52: // stfs
    case 54: // stfd
      // These are the PMLS cases, where we just need to tack a prefix
      // on the insn.  Check that the D field is zero.
      if ((insn2 & 0xffff) != 0)
	return false;
      i1new = ((1ULL << 58) | (2ULL << 56) | (1ULL << 52)
	       | (insn2 & ((63ULL << 26) | (31ULL << 21))));
      break;

    case 58: // lwa, ld
      if ((insn2 & 0xfffd) != 0)
	return false;
      i1new = ((1ULL << 58) | (1ULL << 52)
	       | (insn2 & 2 ? 41ULL << 26 : 57ULL << 26)
	       | (insn2 & (31ULL << 21)));
      break;

    case 57: // lxsd, lxssp
      if ((insn2 & 0xfffc) != 0 || (insn2 & 3) < 2)
	return false;
      i1new = ((1ULL << 58) | (1ULL << 52)
	       | ((40ULL | (insn2 & 3)) << 26)
	       | (insn2 & (31ULL << 21)));
      break;

    case 61: // stxsd, stxssp, lxv, stxv
      if ((insn2 & 3) == 0)
	return false;
      else if ((insn2 & 3) >= 2)
	{
	  if ((insn2 & 0xfffc) != 0)
	    return false;
	  i1new = ((1ULL << 58) | (1ULL << 52)
		   | ((44ULL | (insn2 & 3)) << 26)
		   | (insn2 & (31ULL << 21)));
	}
      else
	{
	  if ((insn2 & 0xfff0) != 0)
	    return false;
	  i1new = ((1ULL << 58) | (1ULL << 52)
		   | ((50ULL | (insn2 & 4) | ((insn2 & 8) >> 3)) << 26)
		   | (insn2 & (31ULL << 21)));
	}
      break;

    case 56: // lq
      if ((insn2 & 0xffff) != 0)
	return false;
      i1new = ((1ULL << 58) | (1ULL << 52)
	       | (insn2 & ((63ULL << 26) | (31ULL << 21))));
      break;

    case 62: // std, stq
      if ((insn2 & 0xfffd) != 0)
	return false;
      i1new = ((1ULL << 58) | (1ULL << 52)
	       | ((insn2 & 2) == 0 ? 61ULL << 26 : 60ULL << 26)
	       | (insn2 & (31ULL << 21)));
      break;
    }

  *pinsn1 = i1new;
  *pinsn2 = (uint64_t) nop << 32;
  return true;
}

// Perform a relocation.

template<int size, bool big_endian>
inline bool
Target_powerpc<size, big_endian>::Relocate::relocate(
    const Relocate_info<size, big_endian>* relinfo,
    unsigned int,
    Target_powerpc* target,
    Output_section* os,
    size_t relnum,
    const unsigned char* preloc,
    const Sized_symbol<size>* gsym,
    const Symbol_value<size>* psymval,
    unsigned char* view,
    Address address,
    section_size_type view_size)
{
  typedef Powerpc_relocate_functions<size, big_endian> Reloc;
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insn;
  typedef typename elfcpp::Rela<size, big_endian> Reltype;

  if (view == NULL)
    return true;

  if (target->replace_tls_get_addr(gsym))
    gsym = static_cast<const Sized_symbol<size>*>(target->tls_get_addr_opt());

  const elfcpp::Rela<size, big_endian> rela(preloc);
  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
  Powerpc_relobj<size, big_endian>* const object
    = static_cast<Powerpc_relobj<size, big_endian>*>(relinfo->object);
  switch (this->maybe_skip_tls_get_addr_call(target, r_type, gsym))
    {
    case Track_tls::NOT_EXPECTED:
      if (!parameters->options().shared()
	  && parameters->options().tls_optimize())
	{
	  // It is a hard error to see a __tls_get_addr call without
	  // marker relocs after seeing calls with marker relocs in the
	  // same object file, because dynamic relocation accounting
	  // will be wrong.
	  if (object->tls_opt_error())
	    gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
				   _("__tls_get_addr call lacks marker reloc"));
	  else
	    gold_warning_at_location(relinfo, relnum, rela.get_r_offset(),
				     _("__tls_get_addr call lacks marker reloc"));
	}
      break;
    case Track_tls::EXPECTED:
      // We have already complained.
      break;
    case Track_tls::SKIP:
      if (is_plt16_reloc<size>(r_type)
	  || r_type == elfcpp::R_POWERPC_PLTSEQ
	  || r_type == elfcpp::R_PPC64_PLTSEQ_NOTOC)
	{
	  Insn* iview = reinterpret_cast<Insn*>(view);
	  elfcpp::Swap<32, big_endian>::writeval(iview, nop);
	}
      else if (size == 64 && r_type == elfcpp::R_POWERPC_PLTCALL)
	{
	  Insn* iview = reinterpret_cast<Insn*>(view);
	  elfcpp::Swap<32, big_endian>::writeval(iview + 1, nop);
	}
      else if (size == 64 && (r_type == elfcpp::R_PPC64_PLT_PCREL34
			      || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
	{
	  Insn* iview = reinterpret_cast<Insn*>(view);
	  elfcpp::Swap<32, big_endian>::writeval(iview, pnop >> 32);
	  elfcpp::Swap<32, big_endian>::writeval(iview + 1, pnop & 0xffffffff);
	}
      return true;
    case Track_tls::NORMAL:
      break;
    }

  // Offset from start of insn to d-field reloc.
  const int d_offset = big_endian ? 2 : 0;

  Address value = 0;
  bool has_stub_value = false;
  bool localentry0 = false;
  unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
  bool has_plt_offset
    = (gsym != NULL
       ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target))
       : object->local_has_plt_offset(r_sym));
  if (has_plt_offset
      && !is_got_reloc(r_type)
      && !is_plt16_reloc<size>(r_type)
      && r_type != elfcpp::R_PPC64_PLT_PCREL34
      && r_type != elfcpp::R_PPC64_PLT_PCREL34_NOTOC
      && r_type != elfcpp::R_POWERPC_PLTSEQ
      && r_type != elfcpp::R_POWERPC_PLTCALL
      && r_type != elfcpp::R_PPC64_PLTSEQ_NOTOC
      && r_type != elfcpp::R_PPC64_PLTCALL_NOTOC
      && (!psymval->is_ifunc_symbol()
	  || Scan::reloc_needs_plt_for_ifunc(target, object, r_type, false)))
    {
      if (size == 64
	  && gsym != NULL
	  && target->abiversion() >= 2
	  && !parameters->options().output_is_position_independent()
	  && !is_branch_reloc<size>(r_type))
	{
	  Address off = target->glink_section()->find_global_entry(gsym);
	  if (off != invalid_address)
	    {
	      value = target->glink_section()->global_entry_address() + off;
	      has_stub_value = true;
	    }
	}
      else
	{
	  Stub_table<size, big_endian>* stub_table = NULL;
	  if (target->stub_tables().size() == 1)
	    stub_table = target->stub_tables()[0];
	  if (stub_table == NULL
	      && !(size == 32
		   && gsym != NULL
		   && !parameters->options().output_is_position_independent()
		   && !is_branch_reloc<size>(r_type)))
	    stub_table = object->stub_table(relinfo->data_shndx);
	  if (stub_table == NULL)
	    {
	      // This is a ref from a data section to an ifunc symbol,
	      // or a non-branch reloc for which we always want to use
	      // one set of stubs for resolving function addresses.
	      if (target->stub_tables().size() != 0)
		stub_table = target->stub_tables()[0];
	    }
	  if (stub_table != NULL)
	    {
	      const typename Stub_table<size, big_endian>::Plt_stub_ent* ent;
	      if (gsym != NULL)
		ent = stub_table->find_plt_call_entry(object, gsym, r_type,
						      rela.get_r_addend());
	      else
		ent = stub_table->find_plt_call_entry(object, r_sym, r_type,
						      rela.get_r_addend());
	      if (ent != NULL)
		{
		  value = stub_table->stub_address() + ent->off_;
		  const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
		  elfcpp::Shdr<size, big_endian> shdr(relinfo->reloc_shdr);
		  size_t reloc_count = shdr.get_sh_size() / reloc_size;
		  if (size == 64
		      && r_type != elfcpp::R_PPC64_REL24_NOTOC)
		    value += ent->tocoff_;
		  if (size == 64
		      && ent->r2save_
		      && !(gsym != NULL
			   && target->is_tls_get_addr_opt(gsym)))
		    {
		      if (r_type == elfcpp::R_PPC64_REL24_NOTOC)
			{
			  if (!(target->power10_stubs()
				&& target->power10_stubs_auto()))
			    value += 4;
			}
		      else if (relnum < reloc_count - 1)
			{
			  Reltype next_rela(preloc + reloc_size);
			  if (elfcpp::elf_r_type<size>(next_rela.get_r_info())
			      == elfcpp::R_PPC64_TOCSAVE
			      && (next_rela.get_r_offset()
				  == rela.get_r_offset() + 4))
			    value += 4;
			}
		    }
		  localentry0 = ent->localentry0_;
		  has_stub_value = true;
		}
	    }
	}
      // We don't care too much about bogus debug references to
      // non-local functions, but otherwise there had better be a plt
      // call stub or global entry stub as appropriate.
      gold_assert(has_stub_value || !(os->flags() & elfcpp::SHF_ALLOC));
    }

  if (has_plt_offset && (is_plt16_reloc<size>(r_type)
			 || r_type == elfcpp::R_PPC64_PLT_PCREL34
			 || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
    {
      const Output_data_plt_powerpc<size, big_endian>* plt;
      if (gsym)
	value = target->plt_off(gsym, &plt);
      else
	value = target->plt_off(object, r_sym, &plt);
      value += plt->address();

      if (size == 64)
	{
	  if (r_type != elfcpp::R_PPC64_PLT_PCREL34
	      && r_type != elfcpp::R_PPC64_PLT_PCREL34_NOTOC)
	    value -= target->toc_pointer();
	}
      else if (parameters->options().output_is_position_independent())
	{
	  if (rela.get_r_addend() >= 32768)
	    {
	      unsigned int got2 = object->got2_shndx();
	      value -= (object->get_output_section_offset(got2)
			+ object->output_section(got2)->address()
			+ rela.get_r_addend());
	    }
	  else
	    value -= target->toc_pointer();
	}
    }
  else if (!has_plt_offset
	   && (is_plt16_reloc<size>(r_type)
	       || r_type == elfcpp::R_POWERPC_PLTSEQ
	       || r_type == elfcpp::R_PPC64_PLTSEQ_NOTOC))
    {
      Insn* iview = reinterpret_cast<Insn*>(view);
      elfcpp::Swap<32, big_endian>::writeval(iview, nop);
      r_type = elfcpp::R_POWERPC_NONE;
    }
  else if (!has_plt_offset
	   && (r_type == elfcpp::R_PPC64_PLT_PCREL34
	       || r_type == elfcpp::R_PPC64_PLT_PCREL34_NOTOC))
    {
      Insn* iview = reinterpret_cast<Insn*>(view);
      elfcpp::Swap<32, big_endian>::writeval(iview, pnop >> 32);
      elfcpp::Swap<32, big_endian>::writeval(iview + 1, pnop & 0xffffffff);
      r_type = elfcpp::R_POWERPC_NONE;
    }
  else if (is_got_reloc(r_type))
    {
      uint64_t addend = size == 32 ? 0 : rela.get_r_addend();
      Got_type got_type = ((size == 32
			    || r_type == elfcpp::R_POWERPC_GOT16
			    || r_type == elfcpp::R_PPC64_GOT16_DS)
			   ? GOT_TYPE_SMALL : GOT_TYPE_STANDARD);
      if (gsym != NULL)
	value = gsym->got_offset(got_type, addend);
      else
	value = object->local_got_offset(r_sym, got_type, addend);
      if (r_type == elfcpp::R_PPC64_GOT_PCREL34)
	value += target->got_section(got_type)->address();
      else
	value -= target->got_base_offset(got_type);
    }
  else if (r_type == elfcpp::R_PPC64_TOC)
    {
      value = target->toc_pointer();
    }
  else if (gsym != NULL
	   && (r_type == elfcpp::R_POWERPC_REL24
	       || r_type == elfcpp::R_PPC_PLTREL24)
	   && has_stub_value)
    {
      if (size == 64)
	{
	  typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
	  Valtype* wv = reinterpret_cast<Valtype*>(view);
	  bool can_plt_call = localentry0 || target->is_tls_get_addr_opt(gsym);
	  if (!can_plt_call && rela.get_r_offset() + 8 <= view_size)
	    {
	      Valtype insn = elfcpp::Swap<32, big_endian>::readval(wv);
	      Valtype insn2 = elfcpp::Swap<32, big_endian>::readval(wv + 1);
	      if ((insn & 1) != 0
		  && (insn2 == nop
		      || insn2 == cror_15_15_15 || insn2 == cror_31_31_31))
		{
		  elfcpp::Swap<32, big_endian>::
		    writeval(wv + 1, ld_2_1 + target->stk_toc());
		  can_plt_call = true;
		}
	    }
	  if (!can_plt_call)
	    {
	      // If we don't have a branch and link followed by a nop,
	      // we can't go via the plt because there is no place to
	      // put a toc restoring instruction.
	      // Unless we know we won't be returning.
	      if (strcmp(gsym->name(), "__libc_start_main") == 0)
		can_plt_call = true;
	    }
	  if (!can_plt_call)
	    {
	      // g++ as of 20130507 emits self-calls without a
	      // following nop.  This is arguably wrong since we have
	      // conflicting information.  On the one hand a global
	      // symbol and on the other a local call sequence, but
	      // don't error for this special case.
	      // It isn't possible to cheaply verify we have exactly
	      // such a call.  Allow all calls to the same section.
	      bool ok = false;
	      Address code = value;
	      if (gsym->source() == Symbol::FROM_OBJECT
		  && gsym->object() == object)
		{
		  unsigned int dest_shndx = 0;
		  if (target->abiversion() < 2)
		    {
		      Address addend = rela.get_r_addend();
		      code = psymval->value(object, addend);
		      target->symval_for_branch(relinfo->symtab, gsym, object,
						&code, &dest_shndx);
		    }
		  bool is_ordinary;
		  if (dest_shndx == 0)
		    dest_shndx = gsym->shndx(&is_ordinary);
		  ok = dest_shndx == relinfo->data_shndx;
		}
	      if (!ok)
		{
		  gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
					 _("call lacks nop, can't restore toc; "
					   "recompile with -fPIC"));
		  value = code;
		}
	    }
	}
    }
  else if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
	   || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO
	   || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_HI
	   || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_HA
	   || r_type == elfcpp::R_PPC64_GOT_TLSGD_PCREL34)
    {
      // First instruction of a global dynamic sequence, arg setup insn.
      tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
      if (!object->no_tls_marker())
	{
	  bool final = gsym == NULL || gsym->final_value_is_known();
	  tls_type = target->optimize_tls_gd(final);
	}
      Got_type got_type = ((size == 32
			    || r_type == elfcpp::R_POWERPC_GOT_TLSGD16)
			   ? GOT_TYPE_SMALL : GOT_TYPE_STANDARD);
      if (tls_type == tls::TLSOPT_NONE)
	got_type = Got_type(got_type | GOT_TYPE_TLSGD);
      else if (tls_type == tls::TLSOPT_TO_IE)
	got_type = Got_type(got_type | GOT_TYPE_TPREL);
      if ((got_type & ~GOT_TYPE_SMALL) != GOT_TYPE_STANDARD)
	{
	  uint64_t addend = size == 32 ? 0 : rela.get_r_addend();
	  if (gsym != NULL)
	    value = gsym->got_offset(got_type, addend);
	  else
	    value = object->local_got_offset(r_sym, got_type, addend);
	  if (r_type == elfcpp::R_PPC64_GOT_TLSGD_PCREL34)
	    value += target->got_section(got_type)->address();
	  else
	    value -= target->got_base_offset(got_type);
	}
      if (tls_type == tls::TLSOPT_TO_IE)
	{
	  if (r_type == elfcpp::R_PPC64_GOT_TLSGD_PCREL34)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view);
	      uint64_t pinsn = elfcpp::Swap<32, big_endian>::readval(iview);
	      pinsn <<= 32;
	      pinsn |= elfcpp::Swap<32, big_endian>::readval(iview + 1);
	      // pla -> pld
	      pinsn += (-2ULL << 56) + (57ULL << 26) - (14ULL << 26);
	      elfcpp::Swap<32, big_endian>::writeval(iview, pinsn >> 32);
	      elfcpp::Swap<32, big_endian>::writeval(iview + 1,
						     pinsn & 0xffffffff);
	      r_type = elfcpp::R_PPC64_GOT_TPREL_PCREL34;
	    }
	  else
	    {
	      if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
		  || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO)
		{
		  Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
		  Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
		  insn &= (1 << 26) - (1 << 16); // extract rt,ra from addi
		  if (size == 32)
		    insn |= 32 << 26; // lwz
		  else
		    insn |= 58 << 26; // ld
		  elfcpp::Swap<32, big_endian>::writeval(iview, insn);
		}
	      r_type += (elfcpp::R_POWERPC_GOT_TPREL16
			 - elfcpp::R_POWERPC_GOT_TLSGD16);
	    }
	}
      else if (tls_type == tls::TLSOPT_TO_LE)
	{
	  if (r_type == elfcpp::R_PPC64_GOT_TLSGD_PCREL34)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view);
	      uint64_t pinsn = elfcpp::Swap<32, big_endian>::readval(iview);
	      pinsn <<= 32;
	      pinsn |= elfcpp::Swap<32, big_endian>::readval(iview + 1);
	      // pla pcrel -> paddi r13
	      pinsn += (-1ULL << 52) + (13ULL << 16);
	      elfcpp::Swap<32, big_endian>::writeval(iview, pinsn >> 32);
	      elfcpp::Swap<32, big_endian>::writeval(iview + 1,
						     pinsn & 0xffffffff);
	      r_type = elfcpp::R_PPC64_TPREL34;
	      value = psymval->value(object, rela.get_r_addend());
	    }
	  else
	    {
	      if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
		  || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO)
		{
		  Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
		  Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
		  insn &= (1 << 26) - (1 << 21); // extract rt
		  if (size == 32)
		    insn |= addis_0_2;
		  else
		    insn |= addis_0_13;
		  elfcpp::Swap<32, big_endian>::writeval(iview, insn);
		  r_type = elfcpp::R_POWERPC_TPREL16_HA;
		  value = psymval->value(object, rela.get_r_addend());
		}
	      else
		{
		  Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
		  Insn insn = nop;
		  elfcpp::Swap<32, big_endian>::writeval(iview, insn);
		  r_type = elfcpp::R_POWERPC_NONE;
		}
	    }
	}
    }
  else if (r_type == elfcpp::R_POWERPC_GOT_TLSLD16
	   || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO
	   || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_HI
	   || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_HA
	   || r_type == elfcpp::R_PPC64_GOT_TLSLD_PCREL34)
    {
      // First instruction of a local dynamic sequence, arg setup insn.
      tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
      if (!object->no_tls_marker())
	tls_type = target->optimize_tls_ld();
      if (tls_type == tls::TLSOPT_NONE)
	{
	  value = target->tlsld_got_offset();
	  if (r_type == elfcpp::R_PPC64_GOT_TLSLD_PCREL34)
	    value += target->got_section(GOT_TYPE_SMALL)->address();
	  else
	    value -= target->got_base_offset(GOT_TYPE_SMALL);
	}
      else
	{
	  gold_assert(tls_type == tls::TLSOPT_TO_LE);
	  if (r_type == elfcpp::R_PPC64_GOT_TLSLD_PCREL34)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view);
	      uint64_t pinsn = elfcpp::Swap<32, big_endian>::readval(iview);
	      pinsn <<= 32;
	      pinsn |= elfcpp::Swap<32, big_endian>::readval(iview + 1);
	      // pla pcrel -> paddi r13
	      pinsn += (-1ULL << 52) + (13ULL << 16);
	      elfcpp::Swap<32, big_endian>::writeval(iview, pinsn >> 32);
	      elfcpp::Swap<32, big_endian>::writeval(iview + 1,
						     pinsn & 0xffffffff);
	      r_type = elfcpp::R_PPC64_TPREL34;
	      value = dtp_offset;
	    }
	  else if (r_type == elfcpp::R_POWERPC_GOT_TLSLD16
		   || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
	      Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
	      insn &= (1 << 26) - (1 << 21); // extract rt
	      if (size == 32)
		insn |= addis_0_2;
	      else
		insn |= addis_0_13;
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	      r_type = elfcpp::R_POWERPC_TPREL16_HA;
	      value = dtp_offset;
	    }
	  else
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
	      Insn insn = nop;
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	      r_type = elfcpp::R_POWERPC_NONE;
	    }
	}
    }
  else if (r_type == elfcpp::R_POWERPC_GOT_DTPREL16
	   || r_type == elfcpp::R_POWERPC_GOT_DTPREL16_LO
	   || r_type == elfcpp::R_POWERPC_GOT_DTPREL16_HI
	   || r_type == elfcpp::R_POWERPC_GOT_DTPREL16_HA
	   || r_type == elfcpp::R_PPC64_GOT_DTPREL_PCREL34)
    {
      // Accesses relative to a local dynamic sequence address,
      // no optimisation here.
      uint64_t addend = size == 32 ? 0 : rela.get_r_addend();
      Got_type got_type = ((size == 32
			    || r_type == elfcpp::R_POWERPC_GOT_DTPREL16)
			   ? GOT_TYPE_SMALL_DTPREL : GOT_TYPE_DTPREL);
      if (gsym != NULL)
	value = gsym->got_offset(got_type, addend);
      else
	value = object->local_got_offset(r_sym, got_type, addend);
      if (r_type == elfcpp::R_PPC64_GOT_DTPREL_PCREL34)
	value += target->got_section(got_type)->address();
      else
	value -= target->got_base_offset(got_type);
    }
  else if (r_type == elfcpp::R_POWERPC_GOT_TPREL16
	   || r_type == elfcpp::R_POWERPC_GOT_TPREL16_LO
	   || r_type == elfcpp::R_POWERPC_GOT_TPREL16_HI
	   || r_type == elfcpp::R_POWERPC_GOT_TPREL16_HA
	   || r_type == elfcpp::R_PPC64_GOT_TPREL_PCREL34)
    {
      // First instruction of initial exec sequence.
      bool final = gsym == NULL || gsym->final_value_is_known();
      tls::Tls_optimization tls_type = target->optimize_tls_ie(final);
      if (tls_type == tls::TLSOPT_NONE)
	{
	  uint64_t addend = size == 32 ? 0 : rela.get_r_addend();
	  Got_type got_type = ((size == 32
				|| r_type == elfcpp::R_POWERPC_GOT_TPREL16)
			       ? GOT_TYPE_SMALL_TPREL : GOT_TYPE_TPREL);
	  if (gsym != NULL)
	    value = gsym->got_offset(got_type, addend);
	  else
	    value = object->local_got_offset(r_sym, got_type, addend);
	  if (r_type == elfcpp::R_PPC64_GOT_TPREL_PCREL34)
	    value += target->got_section(got_type)->address();
	  else
	    value -= target->got_base_offset(got_type);
	}
      else
	{
	  gold_assert(tls_type == tls::TLSOPT_TO_LE);
	  if (r_type == elfcpp::R_PPC64_GOT_TPREL_PCREL34)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view);
	      uint64_t pinsn = elfcpp::Swap<32, big_endian>::readval(iview);
	      pinsn <<= 32;
	      pinsn |= elfcpp::Swap<32, big_endian>::readval(iview + 1);
	      // pld ra,sym@got@tprel@pcrel -> paddi ra,r13,sym@tprel
	      pinsn += ((2ULL << 56) + (-1ULL << 52)
			+ (14ULL << 26) - (57ULL << 26) + (13ULL << 16));
	      elfcpp::Swap<32, big_endian>::writeval(iview, pinsn >> 32);
	      elfcpp::Swap<32, big_endian>::writeval(iview + 1,
						     pinsn & 0xffffffff);
	      r_type = elfcpp::R_PPC64_TPREL34;
	      value = psymval->value(object, rela.get_r_addend());
	    }
	  else if (r_type == elfcpp::R_POWERPC_GOT_TPREL16
		   || r_type == elfcpp::R_POWERPC_GOT_TPREL16_LO)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
	      Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
	      insn &= (1 << 26) - (1 << 21); // extract rt from ld
	      if (size == 32)
		insn |= addis_0_2;
	      else
		insn |= addis_0_13;
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	      r_type = elfcpp::R_POWERPC_TPREL16_HA;
	      value = psymval->value(object, rela.get_r_addend());
	    }
	  else
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
	      Insn insn = nop;
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	      r_type = elfcpp::R_POWERPC_NONE;
	    }
	}
    }
  else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSGD)
	   || (size == 32 && r_type == elfcpp::R_PPC_TLSGD))
    {
      // Second instruction of a global dynamic sequence,
      // the __tls_get_addr call
      this->expect_tls_get_addr_call(relinfo, relnum, rela.get_r_offset());
      tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
      if (!object->no_tls_marker())
	{
	  bool final = gsym == NULL || gsym->final_value_is_known();
	  tls_type = target->optimize_tls_gd(final);
	}
      if (tls_type != tls::TLSOPT_NONE)
	{
	  if (tls_type == tls::TLSOPT_TO_IE)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view);
	      Insn insn = add_3_3_13;
	      if (size == 32)
		insn = add_3_3_2;
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	      r_type = elfcpp::R_POWERPC_NONE;
	    }
	  else
	    {
	      bool is_pcrel = false;
	      const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
	      elfcpp::Shdr<size, big_endian> shdr(relinfo->reloc_shdr);
	      size_t reloc_count = shdr.get_sh_size() / reloc_size;
	      if (relnum < reloc_count - 1)
		{
		  Reltype next_rela(preloc + reloc_size);
		  unsigned int r_type2
		    = elfcpp::elf_r_type<size>(next_rela.get_r_info());
		  if ((r_type2 == elfcpp::R_PPC64_REL24_NOTOC
		       || r_type2 == elfcpp::R_PPC64_PLTCALL_NOTOC)
		      && next_rela.get_r_offset() == rela.get_r_offset())
		    is_pcrel = true;
		}
	      Insn* iview = reinterpret_cast<Insn*>(view);
	      if (is_pcrel)
		{
		  elfcpp::Swap<32, big_endian>::writeval(iview, nop);
		  r_type = elfcpp::R_POWERPC_NONE;
		}
	      else
		{
		  elfcpp::Swap<32, big_endian>::writeval(iview, addi_3_3);
		  r_type = elfcpp::R_POWERPC_TPREL16_LO;
		  view += d_offset;
		  value = psymval->value(object, rela.get_r_addend());
		}
	    }
	  this->skip_next_tls_get_addr_call();
	}
    }
  else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSLD)
	   || (size == 32 && r_type == elfcpp::R_PPC_TLSLD))
    {
      // Second instruction of a local dynamic sequence,
      // the __tls_get_addr call
      this->expect_tls_get_addr_call(relinfo, relnum, rela.get_r_offset());
      tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
      if (!object->no_tls_marker())
	tls_type = target->optimize_tls_ld();
      if (tls_type == tls::TLSOPT_TO_LE)
	{
	  bool is_pcrel = false;
	  const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
	  elfcpp::Shdr<size, big_endian> shdr(relinfo->reloc_shdr);
	  size_t reloc_count = shdr.get_sh_size() / reloc_size;
	  if (relnum < reloc_count - 1)
	    {
	      Reltype next_rela(preloc + reloc_size);
	      unsigned int r_type2
		= elfcpp::elf_r_type<size>(next_rela.get_r_info());
	      if ((r_type2 == elfcpp::R_PPC64_REL24_NOTOC
		   || r_type2 == elfcpp::R_PPC64_PLTCALL_NOTOC)
		  && next_rela.get_r_offset() == rela.get_r_offset())
		is_pcrel = true;
	    }
	  Insn* iview = reinterpret_cast<Insn*>(view);
	  if (is_pcrel)
	    {
	      elfcpp::Swap<32, big_endian>::writeval(iview, nop);
	      r_type = elfcpp::R_POWERPC_NONE;
	    }
	  else
	    {
	      elfcpp::Swap<32, big_endian>::writeval(iview, addi_3_3);
	      r_type = elfcpp::R_POWERPC_TPREL16_LO;
	      view += d_offset;
	      value = dtp_offset;
	    }
	  this->skip_next_tls_get_addr_call();
	}
    }
  else if (r_type == elfcpp::R_POWERPC_TLS)
    {
      // Second instruction of an initial exec sequence
      bool final = gsym == NULL || gsym->final_value_is_known();
      tls::Tls_optimization tls_type = target->optimize_tls_ie(final);
      if (tls_type == tls::TLSOPT_TO_LE)
	{
	  Address roff = rela.get_r_offset() & 3;
	  Insn* iview = reinterpret_cast<Insn*>(view - roff);
	  Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
	  unsigned int reg = size == 32 ? 2 : 13;
	  insn = at_tls_transform(insn, reg);
	  gold_assert(insn != 0);
	  if (roff == 0)
	    {
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	      r_type = elfcpp::R_POWERPC_TPREL16_LO;
	      view += d_offset;
	      value = psymval->value(object, rela.get_r_addend());
	    }
	  else if (roff == 1)
	    {
	      // For pcrel IE to LE we already have the full offset
	      // and thus don't need an addi here.  A nop or mr will do.
	      if ((insn & (0x3f << 26)) == 14 << 26)
		{
		  // Extract regs from addi rt,ra,si.
		  unsigned int rt = (insn >> 21) & 0x1f;
		  unsigned int ra = (insn >> 16) & 0x1f;
		  if (rt == ra)
		    insn = nop;
		  else
		    {
		      // Build or ra,rs,rb with rb==rs, ie. mr ra,rs.
		      insn = (rt << 16) | (ra << 21) | (ra << 11);
		      insn |= (31u << 26) | (444u << 1);
		    }
		}
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	      r_type = elfcpp::R_POWERPC_NONE;
	    }
	}
    }
  else if (!has_stub_value)
    {
      if (!has_plt_offset && (r_type == elfcpp::R_POWERPC_PLTCALL
			      || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC))
	{
	  // PLTCALL without plt entry => convert to direct call
	  Insn* iview = reinterpret_cast<Insn*>(view);
	  Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
	  insn = (insn & 1) | b;
	  elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	  if (size == 32)
	    r_type = elfcpp::R_PPC_PLTREL24;
	  else if (r_type == elfcpp::R_PPC64_PLTCALL_NOTOC)
	    r_type = elfcpp::R_PPC64_REL24_NOTOC;
	  else
	    r_type = elfcpp::R_POWERPC_REL24;
	}
      Address addend = 0;
      if (!(size == 32
	    && (r_type == elfcpp::R_PPC_PLTREL24
		|| r_type == elfcpp::R_POWERPC_PLT16_LO
		|| r_type == elfcpp::R_POWERPC_PLT16_HI
		|| r_type == elfcpp::R_POWERPC_PLT16_HA)))
	addend = rela.get_r_addend();
      value = psymval->value(object, addend);
      unsigned int local_ent = 0;
      if (size == 64 && is_branch_reloc<size>(r_type))
	{
	  if (target->abiversion() >= 2)
	    {
	      if (gsym != NULL)
		local_ent = object->ppc64_local_entry_offset(gsym);
	      else
		local_ent = object->ppc64_local_entry_offset(r_sym);
	    }
	  else
	    {
	      unsigned int dest_shndx;
	      target->symval_for_branch(relinfo->symtab, gsym, object,
					&value, &dest_shndx);
	    }
	}
      Address max_branch = max_branch_delta<size>(r_type);
      if (max_branch != 0
	  && (value + local_ent - address + max_branch >= 2 * max_branch
	      || (size == 64
		  && r_type == elfcpp::R_PPC64_REL24_NOTOC
		  && (gsym != NULL
		      ? object->ppc64_needs_toc(gsym)
		      : object->ppc64_needs_toc(r_sym)))))
	{
	  Stub_table<size, big_endian>* stub_table
	    = object->stub_table(relinfo->data_shndx);
	  if (stub_table != NULL)
	    {
	      const typename Stub_table<size, big_endian>::Branch_stub_ent* ent
		= stub_table->find_long_branch_entry(value);
	      if (ent != NULL)
		{
		  if (ent->save_res_)
		    value = (value - target->savres_section()->address()
			     + stub_table->stub_address()
			     + stub_table->plt_size()
			     + stub_table->branch_size());
		  else
		    {
		      value = (stub_table->stub_address()
			       + stub_table->plt_size()
			       + ent->off_);
		      if (size == 64
			  && r_type != elfcpp::R_PPC64_REL24_NOTOC)
			value += ent->tocoff_;
		    }
		  has_stub_value = true;
		}
	    }
	}
      if (!has_stub_value)
	value += local_ent;
    }

  switch (r_type)
    {
    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	break;
      // Fall through.
    case elfcpp::R_PPC64_REL64:
    case elfcpp::R_POWERPC_REL32:
    case elfcpp::R_POWERPC_REL24:
    case elfcpp::R_PPC_PLTREL24:
    case elfcpp::R_PPC_LOCAL24PC:
    case elfcpp::R_POWERPC_REL16:
    case elfcpp::R_POWERPC_REL16_LO:
    case elfcpp::R_POWERPC_REL16_HI:
    case elfcpp::R_POWERPC_REL16_HA:
    case elfcpp::R_POWERPC_REL16DX_HA:
    case elfcpp::R_PPC64_REL16_HIGH:
    case elfcpp::R_PPC64_REL16_HIGHA:
    case elfcpp::R_PPC64_REL16_HIGHER:
    case elfcpp::R_PPC64_REL16_HIGHERA:
    case elfcpp::R_PPC64_REL16_HIGHEST:
    case elfcpp::R_PPC64_REL16_HIGHESTA:
    case elfcpp::R_POWERPC_REL14:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
    case elfcpp::R_PPC64_PCREL34:
    case elfcpp::R_PPC64_GOT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
    case elfcpp::R_PPC64_PCREL28:
    case elfcpp::R_PPC64_GOT_TLSGD_PCREL34:
    case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
    case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
    case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
    case elfcpp::R_PPC64_REL16_HIGHER34:
    case elfcpp::R_PPC64_REL16_HIGHERA34:
    case elfcpp::R_PPC64_REL16_HIGHEST34:
    case elfcpp::R_PPC64_REL16_HIGHESTA34:
      value -= address;
      break;

    case elfcpp::R_PPC64_TOC16:
    case elfcpp::R_PPC64_TOC16_LO:
    case elfcpp::R_PPC64_TOC16_HI:
    case elfcpp::R_PPC64_TOC16_HA:
    case elfcpp::R_PPC64_TOC16_DS:
    case elfcpp::R_PPC64_TOC16_LO_DS:
      // Subtract the TOC base address.
      value -= target->toc_pointer();
      break;

    case elfcpp::R_POWERPC_SECTOFF:
    case elfcpp::R_POWERPC_SECTOFF_LO:
    case elfcpp::R_POWERPC_SECTOFF_HI:
    case elfcpp::R_POWERPC_SECTOFF_HA:
    case elfcpp::R_PPC64_SECTOFF_DS:
    case elfcpp::R_PPC64_SECTOFF_LO_DS:
      if (os != NULL)
	value -= os->address();
      break;

    case elfcpp::R_PPC64_TPREL16_DS:
    case elfcpp::R_PPC64_TPREL16_LO_DS:
    case elfcpp::R_PPC64_TPREL16_HIGH:
    case elfcpp::R_PPC64_TPREL16_HIGHA:
      if (size != 64)
	// R_PPC_TLSGD, R_PPC_TLSLD, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HI
	break;
      // Fall through.
    case elfcpp::R_POWERPC_TPREL16:
    case elfcpp::R_POWERPC_TPREL16_LO:
    case elfcpp::R_POWERPC_TPREL16_HI:
    case elfcpp::R_POWERPC_TPREL16_HA:
    case elfcpp::R_POWERPC_TPREL:
    case elfcpp::R_PPC64_TPREL16_HIGHER:
    case elfcpp::R_PPC64_TPREL16_HIGHERA:
    case elfcpp::R_PPC64_TPREL16_HIGHEST:
    case elfcpp::R_PPC64_TPREL16_HIGHESTA:
    case elfcpp::R_PPC64_TPREL34:
      // tls symbol values are relative to tls_segment()->vaddr()
      value -= tp_offset;
      break;

    case elfcpp::R_PPC64_DTPREL16_DS:
    case elfcpp::R_PPC64_DTPREL16_LO_DS:
    case elfcpp::R_PPC64_DTPREL16_HIGHER:
    case elfcpp::R_PPC64_DTPREL16_HIGHERA:
    case elfcpp::R_PPC64_DTPREL16_HIGHEST:
    case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
      if (size != 64)
	// R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16, R_PPC_EMB_NADDR16_LO
	// R_PPC_EMB_NADDR16_HI, R_PPC_EMB_NADDR16_HA, R_PPC_EMB_SDAI16
	break;
      // Fall through.
    case elfcpp::R_POWERPC_DTPREL16:
    case elfcpp::R_POWERPC_DTPREL16_LO:
    case elfcpp::R_POWERPC_DTPREL16_HI:
    case elfcpp::R_POWERPC_DTPREL16_HA:
    case elfcpp::R_POWERPC_DTPREL:
    case elfcpp::R_PPC64_DTPREL16_HIGH:
    case elfcpp::R_PPC64_DTPREL16_HIGHA:
    case elfcpp::R_PPC64_DTPREL34:
      // tls symbol values are relative to tls_segment()->vaddr()
      value -= dtp_offset;
      break;

    case elfcpp::R_PPC64_ADDR64_LOCAL:
      if (gsym != NULL)
	value += object->ppc64_local_entry_offset(gsym);
      else
	value += object->ppc64_local_entry_offset(r_sym);
      break;

    default:
      break;
    }

  Insn branch_bit = 0;
  switch (r_type)
    {
    case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
      branch_bit = 1 << 21;
      // Fall through.
    case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
      {
	Insn* iview = reinterpret_cast<Insn*>(view);
	Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
	insn &= ~(1 << 21);
	insn |= branch_bit;
	if (this->is_isa_v2)
	  {
	    // Set 'a' bit.  This is 0b00010 in BO field for branch
	    // on CR(BI) insns (BO == 001at or 011at), and 0b01000
	    // for branch on CTR insns (BO == 1a00t or 1a01t).
	    if ((insn & (0x14 << 21)) == (0x04 << 21))
	      insn |= 0x02 << 21;
	    else if ((insn & (0x14 << 21)) == (0x10 << 21))
	      insn |= 0x08 << 21;
	    else
	      break;
	  }
	else
	  {
	    // Invert 'y' bit if not the default.
	    if (static_cast<Signed_address>(value) < 0)
	      insn ^= 1 << 21;
	  }
	elfcpp::Swap<32, big_endian>::writeval(iview, insn);
      }
      break;

    case elfcpp::R_POWERPC_PLT16_HA:
      if (size == 32
	  && !parameters->options().output_is_position_independent())
	{
	  Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
	  Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);

	  // Convert addis to lis.
	  if ((insn & (0x3f << 26)) == 15u << 26
	      && (insn & (0x1f << 16)) != 0)
	    {
	      insn &= ~(0x1f << 16);
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	    }
	}
      break;

    default:
      break;
    }

  if (gsym
      ? relative_value_is_known(gsym)
      : relative_value_is_known(psymval))
    {
      Insn* iview;
      Insn* iview2;
      Insn insn;
      uint64_t pinsn, pinsn2;

      switch (r_type)
	{
	default:
	  break;

	  // Multi-instruction sequences that access the GOT/TOC can
	  // be optimized, eg.
	  //     addis ra,r2,x@got@ha; ld rb,x@got@l(ra);
	  // to  addis ra,r2,x@toc@ha; addi rb,ra,x@toc@l;
	  // and
	  //     addis ra,r2,0; addi rb,ra,x@toc@l;
	  // to  nop;           addi rb,r2,x@toc;
	case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
	case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
	case elfcpp::R_POWERPC_GOT_TPREL16_HA:
	case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
	case elfcpp::R_POWERPC_GOT16_HA:
	case elfcpp::R_PPC64_TOC16_HA:
	  if (size == 64 && parameters->options().toc_optimize())
	    {
	      iview = reinterpret_cast<Insn*>(view - d_offset);
	      insn = elfcpp::Swap<32, big_endian>::readval(iview);
	      if ((r_type == elfcpp::R_PPC64_TOC16_HA
		   && object->make_toc_relative(target, &value))
		  || (r_type == elfcpp::R_POWERPC_GOT16_HA
		      && object->make_got_relative(target, psymval,
						   rela.get_r_addend(),
						   &value)))
		{
		  gold_assert((insn & ((0x3f << 26) | 0x1f << 16))
			      == ((15u << 26) | (2 << 16)));
		}
	      if (((insn & ((0x3f << 26) | 0x1f << 16))
		   == ((15u << 26) | (2 << 16)) /* addis rt,2,imm */)
		  && value + 0x8000 < 0x10000)
		{
		  elfcpp::Swap<32, big_endian>::writeval(iview, nop);
		  return true;
		}
	    }
	  break;

	case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
	case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
	case elfcpp::R_POWERPC_GOT_TPREL16_LO:
	case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
	case elfcpp::R_POWERPC_GOT16_LO:
	case elfcpp::R_PPC64_GOT16_LO_DS:
	case elfcpp::R_PPC64_TOC16_LO:
	case elfcpp::R_PPC64_TOC16_LO_DS:
	  if (size == 64 && parameters->options().toc_optimize())
	    {
	      iview = reinterpret_cast<Insn*>(view - d_offset);
	      insn = elfcpp::Swap<32, big_endian>::readval(iview);
	      bool changed = false;
	      if ((r_type == elfcpp::R_PPC64_TOC16_LO_DS
		   && object->make_toc_relative(target, &value))
		  || (r_type == elfcpp::R_PPC64_GOT16_LO_DS
		      && object->make_got_relative(target, psymval,
						   rela.get_r_addend(),
						   &value)))
		{
		  gold_assert ((insn & (0x3f << 26)) == 58u << 26 /* ld */);
		  insn ^= (14u << 26) ^ (58u << 26);
		  r_type = elfcpp::R_PPC64_TOC16_LO;
		  changed = true;
		}
	      if (ok_lo_toc_insn(insn, r_type)
		  && value + 0x8000 < 0x10000)
		{
		  if ((insn & (0x3f << 26)) == 12u << 26 /* addic */)
		    {
		      // Transform addic to addi when we change reg.
		      insn &= ~((0x3f << 26) | (0x1f << 16));
		      insn |= (14u << 26) | (2 << 16);
		    }
		  else
		    {
		      insn &= ~(0x1f << 16);
		      insn |= 2 << 16;
		    }
		  changed = true;
		}
	      if (changed)
		elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	    }
	  break;

	case elfcpp::R_PPC64_GOT_PCREL34:
	  if (size == 64 && parameters->options().toc_optimize())
	    {
	      iview = reinterpret_cast<Insn*>(view);
	      pinsn = elfcpp::Swap<32, big_endian>::readval(iview);
	      pinsn <<= 32;
	      pinsn |= elfcpp::Swap<32, big_endian>::readval(iview + 1);
	      if ((pinsn & ((-1ULL << 50) | (63ULL << 26)))
		   != ((1ULL << 58) | (1ULL << 52) | (57ULL << 26) /* pld */))
		break;

	      Address relval = psymval->value(object, rela.get_r_addend());
	      relval -= address;
	      if (relval + (1ULL << 33) < 1ULL << 34)
		{
		  value = relval;
		  // Replace with paddi
		  pinsn += (2ULL << 56) + (14ULL << 26) - (57ULL << 26);
		  elfcpp::Swap<32, big_endian>::writeval(iview, pinsn >> 32);
		  elfcpp::Swap<32, big_endian>::writeval(iview + 1,
							 pinsn & 0xffffffff);
		  goto pcrelopt;
		}
	    }
	  break;

	case elfcpp::R_PPC64_PCREL34:
	  if (size == 64)
	    {
	      iview = reinterpret_cast<Insn*>(view);
	      pinsn = elfcpp::Swap<32, big_endian>::readval(iview);
	      pinsn <<= 32;
	      pinsn |= elfcpp::Swap<32, big_endian>::readval(iview + 1);
	      if ((pinsn & ((-1ULL << 50) | (63ULL << 26)))
		  != ((1ULL << 58) | (2ULL << 56) | (1ULL << 52)
		      | (14ULL << 26) /* paddi */))
		break;

	    pcrelopt:
	      const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
	      elfcpp::Shdr<size, big_endian> shdr(relinfo->reloc_shdr);
	      size_t reloc_count = shdr.get_sh_size() / reloc_size;
	      if (relnum >= reloc_count - 1)
		break;

	      Reltype next_rela(preloc + reloc_size);
	      if ((elfcpp::elf_r_type<size>(next_rela.get_r_info())
		   != elfcpp::R_PPC64_PCREL_OPT)
		  || next_rela.get_r_offset() != rela.get_r_offset())
		break;

	      Address off = next_rela.get_r_addend();
	      if (off == 0)
		off = 8; // zero means next insn.
	      if (off + rela.get_r_offset() + 4 > view_size)
		break;

	      iview2 = reinterpret_cast<Insn*>(view + off);
	      pinsn2 = elfcpp::Swap<32, big_endian>::readval(iview2);
	      pinsn2 <<= 32;
	      if ((pinsn2 & (63ULL << 58)) == 1ULL << 58)
		break;
	      if (xlate_pcrel_opt(&pinsn, &pinsn2))
		{
		  elfcpp::Swap<32, big_endian>::writeval(iview, pinsn >> 32);
		  elfcpp::Swap<32, big_endian>::writeval(iview + 1,
							 pinsn & 0xffffffff);
		  elfcpp::Swap<32, big_endian>::writeval(iview2, pinsn2 >> 32);
		}
	    }
	  break;

	case elfcpp::R_POWERPC_TPREL16_HA:
	  if (target->tprel_opt() && value + 0x8000 < 0x10000)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
	      elfcpp::Swap<32, big_endian>::writeval(iview, nop);
	      return true;
	    }
	  break;

	case elfcpp::R_PPC64_TPREL16_LO_DS:
	  if (size == 32)
	    // R_PPC_TLSGD, R_PPC_TLSLD
	    break;
	  // Fall through.
	case elfcpp::R_POWERPC_TPREL16_LO:
	  if (target->tprel_opt() && value + 0x8000 < 0x10000)
	    {
	      Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
	      Insn insn = elfcpp::Swap<32, big_endian>::readval(iview);
	      insn &= ~(0x1f << 16);
	      insn |= (size == 32 ? 2 : 13) << 16;
	      elfcpp::Swap<32, big_endian>::writeval(iview, insn);
	    }
	  break;

	case elfcpp::R_PPC64_ENTRY:
	  if (size == 64)
	    {
	      value = target->toc_pointer();
	      if (value + 0x80008000 <= 0xffffffff
		  && !parameters->options().output_is_position_independent())
		{
		  Insn* iview = reinterpret_cast<Insn*>(view);
		  Insn insn1 = elfcpp::Swap<32, big_endian>::readval(iview);
		  Insn insn2 = elfcpp::Swap<32, big_endian>::readval(iview + 1);

		  if ((insn1 & ~0xfffc) == ld_2_12
		      && insn2 == add_2_2_12)
		    {
		      insn1 = lis_2 + ha(value);
		      elfcpp::Swap<32, big_endian>::writeval(iview, insn1);
		      insn2 = addi_2_2 + l(value);
		      elfcpp::Swap<32, big_endian>::writeval(iview + 1, insn2);
		      return true;
		    }
		}
	      else
		{
		  value -= address;
		  if (value + 0x80008000 <= 0xffffffff)
		    {
		      Insn* iview = reinterpret_cast<Insn*>(view);
		      Insn insn1 = elfcpp::Swap<32, big_endian>::readval(iview);
		      Insn insn2 = elfcpp::Swap<32, big_endian>::readval(iview + 1);

		      if ((insn1 & ~0xfffc) == ld_2_12
			  && insn2 == add_2_2_12)
			{
			  insn1 = addis_2_12 + ha(value);
			  elfcpp::Swap<32, big_endian>::writeval(iview, insn1);
			  insn2 = addi_2_2 + l(value);
			  elfcpp::Swap<32, big_endian>::writeval(iview + 1, insn2);
			  return true;
			}
		    }
		}
	    }
	  break;

	case elfcpp::R_POWERPC_REL16_LO:
	  // If we are generating a non-PIC executable, edit
	  // 	0:	addis 2,12,.TOC.-0b@ha
	  //		addi 2,2,.TOC.-0b@l
	  // used by ELFv2 global entry points to set up r2, to
	  //		lis 2,.TOC.@ha
	  //		addi 2,2,.TOC.@l
	  // if .TOC. is in range.  */
	  if (size == 64
	      && value + address - 4 + 0x80008000 <= 0xffffffff
	      && relnum + 1 > 1
	      && preloc != NULL
	      && target->abiversion() >= 2
	      && !parameters->options().output_is_position_independent()
	      && rela.get_r_addend() == d_offset + 4
	      && gsym != NULL
	      && strcmp(gsym->name(), ".TOC.") == 0)
	    {
	      const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
	      Reltype prev_rela(preloc - reloc_size);
	      if ((prev_rela.get_r_info()
		   == elfcpp::elf_r_info<size>(r_sym,
					       elfcpp::R_POWERPC_REL16_HA))
		  && prev_rela.get_r_offset() + 4 == rela.get_r_offset()
		  && prev_rela.get_r_addend() + 4 == rela.get_r_addend())
		{
		  Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
		  Insn insn1 = elfcpp::Swap<32, big_endian>::readval(iview - 1);
		  Insn insn2 = elfcpp::Swap<32, big_endian>::readval(iview);

		  if ((insn1 & 0xffff0000) == addis_2_12
		      && (insn2 & 0xffff0000) == addi_2_2)
		    {
		      insn1 = lis_2 + ha(value + address - 4);
		      elfcpp::Swap<32, big_endian>::writeval(iview - 1, insn1);
		      insn2 = addi_2_2 + l(value + address - 4);
		      elfcpp::Swap<32, big_endian>::writeval(iview, insn2);
		      if (relinfo->rr)
			{
			  relinfo->rr->set_strategy(relnum - 1,
						    Relocatable_relocs::RELOC_SPECIAL);
			  relinfo->rr->set_strategy(relnum,
						    Relocatable_relocs::RELOC_SPECIAL);
			}
		      return true;
		    }
		}
	    }
	  break;
	}
    }

  typename Reloc::Overflow_check overflow = Reloc::CHECK_NONE;
  elfcpp::Shdr<size, big_endian> shdr(relinfo->data_shdr);
  switch (r_type)
    {
    case elfcpp::R_POWERPC_ADDR32:
    case elfcpp::R_POWERPC_UADDR32:
      if (size == 64)
	overflow = Reloc::CHECK_BITFIELD;
      break;

    case elfcpp::R_POWERPC_REL32:
    case elfcpp::R_POWERPC_REL16DX_HA:
      if (size == 64)
	overflow = Reloc::CHECK_SIGNED;
      break;

    case elfcpp::R_POWERPC_UADDR16:
      overflow = Reloc::CHECK_BITFIELD;
      break;

    case elfcpp::R_POWERPC_ADDR16:
      // We really should have three separate relocations,
      // one for 16-bit data, one for insns with 16-bit signed fields,
      // and one for insns with 16-bit unsigned fields.
      overflow = Reloc::CHECK_BITFIELD;
      if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
	overflow = Reloc::CHECK_LOW_INSN;
      break;

    case elfcpp::R_POWERPC_ADDR16_HI:
    case elfcpp::R_POWERPC_ADDR16_HA:
    case elfcpp::R_POWERPC_GOT16_HI:
    case elfcpp::R_POWERPC_GOT16_HA:
    case elfcpp::R_POWERPC_PLT16_HI:
    case elfcpp::R_POWERPC_PLT16_HA:
    case elfcpp::R_POWERPC_SECTOFF_HI:
    case elfcpp::R_POWERPC_SECTOFF_HA:
    case elfcpp::R_PPC64_TOC16_HI:
    case elfcpp::R_PPC64_TOC16_HA:
    case elfcpp::R_PPC64_PLTGOT16_HI:
    case elfcpp::R_PPC64_PLTGOT16_HA:
    case elfcpp::R_POWERPC_TPREL16_HI:
    case elfcpp::R_POWERPC_TPREL16_HA:
    case elfcpp::R_POWERPC_DTPREL16_HI:
    case elfcpp::R_POWERPC_DTPREL16_HA:
    case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
    case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
    case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
    case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
    case elfcpp::R_POWERPC_GOT_TPREL16_HI:
    case elfcpp::R_POWERPC_GOT_TPREL16_HA:
    case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
    case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
    case elfcpp::R_POWERPC_REL16_HI:
    case elfcpp::R_POWERPC_REL16_HA:
      if (size != 32)
	overflow = Reloc::CHECK_HIGH_INSN;
      break;

    case elfcpp::R_POWERPC_REL16:
    case elfcpp::R_PPC64_TOC16:
    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_POWERPC_SECTOFF:
    case elfcpp::R_POWERPC_TPREL16:
    case elfcpp::R_POWERPC_DTPREL16:
    case elfcpp::R_POWERPC_GOT_TLSGD16:
    case elfcpp::R_POWERPC_GOT_TLSLD16:
    case elfcpp::R_POWERPC_GOT_TPREL16:
    case elfcpp::R_POWERPC_GOT_DTPREL16:
      overflow = Reloc::CHECK_LOW_INSN;
      break;

    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_ADDR24:
    case elfcpp::R_POWERPC_ADDR14:
    case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
    case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
    case elfcpp::R_PPC64_ADDR16_DS:
    case elfcpp::R_POWERPC_REL24:
    case elfcpp::R_PPC_PLTREL24:
    case elfcpp::R_PPC_LOCAL24PC:
    case elfcpp::R_PPC64_TPREL16_DS:
    case elfcpp::R_PPC64_DTPREL16_DS:
    case elfcpp::R_PPC64_TOC16_DS:
    case elfcpp::R_PPC64_GOT16_DS:
    case elfcpp::R_PPC64_SECTOFF_DS:
    case elfcpp::R_POWERPC_REL14:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
    case elfcpp::R_PPC64_D34:
    case elfcpp::R_PPC64_PCREL34:
    case elfcpp::R_PPC64_GOT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
    case elfcpp::R_PPC64_D28:
    case elfcpp::R_PPC64_PCREL28:
    case elfcpp::R_PPC64_TPREL34:
    case elfcpp::R_PPC64_DTPREL34:
    case elfcpp::R_PPC64_GOT_TLSGD_PCREL34:
    case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
    case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
    case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
      overflow = Reloc::CHECK_SIGNED;
      break;
    }

  Insn* iview = reinterpret_cast<Insn*>(view - d_offset);
  Insn insn = 0;

  if (overflow == Reloc::CHECK_LOW_INSN
      || overflow == Reloc::CHECK_HIGH_INSN)
    {
      insn = elfcpp::Swap<32, big_endian>::readval(iview);

      if ((insn & (0x3f << 26)) == 10u << 26 /* cmpli */)
	overflow = Reloc::CHECK_BITFIELD;
      else if (overflow == Reloc::CHECK_LOW_INSN
	       ? ((insn & (0x3f << 26)) == 28u << 26 /* andi */
		  || (insn & (0x3f << 26)) == 24u << 26 /* ori */
		  || (insn & (0x3f << 26)) == 26u << 26 /* xori */)
	       : ((insn & (0x3f << 26)) == 29u << 26 /* andis */
		  || (insn & (0x3f << 26)) == 25u << 26 /* oris */
		  || (insn & (0x3f << 26)) == 27u << 26 /* xoris */))
	overflow = Reloc::CHECK_UNSIGNED;
      else
	overflow = Reloc::CHECK_SIGNED;
    }

  bool maybe_dq_reloc = false;
  typename Powerpc_relocate_functions<size, big_endian>::Status status
    = Powerpc_relocate_functions<size, big_endian>::STATUS_OK;
  switch (r_type)
    {
    case elfcpp::R_POWERPC_NONE:
    case elfcpp::R_POWERPC_TLS:
    case elfcpp::R_POWERPC_GNU_VTINHERIT:
    case elfcpp::R_POWERPC_GNU_VTENTRY:
    case elfcpp::R_POWERPC_PLTSEQ:
    case elfcpp::R_POWERPC_PLTCALL:
    case elfcpp::R_PPC64_PLTSEQ_NOTOC:
    case elfcpp::R_PPC64_PLTCALL_NOTOC:
    case elfcpp::R_PPC64_PCREL_OPT:
      break;

    case elfcpp::R_PPC64_ADDR64:
    case elfcpp::R_PPC64_REL64:
    case elfcpp::R_PPC64_TOC:
    case elfcpp::R_PPC64_ADDR64_LOCAL:
      Reloc::addr64(view, value);
      break;

    case elfcpp::R_POWERPC_TPREL:
    case elfcpp::R_POWERPC_DTPREL:
      if (size == 64)
	Reloc::addr64(view, value);
      else
	status = Reloc::addr32(view, value, overflow);
      break;

    case elfcpp::R_PPC64_UADDR64:
      Reloc::addr64_u(view, value);
      break;

    case elfcpp::R_POWERPC_ADDR32:
      status = Reloc::addr32(view, value, overflow);
      break;

    case elfcpp::R_POWERPC_REL32:
    case elfcpp::R_POWERPC_UADDR32:
      status = Reloc::addr32_u(view, value, overflow);
      break;

    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	goto unsupp; // R_PPC_EMB_RELSDA
      // Fall through.
    case elfcpp::R_POWERPC_ADDR24:
    case elfcpp::R_POWERPC_REL24:
    case elfcpp::R_PPC_PLTREL24:
    case elfcpp::R_PPC_LOCAL24PC:
      status = Reloc::addr24(view, value, overflow);
      break;

    case elfcpp::R_POWERPC_GOT_DTPREL16:
    case elfcpp::R_POWERPC_GOT_DTPREL16_LO:
    case elfcpp::R_POWERPC_GOT_TPREL16:
    case elfcpp::R_POWERPC_GOT_TPREL16_LO:
      if (size == 64)
	{
	  // On ppc64 these are all ds form
	  maybe_dq_reloc = true;
	  break;
	}
      // Fall through.
    case elfcpp::R_POWERPC_ADDR16:
    case elfcpp::R_POWERPC_REL16:
    case elfcpp::R_PPC64_TOC16:
    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_POWERPC_SECTOFF:
    case elfcpp::R_POWERPC_TPREL16:
    case elfcpp::R_POWERPC_DTPREL16:
    case elfcpp::R_POWERPC_GOT_TLSGD16:
    case elfcpp::R_POWERPC_GOT_TLSLD16:
    case elfcpp::R_POWERPC_ADDR16_LO:
    case elfcpp::R_POWERPC_REL16_LO:
    case elfcpp::R_PPC64_TOC16_LO:
    case elfcpp::R_POWERPC_GOT16_LO:
    case elfcpp::R_POWERPC_PLT16_LO:
    case elfcpp::R_POWERPC_SECTOFF_LO:
    case elfcpp::R_POWERPC_TPREL16_LO:
    case elfcpp::R_POWERPC_DTPREL16_LO:
    case elfcpp::R_POWERPC_GOT_TLSGD16_LO:
    case elfcpp::R_POWERPC_GOT_TLSLD16_LO:
      if (size == 64)
	status = Reloc::addr16(view, value, overflow);
      else
	maybe_dq_reloc = true;
      break;

    case elfcpp::R_POWERPC_UADDR16:
      status = Reloc::addr16_u(view, value, overflow);
      break;

    case elfcpp::R_PPC64_ADDR16_HIGH:
    case elfcpp::R_PPC64_TPREL16_HIGH:
    case elfcpp::R_PPC64_DTPREL16_HIGH:
      if (size == 32)
	// R_PPC_EMB_MRKREF, R_PPC_EMB_RELST_LO, R_PPC_EMB_RELST_HA
	goto unsupp;
      // Fall through.
    case elfcpp::R_POWERPC_ADDR16_HI:
    case elfcpp::R_POWERPC_REL16_HI:
    case elfcpp::R_PPC64_REL16_HIGH:
    case elfcpp::R_PPC64_TOC16_HI:
    case elfcpp::R_POWERPC_GOT16_HI:
    case elfcpp::R_POWERPC_PLT16_HI:
    case elfcpp::R_POWERPC_SECTOFF_HI:
    case elfcpp::R_POWERPC_TPREL16_HI:
    case elfcpp::R_POWERPC_DTPREL16_HI:
    case elfcpp::R_POWERPC_GOT_TLSGD16_HI:
    case elfcpp::R_POWERPC_GOT_TLSLD16_HI:
    case elfcpp::R_POWERPC_GOT_TPREL16_HI:
    case elfcpp::R_POWERPC_GOT_DTPREL16_HI:
      Reloc::addr16_hi(view, value);
      break;

    case elfcpp::R_PPC64_ADDR16_HIGHA:
    case elfcpp::R_PPC64_TPREL16_HIGHA:
    case elfcpp::R_PPC64_DTPREL16_HIGHA:
      if (size == 32)
	// R_PPC_EMB_RELSEC16, R_PPC_EMB_RELST_HI, R_PPC_EMB_BIT_FLD
	goto unsupp;
      // Fall through.
    case elfcpp::R_POWERPC_ADDR16_HA:
    case elfcpp::R_POWERPC_REL16_HA:
    case elfcpp::R_PPC64_REL16_HIGHA:
    case elfcpp::R_PPC64_TOC16_HA:
    case elfcpp::R_POWERPC_GOT16_HA:
    case elfcpp::R_POWERPC_PLT16_HA:
    case elfcpp::R_POWERPC_SECTOFF_HA:
    case elfcpp::R_POWERPC_TPREL16_HA:
    case elfcpp::R_POWERPC_DTPREL16_HA:
    case elfcpp::R_POWERPC_GOT_TLSGD16_HA:
    case elfcpp::R_POWERPC_GOT_TLSLD16_HA:
    case elfcpp::R_POWERPC_GOT_TPREL16_HA:
    case elfcpp::R_POWERPC_GOT_DTPREL16_HA:
      Reloc::addr16_ha(view, value);
      break;

    case elfcpp::R_POWERPC_REL16DX_HA:
      status = Reloc::addr16dx_ha(view, value, overflow);
      break;

    case elfcpp::R_PPC64_DTPREL16_HIGHER:
      if (size == 32)
	// R_PPC_EMB_NADDR16_LO
	goto unsupp;
      // Fall through.
    case elfcpp::R_PPC64_ADDR16_HIGHER:
    case elfcpp::R_PPC64_REL16_HIGHER:
    case elfcpp::R_PPC64_TPREL16_HIGHER:
      Reloc::addr16_hi2(view, value);
      break;

    case elfcpp::R_PPC64_DTPREL16_HIGHERA:
      if (size == 32)
	// R_PPC_EMB_NADDR16_HI
	goto unsupp;
      // Fall through.
    case elfcpp::R_PPC64_ADDR16_HIGHERA:
    case elfcpp::R_PPC64_REL16_HIGHERA:
    case elfcpp::R_PPC64_TPREL16_HIGHERA:
      Reloc::addr16_ha2(view, value);
      break;

    case elfcpp::R_PPC64_DTPREL16_HIGHEST:
      if (size == 32)
	// R_PPC_EMB_NADDR16_HA
	goto unsupp;
      // Fall through.
    case elfcpp::R_PPC64_ADDR16_HIGHEST:
    case elfcpp::R_PPC64_REL16_HIGHEST:
    case elfcpp::R_PPC64_TPREL16_HIGHEST:
      Reloc::addr16_hi3(view, value);
      break;

    case elfcpp::R_PPC64_DTPREL16_HIGHESTA:
      if (size == 32)
	// R_PPC_EMB_SDAI16
	goto unsupp;
      // Fall through.
    case elfcpp::R_PPC64_ADDR16_HIGHESTA:
    case elfcpp::R_PPC64_REL16_HIGHESTA:
    case elfcpp::R_PPC64_TPREL16_HIGHESTA:
      Reloc::addr16_ha3(view, value);
      break;

    case elfcpp::R_PPC64_DTPREL16_DS:
    case elfcpp::R_PPC64_DTPREL16_LO_DS:
      if (size == 32)
	// R_PPC_EMB_NADDR32, R_PPC_EMB_NADDR16
	goto unsupp;
      // Fall through.
    case elfcpp::R_PPC64_TPREL16_DS:
    case elfcpp::R_PPC64_TPREL16_LO_DS:
      if (size == 32)
	// R_PPC_TLSGD, R_PPC_TLSLD
	break;
      // Fall through.
    case elfcpp::R_PPC64_ADDR16_DS:
    case elfcpp::R_PPC64_ADDR16_LO_DS:
    case elfcpp::R_PPC64_TOC16_DS:
    case elfcpp::R_PPC64_TOC16_LO_DS:
    case elfcpp::R_PPC64_GOT16_DS:
    case elfcpp::R_PPC64_GOT16_LO_DS:
    case elfcpp::R_PPC64_PLT16_LO_DS:
    case elfcpp::R_PPC64_SECTOFF_DS:
    case elfcpp::R_PPC64_SECTOFF_LO_DS:
      maybe_dq_reloc = true;
      break;

    case elfcpp::R_POWERPC_ADDR14:
    case elfcpp::R_POWERPC_ADDR14_BRTAKEN:
    case elfcpp::R_POWERPC_ADDR14_BRNTAKEN:
    case elfcpp::R_POWERPC_REL14:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
      status = Reloc::addr14(view, value, overflow);
      break;

    case elfcpp::R_POWERPC_COPY:
    case elfcpp::R_POWERPC_GLOB_DAT:
    case elfcpp::R_POWERPC_JMP_SLOT:
    case elfcpp::R_POWERPC_RELATIVE:
    case elfcpp::R_POWERPC_DTPMOD:
    case elfcpp::R_PPC64_JMP_IREL:
    case elfcpp::R_POWERPC_IRELATIVE:
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unexpected reloc %u in object file"),
			     r_type);
      break;

    case elfcpp::R_PPC64_TOCSAVE:
      if (size == 32)
	// R_PPC_EMB_SDA21
	goto unsupp;
      else
	{
	  Symbol_location loc;
	  loc.object = relinfo->object;
	  loc.shndx = relinfo->data_shndx;
	  loc.offset = rela.get_r_offset();
	  const Tocsave_loc *tocsave = target->tocsave_loc();
	  if (tocsave->find(loc) != tocsave->end())
	    {
	      // If we've generated plt calls using this tocsave, then
	      // the nop needs to be changed to save r2.
	      Insn* iview = reinterpret_cast<Insn*>(view);
	      if (elfcpp::Swap<32, big_endian>::readval(iview) == nop)
		elfcpp::Swap<32, big_endian>::
		  writeval(iview, std_2_1 + target->stk_toc());
	    }
	}
      break;

    case elfcpp::R_PPC_EMB_SDA2I16:
    case elfcpp::R_PPC_EMB_SDA2REL:
      if (size == 32)
	goto unsupp;
      // R_PPC64_TLSGD, R_PPC64_TLSLD
      break;

    case elfcpp::R_PPC64_D34:
    case elfcpp::R_PPC64_D34_LO:
    case elfcpp::R_PPC64_PCREL34:
    case elfcpp::R_PPC64_GOT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34:
    case elfcpp::R_PPC64_PLT_PCREL34_NOTOC:
    case elfcpp::R_PPC64_TPREL34:
    case elfcpp::R_PPC64_DTPREL34:
    case elfcpp::R_PPC64_GOT_TLSGD_PCREL34:
    case elfcpp::R_PPC64_GOT_TLSLD_PCREL34:
    case elfcpp::R_PPC64_GOT_TPREL_PCREL34:
    case elfcpp::R_PPC64_GOT_DTPREL_PCREL34:
      if (size == 32)
	goto unsupp;
      status = Reloc::addr34(view, value, overflow);
      break;

    case elfcpp::R_PPC64_D34_HI30:
      if (size == 32)
	goto unsupp;
      Reloc::addr34_hi(view, value);
      break;

    case elfcpp::R_PPC64_D34_HA30:
      if (size == 32)
	goto unsupp;
      Reloc::addr34_ha(view, value);
      break;

    case elfcpp::R_PPC64_D28:
    case elfcpp::R_PPC64_PCREL28:
      if (size == 32)
	goto unsupp;
      status = Reloc::addr28(view, value, overflow);
      break;

    case elfcpp::R_PPC64_ADDR16_HIGHER34:
    case elfcpp::R_PPC64_REL16_HIGHER34:
      if (size == 32)
	goto unsupp;
      Reloc::addr16_higher34(view, value);
      break;

    case elfcpp::R_PPC64_ADDR16_HIGHERA34:
    case elfcpp::R_PPC64_REL16_HIGHERA34:
      if (size == 32)
	goto unsupp;
      Reloc::addr16_highera34(view, value);
      break;

    case elfcpp::R_PPC64_ADDR16_HIGHEST34:
    case elfcpp::R_PPC64_REL16_HIGHEST34:
      if (size == 32)
	goto unsupp;
      Reloc::addr16_highest34(view, value);
      break;

    case elfcpp::R_PPC64_ADDR16_HIGHESTA34:
    case elfcpp::R_PPC64_REL16_HIGHESTA34:
      if (size == 32)
	goto unsupp;
      Reloc::addr16_highesta34(view, value);
      break;

    case elfcpp::R_POWERPC_PLT32:
    case elfcpp::R_POWERPC_PLTREL32:
    case elfcpp::R_PPC_SDAREL16:
    case elfcpp::R_POWERPC_ADDR30:
    case elfcpp::R_PPC64_PLT64:
    case elfcpp::R_PPC64_PLTREL64:
    case elfcpp::R_PPC64_PLTGOT16:
    case elfcpp::R_PPC64_PLTGOT16_LO:
    case elfcpp::R_PPC64_PLTGOT16_HI:
    case elfcpp::R_PPC64_PLTGOT16_HA:
    case elfcpp::R_PPC64_PLTGOT16_DS:
    case elfcpp::R_PPC64_PLTGOT16_LO_DS:
    case elfcpp::R_PPC_TOC16:
    default:
    unsupp:
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc %u"),
			     r_type);
      break;
    }

  if (maybe_dq_reloc)
    {
      if (insn == 0)
	insn = elfcpp::Swap<32, big_endian>::readval(iview);

      if ((insn & (0x3f << 26)) == 56u << 26 /* lq */
	  || ((insn & (0x3f << 26)) == (61u << 26) /* lxv, stxv */
	      && (insn & 3) == 1))
	status = Reloc::addr16_dq(view, value, overflow);
      else if (size == 64
	       || (insn & (0x3f << 26)) == 58u << 26 /* ld,ldu,lwa */
	       || (insn & (0x3f << 26)) == 62u << 26 /* std,stdu,stq */
	       || (insn & (0x3f << 26)) == 57u << 26 /* lfdp */
	       || (insn & (0x3f << 26)) == 61u << 26 /* stfdp */)
	status = Reloc::addr16_ds(view, value, overflow);
      else
	status = Reloc::addr16(view, value, overflow);
    }

  if (status != Powerpc_relocate_functions<size, big_endian>::STATUS_OK
      && (has_stub_value
	  || !(gsym != NULL
	       && gsym->is_undefined()
	       && is_branch_reloc<size>(r_type))))
    {
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("relocation overflow"));
      if (has_stub_value)
	gold_info(_("try relinking with a smaller --stub-group-size"));
    }

  return true;
}

// Relocate section data.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::relocate_section(
    const Relocate_info<size, big_endian>* relinfo,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    unsigned char* view,
    Address address,
    section_size_type view_size,
    const Reloc_symbol_changes* reloc_symbol_changes)
{
  typedef Target_powerpc<size, big_endian> Powerpc;
  typedef typename Target_powerpc<size, big_endian>::Relocate Powerpc_relocate;
  typedef typename Target_powerpc<size, big_endian>::Relocate_comdat_behavior
    Powerpc_comdat_behavior;
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
      Classify_reloc;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::relocate_section<size, big_endian, Powerpc, Powerpc_relocate,
			 Powerpc_comdat_behavior, Classify_reloc>(
    relinfo,
    this,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    view,
    address,
    view_size,
    reloc_symbol_changes);
}

template<int size, bool big_endian>
class Powerpc_scan_relocatable_reloc
{
public:
  typedef typename elfcpp::Rela<size, big_endian> Reltype;
  static const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
  static const int sh_type = elfcpp::SHT_RELA;

  // Return the symbol referred to by the relocation.
  static inline unsigned int
  get_r_sym(const Reltype* reloc)
  { return elfcpp::elf_r_sym<size>(reloc->get_r_info()); }

  // Return the type of the relocation.
  static inline unsigned int
  get_r_type(const Reltype* reloc)
  { return elfcpp::elf_r_type<size>(reloc->get_r_info()); }

  // 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)
  {
    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, Relobj*)
  {
    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
  }

  // 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 r_type, Relobj*, unsigned int)
  {
    if (size == 32
	&& (r_type == elfcpp::R_PPC_PLTREL24
	    || r_type == elfcpp::R_POWERPC_PLT16_LO
	    || r_type == elfcpp::R_POWERPC_PLT16_HI
	    || r_type == elfcpp::R_POWERPC_PLT16_HA))
      return Relocatable_relocs::RELOC_SPECIAL;
    return Relocatable_relocs::RELOC_COPY;
  }
};

// Scan the relocs during a relocatable link.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::scan_relocatable_relocs(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    unsigned int sh_type,
    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_symbols,
    Relocatable_relocs* rr)
{
  typedef Powerpc_scan_relocatable_reloc<size, big_endian> Scan_strategy;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::scan_relocatable_relocs<size, big_endian, Scan_strategy>(
    symtab,
    layout,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols,
    rr);
}

// Scan the relocs for --emit-relocs.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::emit_relocs_scan(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* object,
    unsigned int data_shndx,
    unsigned int sh_type,
    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 gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
      Classify_reloc;
  typedef gold::Default_emit_relocs_strategy<Classify_reloc>
      Emit_relocs_strategy;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>(
    symtab,
    layout,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_syms,
    rr);
}

// Emit relocations for a section.
// This is a modified version of the function by the same name in
// target-reloc.h.  Using relocate_special_relocatable for
// R_PPC_PLTREL24 would require duplication of the entire body of the
// loop, so we may as well duplicate the whole thing.

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::relocate_relocs(
    const Relocate_info<size, big_endian>* relinfo,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section,
    unsigned char*,
    Address view_address,
    section_size_type,
    unsigned char* reloc_view,
    section_size_type reloc_view_size)
{
  gold_assert(sh_type == elfcpp::SHT_RELA);

  typedef typename elfcpp::Rela<size, big_endian> Reltype;
  typedef typename elfcpp::Rela_write<size, big_endian> Reltype_write;
  const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
  // Offset from start of insn to d-field reloc.
  const int d_offset = big_endian ? 2 : 0;

  Powerpc_relobj<size, big_endian>* const object
    = static_cast<Powerpc_relobj<size, big_endian>*>(relinfo->object);
  const unsigned int local_count = object->local_symbol_count();
  unsigned int got2_shndx = object->got2_shndx();
  Address got2_addend = 0;
  if (got2_shndx != 0)
    {
      got2_addend = object->get_output_section_offset(got2_shndx);
      gold_assert(got2_addend != invalid_address);
    }

  const bool relocatable = parameters->options().relocatable();

  unsigned char* pwrite = reloc_view;
  bool zap_next = false;
  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
    {
      Relocatable_relocs::Reloc_strategy strategy = relinfo->rr->strategy(i);
      if (strategy == Relocatable_relocs::RELOC_DISCARD)
	continue;

      Reltype reloc(prelocs);
      Reltype_write reloc_write(pwrite);

      Address offset = reloc.get_r_offset();
      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 unsigned int orig_r_sym = r_sym;
      typename elfcpp::Elf_types<size>::Elf_Swxword addend
	= reloc.get_r_addend();
      const Symbol* gsym = NULL;

      if (zap_next)
	{
	  // We could arrange to discard these and other relocs for
	  // tls optimised sequences in the strategy methods, but for
	  // now do as BFD ld does.
	  r_type = elfcpp::R_POWERPC_NONE;
	  zap_next = false;
	}

      // Get the new symbol index.
      Output_section* os = NULL;
      if (r_sym < local_count)
	{
	  switch (strategy)
	    {
	    case Relocatable_relocs::RELOC_COPY:
	    case Relocatable_relocs::RELOC_SPECIAL:
	      if (r_sym != 0)
		{
		  r_sym = object->symtab_index(r_sym);
		  gold_assert(r_sym != -1U);
		}
	      break;

	    case Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA:
	      {
		// 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);
		os = object->output_section(shndx);
		gold_assert(os != NULL);
		gold_assert(os->needs_symtab_index());
		r_sym = os->symtab_index();
	      }
	      break;

	    default:
	      gold_unreachable();
	    }
	}
      else
	{
	  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());
	  r_sym = gsym->symtab_index();
	}

      // Get the new offset--the location in the output section where
      // this relocation should be applied.
      if (static_cast<Address>(offset_in_output_section) != invalid_address)
	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);
	  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 (!relocatable)
	{
	  offset += view_address;
	  if (static_cast<Address>(offset_in_output_section) != invalid_address)
	    offset -= offset_in_output_section;
	}

      // Handle the reloc addend based on the strategy.
      if (strategy == Relocatable_relocs::RELOC_COPY)
	;
      else if (strategy == Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA)
	{
	  const Symbol_value<size>* psymval = object->local_symbol(orig_r_sym);
	  addend = psymval->value(object, addend);
	  // In a relocatable link, the symbol value is relative to
	  // the start of the output section. For a non-relocatable
	  // link, we need to adjust the addend.
	  if (!relocatable)
	    {
	      gold_assert(os != NULL);
	      addend -= os->address();
	    }
	}
      else if (strategy == Relocatable_relocs::RELOC_SPECIAL)
	{
	  if (size == 32)
	    {
	      if (addend >= 32768)
		addend += got2_addend;
	    }
	  else if (r_type == elfcpp::R_POWERPC_REL16_HA)
	    {
	      r_type = elfcpp::R_POWERPC_ADDR16_HA;
	      addend -= d_offset;
	    }
	  else if (r_type == elfcpp::R_POWERPC_REL16_LO)
	    {
	      r_type = elfcpp::R_POWERPC_ADDR16_LO;
	      addend -= d_offset + 4;
	    }
	}
      else
	gold_unreachable();

      if (!relocatable)
	{
	  if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
	      || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO
	      || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_HI
	      || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_HA)
	    {
	      // First instruction of a global dynamic sequence,
	      // arg setup insn.
	      tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
	      if (!object->no_tls_marker())
		{
		  bool final = gsym == NULL || gsym->final_value_is_known();
		  tls_type = this->optimize_tls_gd(final);
		}
	      switch (tls_type)
		{
		case tls::TLSOPT_TO_IE:
		  r_type += (elfcpp::R_POWERPC_GOT_TPREL16
			     - elfcpp::R_POWERPC_GOT_TLSGD16);
		  break;
		case tls::TLSOPT_TO_LE:
		  if (r_type == elfcpp::R_POWERPC_GOT_TLSGD16
		      || r_type == elfcpp::R_POWERPC_GOT_TLSGD16_LO)
		    r_type = elfcpp::R_POWERPC_TPREL16_HA;
		  else
		    {
		      r_type = elfcpp::R_POWERPC_NONE;
		      offset -= d_offset;
		    }
		  break;
		default:
		  break;
		}
	    }
	  else if (r_type == elfcpp::R_POWERPC_GOT_TLSLD16
		   || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO
		   || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_HI
		   || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_HA)
	    {
	      // First instruction of a local dynamic sequence,
	      // arg setup insn.
	      tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
	      if (!object->no_tls_marker())
		tls_type = this->optimize_tls_ld();
	      if (tls_type == tls::TLSOPT_TO_LE)
		{
		  if (r_type == elfcpp::R_POWERPC_GOT_TLSLD16
		      || r_type == elfcpp::R_POWERPC_GOT_TLSLD16_LO)
		    {
		      r_type = elfcpp::R_POWERPC_TPREL16_HA;
		      const Output_section* os = relinfo->layout->tls_segment()
			->first_section();
		      gold_assert(os != NULL);
		      gold_assert(os->needs_symtab_index());
		      r_sym = os->symtab_index();
		      addend = dtp_offset;
		    }
		  else
		    {
		      r_type = elfcpp::R_POWERPC_NONE;
		      offset -= d_offset;
		    }
		}
	    }
	  else if (r_type == elfcpp::R_POWERPC_GOT_TPREL16
		   || r_type == elfcpp::R_POWERPC_GOT_TPREL16_LO
		   || r_type == elfcpp::R_POWERPC_GOT_TPREL16_HI
		   || r_type == elfcpp::R_POWERPC_GOT_TPREL16_HA)
	    {
	      // First instruction of initial exec sequence.
	      bool final = gsym == NULL || gsym->final_value_is_known();
	      if (this->optimize_tls_ie(final) == tls::TLSOPT_TO_LE)
		{
		  if (r_type == elfcpp::R_POWERPC_GOT_TPREL16
		      || r_type == elfcpp::R_POWERPC_GOT_TPREL16_LO)
		    r_type = elfcpp::R_POWERPC_TPREL16_HA;
		  else
		    {
		      r_type = elfcpp::R_POWERPC_NONE;
		      offset -= d_offset;
		    }
		}
	    }
	  else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSGD)
		   || (size == 32 && r_type == elfcpp::R_PPC_TLSGD))
	    {
	      // Second instruction of a global dynamic sequence,
	      // the __tls_get_addr call
	      tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
	      if (!object->no_tls_marker())
		{
		  bool final = gsym == NULL || gsym->final_value_is_known();
		  tls_type = this->optimize_tls_gd(final);
		}
	      switch (tls_type)
		{
		case tls::TLSOPT_TO_IE:
		  r_type = elfcpp::R_POWERPC_NONE;
		  zap_next = true;
		  break;
		case tls::TLSOPT_TO_LE:
		  r_type = elfcpp::R_POWERPC_TPREL16_LO;
		  offset += d_offset;
		  zap_next = true;
		  break;
		default:
		  break;
		}
	    }
	  else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSLD)
		   || (size == 32 && r_type == elfcpp::R_PPC_TLSLD))
	    {
	      // Second instruction of a local dynamic sequence,
	      // the __tls_get_addr call
	      tls::Tls_optimization tls_type = tls::TLSOPT_NONE;
	      if (!object->no_tls_marker())
		tls_type = this->optimize_tls_ld();
	      if (tls_type == tls::TLSOPT_TO_LE)
		{
		  const Output_section* os = relinfo->layout->tls_segment()
		    ->first_section();
		  gold_assert(os != NULL);
		  gold_assert(os->needs_symtab_index());
		  r_sym = os->symtab_index();
		  addend = dtp_offset;
		  r_type = elfcpp::R_POWERPC_TPREL16_LO;
		  offset += d_offset;
		  zap_next = true;
		}
	    }
	  else if (r_type == elfcpp::R_POWERPC_TLS)
	    {
	      // Second instruction of an initial exec sequence
	      bool final = gsym == NULL || gsym->final_value_is_known();
	      if (this->optimize_tls_ie(final) == tls::TLSOPT_TO_LE)
		{
		  r_type = elfcpp::R_POWERPC_TPREL16_LO;
		  offset += d_offset;
		}
	    }
	}

      reloc_write.put_r_offset(offset);
      reloc_write.put_r_info(elfcpp::elf_r_info<size>(r_sym, r_type));
      reloc_write.put_r_addend(addend);

      pwrite += reloc_size;
    }

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

// Return the value to use for a dynamic symbol which requires special
// treatment.  This is how we support equality comparisons of function
// pointers across shared library boundaries, as described in the
// processor specific ABI supplement.

template<int size, bool big_endian>
uint64_t
Target_powerpc<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
{
  if (size == 32)
    {
      gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
      for (typename Stub_tables::const_iterator p = this->stub_tables_.begin();
	   p != this->stub_tables_.end();
	   ++p)
	{
	  const typename Stub_table<size, big_endian>::Plt_stub_ent* ent
	    = (*p)->find_plt_call_entry(gsym);
	  if (ent != NULL)
	    return (*p)->stub_address() + ent->off_;
	}
    }
  else if (this->abiversion() >= 2)
    {
      Address off = this->glink_section()->find_global_entry(gsym);
      if (off != invalid_address)
	return this->glink_section()->global_entry_address() + off;
    }
  gold_unreachable();
}

// Return the PLT address to use for a local symbol.
template<int size, bool big_endian>
uint64_t
Target_powerpc<size, big_endian>::do_plt_address_for_local(
    const Relobj* object,
    unsigned int symndx) const
{
  if (size == 32)
    {
      const Sized_relobj<size, big_endian>* relobj
	= static_cast<const Sized_relobj<size, big_endian>*>(object);
      for (typename Stub_tables::const_iterator p = this->stub_tables_.begin();
	   p != this->stub_tables_.end();
	   ++p)
	{
	  const typename Stub_table<size, big_endian>::Plt_stub_ent* ent
	    = (*p)->find_plt_call_entry(relobj->sized_relobj(), symndx);
	  if (ent != NULL)
	    return (*p)->stub_address() + ent->off_;
	}
    }
  gold_unreachable();
}

// Return the PLT address to use for a global symbol.
template<int size, bool big_endian>
uint64_t
Target_powerpc<size, big_endian>::do_plt_address_for_global(
    const Symbol* gsym) const
{
  if (size == 32)
    {
      for (typename Stub_tables::const_iterator p = this->stub_tables_.begin();
	   p != this->stub_tables_.end();
	   ++p)
	{
	  const typename Stub_table<size, big_endian>::Plt_stub_ent* ent
	    = (*p)->find_plt_call_entry(gsym);
	  if (ent != NULL)
	    return (*p)->stub_address() + ent->off_;
	}
    }
  else if (this->abiversion() >= 2)
    {
      Address off = this->glink_section()->find_global_entry(gsym);
      if (off != invalid_address)
	return this->glink_section()->global_entry_address() + off;
    }
  gold_unreachable();
}

// Return the offset to use for the GOT_INDX'th got entry which is
// for a local tls symbol specified by OBJECT, SYMNDX.
template<int size, bool big_endian>
int64_t
Target_powerpc<size, big_endian>::do_tls_offset_for_local(
    const Relobj* object,
    unsigned int symndx,
    Output_data_got_base* got,
    unsigned int got_indx,
    uint64_t addend) const
{
  const Powerpc_relobj<size, big_endian>* ppc_object
    = static_cast<const Powerpc_relobj<size, big_endian>*>(object);
  if (ppc_object->local_symbol(symndx)->is_tls_symbol())
    {
      for (Got_type got_type = (size == 32
				? GOT_TYPE_SMALL_TLSGD : GOT_TYPE_TLSGD);
	   got_type <= GOT_TYPE_SMALL_TPREL;
	   got_type = Got_type(got_type + 1))
	if (got_type != GOT_TYPE_SMALL
	    && ppc_object->local_has_got_offset(symndx, got_type, addend))
	  {
	    unsigned int off
	      = ppc_object->local_got_offset(symndx, got_type, addend);
	    if ((got_type & ~GOT_TYPE_SMALL) == GOT_TYPE_TLSGD)
	      off += size / 8;
	    if (off == got_indx * (size / 8)
		&& (size == 32 || got == this->got_section(got_type)))
	      {
		if ((got_type & ~GOT_TYPE_SMALL) == GOT_TYPE_TPREL)
		  return -tp_offset;
		else
		  return -dtp_offset;
	      }
	  }
    }
  gold_unreachable();
}

// Return the offset to use for the GOT_INDX'th got entry which is
// for global tls symbol GSYM.
template<int size, bool big_endian>
int64_t
Target_powerpc<size, big_endian>::do_tls_offset_for_global(
    Symbol* gsym,
    Output_data_got_base* got,
    unsigned int got_indx,
    uint64_t addend) const
{
  if (gsym->type() == elfcpp::STT_TLS)
    {
      for (Got_type got_type = (size == 32
				? GOT_TYPE_SMALL_TLSGD : GOT_TYPE_TLSGD);
	   got_type <= GOT_TYPE_SMALL_TPREL;
	   got_type = Got_type(got_type + 1))
	if (got_type != GOT_TYPE_SMALL
	    && gsym->has_got_offset(got_type, addend))
	  {
	    unsigned int off = gsym->got_offset(got_type, addend);
	    if ((got_type & ~GOT_TYPE_SMALL) == GOT_TYPE_TLSGD)
	      off += size / 8;
	    if (off == got_indx * (size / 8)
		&& (size == 32 || got == this->got_section(got_type)))
	      {
		if ((got_type & ~GOT_TYPE_SMALL) == GOT_TYPE_TPREL)
		  return -tp_offset;
		else
		  return -dtp_offset;
	      }
	  }
    }
  gold_unreachable();
}

// The selector for powerpc object files.

template<int size, bool big_endian>
class Target_selector_powerpc : public Target_selector
{
public:
  Target_selector_powerpc()
    : Target_selector(size == 64 ? elfcpp::EM_PPC64 : elfcpp::EM_PPC,
		      size, big_endian,
		      (size == 64
		       ? (big_endian ? "elf64-powerpc" : "elf64-powerpcle")
		       : (big_endian ? "elf32-powerpc" : "elf32-powerpcle")),
		      (size == 64
		       ? (big_endian ? "elf64ppc" : "elf64lppc")
		       : (big_endian ? "elf32ppc" : "elf32lppc")))
  { }

  virtual Target*
  do_instantiate_target()
  { return new Target_powerpc<size, big_endian>(); }
};

Target_selector_powerpc<32, true> target_selector_ppc32;
Target_selector_powerpc<32, false> target_selector_ppc32le;
Target_selector_powerpc<64, true> target_selector_ppc64;
Target_selector_powerpc<64, false> target_selector_ppc64le;

// Instantiate these constants for -O0
template<int size, bool big_endian>
const typename Output_data_glink<size, big_endian>::Address
  Output_data_glink<size, big_endian>::invalid_address;
template<int size, bool big_endian>
const typename Stub_table<size, big_endian>::Address
  Stub_table<size, big_endian>::invalid_address;
template<int size, bool big_endian>
const typename Target_powerpc<size, big_endian>::Address
  Target_powerpc<size, big_endian>::invalid_address;

} // End anonymous namespace.
