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

// Copyright (C) 2008-2022 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),
      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];
  }

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

  // 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 if (!parameters->doing_static_link())
      *sec = this->plt_section();
    else
      *sec = this->lplt_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*);

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

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

  // 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(Symbol_table*, 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(Symbol_table*, Layout*,
		       Sized_relobj_file<size, big_endian>*,
		       unsigned int);

  void
  make_local_plt_entry(Symbol_table*, Layout*, Symbol*);

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

// 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_PPC64_REL24_P9NOTOC
      || 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
	  && this->r_type_ != elfcpp::R_PPC64_REL24_P9NOTOC)
	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
		  || this->r_type_ == elfcpp::R_PPC64_REL24_P9NOTOC)
	      && (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,
			  Symbol_table* symtab,
			  Reloc_section* plt_rel,
			  const char* name)
    : Output_section_data_build(size == 32 ? 4 : 8),
      rel_(plt_rel), targ_(targ), symtab_(symtab), name_(name), sym_ents_()
  { }

  // Add an entry to the PLT.
  void
  add_entry(Symbol*, bool = false);

  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:
  struct Local_plt_ent
  {
    Local_plt_ent(Sized_relobj_file<size, big_endian>* obj, unsigned int rsym)
    { rsym_ = rsym; u.obj_ = obj; }
    Local_plt_ent(Symbol* sym)
    { rsym_ = -1u; u.gsym_ = sym; }
    ~Local_plt_ent()
    { }

    unsigned int rsym_;
    union
    {
      Sized_relobj_file<size, big_endian>* obj_;
      Symbol* gsym_;
    } u;
  };

  // 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_;
  Symbol_table* symtab_;
  // What to report in map file.
  const char *name_;

  std::vector<Local_plt_ent> sym_ents_;
};

// Add an entry to the PLT.

template<int size, bool big_endian>
void
Output_data_plt_powerpc<size, big_endian>::add_entry(Symbol* gsym,
						     bool stash)
{
  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);
      if (this->rel_)
	{
	  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);
      if (stash)
	{
	  Local_plt_ent sym(gsym);
	  this->sym_ents_.push_back(sym);
	}
    }
}

// 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);
      Local_plt_ent sym(relobj, local_sym_index);
      this->sym_ents_.push_back(sym);
    }
}

// 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 (!this->sym_ents_.empty()
      && !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);
      unsigned char* pov = oview;
      unsigned char* endpov = oview + oview_size;

      for (typename std::vector<Local_plt_ent>::iterator e
	     = this->sym_ents_.begin();
	   e != this->sym_ents_.end();
	   e++)
	{
	  typename elfcpp::Elf_types<size>::Elf_Addr val;
	  Sized_symbol<size>* gsym = NULL;
	  Powerpc_relobj<size, big_endian>* obj = NULL;
	  if (e->rsym_ == -1u)
	    {
	      gsym = static_cast<Sized_symbol<size>*>(e->u.gsym_);
	      val = gsym->value();
	    }
	  else
	    {
	      obj = static_cast<Powerpc_relobj<size, big_endian>*>(e->u.obj_);
	      val = obj->local_symbol(e->rsym_)->value(obj, 0);
	    }
	  if (this->targ_->abiversion() >= 2)
	    {
	      elfcpp::Swap<size, big_endian>::writeval(pov, val);
	      pov += size / 8;
	    }
	  else
	    {
	      unsigned int shndx;
	      this->targ_->symval_for_branch(this->symtab_, gsym, obj,
					     &val, &shndx);
	      elfcpp::Swap<size, big_endian>::writeval(pov, val);
	      pov += size / 8;
	      val = this->targ_->toc_pointer();
	      elfcpp::Swap<size, big_endian>::writeval(pov, val);
	      pov += size / 8;
	      if (this->plt_entry_size() > 16)
		{
		  elfcpp::Swap<size, big_endian>::writeval(pov, 0);
		  pov += size / 8;
		}
	    }
	}
      gold_assert(pov == endpov);
    }

  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, symtab, 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(symtab, 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, symtab, 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(Symbol_table* symtab,
						    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, symtab, 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), tocoff_(0), p9off_(0), tsize_ (0), iter_(0),
	toc_(0), notoc_(0), p9notoc_(0), r2save_(0), localentry0_(0)
    { }

    unsigned int off_;
    unsigned int indx_;
    // off_ points at p10 notoc stub, tocoff_ is offset from there to
    // toc stub, p9off_ is offset to p9notoc stub
    unsigned int tocoff_ : 8;
    unsigned int p9off_ : 8;
    // The size of the toc stub, used to locate blr on tls_get_addr stub.
    unsigned int tsize_ : 8;
    // Stub revision management
    unsigned int iter_ : 1;
    // The three types of stubs.
    unsigned int toc_ : 1;
    unsigned int notoc_ : 1;
    unsigned int p9notoc_ : 1;
    // Each with a possible variant saving r2 first
    unsigned int r2save_ : 1;
    // Handy cached info from symbol
    unsigned int localentry0_ : 1;
  };
  struct Branch_stub_ent
  {
    Branch_stub_ent(unsigned int off)
      : off_(off), tocoff_(0), p9off_(0), iter_(0), toc_(0), notoc_(0),
	p9notoc_(0), save_res_(0), other_(0)
    { }

    unsigned int off_;
    // off_ points at p10 notoc stub, tocoff_ is offset from there to
    // toc stub, p9off_ is offset to p9notoc stub
    unsigned int tocoff_ : 8;
    unsigned int p9off_ : 8;
    // Stub revision management
    unsigned int iter_ : 1;
    // Four types of stubs.
    unsigned int toc_ : 1;
    unsigned int notoc_ : 1;
    unsigned int p9notoc_ : 1;
    unsigned int save_res_ : 1;
    // Handy cached info from symbol
    unsigned int other_ : 3;
  };
  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
	  || r_type == elfcpp::R_PPC64_REL24_P9NOTOC)
	{
	  if (this->targ_->power10_stubs()
	      && (!this->targ_->power10_stubs_auto()
		  || r_type == elfcpp::R_PPC64_REL24_NOTOC))
	    {
	      if (!p.second && !p.first->second.notoc_)
		this->need_resize_ = true;
	      p.first->second.notoc_ = 1;
	    }
	  else
	    {
	      if (!p.second && !p.first->second.p9notoc_)
		this->need_resize_ = true;
	      p.first->second.p9notoc_ = 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();
    }
  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
	  || r_type == elfcpp::R_PPC64_REL24_P9NOTOC)
	{
	  if (this->targ_->power10_stubs()
	      && (!this->targ_->power10_stubs_auto()
		  || r_type == elfcpp::R_PPC64_REL24_NOTOC))
	    {
	      if (!p.second && !p.first->second.notoc_)
		this->need_resize_ = true;
	      p.first->second.notoc_ = 1;
	    }
	  else
	    {
	      if (!p.second && !p.first->second.p9notoc_)
		this->need_resize_ = true;
	      p.first->second.p9notoc_ = 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);
    }
  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);
  Branch_stub_ent ent(this->branch_size_);
  std::pair<typename Branch_stub_entries::iterator, bool> p
    = this->long_branch_stubs_.insert(std::make_pair(key, ent));
  if (save_res)
    {
      if (!p.second && !p.first->second.save_res_)
	this->need_resize_ = true;
      p.first->second.save_res_ = true;
    }
  else if (size == 64
	   && (r_type == elfcpp::R_PPC64_REL24_NOTOC
	       || r_type == elfcpp::R_PPC64_REL24_P9NOTOC))
    {
      if (this->targ_->power10_stubs()
	  && (!this->targ_->power10_stubs_auto()
	      || r_type == elfcpp::R_PPC64_REL24_NOTOC))
	{
	  if (!p.second && !p.first->second.notoc_)
	    this->need_resize_ = true;
	  p.first->second.notoc_ = true;
	}
      else
	{
	  if (!p.second && !p.first->second.p9notoc_)
	    this->need_resize_ = true;
	  p.first->second.p9notoc_ = 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;
  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 (cs->second.p9notoc_
	  || (cs->second.toc_
	      && cs->second.r2save_
	      && !cs->second.localentry0_
	      && this->targ_->is_tls_get_addr_opt(cs->first.sym_)))
	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.toc_
	      && cs->second.r2save_
	      && !cs->second.localentry0_)
	    {
	      off += cs->second.tocoff_ + 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 = cs->second.tsize_ - 9 * 4 - 4;
	      *p++ = elfcpp::DW_CFA_advance_loc + delta / 4;
	      *p++ = elfcpp::DW_CFA_restore_extended;
	      *p++ = 65;
	      last_eh_loc = off + delta;
	      off = cs->second.off_ + 7 * 4;
	    }
	}
      // notoc stubs also should describe LR changes, to support
      // asynchronous exceptions.
      if (cs->second.p9notoc_)
	{
	  off += cs->second.p9off_;
	  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_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)
    {
      unsigned int bytes = 4 * 4;
      if (this->targ_->is_tls_get_addr_opt(p->first.sym_))
	bytes = 12 * 4;
      return this->plt_call_align(bytes);
    }

  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);
	}
      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 + 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);
	  p->second.tsize_ = bytes - p->second.tocoff_;
	  bytes = this->plt_call_align(bytes);
	}
      if (p->second.p9notoc_)
	{
	  p->second.p9off_ = bytes;
	  if (this->targ_->is_tls_get_addr_opt(p->first.sym_))
	    bytes += 7 * 4;
	  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;
	    }
	  bytes = this->plt_call_align(bytes);
	}
      return bytes;
    }
  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 this->plt_call_align(bytes + tail);
	}

      if (p->second.p9notoc_)
	{
	  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 this->plt_call_align(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 this->plt_call_align(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);
		    }
		  if (cs->second.p9notoc_)
		    {
		      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_notoc_offset<big_endian>(p, delta, 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);
		    }
		}
	      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);
		    }
		}
	      if (bs->second.p9notoc_)
		{
		  unsigned char* startp = p;
		  p = build_notoc_offset<big_endian>(p, delta, 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;
		}
	    }
	  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.p9notoc_)
		{
		  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.p9notoc_)
	    delta += elfcpp::ppc64_decode_local_entry(bs->second.other_);
	  if (bs->second.p9notoc_)
	    {
	      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(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* relobj,
    unsigned int r_sym)
{
  if (this->lplt_ == NULL)
    this->make_lplt_section(symtab, layout);
  this->lplt_->add_local_entry(relobj, r_sym);
}

template<int size, bool big_endian>
void
Target_powerpc<size, big_endian>::make_local_plt_entry(Symbol_table* symtab,
						       Layout* layout,
						       Symbol* gsym)
{
  if (this->lplt_ == NULL)
    this->make_lplt_section(symtab, layout);
  this->lplt_->add_entry(gsym, true);
}

// 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_PPC64_TOC:
      if (size != 64)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_NONE:
    case elfcpp::R_POWERPC_GNU_VTINHERIT:
    case elfcpp::R_POWERPC_GNU_VTENTRY:
      // No symbol reference.
      break;

    case elfcpp::R_PPC64_ADDR64:
    case elfcpp::R_PPC64_UADDR64:
    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:
      if (size != 64)
	break;
      // Fall through.
    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:
      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_PPC_LOCAL24PC:
      if (size != 32)
	break;
      // Fall through.
      ref = Symbol::RELATIVE_REF;
      break;

    case elfcpp::R_PPC64_REL64:
    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:
      if (size != 64)
	break;
      // Fall through.
    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:
      ref = Symbol::RELATIVE_REF;
      break;

    case elfcpp::R_PPC_PLTREL24:
      if (size != 32)
	break;
      ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
      break;

    case elfcpp::R_PPC64_REL24_NOTOC:
    case elfcpp::R_PPC64_REL24_P9NOTOC:
    case elfcpp::R_PPC64_PLT16_LO_DS:
    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:
      if (size != 64)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_REL24:
    case elfcpp::R_POWERPC_REL14:
    case elfcpp::R_POWERPC_REL14_BRTAKEN:
    case elfcpp::R_POWERPC_REL14_BRNTAKEN:
    case elfcpp::R_POWERPC_PLT16_LO:
    case elfcpp::R_POWERPC_PLT16_HI:
    case elfcpp::R_POWERPC_PLT16_HA:
    case elfcpp::R_POWERPC_PLTSEQ:
    case elfcpp::R_POWERPC_PLTCALL:
      ref = Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;
      break;

    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:
      if (size != 64)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_GOT16:
    case elfcpp::R_POWERPC_GOT16_LO:
    case elfcpp::R_POWERPC_GOT16_HI:
    case elfcpp::R_POWERPC_GOT16_HA:
      ref = Symbol::RELATIVE_REF;
      break;

    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:
      if (size != 64)
	break;
      // Fall through.
    case elfcpp::R_POWERPC_GOT_TPREL16:
    case elfcpp::R_POWERPC_TLS:
      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_PPC64_REL24_P9NOTOC:
    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);

  this->maybe_skip_tls_get_addr_call(target, r_type, NULL);

  if ((size == 64 && r_type == elfcpp::R_PPC64_TLSGD)
      || (size == 32 && r_type == elfcpp::R_PPC_TLSGD))
    {
      this->expect_tls_get_addr_call();
      tls::Tls_optimization tls_type = target->optimize_tls_gd(true);
      if (tls_type != tls::TLSOPT_NONE)
	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))
    {
      this->expect_tls_get_addr_call();
      tls::Tls_optimization tls_type = target->optimize_tls_ld();
      if (tls_type != tls::TLSOPT_NONE)
	this->skip_next_tls_get_addr_call();
    }

  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 = got->g_o_t();
	    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(symtab, layout, object, r_sym);
	}
      break;

    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	break;
      // Fall through.
    case elfcpp::R_PPC64_REL24_P9NOTOC:
    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 = 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.
	  }
	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 = 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();
	      }
	  }
	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::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();
      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();
    }
  else if ((size == 64 && r_type == elfcpp::R_PPC64_TLSLD)
	   || (size == 32 && r_type == elfcpp::R_PPC_TLSLD))
    {
      this->expect_tls_get_addr_call();
      tls::Tls_optimization tls_type = target->optimize_tls_ld();
      if (tls_type != tls::TLSOPT_NONE)
	this->skip_next_tls_get_addr_call();
    }

  // 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 = got->g_o_t();
	    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)
	{
	  if (!parameters->doing_static_link())
	    target->make_plt_entry(symtab, layout, gsym);
	  else
	    target->make_local_plt_entry(symtab, layout, gsym);
	}
      break;

    case elfcpp::R_PPC64_REL24_NOTOC:
      if (size == 32)
	break;
      // Fall through.
    case elfcpp::R_PPC64_REL24_P9NOTOC:
    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:
      {
	bool final = gsym->final_value_is_known();
	tls::Tls_optimization 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);
		  }
	      }
	  }
	else if (tls_type == tls::TLSOPT_TO_LE)
	  {
	    // no GOT relocs needed for Local Exec.
	  }
	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 = 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();
	      }
	  }
	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:
      // No warning.  This will result in really old code without tls
      // marker relocs being mis-optimised, but there shouldn't be too
      // much of that code around.  The problem with warning is that
      // glibc and libphobos both construct direct calls to
      // __tls_get_addr in a way that is harmless.
      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 pltcall_to_direct = false;

  if (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_PPC64_PLTSEQ_NOTOC
      || r_type == elfcpp::R_POWERPC_PLTCALL
      || r_type == elfcpp::R_PPC64_PLTCALL_NOTOC)
    {
      // It would be possible to replace inline plt calls with direct
      // calls if the PLTCALL is in range.  The only difficulty is
      // that the decision depends on the PLTCALL reloc, and we don't
      // know the address of that instruction when processing others
      // in the sequence.  So the decision needs to be made in
      // do_relax().
      pltcall_to_direct = !(gsym != NULL
			    ? gsym->has_plt_offset()
			    : object->local_has_plt_offset(r_sym));
    }
  else if ((gsym != NULL
	    ? gsym->use_plt_offset(Scan::get_reference_flags(r_type, target))
	    : psymval->is_ifunc_symbol() && object->local_has_plt_offset(r_sym))
	   && !is_got_reloc(r_type)
	   && (!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)
		    {
		      if (r_type == elfcpp::R_PPC64_REL24_NOTOC)
			{
			  if (!ent->notoc_)
			    value += ent->p9off_;
			}
		      else if (r_type == elfcpp::R_PPC64_REL24_P9NOTOC)
			value += ent->p9off_;
		      else
			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
			  || r_type == elfcpp::R_PPC64_REL24_P9NOTOC)
			{
			  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 (!pltcall_to_direct && (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 (pltcall_to_direct
	   && (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 (pltcall_to_direct
	   && (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.
      bool final = gsym == NULL || gsym->final_value_is_known();
      tls::Tls_optimization 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 = 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());
      bool final = gsym == NULL || gsym->final_value_is_known();
      tls::Tls_optimization 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_REL24_P9NOTOC
		       || 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 = 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_REL24_P9NOTOC
		   || 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 (pltcall_to_direct && (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
		      || 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)
			{
			  if (r_type == elfcpp::R_PPC64_REL24_NOTOC)
			    {
			      if (!ent->notoc_)
				value += ent->p9off_;
			    }
			  else if (r_type == elfcpp::R_PPC64_REL24_P9NOTOC)
			    value += ent->p9off_;
			  else
			    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_REL24_P9NOTOC:
    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_PPC64_REL24_P9NOTOC:
    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_PPC64_REL24_P9NOTOC:
    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.
	      bool final = gsym == NULL || gsym->final_value_is_known();
	      tls::Tls_optimization 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 = 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
	      bool final = gsym == NULL || gsym->final_value_is_known();
	      tls::Tls_optimization 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 = 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.
