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

// Copyright (C) 2014-2016 Free Software Foundation, Inc.
// Written by Jing Yu <jingyu@google.com> and Han Shen <shenhan@google.com>.

// This file is part of gold.

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

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

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

#include "gold.h"

#include <cstring>
#include <map>
#include <set>

#include "elfcpp.h"
#include "dwarf.h"
#include "parameters.h"
#include "reloc.h"
#include "aarch64.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 "freebsd.h"
#include "nacl.h"
#include "gc.h"
#include "icf.h"
#include "aarch64-reloc-property.h"

// The first three .got.plt entries are reserved.
const int32_t AARCH64_GOTPLT_RESERVE_COUNT = 3;


namespace
{

using namespace gold;

template<int size, bool big_endian>
class Output_data_plt_aarch64;

template<int size, bool big_endian>
class Output_data_plt_aarch64_standard;

template<int size, bool big_endian>
class Target_aarch64;

template<int size, bool big_endian>
class AArch64_relocate_functions;

// Utility class dealing with insns. This is ported from macros in
// bfd/elfnn-aarch64.cc, but wrapped inside a class as static members. This
// class is used in erratum sequence scanning.

template<bool big_endian>
class AArch64_insn_utilities
{
public:
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;

  static const int BYTES_PER_INSN;

  // Zero register encoding - 31.
  static const unsigned int AARCH64_ZR;

  static unsigned int
  aarch64_bit(Insntype insn, int pos)
  { return ((1 << pos)  & insn) >> pos; }

  static unsigned int
  aarch64_bits(Insntype insn, int pos, int l)
  { return (insn >> pos) & ((1 << l) - 1); }

  // Get the encoding field "op31" of 3-source data processing insns. "op31" is
  // the name defined in armv8 insn manual C3.5.9.
  static unsigned int
  aarch64_op31(Insntype insn)
  { return aarch64_bits(insn, 21, 3); }

  // Get the encoding field "ra" of 3-source data processing insns. "ra" is the
  // third source register. See armv8 insn manual C3.5.9.
  static unsigned int
  aarch64_ra(Insntype insn)
  { return aarch64_bits(insn, 10, 5); }

  static bool
  is_adr(const Insntype insn)
  { return (insn & 0x9F000000) == 0x10000000; }

  static bool
  is_adrp(const Insntype insn)
  { return (insn & 0x9F000000) == 0x90000000; }

  static unsigned int
  aarch64_rm(const Insntype insn)
  { return aarch64_bits(insn, 16, 5); }

  static unsigned int
  aarch64_rn(const Insntype insn)
  { return aarch64_bits(insn, 5, 5); }

  static unsigned int
  aarch64_rd(const Insntype insn)
  { return aarch64_bits(insn, 0, 5); }

  static unsigned int
  aarch64_rt(const Insntype insn)
  { return aarch64_bits(insn, 0, 5); }

  static unsigned int
  aarch64_rt2(const Insntype insn)
  { return aarch64_bits(insn, 10, 5); }

  // Encode imm21 into adr. Signed imm21 is in the range of [-1M, 1M).
  static Insntype
  aarch64_adr_encode_imm(Insntype adr, int imm21)
  {
    gold_assert(is_adr(adr));
    gold_assert(-(1 << 20) <= imm21 && imm21 < (1 << 20));
    const int mask19 = (1 << 19) - 1;
    const int mask2 = 3;
    adr &= ~((mask19 << 5) | (mask2 << 29));
    adr |= ((imm21 & mask2) << 29) | (((imm21 >> 2) & mask19) << 5);
    return adr;
  }

  // Retrieve encoded adrp 33-bit signed imm value. This value is obtained by
  // 21-bit signed imm encoded in the insn multiplied by 4k (page size) and
  // 64-bit sign-extended, resulting in [-4G, 4G) with 12-lsb being 0.
  static int64_t
  aarch64_adrp_decode_imm(const Insntype adrp)
  {
    const int mask19 = (1 << 19) - 1;
    const int mask2 = 3;
    gold_assert(is_adrp(adrp));
    // 21-bit imm encoded in adrp.
    uint64_t imm = ((adrp >> 29) & mask2) | (((adrp >> 5) & mask19) << 2);
    // Retrieve msb of 21-bit-signed imm for sign extension.
    uint64_t msbt = (imm >> 20) & 1;
    // Real value is imm multipled by 4k. Value now has 33-bit information.
    int64_t value = imm << 12;
    // Sign extend to 64-bit by repeating msbt 31 (64-33) times and merge it
    // with value.
    return ((((uint64_t)(1) << 32) - msbt) << 33) | value;
  }

  static bool
  aarch64_b(const Insntype insn)
  { return (insn & 0xFC000000) == 0x14000000; }

  static bool
  aarch64_bl(const Insntype insn)
  { return (insn & 0xFC000000) == 0x94000000; }

  static bool
  aarch64_blr(const Insntype insn)
  { return (insn & 0xFFFFFC1F) == 0xD63F0000; }

  static bool
  aarch64_br(const Insntype insn)
  { return (insn & 0xFFFFFC1F) == 0xD61F0000; }

  // All ld/st ops.  See C4-182 of the ARM ARM.  The encoding space for
  // LD_PCREL, LDST_RO, LDST_UI and LDST_UIMM cover prefetch ops.
  static bool
  aarch64_ld(Insntype insn) { return aarch64_bit(insn, 22) == 1; }

  static bool
  aarch64_ldst(Insntype insn)
  { return (insn & 0x0a000000) == 0x08000000; }

  static bool
  aarch64_ldst_ex(Insntype insn)
  { return (insn & 0x3f000000) == 0x08000000; }

  static bool
  aarch64_ldst_pcrel(Insntype insn)
  { return (insn & 0x3b000000) == 0x18000000; }

  static bool
  aarch64_ldst_nap(Insntype insn)
  { return (insn & 0x3b800000) == 0x28000000; }

  static bool
  aarch64_ldstp_pi(Insntype insn)
  { return (insn & 0x3b800000) == 0x28800000; }

  static bool
  aarch64_ldstp_o(Insntype insn)
  { return (insn & 0x3b800000) == 0x29000000; }

  static bool
  aarch64_ldstp_pre(Insntype insn)
  { return (insn & 0x3b800000) == 0x29800000; }

  static bool
  aarch64_ldst_ui(Insntype insn)
  { return (insn & 0x3b200c00) == 0x38000000; }

  static bool
  aarch64_ldst_piimm(Insntype insn)
  { return (insn & 0x3b200c00) == 0x38000400; }

  static bool
  aarch64_ldst_u(Insntype insn)
  { return (insn & 0x3b200c00) == 0x38000800; }

  static bool
  aarch64_ldst_preimm(Insntype insn)
  { return (insn & 0x3b200c00) == 0x38000c00; }

  static bool
  aarch64_ldst_ro(Insntype insn)
  { return (insn & 0x3b200c00) == 0x38200800; }

  static bool
  aarch64_ldst_uimm(Insntype insn)
  { return (insn & 0x3b000000) == 0x39000000; }

  static bool
  aarch64_ldst_simd_m(Insntype insn)
  { return (insn & 0xbfbf0000) == 0x0c000000; }

  static bool
  aarch64_ldst_simd_m_pi(Insntype insn)
  { return (insn & 0xbfa00000) == 0x0c800000; }

  static bool
  aarch64_ldst_simd_s(Insntype insn)
  { return (insn & 0xbf9f0000) == 0x0d000000; }

  static bool
  aarch64_ldst_simd_s_pi(Insntype insn)
  { return (insn & 0xbf800000) == 0x0d800000; }

  // Classify an INSN if it is indeed a load/store. Return true if INSN is a
  // LD/ST instruction otherwise return false. For scalar LD/ST instructions
  // PAIR is FALSE, RT is returned and RT2 is set equal to RT. For LD/ST pair
  // instructions PAIR is TRUE, RT and RT2 are returned.
  static bool
  aarch64_mem_op_p(Insntype insn, unsigned int *rt, unsigned int *rt2,
		   bool *pair, bool *load)
  {
    uint32_t opcode;
    unsigned int r;
    uint32_t opc = 0;
    uint32_t v = 0;
    uint32_t opc_v = 0;

    /* Bail out quickly if INSN doesn't fall into the the load-store
       encoding space.  */
    if (!aarch64_ldst (insn))
      return false;

    *pair = false;
    *load = false;
    if (aarch64_ldst_ex (insn))
      {
	*rt = aarch64_rt (insn);
	*rt2 = *rt;
	if (aarch64_bit (insn, 21) == 1)
	  {
	    *pair = true;
	    *rt2 = aarch64_rt2 (insn);
	  }
	*load = aarch64_ld (insn);
	return true;
      }
    else if (aarch64_ldst_nap (insn)
	     || aarch64_ldstp_pi (insn)
	     || aarch64_ldstp_o (insn)
	     || aarch64_ldstp_pre (insn))
      {
	*pair = true;
	*rt = aarch64_rt (insn);
	*rt2 = aarch64_rt2 (insn);
	*load = aarch64_ld (insn);
	return true;
      }
    else if (aarch64_ldst_pcrel (insn)
	     || aarch64_ldst_ui (insn)
	     || aarch64_ldst_piimm (insn)
	     || aarch64_ldst_u (insn)
	     || aarch64_ldst_preimm (insn)
	     || aarch64_ldst_ro (insn)
	     || aarch64_ldst_uimm (insn))
      {
	*rt = aarch64_rt (insn);
	*rt2 = *rt;
	if (aarch64_ldst_pcrel (insn))
	  *load = true;
	opc = aarch64_bits (insn, 22, 2);
	v = aarch64_bit (insn, 26);
	opc_v = opc | (v << 2);
	*load =  (opc_v == 1 || opc_v == 2 || opc_v == 3
		  || opc_v == 5 || opc_v == 7);
	return true;
      }
    else if (aarch64_ldst_simd_m (insn)
	     || aarch64_ldst_simd_m_pi (insn))
      {
	*rt = aarch64_rt (insn);
	*load = aarch64_bit (insn, 22);
	opcode = (insn >> 12) & 0xf;
	switch (opcode)
	  {
	  case 0:
	  case 2:
	    *rt2 = *rt + 3;
	    break;

	  case 4:
	  case 6:
	    *rt2 = *rt + 2;
	    break;

	  case 7:
	    *rt2 = *rt;
	    break;

	  case 8:
	  case 10:
	    *rt2 = *rt + 1;
	    break;

	  default:
	    return false;
	  }
	return true;
      }
    else if (aarch64_ldst_simd_s (insn)
	     || aarch64_ldst_simd_s_pi (insn))
      {
	*rt = aarch64_rt (insn);
	r = (insn >> 21) & 1;
	*load = aarch64_bit (insn, 22);
	opcode = (insn >> 13) & 0x7;
	switch (opcode)
	  {
	  case 0:
	  case 2:
	  case 4:
	    *rt2 = *rt + r;
	    break;

	  case 1:
	  case 3:
	  case 5:
	    *rt2 = *rt + (r == 0 ? 2 : 3);
	    break;

	  case 6:
	    *rt2 = *rt + r;
	    break;

	  case 7:
	    *rt2 = *rt + (r == 0 ? 2 : 3);
	    break;

	  default:
	    return false;
	  }
	return true;
      }
    return false;
  }  // End of "aarch64_mem_op_p".

  // Return true if INSN is mac insn.
  static bool
  aarch64_mac(Insntype insn)
  { return (insn & 0xff000000) == 0x9b000000; }

  // Return true if INSN is multiply-accumulate.
  // (This is similar to implementaton in elfnn-aarch64.c.)
  static bool
  aarch64_mlxl(Insntype insn)
  {
    uint32_t op31 = aarch64_op31(insn);
    if (aarch64_mac(insn)
	&& (op31 == 0 || op31 == 1 || op31 == 5)
	/* Exclude MUL instructions which are encoded as a multiple-accumulate
	   with RA = XZR.  */
	&& aarch64_ra(insn) != AARCH64_ZR)
      {
	return true;
      }
    return false;
  }
};  // End of "AArch64_insn_utilities".


// Insn length in byte.

template<bool big_endian>
const int AArch64_insn_utilities<big_endian>::BYTES_PER_INSN = 4;


// Zero register encoding - 31.

template<bool big_endian>
const unsigned int AArch64_insn_utilities<big_endian>::AARCH64_ZR = 0x1f;


// Output_data_got_aarch64 class.

template<int size, bool big_endian>
class Output_data_got_aarch64 : public Output_data_got<size, big_endian>
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype;
  Output_data_got_aarch64(Symbol_table* symtab, Layout* layout)
    : Output_data_got<size, big_endian>(),
      symbol_table_(symtab), layout_(layout)
  { }

  // Add a static entry for the GOT entry at OFFSET.  GSYM is a global
  // symbol and R_TYPE is the code of a dynamic relocation that needs to be
  // applied in a static link.
  void
  add_static_reloc(unsigned int got_offset, unsigned int r_type, Symbol* gsym)
  { this->static_relocs_.push_back(Static_reloc(got_offset, r_type, gsym)); }


  // Add a static reloc for the GOT entry at OFFSET.  RELOBJ is an object
  // defining a local symbol with INDEX.  R_TYPE is the code of a dynamic
  // relocation that needs to be applied in a static link.
  void
  add_static_reloc(unsigned int got_offset, unsigned int r_type,
		   Sized_relobj_file<size, big_endian>* relobj,
		   unsigned int index)
  {
    this->static_relocs_.push_back(Static_reloc(got_offset, r_type, relobj,
						index));
  }


 protected:
  // Write out the GOT table.
  void
  do_write(Output_file* of) {
    // The first entry in the GOT is the address of the .dynamic section.
    gold_assert(this->data_size() >= size / 8);
    Output_section* dynamic = this->layout_->dynamic_section();
    Valtype dynamic_addr = dynamic == NULL ? 0 : dynamic->address();
    this->replace_constant(0, dynamic_addr);
    Output_data_got<size, big_endian>::do_write(of);

    // Handling static relocs
    if (this->static_relocs_.empty())
      return;

    typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;

    gold_assert(parameters->doing_static_link());
    const off_t 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);

    Output_segment* tls_segment = this->layout_->tls_segment();
    gold_assert(tls_segment != NULL);

    AArch64_address aligned_tcb_address =
      align_address(Target_aarch64<size, big_endian>::TCB_SIZE,
		    tls_segment->maximum_alignment());

    for (size_t i = 0; i < this->static_relocs_.size(); ++i)
      {
	Static_reloc& reloc(this->static_relocs_[i]);
	AArch64_address value;

	if (!reloc.symbol_is_global())
	  {
	    Sized_relobj_file<size, big_endian>* object = reloc.relobj();
	    const Symbol_value<size>* psymval =
	      reloc.relobj()->local_symbol(reloc.index());

	    // We are doing static linking.  Issue an error and skip this
	    // relocation if the symbol is undefined or in a discarded_section.
	    bool is_ordinary;
	    unsigned int shndx = psymval->input_shndx(&is_ordinary);
	    if ((shndx == elfcpp::SHN_UNDEF)
		|| (is_ordinary
		    && shndx != elfcpp::SHN_UNDEF
		    && !object->is_section_included(shndx)
		    && !this->symbol_table_->is_section_folded(object, shndx)))
	      {
		gold_error(_("undefined or discarded local symbol %u from "
			     " object %s in GOT"),
			   reloc.index(), reloc.relobj()->name().c_str());
		continue;
	      }
	    value = psymval->value(object, 0);
	  }
	else
	  {
	    const Symbol* gsym = reloc.symbol();
	    gold_assert(gsym != NULL);
	    if (gsym->is_forwarder())
	      gsym = this->symbol_table_->resolve_forwards(gsym);

	    // We are doing static linking.  Issue an error and skip this
	    // relocation if the symbol is undefined or in a discarded_section
	    // unless it is a weakly_undefined symbol.
	    if ((gsym->is_defined_in_discarded_section()
		 || gsym->is_undefined())
		&& !gsym->is_weak_undefined())
	      {
		gold_error(_("undefined or discarded symbol %s in GOT"),
			   gsym->name());
		continue;
	      }

	    if (!gsym->is_weak_undefined())
	      {
		const Sized_symbol<size>* sym =
		  static_cast<const Sized_symbol<size>*>(gsym);
		value = sym->value();
	      }
	    else
	      value = 0;
	  }

	unsigned got_offset = reloc.got_offset();
	gold_assert(got_offset < oview_size);

	typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
	Valtype* wv = reinterpret_cast<Valtype*>(oview + got_offset);
	Valtype x;
	switch (reloc.r_type())
	  {
	  case elfcpp::R_AARCH64_TLS_DTPREL64:
	    x = value;
	    break;
	  case elfcpp::R_AARCH64_TLS_TPREL64:
	    x = value + aligned_tcb_address;
	    break;
	  default:
	    gold_unreachable();
	  }
	elfcpp::Swap<size, big_endian>::writeval(wv, x);
      }

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

 private:
  // Symbol table of the output object.
  Symbol_table* symbol_table_;
  // A pointer to the Layout class, so that we can find the .dynamic
  // section when we write out the GOT section.
  Layout* layout_;

  // This class represent dynamic relocations that need to be applied by
  // gold because we are using TLS relocations in a static link.
  class Static_reloc
  {
   public:
    Static_reloc(unsigned int got_offset, unsigned int r_type, Symbol* gsym)
      : got_offset_(got_offset), r_type_(r_type), symbol_is_global_(true)
    { this->u_.global.symbol = gsym; }

    Static_reloc(unsigned int got_offset, unsigned int r_type,
	  Sized_relobj_file<size, big_endian>* relobj, unsigned int index)
      : got_offset_(got_offset), r_type_(r_type), symbol_is_global_(false)
    {
      this->u_.local.relobj = relobj;
      this->u_.local.index = index;
    }

    // Return the GOT offset.
    unsigned int
    got_offset() const
    { return this->got_offset_; }

    // Relocation type.
    unsigned int
    r_type() const
    { return this->r_type_; }

    // Whether the symbol is global or not.
    bool
    symbol_is_global() const
    { return this->symbol_is_global_; }

    // For a relocation against a global symbol, the global symbol.
    Symbol*
    symbol() const
    {
      gold_assert(this->symbol_is_global_);
      return this->u_.global.symbol;
    }

    // For a relocation against a local symbol, the defining object.
    Sized_relobj_file<size, big_endian>*
    relobj() const
    {
      gold_assert(!this->symbol_is_global_);
      return this->u_.local.relobj;
    }

    // For a relocation against a local symbol, the local symbol index.
    unsigned int
    index() const
    {
      gold_assert(!this->symbol_is_global_);
      return this->u_.local.index;
    }

   private:
    // GOT offset of the entry to which this relocation is applied.
    unsigned int got_offset_;
    // Type of relocation.
    unsigned int r_type_;
    // Whether this relocation is against a global symbol.
    bool symbol_is_global_;
    // A global or local symbol.
    union
    {
      struct
      {
	// For a global symbol, the symbol itself.
	Symbol* symbol;
      } global;
      struct
      {
	// For a local symbol, the object defining the symbol.
	Sized_relobj_file<size, big_endian>* relobj;
	// For a local symbol, the symbol index.
	unsigned int index;
      } local;
    } u_;
  };  // End of inner class Static_reloc

  std::vector<Static_reloc> static_relocs_;
};  // End of Output_data_got_aarch64


template<int size, bool big_endian>
class AArch64_input_section;


template<int size, bool big_endian>
class AArch64_output_section;


template<int size, bool big_endian>
class AArch64_relobj;


// Stub type enum constants.

enum
{
  ST_NONE = 0,

  // Using adrp/add pair, 4 insns (including alignment) without mem access,
  // the fastest stub. This has a limited jump distance, which is tested by
  // aarch64_valid_for_adrp_p.
  ST_ADRP_BRANCH = 1,

  // Using ldr-absolute-address/br-register, 4 insns with 1 mem access,
  // unlimited in jump distance.
  ST_LONG_BRANCH_ABS = 2,

  // Using ldr/calculate-pcrel/jump, 8 insns (including alignment) with 1
  // mem access, slowest one. Only used in position independent executables.
  ST_LONG_BRANCH_PCREL = 3,

  // Stub for erratum 843419 handling.
  ST_E_843419 = 4,

  // Stub for erratum 835769 handling.
  ST_E_835769 = 5,

  // Number of total stub types.
  ST_NUMBER = 6
};


// Struct that wraps insns for a particular stub. All stub templates are
// created/initialized as constants by Stub_template_repertoire.

template<bool big_endian>
struct Stub_template
{
  const typename AArch64_insn_utilities<big_endian>::Insntype* insns;
  const int insn_num;
};


// Simple singleton class that creates/initializes/stores all types of stub
// templates.

template<bool big_endian>
class Stub_template_repertoire
{
public:
  typedef typename AArch64_insn_utilities<big_endian>::Insntype Insntype;

  // Single static method to get stub template for a given stub type.
  static const Stub_template<big_endian>*
  get_stub_template(int type)
  {
    static Stub_template_repertoire<big_endian> singleton;
    return singleton.stub_templates_[type];
  }

private:
  // Constructor - creates/initializes all stub templates.
  Stub_template_repertoire();
  ~Stub_template_repertoire()
  { }

  // Disallowing copy ctor and copy assignment operator.
  Stub_template_repertoire(Stub_template_repertoire&);
  Stub_template_repertoire& operator=(Stub_template_repertoire&);

  // Data that stores all insn templates.
  const Stub_template<big_endian>* stub_templates_[ST_NUMBER];
};  // End of "class Stub_template_repertoire".


// Constructor - creates/initilizes all stub templates.

template<bool big_endian>
Stub_template_repertoire<big_endian>::Stub_template_repertoire()
{
  // Insn array definitions.
  const static Insntype ST_NONE_INSNS[] = {};

  const static Insntype ST_ADRP_BRANCH_INSNS[] =
    {
      0x90000010,	/*	adrp	ip0, X		   */
			/*	  ADR_PREL_PG_HI21(X)	   */
      0x91000210,	/*	add	ip0, ip0, :lo12:X  */
			/*	  ADD_ABS_LO12_NC(X)	   */
      0xd61f0200,	/*	br	ip0		   */
      0x00000000,	/*	alignment padding	   */
    };

  const static Insntype ST_LONG_BRANCH_ABS_INSNS[] =
    {
      0x58000050,	/*	ldr   ip0, 0x8		   */
      0xd61f0200,	/*	br    ip0		   */
      0x00000000,	/*	address field		   */
      0x00000000,	/*	address fields		   */
    };

  const static Insntype ST_LONG_BRANCH_PCREL_INSNS[] =
    {
      0x58000090,	/*	ldr   ip0, 0x10            */
      0x10000011,	/*	adr   ip1, #0		   */
      0x8b110210,	/*	add   ip0, ip0, ip1	   */
      0xd61f0200,	/*	br    ip0		   */
      0x00000000,	/*	address field		   */
      0x00000000,	/*	address field		   */
      0x00000000,	/*	alignment padding	   */
      0x00000000,	/*	alignment padding	   */
    };

  const static Insntype ST_E_843419_INSNS[] =
    {
      0x00000000,    /* Placeholder for erratum insn. */
      0x14000000,    /* b <label> */
    };

  // ST_E_835769 has the same stub template as ST_E_843419.
  const static Insntype* ST_E_835769_INSNS = ST_E_843419_INSNS;

#define install_insn_template(T) \
  const static Stub_template<big_endian> template_##T = {  \
    T##_INSNS, sizeof(T##_INSNS) / sizeof(T##_INSNS[0]) }; \
  this->stub_templates_[T] = &template_##T

  install_insn_template(ST_NONE);
  install_insn_template(ST_ADRP_BRANCH);
  install_insn_template(ST_LONG_BRANCH_ABS);
  install_insn_template(ST_LONG_BRANCH_PCREL);
  install_insn_template(ST_E_843419);
  install_insn_template(ST_E_835769);

#undef install_insn_template
}


// Base class for stubs.

template<int size, bool big_endian>
class Stub_base
{
public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
  typedef typename AArch64_insn_utilities<big_endian>::Insntype Insntype;

  static const AArch64_address invalid_address =
    static_cast<AArch64_address>(-1);

  static const section_offset_type invalid_offset =
    static_cast<section_offset_type>(-1);

  Stub_base(int type)
    : destination_address_(invalid_address),
      offset_(invalid_offset),
      type_(type)
  {}

  ~Stub_base()
  {}

  // Get stub type.
  int
  type() const
  { return this->type_; }

  // Get stub template that provides stub insn information.
  const Stub_template<big_endian>*
  stub_template() const
  {
    return Stub_template_repertoire<big_endian>::
      get_stub_template(this->type());
  }

  // Get destination address.
  AArch64_address
  destination_address() const
  {
    gold_assert(this->destination_address_ != this->invalid_address);
    return this->destination_address_;
  }

  // Set destination address.
  void
  set_destination_address(AArch64_address address)
  {
    gold_assert(address != this->invalid_address);
    this->destination_address_ = address;
  }

  // Reset the destination address.
  void
  reset_destination_address()
  { this->destination_address_ = this->invalid_address; }

  // Get offset of code stub. For Reloc_stub, it is the offset from the
  // beginning of its containing stub table; for Erratum_stub, it is the offset
  // from the end of reloc_stubs.
  section_offset_type
  offset() const
  {
    gold_assert(this->offset_ != this->invalid_offset);
    return this->offset_;
  }

  // Set stub offset.
  void
  set_offset(section_offset_type offset)
  { this->offset_ = offset; }

  // Return the stub insn.
  const Insntype*
  insns() const
  { return this->stub_template()->insns; }

  // Return num of stub insns.
  unsigned int
  insn_num() const
  { return this->stub_template()->insn_num; }

  // Get size of the stub.
  int
  stub_size() const
  {
    return this->insn_num() *
      AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;
  }

  // Write stub to output file.
  void
  write(unsigned char* view, section_size_type view_size)
  { this->do_write(view, view_size); }

protected:
  // Abstract method to be implemented by sub-classes.
  virtual void
  do_write(unsigned char*, section_size_type) = 0;

private:
  // The last insn of a stub is a jump to destination insn. This field records
  // the destination address.
  AArch64_address destination_address_;
  // The stub offset. Note this has difference interpretations between an
  // Reloc_stub and an Erratum_stub. For Reloc_stub this is the offset from the
  // beginning of the containing stub_table, whereas for Erratum_stub, this is
  // the offset from the end of reloc_stubs.
  section_offset_type offset_;
  // Stub type.
  const int type_;
};  // End of "Stub_base".


// Erratum stub class. An erratum stub differs from a reloc stub in that for
// each erratum occurrence, we generate an erratum stub. We never share erratum
// stubs, whereas for reloc stubs, different branches insns share a single reloc
// stub as long as the branch targets are the same. (More to the point, reloc
// stubs can be shared because they're used to reach a specific target, whereas
// erratum stubs branch back to the original control flow.)

template<int size, bool big_endian>
class Erratum_stub : public Stub_base<size, big_endian>
{
public:
  typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
  typedef AArch64_insn_utilities<big_endian> Insn_utilities;
  typedef typename AArch64_insn_utilities<big_endian>::Insntype Insntype;

  static const int STUB_ADDR_ALIGN;

  static const Insntype invalid_insn = static_cast<Insntype>(-1);

  Erratum_stub(The_aarch64_relobj* relobj, int type,
	       unsigned shndx, unsigned int sh_offset)
    : Stub_base<size, big_endian>(type), relobj_(relobj),
      shndx_(shndx), sh_offset_(sh_offset),
      erratum_insn_(invalid_insn),
      erratum_address_(this->invalid_address)
  {}

  ~Erratum_stub() {}

  // Return the object that contains the erratum.
  The_aarch64_relobj*
  relobj()
  { return this->relobj_; }

  // Get section index of the erratum.
  unsigned int
  shndx() const
  { return this->shndx_; }

  // Get section offset of the erratum.
  unsigned int
  sh_offset() const
  { return this->sh_offset_; }

  // Get the erratum insn. This is the insn located at erratum_insn_address.
  Insntype
  erratum_insn() const
  {
    gold_assert(this->erratum_insn_ != this->invalid_insn);
    return this->erratum_insn_;
  }

  // Set the insn that the erratum happens to.
  void
  set_erratum_insn(Insntype insn)
  { this->erratum_insn_ = insn; }

  // For 843419, the erratum insn is ld/st xt, [xn, #uimm], which may be a
  // relocation spot, in this case, the erratum_insn_ recorded at scanning phase
  // is no longer the one we want to write out to the stub, update erratum_insn_
  // with relocated version. Also note that in this case xn must not be "PC", so
  // it is safe to move the erratum insn from the origin place to the stub. For
  // 835769, the erratum insn is multiply-accumulate insn, which could not be a
  // relocation spot (assertion added though).
  void
  update_erratum_insn(Insntype insn)
  {
    gold_assert(this->erratum_insn_ != this->invalid_insn);
    switch (this->type())
      {
      case ST_E_843419:
	gold_assert(Insn_utilities::aarch64_ldst_uimm(insn));
	gold_assert(Insn_utilities::aarch64_ldst_uimm(this->erratum_insn()));
	gold_assert(Insn_utilities::aarch64_rd(insn) ==
		    Insn_utilities::aarch64_rd(this->erratum_insn()));
	gold_assert(Insn_utilities::aarch64_rn(insn) ==
		    Insn_utilities::aarch64_rn(this->erratum_insn()));
	// Update plain ld/st insn with relocated insn.
	this->erratum_insn_ = insn;
	break;
      case ST_E_835769:
	gold_assert(insn == this->erratum_insn());
	break;
      default:
	gold_unreachable();
      }
  }


  // Return the address where an erratum must be done.
  AArch64_address
  erratum_address() const
  {
    gold_assert(this->erratum_address_ != this->invalid_address);
    return this->erratum_address_;
  }

  // Set the address where an erratum must be done.
  void
  set_erratum_address(AArch64_address addr)
  { this->erratum_address_ = addr; }

  // Comparator used to group Erratum_stubs in a set by (obj, shndx,
  // sh_offset). We do not include 'type' in the calculation, becuase there is
  // at most one stub type at (obj, shndx, sh_offset).
  bool
  operator<(const Erratum_stub<size, big_endian>& k) const
  {
    if (this == &k)
      return false;
    // We group stubs by relobj.
    if (this->relobj_ != k.relobj_)
      return this->relobj_ < k.relobj_;
    // Then by section index.
    if (this->shndx_ != k.shndx_)
      return this->shndx_ < k.shndx_;
    // Lastly by section offset.
    return this->sh_offset_ < k.sh_offset_;
  }

protected:
  virtual void
  do_write(unsigned char*, section_size_type);

private:
  // The object that needs to be fixed.
  The_aarch64_relobj* relobj_;
  // The shndx in the object that needs to be fixed.
  const unsigned int shndx_;
  // The section offset in the obejct that needs to be fixed.
  const unsigned int sh_offset_;
  // The insn to be fixed.
  Insntype erratum_insn_;
  // The address of the above insn.
  AArch64_address erratum_address_;
};  // End of "Erratum_stub".


// Erratum sub class to wrap additional info needed by 843419.  In fixing this
// erratum, we may choose to replace 'adrp' with 'adr', in this case, we need
// adrp's code position (two or three insns before erratum insn itself).

template<int size, bool big_endian>
class E843419_stub : public Erratum_stub<size, big_endian>
{
public:
  typedef typename AArch64_insn_utilities<big_endian>::Insntype Insntype;

  E843419_stub(AArch64_relobj<size, big_endian>* relobj,
		      unsigned int shndx, unsigned int sh_offset,
		      unsigned int adrp_sh_offset)
    : Erratum_stub<size, big_endian>(relobj, ST_E_843419, shndx, sh_offset),
      adrp_sh_offset_(adrp_sh_offset)
  {}

  unsigned int
  adrp_sh_offset() const
  { return this->adrp_sh_offset_; }

private:
  // Section offset of "adrp". (We do not need a "adrp_shndx_" field, because we
  // can can obtain it from its parent.)
  const unsigned int adrp_sh_offset_;
};


template<int size, bool big_endian>
const int Erratum_stub<size, big_endian>::STUB_ADDR_ALIGN = 4;

// Comparator used in set definition.
template<int size, bool big_endian>
struct Erratum_stub_less
{
  bool
  operator()(const Erratum_stub<size, big_endian>* s1,
	     const Erratum_stub<size, big_endian>* s2) const
  { return *s1 < *s2; }
};

// Erratum_stub implementation for writing stub to output file.

template<int size, bool big_endian>
void
Erratum_stub<size, big_endian>::do_write(unsigned char* view, section_size_type)
{
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
  const Insntype* insns = this->insns();
  uint32_t num_insns = this->insn_num();
  Insntype* ip = reinterpret_cast<Insntype*>(view);
  // For current implemented erratum 843419 and 835769, the first insn in the
  // stub is always a copy of the problematic insn (in 843419, the mem access
  // insn, in 835769, the mac insn), followed by a jump-back.
  elfcpp::Swap<32, big_endian>::writeval(ip, this->erratum_insn());
  for (uint32_t i = 1; i < num_insns; ++i)
    elfcpp::Swap<32, big_endian>::writeval(ip + i, insns[i]);
}


// Reloc stub class.

template<int size, bool big_endian>
class Reloc_stub : public Stub_base<size, big_endian>
{
 public:
  typedef Reloc_stub<size, big_endian> This;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;

  // Branch range. This is used to calculate the section group size, as well as
  // determine whether a stub is needed.
  static const int MAX_BRANCH_OFFSET = ((1 << 25) - 1) << 2;
  static const int MIN_BRANCH_OFFSET = -((1 << 25) << 2);

  // Constant used to determine if an offset fits in the adrp instruction
  // encoding.
  static const int MAX_ADRP_IMM = (1 << 20) - 1;
  static const int MIN_ADRP_IMM = -(1 << 20);

  static const int BYTES_PER_INSN = 4;
  static const int STUB_ADDR_ALIGN;

  // Determine whether the offset fits in the jump/branch instruction.
  static bool
  aarch64_valid_branch_offset_p(int64_t offset)
  { return offset >= MIN_BRANCH_OFFSET && offset <= MAX_BRANCH_OFFSET; }

  // Determine whether the offset fits in the adrp immediate field.
  static bool
  aarch64_valid_for_adrp_p(AArch64_address location, AArch64_address dest)
  {
    typedef AArch64_relocate_functions<size, big_endian> Reloc;
    int64_t adrp_imm = (Reloc::Page(dest) - Reloc::Page(location)) >> 12;
    return adrp_imm >= MIN_ADRP_IMM && adrp_imm <= MAX_ADRP_IMM;
  }

  // Determine the stub type for a certain relocation or ST_NONE, if no stub is
  // needed.
  static int
  stub_type_for_reloc(unsigned int r_type, AArch64_address address,
		      AArch64_address target);

  Reloc_stub(int type)
    : Stub_base<size, big_endian>(type)
  { }

  ~Reloc_stub()
  { }

  // The key class used to index the stub instance in the stub table's stub map.
  class Key
  {
   public:
    Key(int type, const Symbol* symbol, const Relobj* relobj,
	unsigned int r_sym, int32_t addend)
      : type_(type), addend_(addend)
    {
      if (symbol != NULL)
	{
	  this->r_sym_ = Reloc_stub::invalid_index;
	  this->u_.symbol = symbol;
	}
      else
	{
	  gold_assert(relobj != NULL && r_sym != invalid_index);
	  this->r_sym_ = r_sym;
	  this->u_.relobj = relobj;
	}
    }

    ~Key()
    { }

    // Return stub type.
    int
    type() const
    { return this->type_; }

    // Return the local symbol index or invalid_index.
    unsigned int
    r_sym() const
    { return this->r_sym_; }

    // Return the symbol if there is one.
    const Symbol*
    symbol() const
    { return this->r_sym_ == invalid_index ? this->u_.symbol : NULL; }

    // Return the relobj if there is one.
    const Relobj*
    relobj() const
    { return this->r_sym_ != invalid_index ? this->u_.relobj : NULL; }

    // Whether this equals to another key k.
    bool
    eq(const Key& k) const
    {
      return ((this->type_ == k.type_)
	      && (this->r_sym_ == k.r_sym_)
	      && ((this->r_sym_ != Reloc_stub::invalid_index)
		  ? (this->u_.relobj == k.u_.relobj)
		  : (this->u_.symbol == k.u_.symbol))
	      && (this->addend_ == k.addend_));
    }

    // Return a hash value.
    size_t
    hash_value() const
    {
      size_t name_hash_value = gold::string_hash<char>(
	  (this->r_sym_ != Reloc_stub::invalid_index)
	  ? this->u_.relobj->name().c_str()
	  : this->u_.symbol->name());
      // We only have 4 stub types.
      size_t stub_type_hash_value = 0x03 & this->type_;
      return (name_hash_value
	      ^ stub_type_hash_value
	      ^ ((this->r_sym_ & 0x3fff) << 2)
	      ^ ((this->addend_ & 0xffff) << 16));
    }

    // Functors for STL associative containers.
    struct hash
    {
      size_t
      operator()(const Key& k) const
      { return k.hash_value(); }
    };

    struct equal_to
    {
      bool
      operator()(const Key& k1, const Key& k2) const
      { return k1.eq(k2); }
    };

   private:
    // Stub type.
    const int type_;
    // If this is a local symbol, this is the index in the defining object.
    // Otherwise, it is invalid_index for a global symbol.
    unsigned int r_sym_;
    // If r_sym_ is an invalid index, this points to a global symbol.
    // Otherwise, it points to a relobj.  We used the unsized and target
    // independent Symbol and Relobj classes instead of Sized_symbol<32> and
    // Arm_relobj, in order to avoid making the stub class a template
    // as most of the stub machinery is endianness-neutral.  However, it
    // may require a bit of casting done by users of this class.
    union
    {
      const Symbol* symbol;
      const Relobj* relobj;
    } u_;
    // Addend associated with a reloc.
    int32_t addend_;
  };  // End of inner class Reloc_stub::Key

 protected:
  // This may be overridden in the child class.
  virtual void
  do_write(unsigned char*, section_size_type);

 private:
  static const unsigned int invalid_index = static_cast<unsigned int>(-1);
};  // End of Reloc_stub

template<int size, bool big_endian>
const int Reloc_stub<size, big_endian>::STUB_ADDR_ALIGN = 4;

// Write data to output file.

template<int size, bool big_endian>
void
Reloc_stub<size, big_endian>::
do_write(unsigned char* view, section_size_type)
{
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
  const uint32_t* insns = this->insns();
  uint32_t num_insns = this->insn_num();
  Insntype* ip = reinterpret_cast<Insntype*>(view);
  for (uint32_t i = 0; i < num_insns; ++i)
    elfcpp::Swap<32, big_endian>::writeval(ip + i, insns[i]);
}


// Determine the stub type for a certain relocation or ST_NONE, if no stub is
// needed.

template<int size, bool big_endian>
inline int
Reloc_stub<size, big_endian>::stub_type_for_reloc(
    unsigned int r_type, AArch64_address location, AArch64_address dest)
{
  int64_t branch_offset = 0;
  switch(r_type)
    {
    case elfcpp::R_AARCH64_CALL26:
    case elfcpp::R_AARCH64_JUMP26:
      branch_offset = dest - location;
      break;
    default:
      gold_unreachable();
    }

  if (aarch64_valid_branch_offset_p(branch_offset))
    return ST_NONE;

  if (aarch64_valid_for_adrp_p(location, dest))
    return ST_ADRP_BRANCH;

  // Always use PC-relative addressing in case of -shared or -pie.
  if (parameters->options().output_is_position_independent())
    return ST_LONG_BRANCH_PCREL;

  // This saves 2 insns per stub, compared to ST_LONG_BRANCH_PCREL.
  // But is only applicable to non-shared or non-pie.
  return ST_LONG_BRANCH_ABS;
}

// A class to hold stubs for the ARM target.

template<int size, bool big_endian>
class Stub_table : public Output_data
{
 public:
  typedef Target_aarch64<size, big_endian> The_target_aarch64;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
  typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
  typedef AArch64_input_section<size, big_endian> The_aarch64_input_section;
  typedef Reloc_stub<size, big_endian> The_reloc_stub;
  typedef typename The_reloc_stub::Key The_reloc_stub_key;
  typedef Erratum_stub<size, big_endian> The_erratum_stub;
  typedef Erratum_stub_less<size, big_endian> The_erratum_stub_less;
  typedef typename The_reloc_stub_key::hash The_reloc_stub_key_hash;
  typedef typename The_reloc_stub_key::equal_to The_reloc_stub_key_equal_to;
  typedef Stub_table<size, big_endian> The_stub_table;
  typedef Unordered_map<The_reloc_stub_key, The_reloc_stub*,
			The_reloc_stub_key_hash, The_reloc_stub_key_equal_to>
			Reloc_stub_map;
  typedef typename Reloc_stub_map::const_iterator Reloc_stub_map_const_iter;
  typedef Relocate_info<size, big_endian> The_relocate_info;

  typedef std::set<The_erratum_stub*, The_erratum_stub_less> Erratum_stub_set;
  typedef typename Erratum_stub_set::iterator Erratum_stub_set_iter;

  Stub_table(The_aarch64_input_section* owner)
    : Output_data(), owner_(owner), reloc_stubs_size_(0),
      erratum_stubs_size_(0), prev_data_size_(0)
  { }

  ~Stub_table()
  { }

  The_aarch64_input_section*
  owner() const
  { return owner_; }

  // Whether this stub table is empty.
  bool
  empty() const
  { return reloc_stubs_.empty() && erratum_stubs_.empty(); }

  // Return the current data size.
  off_t
  current_data_size() const
  { return this->current_data_size_for_child(); }

  // Add a STUB using KEY.  The caller is responsible for avoiding addition
  // if a STUB with the same key has already been added.
  void
  add_reloc_stub(The_reloc_stub* stub, const The_reloc_stub_key& key);

  // Add an erratum stub into the erratum stub set. The set is ordered by
  // (relobj, shndx, sh_offset).
  void
  add_erratum_stub(The_erratum_stub* stub);

  // Find if such erratum exists for any given (obj, shndx, sh_offset).
  The_erratum_stub*
  find_erratum_stub(The_aarch64_relobj* a64relobj,
		    unsigned int shndx, unsigned int sh_offset);

  // Find all the erratums for a given input section. The return value is a pair
  // of iterators [begin, end).
  std::pair<Erratum_stub_set_iter, Erratum_stub_set_iter>
  find_erratum_stubs_for_input_section(The_aarch64_relobj* a64relobj,
				       unsigned int shndx);

  // Compute the erratum stub address.
  AArch64_address
  erratum_stub_address(The_erratum_stub* stub) const
  {
    AArch64_address r = align_address(this->address() + this->reloc_stubs_size_,
				      The_erratum_stub::STUB_ADDR_ALIGN);
    r += stub->offset();
    return r;
  }

  // Finalize stubs. No-op here, just for completeness.
  void
  finalize_stubs()
  { }

  // Look up a relocation stub using KEY. Return NULL if there is none.
  The_reloc_stub*
  find_reloc_stub(The_reloc_stub_key& key)
  {
    Reloc_stub_map_const_iter p = this->reloc_stubs_.find(key);
    return (p != this->reloc_stubs_.end()) ? p->second : NULL;
  }

  // Relocate stubs in this stub table.
  void
  relocate_stubs(const The_relocate_info*,
		 The_target_aarch64*,
		 Output_section*,
		 unsigned char*,
		 AArch64_address,
		 section_size_type);

  // Update data size at the end of a relaxation pass.  Return true if data size
  // is different from that of the previous relaxation pass.
  bool
  update_data_size_changed_p()
  {
    // No addralign changed here.
    off_t s = align_address(this->reloc_stubs_size_,
			    The_erratum_stub::STUB_ADDR_ALIGN)
	      + this->erratum_stubs_size_;
    bool changed = (s != this->prev_data_size_);
    this->prev_data_size_ = s;
    return changed;
  }

 protected:
  // Write out section contents.
  void
  do_write(Output_file*);

  // Return the required alignment.
  uint64_t
  do_addralign() const
  {
    return std::max(The_reloc_stub::STUB_ADDR_ALIGN,
		    The_erratum_stub::STUB_ADDR_ALIGN);
  }

  // Reset address and file offset.
  void
  do_reset_address_and_file_offset()
  { this->set_current_data_size_for_child(this->prev_data_size_); }

  // Set final data size.
  void
  set_final_data_size()
  { this->set_data_size(this->current_data_size()); }

 private:
  // Relocate one stub.
  void
  relocate_stub(The_reloc_stub*,
		const The_relocate_info*,
		The_target_aarch64*,
		Output_section*,
		unsigned char*,
		AArch64_address,
		section_size_type);

 private:
  // Owner of this stub table.
  The_aarch64_input_section* owner_;
  // The relocation stubs.
  Reloc_stub_map reloc_stubs_;
  // The erratum stubs.
  Erratum_stub_set erratum_stubs_;
  // Size of reloc stubs.
  off_t reloc_stubs_size_;
  // Size of erratum stubs.
  off_t erratum_stubs_size_;
  // data size of this in the previous pass.
  off_t prev_data_size_;
};  // End of Stub_table


// Add an erratum stub into the erratum stub set. The set is ordered by
// (relobj, shndx, sh_offset).

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::add_erratum_stub(The_erratum_stub* stub)
{
  std::pair<Erratum_stub_set_iter, bool> ret =
    this->erratum_stubs_.insert(stub);
  gold_assert(ret.second);
  this->erratum_stubs_size_ = align_address(
	this->erratum_stubs_size_, The_erratum_stub::STUB_ADDR_ALIGN);
  stub->set_offset(this->erratum_stubs_size_);
  this->erratum_stubs_size_ += stub->stub_size();
}


// Find if such erratum exists for given (obj, shndx, sh_offset).

template<int size, bool big_endian>
Erratum_stub<size, big_endian>*
Stub_table<size, big_endian>::find_erratum_stub(
    The_aarch64_relobj* a64relobj, unsigned int shndx, unsigned int sh_offset)
{
  // A dummy object used as key to search in the set.
  The_erratum_stub key(a64relobj, ST_NONE,
			 shndx, sh_offset);
  Erratum_stub_set_iter i = this->erratum_stubs_.find(&key);
  if (i != this->erratum_stubs_.end())
    {
	The_erratum_stub* stub(*i);
	gold_assert(stub->erratum_insn() != 0);
	return stub;
    }
  return NULL;
}


// Find all the errata for a given input section. The return value is a pair of
// iterators [begin, end).

template<int size, bool big_endian>
std::pair<typename Stub_table<size, big_endian>::Erratum_stub_set_iter,
	  typename Stub_table<size, big_endian>::Erratum_stub_set_iter>
Stub_table<size, big_endian>::find_erratum_stubs_for_input_section(
    The_aarch64_relobj* a64relobj, unsigned int shndx)
{
  typedef std::pair<Erratum_stub_set_iter, Erratum_stub_set_iter> Result_pair;
  Erratum_stub_set_iter start, end;
  The_erratum_stub low_key(a64relobj, ST_NONE, shndx, 0);
  start = this->erratum_stubs_.lower_bound(&low_key);
  if (start == this->erratum_stubs_.end())
    return Result_pair(this->erratum_stubs_.end(),
		       this->erratum_stubs_.end());
  end = start;
  while (end != this->erratum_stubs_.end() &&
	 (*end)->relobj() == a64relobj && (*end)->shndx() == shndx)
    ++end;
  return Result_pair(start, end);
}


// Add a STUB using KEY.  The caller is responsible for avoiding addition
// if a STUB with the same key has already been added.

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::add_reloc_stub(
    The_reloc_stub* stub, const The_reloc_stub_key& key)
{
  gold_assert(stub->type() == key.type());
  this->reloc_stubs_[key] = stub;

  // Assign stub offset early.  We can do this because we never remove
  // reloc stubs and they are in the beginning of the stub table.
  this->reloc_stubs_size_ = align_address(this->reloc_stubs_size_,
					  The_reloc_stub::STUB_ADDR_ALIGN);
  stub->set_offset(this->reloc_stubs_size_);
  this->reloc_stubs_size_ += stub->stub_size();
}


// Relocate all stubs in this stub table.

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::
relocate_stubs(const The_relocate_info* relinfo,
	       The_target_aarch64* target_aarch64,
	       Output_section* output_section,
	       unsigned char* view,
	       AArch64_address address,
	       section_size_type view_size)
{
  // "view_size" is the total size of the stub_table.
  gold_assert(address == this->address() &&
	      view_size == static_cast<section_size_type>(this->data_size()));
  for(Reloc_stub_map_const_iter p = this->reloc_stubs_.begin();
      p != this->reloc_stubs_.end(); ++p)
    relocate_stub(p->second, relinfo, target_aarch64, output_section,
		  view, address, view_size);

  // Just for convenience.
  const int BPI = AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;

  // Now 'relocate' erratum stubs.
  for(Erratum_stub_set_iter i = this->erratum_stubs_.begin();
      i != this->erratum_stubs_.end(); ++i)
    {
      AArch64_address stub_address = this->erratum_stub_address(*i);
      // The address of "b" in the stub that is to be "relocated".
      AArch64_address stub_b_insn_address;
      // Branch offset that is to be filled in "b" insn.
      int b_offset = 0;
      switch ((*i)->type())
	{
	case ST_E_843419:
	case ST_E_835769:
	  // The 1st insn of the erratum could be a relocation spot,
	  // in this case we need to fix it with
	  // "(*i)->erratum_insn()".
	  elfcpp::Swap<32, big_endian>::writeval(
	      view + (stub_address - this->address()),
	      (*i)->erratum_insn());
	  // For the erratum, the 2nd insn is a b-insn to be patched
	  // (relocated).
	  stub_b_insn_address = stub_address + 1 * BPI;
	  b_offset = (*i)->destination_address() - stub_b_insn_address;
	  AArch64_relocate_functions<size, big_endian>::construct_b(
	      view + (stub_b_insn_address - this->address()),
	      ((unsigned int)(b_offset)) & 0xfffffff);
	  break;
	default:
	  gold_unreachable();
	  break;
	}
    }
}


// Relocate one stub.  This is a helper for Stub_table::relocate_stubs().

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::
relocate_stub(The_reloc_stub* stub,
	      const The_relocate_info* relinfo,
	      The_target_aarch64* target_aarch64,
	      Output_section* output_section,
	      unsigned char* view,
	      AArch64_address address,
	      section_size_type view_size)
{
  // "offset" is the offset from the beginning of the stub_table.
  section_size_type offset = stub->offset();
  section_size_type stub_size = stub->stub_size();
  // "view_size" is the total size of the stub_table.
  gold_assert(offset + stub_size <= view_size);

  target_aarch64->relocate_stub(stub, relinfo, output_section,
				view + offset, address + offset, view_size);
}


// Write out the stubs to file.

template<int size, bool big_endian>
void
Stub_table<size, big_endian>::do_write(Output_file* of)
{
  off_t 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);

  // Write relocation stubs.
  for (typename Reloc_stub_map::const_iterator p = this->reloc_stubs_.begin();
      p != this->reloc_stubs_.end(); ++p)
    {
      The_reloc_stub* stub = p->second;
      AArch64_address address = this->address() + stub->offset();
      gold_assert(address ==
		  align_address(address, The_reloc_stub::STUB_ADDR_ALIGN));
      stub->write(oview + stub->offset(), stub->stub_size());
    }

  // Write erratum stubs.
  unsigned int erratum_stub_start_offset =
    align_address(this->reloc_stubs_size_, The_erratum_stub::STUB_ADDR_ALIGN);
  for (typename Erratum_stub_set::iterator p = this->erratum_stubs_.begin();
       p != this->erratum_stubs_.end(); ++p)
    {
      The_erratum_stub* stub(*p);
      stub->write(oview + erratum_stub_start_offset + stub->offset(),
		  stub->stub_size());
    }

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


// AArch64_relobj class.

template<int size, bool big_endian>
class AArch64_relobj : public Sized_relobj_file<size, big_endian>
{
 public:
  typedef AArch64_relobj<size, big_endian> This;
  typedef Target_aarch64<size, big_endian> The_target_aarch64;
  typedef AArch64_input_section<size, big_endian> The_aarch64_input_section;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
  typedef Stub_table<size, big_endian> The_stub_table;
  typedef Erratum_stub<size, big_endian> The_erratum_stub;
  typedef typename The_stub_table::Erratum_stub_set_iter Erratum_stub_set_iter;
  typedef std::vector<The_stub_table*> Stub_table_list;
  static const AArch64_address invalid_address =
      static_cast<AArch64_address>(-1);

  AArch64_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),
      stub_tables_()
  { }

  ~AArch64_relobj()
  { }

  // Return the stub table of the SHNDX-th section if there is one.
  The_stub_table*
  stub_table(unsigned int shndx) const
  {
    gold_assert(shndx < this->stub_tables_.size());
    return this->stub_tables_[shndx];
  }

  // Set STUB_TABLE to be the stub_table of the SHNDX-th section.
  void
  set_stub_table(unsigned int shndx, The_stub_table* stub_table)
  {
    gold_assert(shndx < this->stub_tables_.size());
    this->stub_tables_[shndx] = stub_table;
  }

  // Entrance to errata scanning.
  void
  scan_errata(unsigned int shndx,
	      const elfcpp::Shdr<size, big_endian>&,
	      Output_section*, const Symbol_table*,
	      The_target_aarch64*);

  // Scan all relocation sections for stub generation.
  void
  scan_sections_for_stubs(The_target_aarch64*, const Symbol_table*,
			  const Layout*);

  // Whether a section is a scannable text section.
  bool
  text_section_is_scannable(const elfcpp::Shdr<size, big_endian>&, unsigned int,
			    const Output_section*, const Symbol_table*);

  // Convert regular input section with index SHNDX to a relaxed section.
  void
  convert_input_section_to_relaxed_section(unsigned /* shndx */)
  {
    // The stubs have relocations and we need to process them after writing
    // out the stubs.  So relocation now must follow section write.
    this->set_relocs_must_follow_section_writes();
  }

  // Structure for mapping symbol position.
  struct Mapping_symbol_position
  {
    Mapping_symbol_position(unsigned int shndx, AArch64_address offset):
      shndx_(shndx), offset_(offset)
    {}

    // "<" comparator used in ordered_map container.
    bool
    operator<(const Mapping_symbol_position& p) const
    {
      return (this->shndx_ < p.shndx_
	      || (this->shndx_ == p.shndx_ && this->offset_ < p.offset_));
    }

    // Section index.
    unsigned int shndx_;

    // Section offset.
    AArch64_address offset_;
  };

  typedef std::map<Mapping_symbol_position, char> Mapping_symbol_info;

 protected:
  // Post constructor setup.
  void
  do_setup()
  {
    // Call parent's setup method.
    Sized_relobj_file<size, big_endian>::do_setup();

    // Initialize look-up tables.
    this->stub_tables_.resize(this->shnum());
  }

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

  // Count local symbols and (optionally) record mapping info.
  virtual void
  do_count_local_symbols(Stringpool_template<char>*,
			 Stringpool_template<char>*);

 private:
  // Fix all errata in the object.
  void
  fix_errata(typename Sized_relobj_file<size, big_endian>::Views* pviews);

  // Try to fix erratum 843419 in an optimized way. Return true if patch is
  // applied.
  bool
  try_fix_erratum_843419_optimized(
      The_erratum_stub*,
      typename Sized_relobj_file<size, big_endian>::View_size&);

  // Whether a section needs to be scanned for relocation stubs.
  bool
  section_needs_reloc_stub_scanning(const elfcpp::Shdr<size, big_endian>&,
				    const Relobj::Output_sections&,
				    const Symbol_table*, const unsigned char*);

  // List of stub tables.
  Stub_table_list stub_tables_;

  // Mapping symbol information sorted by (section index, section_offset).
  Mapping_symbol_info mapping_symbol_info_;
};  // End of AArch64_relobj


// Override to record mapping symbol information.
template<int size, bool big_endian>
void
AArch64_relobj<size, big_endian>::do_count_local_symbols(
    Stringpool_template<char>* pool, Stringpool_template<char>* dynpool)
{
  Sized_relobj_file<size, big_endian>::do_count_local_symbols(pool, dynpool);

  // Only erratum-fixing work needs mapping symbols, so skip this time consuming
  // processing if not fixing erratum.
  if (!parameters->options().fix_cortex_a53_843419()
      && !parameters->options().fix_cortex_a53_835769())
    return;

  const unsigned int loccount = this->local_symbol_count();
  if (loccount == 0)
    return;

  // Read the symbol table section header.
  const unsigned int symtab_shndx = this->symtab_shndx();
  elfcpp::Shdr<size, big_endian>
      symtabshdr(this, this->elf_file()->section_header(symtab_shndx));
  gold_assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);

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

  // For mapping symbol processing, we need to read the symbol names.
  unsigned int strtab_shndx = this->adjust_shndx(symtabshdr.get_sh_link());
  if (strtab_shndx >= this->shnum())
    {
      this->error(_("invalid symbol table name index: %u"), strtab_shndx);
      return;
    }

  elfcpp::Shdr<size, big_endian>
    strtabshdr(this, this->elf_file()->section_header(strtab_shndx));
  if (strtabshdr.get_sh_type() != elfcpp::SHT_STRTAB)
    {
      this->error(_("symbol table name section has wrong type: %u"),
		  static_cast<unsigned int>(strtabshdr.get_sh_type()));
      return;
    }

  const char* pnames =
    reinterpret_cast<const char*>(this->get_view(strtabshdr.get_sh_offset(),
						 strtabshdr.get_sh_size(),
						 false, false));

  // Skip the first dummy symbol.
  psyms += sym_size;
  typename Sized_relobj_file<size, big_endian>::Local_values*
    plocal_values = this->local_values();
  for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
    {
      elfcpp::Sym<size, big_endian> sym(psyms);
      Symbol_value<size>& lv((*plocal_values)[i]);
      AArch64_address input_value = lv.input_value();

      // Check to see if this is a mapping symbol. AArch64 mapping symbols are
      // defined in "ELF for the ARM 64-bit Architecture", Table 4-4, Mapping
      // symbols.
      // Mapping symbols could be one of the following 4 forms -
      //   a) $x
      //   b) $x.<any...>
      //   c) $d
      //   d) $d.<any...>
      const char* sym_name = pnames + sym.get_st_name();
      if (sym_name[0] == '$' && (sym_name[1] == 'x' || sym_name[1] == 'd')
	  && (sym_name[2] == '\0' || sym_name[2] == '.'))
	{
	  bool is_ordinary;
	  unsigned int input_shndx =
	    this->adjust_sym_shndx(i, sym.get_st_shndx(), &is_ordinary);
	  gold_assert(is_ordinary);

	  Mapping_symbol_position msp(input_shndx, input_value);
	  // Insert mapping_symbol_info into map whose ordering is defined by
	  // (shndx, offset_within_section).
	  this->mapping_symbol_info_[msp] = sym_name[1];
	}
   }
}


// Fix all errata in the object.

template<int size, bool big_endian>
void
AArch64_relobj<size, big_endian>::fix_errata(
    typename Sized_relobj_file<size, big_endian>::Views* pviews)
{
  typedef typename elfcpp::Swap<32,big_endian>::Valtype Insntype;
  unsigned int shnum = this->shnum();
  for (unsigned int i = 1; i < shnum; ++i)
    {
      The_stub_table* stub_table = this->stub_table(i);
      if (!stub_table)
	continue;
      std::pair<Erratum_stub_set_iter, Erratum_stub_set_iter>
	ipair(stub_table->find_erratum_stubs_for_input_section(this, i));
      Erratum_stub_set_iter p = ipair.first, end = ipair.second;
      while (p != end)
	{
	  The_erratum_stub* stub = *p;
	  typename Sized_relobj_file<size, big_endian>::View_size&
	    pview((*pviews)[i]);

	  // Double check data before fix.
	  gold_assert(pview.address + stub->sh_offset()
		      == stub->erratum_address());

	  // Update previously recorded erratum insn with relocated
	  // version.
	  Insntype* ip =
	    reinterpret_cast<Insntype*>(pview.view + stub->sh_offset());
	  Insntype insn_to_fix = ip[0];
	  stub->update_erratum_insn(insn_to_fix);

	  // First try to see if erratum is 843419 and if it can be fixed
	  // without using branch-to-stub.
	  if (!try_fix_erratum_843419_optimized(stub, pview))
	    {
	      // Replace the erratum insn with a branch-to-stub.
	      AArch64_address stub_address =
		stub_table->erratum_stub_address(stub);
	      unsigned int b_offset = stub_address - stub->erratum_address();
	      AArch64_relocate_functions<size, big_endian>::construct_b(
		pview.view + stub->sh_offset(), b_offset & 0xfffffff);
	    }
	  ++p;
	}
    }
}


// This is an optimization for 843419. This erratum requires the sequence begin
// with 'adrp', when final value calculated by adrp fits in adr, we can just
// replace 'adrp' with 'adr', so we save 2 jumps per occurrence. (Note, however,
// in this case, we do not delete the erratum stub (too late to do so), it is
// merely generated without ever being called.)

template<int size, bool big_endian>
bool
AArch64_relobj<size, big_endian>::try_fix_erratum_843419_optimized(
    The_erratum_stub* stub,
    typename Sized_relobj_file<size, big_endian>::View_size& pview)
{
  if (stub->type() != ST_E_843419)
    return false;

  typedef AArch64_insn_utilities<big_endian> Insn_utilities;
  typedef typename elfcpp::Swap<32,big_endian>::Valtype Insntype;
  E843419_stub<size, big_endian>* e843419_stub =
    reinterpret_cast<E843419_stub<size, big_endian>*>(stub);
  AArch64_address pc = pview.address + e843419_stub->adrp_sh_offset();
  Insntype* adrp_view = reinterpret_cast<Insntype*>(
    pview.view + e843419_stub->adrp_sh_offset());
  Insntype adrp_insn = adrp_view[0];
  gold_assert(Insn_utilities::is_adrp(adrp_insn));
  // Get adrp 33-bit signed imm value.
  int64_t adrp_imm = Insn_utilities::
    aarch64_adrp_decode_imm(adrp_insn);
  // adrp - final value transferred to target register is calculated as:
  //     PC[11:0] = Zeros(12)
  //     adrp_dest_value = PC + adrp_imm;
  int64_t adrp_dest_value = (pc & ~((1 << 12) - 1)) + adrp_imm;
  // adr -final value transferred to target register is calucalted as:
  //     PC + adr_imm
  // So we have:
  //     PC + adr_imm = adrp_dest_value
  //   ==>
  //     adr_imm = adrp_dest_value - PC
  int64_t adr_imm = adrp_dest_value - pc;
  // Check if imm fits in adr (21-bit signed).
  if (-(1 << 20) <= adr_imm && adr_imm < (1 << 20))
    {
      // Convert 'adrp' into 'adr'.
      Insntype adr_insn = adrp_insn & ((1u << 31) - 1);
      adr_insn = Insn_utilities::
	aarch64_adr_encode_imm(adr_insn, adr_imm);
      elfcpp::Swap<32, big_endian>::writeval(adrp_view, adr_insn);
      return true;
    }
  return false;
}


// Relocate sections.

template<int size, bool big_endian>
void
AArch64_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)
{
  // Call parent to relocate sections.
  Sized_relobj_file<size, big_endian>::do_relocate_sections(symtab, layout,
							    pshdrs, of, pviews);

  // We do not generate stubs if doing a relocatable link.
  if (parameters->options().relocatable())
    return;

  if (parameters->options().fix_cortex_a53_843419()
      || parameters->options().fix_cortex_a53_835769())
    this->fix_errata(pviews);

  Relocate_info<size, big_endian> relinfo;
  relinfo.symtab = symtab;
  relinfo.layout = layout;
  relinfo.object = this;

  // Relocate stub tables.
  unsigned int shnum = this->shnum();
  The_target_aarch64* target = The_target_aarch64::current_target();

  for (unsigned int i = 1; i < shnum; ++i)
    {
      The_aarch64_input_section* aarch64_input_section =
	  target->find_aarch64_input_section(this, i);
      if (aarch64_input_section != NULL
	  && aarch64_input_section->is_stub_table_owner()
	  && !aarch64_input_section->stub_table()->empty())
	{
	  Output_section* os = this->output_section(i);
	  gold_assert(os != NULL);

	  relinfo.reloc_shndx = elfcpp::SHN_UNDEF;
	  relinfo.reloc_shdr = NULL;
	  relinfo.data_shndx = i;
	  relinfo.data_shdr = pshdrs + i * elfcpp::Elf_sizes<size>::shdr_size;

	  typename Sized_relobj_file<size, big_endian>::View_size&
	      view_struct = (*pviews)[i];
	  gold_assert(view_struct.view != NULL);

	  The_stub_table* stub_table = aarch64_input_section->stub_table();
	  off_t offset = stub_table->address() - view_struct.address;
	  unsigned char* view = view_struct.view + offset;
	  AArch64_address address = stub_table->address();
	  section_size_type view_size = stub_table->data_size();
	  stub_table->relocate_stubs(&relinfo, target, os, view, address,
				     view_size);
	}
    }
}


// Determine if an input section is scannable for stub processing.  SHDR is
// the header of the section and SHNDX is the section index.  OS is the output
// section for the input section and SYMTAB is the global symbol table used to
// look up ICF information.

template<int size, bool big_endian>
bool
AArch64_relobj<size, big_endian>::text_section_is_scannable(
    const elfcpp::Shdr<size, big_endian>& text_shdr,
    unsigned int text_shndx,
    const Output_section* os,
    const Symbol_table* symtab)
{
  // Skip any empty sections, unallocated sections or sections whose
  // type are not SHT_PROGBITS.
  if (text_shdr.get_sh_size() == 0
      || (text_shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0
      || text_shdr.get_sh_type() != elfcpp::SHT_PROGBITS)
    return false;

  // Skip any discarded or ICF'ed sections.
  if (os == NULL || symtab->is_section_folded(this, text_shndx))
    return false;

  // Skip exception frame.
  if (strcmp(os->name(), ".eh_frame") == 0)
    return false ;

  gold_assert(!this->is_output_section_offset_invalid(text_shndx) ||
	      os->find_relaxed_input_section(this, text_shndx) != NULL);

  return true;
}


// Determine if we want to scan the SHNDX-th section for relocation stubs.
// This is a helper for AArch64_relobj::scan_sections_for_stubs().

template<int size, bool big_endian>
bool
AArch64_relobj<size, big_endian>::section_needs_reloc_stub_scanning(
    const elfcpp::Shdr<size, big_endian>& shdr,
    const Relobj::Output_sections& out_sections,
    const Symbol_table* symtab,
    const unsigned char* pshdrs)
{
  unsigned int sh_type = shdr.get_sh_type();
  if (sh_type != elfcpp::SHT_RELA)
    return false;

  // Ignore empty section.
  off_t sh_size = shdr.get_sh_size();
  if (sh_size == 0)
    return false;

  // Ignore reloc section with unexpected symbol table.  The
  // error will be reported in the final link.
  if (this->adjust_shndx(shdr.get_sh_link()) != this->symtab_shndx())
    return false;

  gold_assert(sh_type == elfcpp::SHT_RELA);
  unsigned int reloc_size = elfcpp::Elf_sizes<size>::rela_size;

  // Ignore reloc section with unexpected entsize or uneven size.
  // The error will be reported in the final link.
  if (reloc_size != shdr.get_sh_entsize() || sh_size % reloc_size != 0)
    return false;

  // Ignore reloc section with bad info.  This error will be
  // reported in the final link.
  unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_info());
  if (text_shndx >= this->shnum())
    return false;

  const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
  const elfcpp::Shdr<size, big_endian> text_shdr(pshdrs +
						 text_shndx * shdr_size);
  return this->text_section_is_scannable(text_shdr, text_shndx,
					 out_sections[text_shndx], symtab);
}


// Scan section SHNDX for erratum 843419 and 835769.

template<int size, bool big_endian>
void
AArch64_relobj<size, big_endian>::scan_errata(
    unsigned int shndx, const elfcpp::Shdr<size, big_endian>& shdr,
    Output_section* os, const Symbol_table* symtab,
    The_target_aarch64* target)
{
  if (shdr.get_sh_size() == 0
      || (shdr.get_sh_flags() &
	  (elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR)) == 0
      || shdr.get_sh_type() != elfcpp::SHT_PROGBITS)
    return;

  if (!os || symtab->is_section_folded(this, shndx)) return;

  AArch64_address output_offset = this->get_output_section_offset(shndx);
  AArch64_address output_address;
  if (output_offset != invalid_address)
    output_address = os->address() + output_offset;
  else
    {
      const Output_relaxed_input_section* poris =
	os->find_relaxed_input_section(this, shndx);
      if (!poris) return;
      output_address = poris->address();
    }

  section_size_type input_view_size = 0;
  const unsigned char* input_view =
    this->section_contents(shndx, &input_view_size, false);

  Mapping_symbol_position section_start(shndx, 0);
  // Find the first mapping symbol record within section shndx.
  typename Mapping_symbol_info::const_iterator p =
    this->mapping_symbol_info_.lower_bound(section_start);
  while (p != this->mapping_symbol_info_.end() &&
	 p->first.shndx_ == shndx)
    {
      typename Mapping_symbol_info::const_iterator prev = p;
      ++p;
      if (prev->second == 'x')
	{
	  section_size_type span_start =
	    convert_to_section_size_type(prev->first.offset_);
	  section_size_type span_end;
	  if (p != this->mapping_symbol_info_.end()
	      && p->first.shndx_ == shndx)
	    span_end = convert_to_section_size_type(p->first.offset_);
	  else
	    span_end = convert_to_section_size_type(shdr.get_sh_size());

	  // Here we do not share the scanning code of both errata. For 843419,
	  // only the last few insns of each page are examined, which is fast,
	  // whereas, for 835769, every insn pair needs to be checked.

	  if (parameters->options().fix_cortex_a53_843419())
	    target->scan_erratum_843419_span(
	      this, shndx, span_start, span_end,
	      const_cast<unsigned char*>(input_view), output_address);

	  if (parameters->options().fix_cortex_a53_835769())
	    target->scan_erratum_835769_span(
	      this, shndx, span_start, span_end,
	      const_cast<unsigned char*>(input_view), output_address);
	}
    }
}


// Scan relocations for stub generation.

template<int size, bool big_endian>
void
AArch64_relobj<size, big_endian>::scan_sections_for_stubs(
    The_target_aarch64* target,
    const Symbol_table* symtab,
    const Layout* layout)
{
  unsigned int shnum = this->shnum();
  const unsigned int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;

  // Read the section headers.
  const unsigned char* pshdrs = this->get_view(this->elf_file()->shoff(),
					       shnum * shdr_size,
					       true, true);

  // To speed up processing, we set up hash tables for fast lookup of
  // input offsets to output addresses.
  this->initialize_input_to_output_maps();

  const Relobj::Output_sections& out_sections(this->output_sections());

  Relocate_info<size, big_endian> relinfo;
  relinfo.symtab = symtab;
  relinfo.layout = layout;
  relinfo.object = this;

  // Do relocation stubs scanning.
  const unsigned char* p = pshdrs + shdr_size;
  for (unsigned int i = 1; i < shnum; ++i, p += shdr_size)
    {
      const elfcpp::Shdr<size, big_endian> shdr(p);
      if (parameters->options().fix_cortex_a53_843419()
	  || parameters->options().fix_cortex_a53_835769())
	scan_errata(i, shdr, out_sections[i], symtab, target);
      if (this->section_needs_reloc_stub_scanning(shdr, out_sections, symtab,
						  pshdrs))
	{
	  unsigned int index = this->adjust_shndx(shdr.get_sh_info());
	  AArch64_address output_offset =
	      this->get_output_section_offset(index);
	  AArch64_address output_address;
	  if (output_offset != invalid_address)
	    {
	      output_address = out_sections[index]->address() + output_offset;
	    }
	  else
	    {
	      // Currently this only happens for a relaxed section.
	      const Output_relaxed_input_section* poris =
		  out_sections[index]->find_relaxed_input_section(this, index);
	      gold_assert(poris != NULL);
	      output_address = poris->address();
	    }

	  // Get the relocations.
	  const unsigned char* prelocs = this->get_view(shdr.get_sh_offset(),
							shdr.get_sh_size(),
							true, false);

	  // Get the section contents.
	  section_size_type input_view_size = 0;
	  const unsigned char* input_view =
	      this->section_contents(index, &input_view_size, false);

	  relinfo.reloc_shndx = i;
	  relinfo.data_shndx = index;
	  unsigned int sh_type = shdr.get_sh_type();
	  unsigned int reloc_size;
	  gold_assert (sh_type == elfcpp::SHT_RELA);
	  reloc_size = elfcpp::Elf_sizes<size>::rela_size;

	  Output_section* os = out_sections[index];
	  target->scan_section_for_stubs(&relinfo, sh_type, prelocs,
					 shdr.get_sh_size() / reloc_size,
					 os,
					 output_offset == invalid_address,
					 input_view, output_address,
					 input_view_size);
	}
    }
}


// A class to wrap an ordinary input section containing executable code.

template<int size, bool big_endian>
class AArch64_input_section : public Output_relaxed_input_section
{
 public:
  typedef Stub_table<size, big_endian> The_stub_table;

  AArch64_input_section(Relobj* relobj, unsigned int shndx)
    : Output_relaxed_input_section(relobj, shndx, 1),
      stub_table_(NULL),
      original_contents_(NULL), original_size_(0),
      original_addralign_(1)
  { }

  ~AArch64_input_section()
  { delete[] this->original_contents_; }

  // Initialize.
  void
  init();

  // Set the stub_table.
  void
  set_stub_table(The_stub_table* st)
  { this->stub_table_ = st; }

  // Whether this is a stub table owner.
  bool
  is_stub_table_owner() const
  { return this->stub_table_ != NULL && this->stub_table_->owner() == this; }

  // Return the original size of the section.
  uint32_t
  original_size() const
  { return this->original_size_; }

  // Return the stub table.
  The_stub_table*
  stub_table()
  { return stub_table_; }

 protected:
  // Write out this input section.
  void
  do_write(Output_file*);

  // Return required alignment of this.
  uint64_t
  do_addralign() const
  {
    if (this->is_stub_table_owner())
      return std::max(this->stub_table_->addralign(),
		      static_cast<uint64_t>(this->original_addralign_));
    else
      return this->original_addralign_;
  }

  // Finalize data size.
  void
  set_final_data_size();

  // Reset address and file offset.
  void
  do_reset_address_and_file_offset();

  // Output offset.
  bool
  do_output_offset(const Relobj* object, unsigned int shndx,
		   section_offset_type offset,
		   section_offset_type* poutput) const
  {
    if ((object == this->relobj())
	&& (shndx == this->shndx())
	&& (offset >= 0)
	&& (offset <=
	    convert_types<section_offset_type, uint32_t>(this->original_size_)))
      {
	*poutput = offset;
	return true;
      }
    else
      return false;
  }

 private:
  // Copying is not allowed.
  AArch64_input_section(const AArch64_input_section&);
  AArch64_input_section& operator=(const AArch64_input_section&);

  // The relocation stubs.
  The_stub_table* stub_table_;
  // Original section contents.  We have to make a copy here since the file
  // containing the original section may not be locked when we need to access
  // the contents.
  unsigned char* original_contents_;
  // Section size of the original input section.
  uint32_t original_size_;
  // Address alignment of the original input section.
  uint32_t original_addralign_;
};  // End of AArch64_input_section


// Finalize data size.

template<int size, bool big_endian>
void
AArch64_input_section<size, big_endian>::set_final_data_size()
{
  off_t off = convert_types<off_t, uint64_t>(this->original_size_);

  if (this->is_stub_table_owner())
    {
      this->stub_table_->finalize_data_size();
      off = align_address(off, this->stub_table_->addralign());
      off += this->stub_table_->data_size();
    }
  this->set_data_size(off);
}


// Reset address and file offset.

template<int size, bool big_endian>
void
AArch64_input_section<size, big_endian>::do_reset_address_and_file_offset()
{
  // Size of the original input section contents.
  off_t off = convert_types<off_t, uint64_t>(this->original_size_);

  // If this is a stub table owner, account for the stub table size.
  if (this->is_stub_table_owner())
    {
      The_stub_table* stub_table = this->stub_table_;

      // Reset the stub table's address and file offset.  The
      // current data size for child will be updated after that.
      stub_table_->reset_address_and_file_offset();
      off = align_address(off, stub_table_->addralign());
      off += stub_table->current_data_size();
    }

  this->set_current_data_size(off);
}


// Initialize an Arm_input_section.

template<int size, bool big_endian>
void
AArch64_input_section<size, big_endian>::init()
{
  Relobj* relobj = this->relobj();
  unsigned int shndx = this->shndx();

  // We have to cache original size, alignment and contents to avoid locking
  // the original file.
  this->original_addralign_ =
      convert_types<uint32_t, uint64_t>(relobj->section_addralign(shndx));

  // This is not efficient but we expect only a small number of relaxed
  // input sections for stubs.
  section_size_type section_size;
  const unsigned char* section_contents =
      relobj->section_contents(shndx, &section_size, false);
  this->original_size_ =
      convert_types<uint32_t, uint64_t>(relobj->section_size(shndx));

  gold_assert(this->original_contents_ == NULL);
  this->original_contents_ = new unsigned char[section_size];
  memcpy(this->original_contents_, section_contents, section_size);

  // We want to make this look like the original input section after
  // output sections are finalized.
  Output_section* os = relobj->output_section(shndx);
  off_t offset = relobj->output_section_offset(shndx);
  gold_assert(os != NULL && !relobj->is_output_section_offset_invalid(shndx));
  this->set_address(os->address() + offset);
  this->set_file_offset(os->offset() + offset);
  this->set_current_data_size(this->original_size_);
  this->finalize_data_size();
}


// Write data to output file.

template<int size, bool big_endian>
void
AArch64_input_section<size, big_endian>::do_write(Output_file* of)
{
  // We have to write out the original section content.
  gold_assert(this->original_contents_ != NULL);
  of->write(this->offset(), this->original_contents_,
	    this->original_size_);

  // If this owns a stub table and it is not empty, write it.
  if (this->is_stub_table_owner() && !this->stub_table_->empty())
    this->stub_table_->write(of);
}


// Arm output section class.  This is defined mainly to add a number of stub
// generation methods.

template<int size, bool big_endian>
class AArch64_output_section : public Output_section
{
 public:
  typedef Target_aarch64<size, big_endian> The_target_aarch64;
  typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
  typedef Stub_table<size, big_endian> The_stub_table;
  typedef AArch64_input_section<size, big_endian> The_aarch64_input_section;

 public:
  AArch64_output_section(const char* name, elfcpp::Elf_Word type,
			 elfcpp::Elf_Xword flags)
    : Output_section(name, type, flags)
  { }

  ~AArch64_output_section() {}

  // Group input sections for stub generation.
  void
  group_sections(section_size_type, bool, Target_aarch64<size, big_endian>*,
		 const Task*);

 private:
  typedef Output_section::Input_section Input_section;
  typedef Output_section::Input_section_list Input_section_list;

  // Create a stub group.
  void
  create_stub_group(Input_section_list::const_iterator,
		    Input_section_list::const_iterator,
		    Input_section_list::const_iterator,
		    The_target_aarch64*,
		    std::vector<Output_relaxed_input_section*>&,
		    const Task*);
};  // End of AArch64_output_section


// Create a stub group for input sections from FIRST to LAST. OWNER points to
// the input section that will be the owner of the stub table.

template<int size, bool big_endian> void
AArch64_output_section<size, big_endian>::create_stub_group(
    Input_section_list::const_iterator first,
    Input_section_list::const_iterator last,
    Input_section_list::const_iterator owner,
    The_target_aarch64* target,
    std::vector<Output_relaxed_input_section*>& new_relaxed_sections,
    const Task* task)
{
  // Currently we convert ordinary input sections into relaxed sections only
  // at this point.
  The_aarch64_input_section* input_section;
  if (owner->is_relaxed_input_section())
    gold_unreachable();
  else
    {
      gold_assert(owner->is_input_section());
      // Create a new relaxed input section.  We need to lock the original
      // file.
      Task_lock_obj<Object> tl(task, owner->relobj());
      input_section =
	  target->new_aarch64_input_section(owner->relobj(), owner->shndx());
      new_relaxed_sections.push_back(input_section);
    }

  // Create a stub table.
  The_stub_table* stub_table =
      target->new_stub_table(input_section);

  input_section->set_stub_table(stub_table);

  Input_section_list::const_iterator p = first;
  // Look for input sections or relaxed input sections in [first ... last].
  do
    {
      if (p->is_input_section() || p->is_relaxed_input_section())
	{
	  // The stub table information for input sections live
	  // in their objects.
	  The_aarch64_relobj* aarch64_relobj =
	      static_cast<The_aarch64_relobj*>(p->relobj());
	  aarch64_relobj->set_stub_table(p->shndx(), stub_table);
	}
    }
  while (p++ != last);
}


// Group input sections for stub generation. GROUP_SIZE is roughly the limit of
// stub groups. We grow a stub group by adding input section until the size is
// just below GROUP_SIZE. The last input section will be converted into a stub
// table owner. If STUB_ALWAYS_AFTER_BRANCH is false, we also add input sectiond
// after the stub table, effectively doubling the group size.
//
// This is similar to the group_sections() function in elf32-arm.c but is
// implemented differently.

template<int size, bool big_endian>
void AArch64_output_section<size, big_endian>::group_sections(
    section_size_type group_size,
    bool stubs_always_after_branch,
    Target_aarch64<size, big_endian>* target,
    const Task* task)
{
  typedef enum
  {
    NO_GROUP,
    FINDING_STUB_SECTION,
    HAS_STUB_SECTION
  } State;

  std::vector<Output_relaxed_input_section*> new_relaxed_sections;

  State state = NO_GROUP;
  section_size_type off = 0;
  section_size_type group_begin_offset = 0;
  section_size_type group_end_offset = 0;
  section_size_type stub_table_end_offset = 0;
  Input_section_list::const_iterator group_begin =
      this->input_sections().end();
  Input_section_list::const_iterator stub_table =
      this->input_sections().end();
  Input_section_list::const_iterator group_end = this->input_sections().end();
  for (Input_section_list::const_iterator p = this->input_sections().begin();
       p != this->input_sections().end();
       ++p)
    {
      section_size_type section_begin_offset =
	align_address(off, p->addralign());
      section_size_type section_end_offset =
	section_begin_offset + p->data_size();

      // Check to see if we should group the previously seen sections.
      switch (state)
	{
	case NO_GROUP:
	  break;

	case FINDING_STUB_SECTION:
	  // Adding this section makes the group larger than GROUP_SIZE.
	  if (section_end_offset - group_begin_offset >= group_size)
	    {
	      if (stubs_always_after_branch)
		{
		  gold_assert(group_end != this->input_sections().end());
		  this->create_stub_group(group_begin, group_end, group_end,
					  target, new_relaxed_sections,
					  task);
		  state = NO_GROUP;
		}
	      else
		{
		  // Input sections up to stub_group_size bytes after the stub
		  // table can be handled by it too.
		  state = HAS_STUB_SECTION;
		  stub_table = group_end;
		  stub_table_end_offset = group_end_offset;
		}
	    }
	    break;

	case HAS_STUB_SECTION:
	  // Adding this section makes the post stub-section group larger
	  // than GROUP_SIZE.
	  gold_unreachable();
	  // NOT SUPPORTED YET. For completeness only.
	  if (section_end_offset - stub_table_end_offset >= group_size)
	   {
	     gold_assert(group_end != this->input_sections().end());
	     this->create_stub_group(group_begin, group_end, stub_table,
				     target, new_relaxed_sections, task);
	     state = NO_GROUP;
	   }
	   break;

	  default:
	    gold_unreachable();
	}

      // If we see an input section and currently there is no group, start
      // a new one.  Skip any empty sections.  We look at the data size
      // instead of calling p->relobj()->section_size() to avoid locking.
      if ((p->is_input_section() || p->is_relaxed_input_section())
	  && (p->data_size() != 0))
	{
	  if (state == NO_GROUP)
	    {
	      state = FINDING_STUB_SECTION;
	      group_begin = p;
	      group_begin_offset = section_begin_offset;
	    }

	  // Keep track of the last input section seen.
	  group_end = p;
	  group_end_offset = section_end_offset;
	}

      off = section_end_offset;
    }

  // Create a stub group for any ungrouped sections.
  if (state == FINDING_STUB_SECTION || state == HAS_STUB_SECTION)
    {
      gold_assert(group_end != this->input_sections().end());
      this->create_stub_group(group_begin, group_end,
			      (state == FINDING_STUB_SECTION
			       ? group_end
			       : stub_table),
			      target, new_relaxed_sections, task);
    }

  if (!new_relaxed_sections.empty())
    this->convert_input_sections_to_relaxed_sections(new_relaxed_sections);

  // Update the section offsets
  for (size_t i = 0; i < new_relaxed_sections.size(); ++i)
    {
      The_aarch64_relobj* relobj = static_cast<The_aarch64_relobj*>(
	  new_relaxed_sections[i]->relobj());
      unsigned int shndx = new_relaxed_sections[i]->shndx();
      // Tell AArch64_relobj that this input section is converted.
      relobj->convert_input_section_to_relaxed_section(shndx);
    }
}  // End of AArch64_output_section::group_sections


AArch64_reloc_property_table* aarch64_reloc_property_table = NULL;


// The aarch64 target class.
// See the ABI at
// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf
template<int size, bool big_endian>
class Target_aarch64 : public Sized_target<size, big_endian>
{
 public:
  typedef Target_aarch64<size, big_endian> This;
  typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
      Reloc_section;
  typedef Relocate_info<size, big_endian> The_relocate_info;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
  typedef Reloc_stub<size, big_endian> The_reloc_stub;
  typedef Erratum_stub<size, big_endian> The_erratum_stub;
  typedef typename Reloc_stub<size, big_endian>::Key The_reloc_stub_key;
  typedef Stub_table<size, big_endian> The_stub_table;
  typedef std::vector<The_stub_table*> Stub_table_list;
  typedef typename Stub_table_list::iterator Stub_table_iterator;
  typedef AArch64_input_section<size, big_endian> The_aarch64_input_section;
  typedef AArch64_output_section<size, big_endian> The_aarch64_output_section;
  typedef Unordered_map<Section_id,
			AArch64_input_section<size, big_endian>*,
			Section_id_hash> AArch64_input_section_map;
  typedef AArch64_insn_utilities<big_endian> Insn_utilities;
  const static int TCB_SIZE = size / 8 * 2;

  Target_aarch64(const Target::Target_info* info = &aarch64_info)
    : Sized_target<size, big_endian>(info),
      got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL),
      got_tlsdesc_(NULL), global_offset_table_(NULL), rela_dyn_(NULL),
      rela_irelative_(NULL), copy_relocs_(elfcpp::R_AARCH64_COPY),
      got_mod_index_offset_(-1U),
      tlsdesc_reloc_info_(), tls_base_symbol_defined_(false),
      stub_tables_(), stub_group_size_(0), aarch64_input_section_map_()
  { }

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

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

  // 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,
		   typename elfcpp::Elf_types<size>::Elf_Addr 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);

  // Relocate a section during a relocatable link.
  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* view,
      typename elfcpp::Elf_types<size>::Elf_Addr view_address,
      section_size_type view_size,
      unsigned char* reloc_view,
      section_size_type reloc_view_size);

  // Return the symbol index to use for a target specific relocation.
  // The only target specific relocation is R_AARCH64_TLSDESC for a
  // local symbol, which is an absolute reloc.
  unsigned int
  do_reloc_symbol_index(void*, unsigned int r_type) const
  {
    gold_assert(r_type == elfcpp::R_AARCH64_TLSDESC);
    return 0;
  }

  // Return the addend to use for a target specific relocation.
  uint64_t
  do_reloc_addend(void* arg, unsigned int r_type, uint64_t addend) const;

  // Return the PLT section.
  uint64_t
  do_plt_address_for_global(const Symbol* gsym) const
  { return this->plt_section()->address_for_global(gsym); }

  uint64_t
  do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const
  { return this->plt_section()->address_for_local(relobj, symndx); }

  // This function should be defined in targets that can use relocation
  // types to determine (implemented in local_reloc_may_be_function_pointer
  // and global_reloc_may_be_function_pointer)
  // if a function's pointer is taken.  ICF uses this in safe mode to only
  // fold those functions whose pointer is defintely not taken.
  bool
  do_can_check_for_function_pointers() const
  { return true; }

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

  // Return the size of each PLT entry.
  unsigned int
  plt_entry_size() const;

  // Create a stub table.
  The_stub_table*
  new_stub_table(The_aarch64_input_section*);

  // Create an aarch64 input section.
  The_aarch64_input_section*
  new_aarch64_input_section(Relobj*, unsigned int);

  // Find an aarch64 input section instance for a given OBJ and SHNDX.
  The_aarch64_input_section*
  find_aarch64_input_section(Relobj*, unsigned int) const;

  // Return the thread control block size.
  unsigned int
  tcb_size() const { return This::TCB_SIZE; }

  // Scan a section for stub generation.
  void
  scan_section_for_stubs(const Relocate_info<size, big_endian>*, unsigned int,
			 const unsigned char*, size_t, Output_section*,
			 bool, const unsigned char*,
			 Address,
			 section_size_type);

  // Scan a relocation section for stub.
  template<int sh_type>
  void
  scan_reloc_section_for_stubs(
      const The_relocate_info* relinfo,
      const unsigned char* prelocs,
      size_t reloc_count,
      Output_section* output_section,
      bool needs_special_offset_handling,
      const unsigned char* view,
      Address view_address,
      section_size_type);

  // Relocate a single stub.
  void
  relocate_stub(The_reloc_stub*, const Relocate_info<size, big_endian>*,
		Output_section*, unsigned char*, Address,
		section_size_type);

  // Get the default AArch64 target.
  static This*
  current_target()
  {
    gold_assert(parameters->target().machine_code() == elfcpp::EM_AARCH64
		&& parameters->target().get_size() == size
		&& parameters->target().is_big_endian() == big_endian);
    return static_cast<This*>(parameters->sized_target<size, big_endian>());
  }


  // Scan erratum 843419 for a part of a section.
  void
  scan_erratum_843419_span(
    AArch64_relobj<size, big_endian>*,
    unsigned int,
    const section_size_type,
    const section_size_type,
    unsigned char*,
    Address);

  // Scan erratum 835769 for a part of a section.
  void
  scan_erratum_835769_span(
    AArch64_relobj<size, big_endian>*,
    unsigned int,
    const section_size_type,
    const section_size_type,
    unsigned char*,
    Address);

 protected:
  void
  do_select_as_default_target()
  {
    gold_assert(aarch64_reloc_property_table == NULL);
    aarch64_reloc_property_table = new AArch64_reloc_property_table();
  }

  // Add a new reloc argument, returning the index in the vector.
  size_t
  add_tlsdesc_info(Sized_relobj_file<size, big_endian>* object,
		   unsigned int r_sym)
  {
    this->tlsdesc_reloc_info_.push_back(Tlsdesc_info(object, r_sym));
    return this->tlsdesc_reloc_info_.size() - 1;
  }

  virtual Output_data_plt_aarch64<size, big_endian>*
  do_make_data_plt(Layout* layout,
		   Output_data_got_aarch64<size, big_endian>* got,
		   Output_data_space* got_plt,
		   Output_data_space* got_irelative)
  {
    return new Output_data_plt_aarch64_standard<size, big_endian>(
      layout, got, got_plt, got_irelative);
  }


  // do_make_elf_object to override the same function in the base class.
  Object*
  do_make_elf_object(const std::string&, Input_file*, off_t,
		     const elfcpp::Ehdr<size, big_endian>&);

  Output_data_plt_aarch64<size, big_endian>*
  make_data_plt(Layout* layout,
		Output_data_got_aarch64<size, big_endian>* got,
		Output_data_space* got_plt,
		Output_data_space* got_irelative)
  {
    return this->do_make_data_plt(layout, got, got_plt, got_irelative);
  }

  // We only need to generate stubs, and hence perform relaxation if we are
  // not doing relocatable linking.
  virtual bool
  do_may_relax() const
  { return !parameters->options().relocatable(); }

  // Relaxation hook.  This is where we do stub generation.
  virtual bool
  do_relax(int, const Input_objects*, Symbol_table*, Layout*, const Task*);

  void
  group_sections(Layout* layout,
		 section_size_type group_size,
		 bool stubs_always_after_branch,
		 const Task* task);

  void
  scan_reloc_for_stub(const The_relocate_info*, unsigned int,
		      const Sized_symbol<size>*, unsigned int,
		      const Symbol_value<size>*,
		      typename elfcpp::Elf_types<size>::Elf_Swxword,
		      Address Elf_Addr);

  // Make an output section.
  Output_section*
  do_make_output_section(const char* name, elfcpp::Elf_Word type,
			 elfcpp::Elf_Xword flags)
  { return new The_aarch64_output_section(name, type, flags); }

 private:
  // The class which scans relocations.
  class Scan
  {
  public:
    Scan()
      : issued_non_pic_error_(false)
    { }

    inline void
    local(Symbol_table* symtab, Layout* layout, Target_aarch64* 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_aarch64* 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_aarch64<size, big_endian>* ,
					Sized_relobj_file<size, big_endian>* ,
					unsigned int ,
					Output_section* ,
					const elfcpp::Rela<size, big_endian>& ,
					unsigned int r_type,
					const elfcpp::Sym<size, big_endian>&);

    inline bool
    global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
					 Target_aarch64<size, big_endian>* ,
					 Sized_relobj_file<size, big_endian>* ,
					 unsigned int ,
					 Output_section* ,
					 const elfcpp::Rela<size, big_endian>& ,
					 unsigned int r_type,
					 Symbol* gsym);

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

    inline bool
    possible_function_pointer_reloc(unsigned int r_type);

    void
    check_non_pic(Relobj*, unsigned int r_type);

    bool
    reloc_needs_plt_for_ifunc(Sized_relobj_file<size, big_endian>*,
			      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
  {
   public:
    Relocate()
      : skip_call_tls_get_addr_(false)
    { }

    ~Relocate()
    { }

    // 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_aarch64*, 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);

  private:
    inline typename AArch64_relocate_functions<size, big_endian>::Status
    relocate_tls(const Relocate_info<size, big_endian>*,
		 Target_aarch64<size, big_endian>*,
		 size_t,
		 const elfcpp::Rela<size, big_endian>&,
		 unsigned int r_type, const Sized_symbol<size>*,
		 const Symbol_value<size>*,
		 unsigned char*,
		 typename elfcpp::Elf_types<size>::Elf_Addr);

    inline typename AArch64_relocate_functions<size, big_endian>::Status
    tls_gd_to_le(
		 const Relocate_info<size, big_endian>*,
		 Target_aarch64<size, big_endian>*,
		 const elfcpp::Rela<size, big_endian>&,
		 unsigned int,
		 unsigned char*,
		 const Symbol_value<size>*);

    inline typename AArch64_relocate_functions<size, big_endian>::Status
    tls_ld_to_le(
		 const Relocate_info<size, big_endian>*,
		 Target_aarch64<size, big_endian>*,
		 const elfcpp::Rela<size, big_endian>&,
		 unsigned int,
		 unsigned char*,
		 const Symbol_value<size>*);

    inline typename AArch64_relocate_functions<size, big_endian>::Status
    tls_ie_to_le(
		 const Relocate_info<size, big_endian>*,
		 Target_aarch64<size, big_endian>*,
		 const elfcpp::Rela<size, big_endian>&,
		 unsigned int,
		 unsigned char*,
		 const Symbol_value<size>*);

    inline typename AArch64_relocate_functions<size, big_endian>::Status
    tls_desc_gd_to_le(
		 const Relocate_info<size, big_endian>*,
		 Target_aarch64<size, big_endian>*,
		 const elfcpp::Rela<size, big_endian>&,
		 unsigned int,
		 unsigned char*,
		 const Symbol_value<size>*);

    inline typename AArch64_relocate_functions<size, big_endian>::Status
    tls_desc_gd_to_ie(
		 const Relocate_info<size, big_endian>*,
		 Target_aarch64<size, big_endian>*,
		 const elfcpp::Rela<size, big_endian>&,
		 unsigned int,
		 unsigned char*,
		 const Symbol_value<size>*,
		 typename elfcpp::Elf_types<size>::Elf_Addr,
		 typename elfcpp::Elf_types<size>::Elf_Addr);

    bool skip_call_tls_get_addr_;

  };  // End of class Relocate

  // Adjust TLS relocation type based on the options and whether this
  // is a local symbol.
  static tls::Tls_optimization
  optimize_tls_reloc(bool is_final, int r_type);

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

  // Get the GOT PLT section.
  Output_data_space*
  got_plt_section() const
  {
    gold_assert(this->got_plt_ != NULL);
    return this->got_plt_;
  }

  // Get the GOT section for TLSDESC entries.
  Output_data_got<size, big_endian>*
  got_tlsdesc_section() const
  {
    gold_assert(this->got_tlsdesc_ != NULL);
    return this->got_tlsdesc_;
  }

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

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

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

  // Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
  void
  define_tls_base_symbol(Symbol_table*, Layout*);

  // Create the reserved PLT and GOT entries for the TLS descriptor resolver.
  void
  reserve_tlsdesc_entries(Symbol_table* symtab, Layout* layout);

  // Create a GOT entry for the TLS module index.
  unsigned int
  got_mod_index_entry(Symbol_table* symtab, Layout* layout,
		      Sized_relobj_file<size, big_endian>* object);

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

  // Helper method to create erratum stubs for ST_E_843419 and ST_E_835769. For
  // ST_E_843419, we need an additional field for adrp offset.
  void create_erratum_stub(
    AArch64_relobj<size, big_endian>* relobj,
    unsigned int shndx,
    section_size_type erratum_insn_offset,
    Address erratum_address,
    typename Insn_utilities::Insntype erratum_insn,
    int erratum_type,
    unsigned int e843419_adrp_offset=0);

  // Return whether this is a 3-insn erratum sequence.
  bool is_erratum_843419_sequence(
      typename elfcpp::Swap<32,big_endian>::Valtype insn1,
      typename elfcpp::Swap<32,big_endian>::Valtype insn2,
      typename elfcpp::Swap<32,big_endian>::Valtype insn3);

  // Return whether this is a 835769 sequence.
  // (Similarly implemented as in elfnn-aarch64.c.)
  bool is_erratum_835769_sequence(
      typename elfcpp::Swap<32,big_endian>::Valtype,
      typename elfcpp::Swap<32,big_endian>::Valtype);

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

  // Get the section to use for TLSDESC relocations.
  Reloc_section*
  rela_tlsdesc_section(Layout*) const;

  // Get the section to use for IRELATIVE relocations.
  Reloc_section*
  rela_irelative_section(Layout*);

  // Add a potential copy relocation.
  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));
  }

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

  // The types of GOT entries needed for this platform.
  // These values are exposed to the ABI in an incremental link.
  // Do not renumber existing values without changing the version
  // number of the .gnu_incremental_inputs section.
  enum Got_type
  {
    GOT_TYPE_STANDARD = 0,      // GOT entry for a regular symbol
    GOT_TYPE_TLS_OFFSET = 1,    // GOT entry for TLS offset
    GOT_TYPE_TLS_PAIR = 2,      // GOT entry for TLS module/offset pair
    GOT_TYPE_TLS_DESC = 3       // GOT entry for TLS_DESC pair
  };

  // This type is used as the argument to the target specific
  // relocation routines.  The only target specific reloc is
  // R_AARCh64_TLSDESC against a local symbol.
  struct Tlsdesc_info
  {
    Tlsdesc_info(Sized_relobj_file<size, big_endian>* a_object,
		 unsigned int a_r_sym)
      : object(a_object), r_sym(a_r_sym)
    { }

    // The object in which the local symbol is defined.
    Sized_relobj_file<size, big_endian>* object;
    // The local symbol index in the object.
    unsigned int r_sym;
  };

  // The GOT section.
  Output_data_got_aarch64<size, big_endian>* got_;
  // The PLT section.
  Output_data_plt_aarch64<size, big_endian>* plt_;
  // The GOT PLT section.
  Output_data_space* got_plt_;
  // The GOT section for IRELATIVE relocations.
  Output_data_space* got_irelative_;
  // The GOT section for TLSDESC relocations.
  Output_data_got<size, big_endian>* got_tlsdesc_;
  // The _GLOBAL_OFFSET_TABLE_ symbol.
  Symbol* global_offset_table_;
  // The dynamic reloc section.
  Reloc_section* rela_dyn_;
  // The section to use for IRELATIVE relocs.
  Reloc_section* rela_irelative_;
  // Relocs saved to avoid a COPY reloc.
  Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_;
  // Offset of the GOT entry for the TLS module index.
  unsigned int got_mod_index_offset_;
  // We handle R_AARCH64_TLSDESC against a local symbol as a target
  // specific relocation. Here we store the object and local symbol
  // index for the relocation.
  std::vector<Tlsdesc_info> tlsdesc_reloc_info_;
  // True if the _TLS_MODULE_BASE_ symbol has been defined.
  bool tls_base_symbol_defined_;
  // List of stub_tables
  Stub_table_list stub_tables_;
  // Actual stub group size
  section_size_type stub_group_size_;
  AArch64_input_section_map aarch64_input_section_map_;
};  // End of Target_aarch64


template<>
const Target::Target_info Target_aarch64<64, false>::aarch64_info =
{
  64,			// size
  false,		// is_big_endian
  elfcpp::EM_AARCH64,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  false,		// has_code_fill
  true,			// is_default_stack_executable
  true,			// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/lib/ld.so.1",	// program interpreter
  0x400000,		// default_text_segment_address
  0x10000,		// abi_pagesize (overridable by -z max-page-size)
  0x1000,		// 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
};

template<>
const Target::Target_info Target_aarch64<32, false>::aarch64_info =
{
  32,			// size
  false,		// is_big_endian
  elfcpp::EM_AARCH64,	// 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
  "/lib/ld.so.1",	// program interpreter
  0x400000,		// default_text_segment_address
  0x10000,		// abi_pagesize (overridable by -z max-page-size)
  0x1000,		// 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
};

template<>
const Target::Target_info Target_aarch64<64, true>::aarch64_info =
{
  64,			// size
  true,			// is_big_endian
  elfcpp::EM_AARCH64,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  false,		// has_code_fill
  true,			// is_default_stack_executable
  true,			// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/lib/ld.so.1",	// program interpreter
  0x400000,		// default_text_segment_address
  0x10000,		// abi_pagesize (overridable by -z max-page-size)
  0x1000,		// 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
};

template<>
const Target::Target_info Target_aarch64<32, true>::aarch64_info =
{
  32,			// size
  true,			// is_big_endian
  elfcpp::EM_AARCH64,	// 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
  "/lib/ld.so.1",	// program interpreter
  0x400000,		// default_text_segment_address
  0x10000,		// abi_pagesize (overridable by -z max-page-size)
  0x1000,		// 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
};

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

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

      // When using -z now, we can treat .got.plt as a relro section.
      // Without -z now, it is modified after program startup by lazy
      // PLT relocations.
      bool is_got_plt_relro = parameters->options().now();
      Output_section_order got_order = (is_got_plt_relro
					? ORDER_RELRO
					: ORDER_RELRO_LAST);
      Output_section_order got_plt_order = (is_got_plt_relro
					    ? ORDER_RELRO
					    : ORDER_NON_RELRO_FIRST);

      // Layout of .got and .got.plt sections.
      // .got[0] &_DYNAMIC                          <-_GLOBAL_OFFSET_TABLE_
      // ...
      // .gotplt[0] reserved for ld.so (&linkmap)   <--DT_PLTGOT
      // .gotplt[1] reserved for ld.so (resolver)
      // .gotplt[2] reserved

      // Generate .got section.
      this->got_ = new Output_data_got_aarch64<size, big_endian>(symtab,
								 layout);
      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
				      this->got_, got_order, true);
      // The first word of GOT is reserved for the address of .dynamic.
      // We put 0 here now. The value will be replaced later in
      // Output_data_got_aarch64::do_write.
      this->got_->add_constant(0);

      // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
      // _GLOBAL_OFFSET_TABLE_ value points to the start of the .got section,
      // even if there is a .got.plt section.
      this->global_offset_table_ =
	symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
				      Symbol_table::PREDEFINED,
				      this->got_,
				      0, 0, elfcpp::STT_OBJECT,
				      elfcpp::STB_LOCAL,
				      elfcpp::STV_HIDDEN, 0,
				      false, false);

      // Generate .got.plt section.
      this->got_plt_ = new Output_data_space(size / 8, "** GOT PLT");
      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_WRITE),
				      this->got_plt_, got_plt_order,
				      is_got_plt_relro);

      // The first three entries are reserved.
      this->got_plt_->set_current_data_size(
	AARCH64_GOTPLT_RESERVE_COUNT * (size / 8));

      // If there are any IRELATIVE relocations, they get GOT entries
      // in .got.plt after the jump slot entries.
      this->got_irelative_ = new Output_data_space(size / 8,
						   "** GOT IRELATIVE PLT");
      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_WRITE),
				      this->got_irelative_,
				      got_plt_order,
				      is_got_plt_relro);

      // If there are any TLSDESC relocations, they get GOT entries in
      // .got.plt after the jump slot and IRELATIVE entries.
      this->got_tlsdesc_ = new Output_data_got<size, big_endian>();
      layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_WRITE),
				      this->got_tlsdesc_,
				      got_plt_order,
				      is_got_plt_relro);

      if (!is_got_plt_relro)
	{
	  // Those bytes can go into the relro segment.
	  layout->increase_relro(
	    AARCH64_GOTPLT_RESERVE_COUNT * (size / 8));
	}

    }
  return this->got_;
}

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

template<int size, bool big_endian>
typename Target_aarch64<size, big_endian>::Reloc_section*
Target_aarch64<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_;
}

// Get the section to use for IRELATIVE relocs, creating it if
// necessary.  These go in .rela.dyn, but only after all other dynamic
// relocations.  They need to follow the other dynamic relocations so
// that they can refer to global variables initialized by those
// relocs.

template<int size, bool big_endian>
typename Target_aarch64<size, big_endian>::Reloc_section*
Target_aarch64<size, big_endian>::rela_irelative_section(Layout* layout)
{
  if (this->rela_irelative_ == NULL)
    {
      // Make sure we have already created the dynamic reloc section.
      this->rela_dyn_section(layout);
      this->rela_irelative_ = new Reloc_section(false);
      layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA,
				      elfcpp::SHF_ALLOC, this->rela_irelative_,
				      ORDER_DYNAMIC_RELOCS, false);
      gold_assert(this->rela_dyn_->output_section()
		  == this->rela_irelative_->output_section());
    }
  return this->rela_irelative_;
}


// do_make_elf_object to override the same function in the base class.  We need
// to use a target-specific sub-class of Sized_relobj_file<size, big_endian> to
// store backend specific information. Hence we need to have our own ELF object
// creation.

template<int size, bool big_endian>
Object*
Target_aarch64<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_EXEC && input_file->just_symbols())
    return Sized_target<size, big_endian>::do_make_elf_object(
	name, input_file, offset, ehdr);
  else if (et == elfcpp::ET_REL)
    {
      AArch64_relobj<size, big_endian>* obj =
	new AArch64_relobj<size, big_endian>(name, input_file, offset, ehdr);
      obj->setup();
      return obj;
    }
  else if (et == elfcpp::ET_DYN)
    {
      // Keep base implementation.
      Sized_dynobj<size, big_endian>* obj =
	  new Sized_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;
    }
}


// Scan a relocation for stub generation.

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::scan_reloc_for_stub(
    const Relocate_info<size, big_endian>* relinfo,
    unsigned int r_type,
    const Sized_symbol<size>* gsym,
    unsigned int r_sym,
    const Symbol_value<size>* psymval,
    typename elfcpp::Elf_types<size>::Elf_Swxword addend,
    Address address)
{
  const AArch64_relobj<size, big_endian>* aarch64_relobj =
      static_cast<AArch64_relobj<size, big_endian>*>(relinfo->object);

  Symbol_value<size> symval;
  if (gsym != NULL)
    {
      const AArch64_reloc_property* arp = aarch64_reloc_property_table->
	get_reloc_property(r_type);
      if (gsym->use_plt_offset(arp->reference_flags()))
	{
	  // This uses a PLT, change the symbol value.
	  symval.set_output_value(this->plt_section()->address()
				  + gsym->plt_offset());
	  psymval = &symval;
	}
      else if (gsym->is_undefined())
	// There is no need to generate a stub symbol is undefined.
	return;
    }

  // Get the symbol value.
  typename Symbol_value<size>::Value value = psymval->value(aarch64_relobj, 0);

  // Owing to pipelining, the PC relative branches below actually skip
  // two instructions when the branch offset is 0.
  Address destination = static_cast<Address>(-1);
  switch (r_type)
    {
    case elfcpp::R_AARCH64_CALL26:
    case elfcpp::R_AARCH64_JUMP26:
      destination = value + addend;
      break;
    default:
      gold_unreachable();
    }

  int stub_type = The_reloc_stub::
      stub_type_for_reloc(r_type, address, destination);
  if (stub_type == ST_NONE)
    return;

  The_stub_table* stub_table = aarch64_relobj->stub_table(relinfo->data_shndx);
  gold_assert(stub_table != NULL);

  The_reloc_stub_key key(stub_type, gsym, aarch64_relobj, r_sym, addend);
  The_reloc_stub* stub = stub_table->find_reloc_stub(key);
  if (stub == NULL)
    {
      stub = new The_reloc_stub(stub_type);
      stub_table->add_reloc_stub(stub, key);
    }
  stub->set_destination_address(destination);
}  // End of Target_aarch64::scan_reloc_for_stub


// This function scans a relocation section for stub generation.
// The template parameter Relocate must be a class type which provides
// a single function, relocate(), which implements the machine
// specific part of a relocation.

// BIG_ENDIAN is the endianness of the data.  SH_TYPE is the section type:
// SHT_REL or SHT_RELA.

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

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

template<int size, bool big_endian>
template<int sh_type>
void inline
Target_aarch64<size, big_endian>::scan_reloc_section_for_stubs(
    const Relocate_info<size, big_endian>* relinfo,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* /*output_section*/,
    bool /*needs_special_offset_handling*/,
    const unsigned char* /*view*/,
    Address view_address,
    section_size_type)
{
  typedef typename Reloc_types<sh_type,size,big_endian>::Reloc Reltype;

  const int reloc_size =
      Reloc_types<sh_type,size,big_endian>::reloc_size;
  AArch64_relobj<size, big_endian>* object =
      static_cast<AArch64_relobj<size, big_endian>*>(relinfo->object);
  unsigned int local_count = object->local_symbol_count();

  gold::Default_comdat_behavior default_comdat_behavior;
  Comdat_behavior comdat_behavior = CB_UNDETERMINED;

  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_sym = elfcpp::elf_r_sym<size>(r_info);
      unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
      if (r_type != elfcpp::R_AARCH64_CALL26
	  && r_type != elfcpp::R_AARCH64_JUMP26)
	continue;

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

      // Get the addend.
      typename elfcpp::Elf_types<size>::Elf_Swxword addend =
	  reloc.get_r_addend();

      const Sized_symbol<size>* sym;
      Symbol_value<size> symval;
      const Symbol_value<size> *psymval;
      bool is_defined_in_discarded_section;
      unsigned int shndx;
      if (r_sym < local_count)
	{
	  sym = NULL;
	  psymval = object->local_symbol(r_sym);

	  // If the local symbol belongs to a section we are discarding,
	  // and that section is a debug section, try to find the
	  // corresponding kept section and map this symbol to its
	  // counterpart in the kept section.  The symbol must not
	  // correspond to a section we are folding.
	  bool is_ordinary;
	  shndx = psymval->input_shndx(&is_ordinary);
	  is_defined_in_discarded_section =
	    (is_ordinary
	     && shndx != elfcpp::SHN_UNDEF
	     && !object->is_section_included(shndx)
	     && !relinfo->symtab->is_section_folded(object, shndx));

	  // We need to compute the would-be final value of this local
	  // symbol.
	  if (!is_defined_in_discarded_section)
	    {
	      typedef Sized_relobj_file<size, big_endian> ObjType;
	      typename ObjType::Compute_final_local_value_status status =
		object->compute_final_local_value(r_sym, psymval, &symval,
						  relinfo->symtab);
	      if (status == ObjType::CFLV_OK)
		{
		  // Currently we cannot handle a branch to a target in
		  // a merged section.  If this is the case, issue an error
		  // and also free the merge symbol value.
		  if (!symval.has_output_value())
		    {
		      const std::string& section_name =
			object->section_name(shndx);
		      object->error(_("cannot handle branch to local %u "
					  "in a merged section %s"),
					r_sym, section_name.c_str());
		    }
		  psymval = &symval;
		}
	      else
		{
		  // We cannot determine the final value.
		  continue;
		}
	    }
	}
      else
	{
	  const Symbol* gsym;
	  gsym = object->global_symbol(r_sym);
	  gold_assert(gsym != NULL);
	  if (gsym->is_forwarder())
	    gsym = relinfo->symtab->resolve_forwards(gsym);

	  sym = static_cast<const Sized_symbol<size>*>(gsym);
	  if (sym->has_symtab_index() && sym->symtab_index() != -1U)
	    symval.set_output_symtab_index(sym->symtab_index());
	  else
	    symval.set_no_output_symtab_entry();

	  // We need to compute the would-be final value of this global
	  // symbol.
	  const Symbol_table* symtab = relinfo->symtab;
	  const Sized_symbol<size>* sized_symbol =
	      symtab->get_sized_symbol<size>(gsym);
	  Symbol_table::Compute_final_value_status status;
	  typename elfcpp::Elf_types<size>::Elf_Addr value =
	      symtab->compute_final_value<size>(sized_symbol, &status);

	  // Skip this if the symbol has not output section.
	  if (status == Symbol_table::CFVS_NO_OUTPUT_SECTION)
	    continue;
	  symval.set_output_value(value);

	  if (gsym->type() == elfcpp::STT_TLS)
	    symval.set_is_tls_symbol();
	  else if (gsym->type() == elfcpp::STT_GNU_IFUNC)
	    symval.set_is_ifunc_symbol();
	  psymval = &symval;

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

      Symbol_value<size> symval2;
      if (is_defined_in_discarded_section)
	{
	  if (comdat_behavior == CB_UNDETERMINED)
	    {
	      std::string name = object->section_name(relinfo->data_shndx);
	      comdat_behavior = default_comdat_behavior.get(name.c_str());
	    }
	  if (comdat_behavior == CB_PRETEND)
	    {
	      bool found;
	      typename elfcpp::Elf_types<size>::Elf_Addr value =
		object->map_to_kept_section(shndx, &found);
	      if (found)
		symval2.set_output_value(value + psymval->input_value());
	      else
		symval2.set_output_value(0);
	    }
	  else
	    {
	      if (comdat_behavior == CB_WARNING)
		gold_warning_at_location(relinfo, i, offset,
					 _("relocation refers to discarded "
					   "section"));
	      symval2.set_output_value(0);
	    }
	  symval2.set_no_output_symtab_entry();
	  psymval = &symval2;
	}

      // If symbol is a section symbol, we don't know the actual type of
      // destination.  Give up.
      if (psymval->is_section_symbol())
	continue;

      this->scan_reloc_for_stub(relinfo, r_type, sym, r_sym, psymval,
				addend, view_address + offset);
    }  // End of iterating relocs in a section
}  // End of Target_aarch64::scan_reloc_section_for_stubs


// Scan an input section for stub generation.

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::scan_section_for_stubs(
    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,
    const unsigned char* view,
    Address view_address,
    section_size_type view_size)
{
  gold_assert(sh_type == elfcpp::SHT_RELA);
  this->scan_reloc_section_for_stubs<elfcpp::SHT_RELA>(
      relinfo,
      prelocs,
      reloc_count,
      output_section,
      needs_special_offset_handling,
      view,
      view_address,
      view_size);
}


// Relocate a single stub.

template<int size, bool big_endian>
void Target_aarch64<size, big_endian>::
relocate_stub(The_reloc_stub* stub,
	      const The_relocate_info*,
	      Output_section*,
	      unsigned char* view,
	      Address address,
	      section_size_type)
{
  typedef AArch64_relocate_functions<size, big_endian> The_reloc_functions;
  typedef typename The_reloc_functions::Status The_reloc_functions_status;
  typedef typename elfcpp::Swap<32,big_endian>::Valtype Insntype;

  Insntype* ip = reinterpret_cast<Insntype*>(view);
  int insn_number = stub->insn_num();
  const uint32_t* insns = stub->insns();
  // Check the insns are really those stub insns.
  for (int i = 0; i < insn_number; ++i)
    {
      Insntype insn = elfcpp::Swap<32,big_endian>::readval(ip + i);
      gold_assert(((uint32_t)insn == insns[i]));
    }

  Address dest = stub->destination_address();

  switch(stub->type())
    {
    case ST_ADRP_BRANCH:
      {
	// 1st reloc is ADR_PREL_PG_HI21
	The_reloc_functions_status status =
	    The_reloc_functions::adrp(view, dest, address);
	// An error should never arise in the above step. If so, please
	// check 'aarch64_valid_for_adrp_p'.
	gold_assert(status == The_reloc_functions::STATUS_OKAY);

	// 2nd reloc is ADD_ABS_LO12_NC
	const AArch64_reloc_property* arp =
	    aarch64_reloc_property_table->get_reloc_property(
		elfcpp::R_AARCH64_ADD_ABS_LO12_NC);
	gold_assert(arp != NULL);
	status = The_reloc_functions::template
	    rela_general<32>(view + 4, dest, 0, arp);
	// An error should never arise, it is an "_NC" relocation.
	gold_assert(status == The_reloc_functions::STATUS_OKAY);
      }
      break;

    case ST_LONG_BRANCH_ABS:
      // 1st reloc is R_AARCH64_PREL64, at offset 8
      elfcpp::Swap<64,big_endian>::writeval(view + 8, dest);
      break;

    case ST_LONG_BRANCH_PCREL:
      {
	// "PC" calculation is the 2nd insn in the stub.
	uint64_t offset = dest - (address + 4);
	// Offset is placed at offset 4 and 5.
	elfcpp::Swap<64,big_endian>::writeval(view + 16, offset);
      }
      break;

    default:
      gold_unreachable();
    }
}


// A class to handle the PLT data.
// This is an abstract base class that handles most of the linker details
// but does not know the actual contents of PLT entries.  The derived
// classes below fill in those details.

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

  Output_data_plt_aarch64(Layout* layout,
			  uint64_t addralign,
			  Output_data_got_aarch64<size, big_endian>* got,
			  Output_data_space* got_plt,
			  Output_data_space* got_irelative)
    : Output_section_data(addralign), tlsdesc_rel_(NULL), irelative_rel_(NULL),
      got_(got), got_plt_(got_plt), got_irelative_(got_irelative),
      count_(0), irelative_count_(0), tlsdesc_got_offset_(-1U)
  { this->init(layout); }

  // Initialize the PLT section.
  void
  init(Layout* layout);

  // Add an entry to the PLT.
  void
  add_entry(Symbol_table*, Layout*, Symbol* gsym);

  // Add an entry to the PLT for a local STT_GNU_IFUNC symbol.
  unsigned int
  add_local_ifunc_entry(Symbol_table* symtab, Layout*,
			Sized_relobj_file<size, big_endian>* relobj,
			unsigned int local_sym_index);

  // Add the relocation for a PLT entry.
  void
  add_relocation(Symbol_table*, Layout*, Symbol* gsym,
		 unsigned int got_offset);

  // Add the reserved TLSDESC_PLT entry to the PLT.
  void
  reserve_tlsdesc_entry(unsigned int got_offset)
  { this->tlsdesc_got_offset_ = got_offset; }

  // Return true if a TLSDESC_PLT entry has been reserved.
  bool
  has_tlsdesc_entry() const
  { return this->tlsdesc_got_offset_ != -1U; }

  // Return the GOT offset for the reserved TLSDESC_PLT entry.
  unsigned int
  get_tlsdesc_got_offset() const
  { return this->tlsdesc_got_offset_; }

  // Return the PLT offset of the reserved TLSDESC_PLT entry.
  unsigned int
  get_tlsdesc_plt_offset() const
  {
    return (this->first_plt_entry_offset() +
	    (this->count_ + this->irelative_count_)
	    * this->get_plt_entry_size());
  }

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

  // Return where the TLSDESC relocations should go.
  Reloc_section*
  rela_tlsdesc(Layout*);

  // Return where the IRELATIVE relocations should go in the PLT
  // relocations.
  Reloc_section*
  rela_irelative(Symbol_table*, Layout*);

  // Return whether we created a section for IRELATIVE relocations.
  bool
  has_irelative_section() const
  { return this->irelative_rel_ != NULL; }

  // Return the number of PLT entries.
  unsigned int
  entry_count() const
  { return this->count_ + this->irelative_count_; }

  // Return the offset of the first non-reserved PLT entry.
  unsigned int
  first_plt_entry_offset() const
  { return this->do_first_plt_entry_offset(); }

  // Return the size of a PLT entry.
  unsigned int
  get_plt_entry_size() const
  { return this->do_get_plt_entry_size(); }

  // Return the reserved tlsdesc entry size.
  unsigned int
  get_plt_tlsdesc_entry_size() const
  { return this->do_get_plt_tlsdesc_entry_size(); }

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

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

 protected:
  // Fill in the first PLT entry.
  void
  fill_first_plt_entry(unsigned char* pov,
		       Address got_address,
		       Address plt_address)
  { this->do_fill_first_plt_entry(pov, got_address, plt_address); }

  // Fill in a normal PLT entry.
  void
  fill_plt_entry(unsigned char* pov,
		 Address got_address,
		 Address plt_address,
		 unsigned int got_offset,
		 unsigned int plt_offset)
  {
    this->do_fill_plt_entry(pov, got_address, plt_address,
			    got_offset, plt_offset);
  }

  // Fill in the reserved TLSDESC PLT entry.
  void
  fill_tlsdesc_entry(unsigned char* pov,
		     Address gotplt_address,
		     Address plt_address,
		     Address got_base,
		     unsigned int tlsdesc_got_offset,
		     unsigned int plt_offset)
  {
    this->do_fill_tlsdesc_entry(pov, gotplt_address, plt_address, got_base,
				tlsdesc_got_offset, plt_offset);
  }

  virtual unsigned int
  do_first_plt_entry_offset() const = 0;

  virtual unsigned int
  do_get_plt_entry_size() const = 0;

  virtual unsigned int
  do_get_plt_tlsdesc_entry_size() const = 0;

  virtual void
  do_fill_first_plt_entry(unsigned char* pov,
			  Address got_addr,
			  Address plt_addr) = 0;

  virtual void
  do_fill_plt_entry(unsigned char* pov,
		    Address got_address,
		    Address plt_address,
		    unsigned int got_offset,
		    unsigned int plt_offset) = 0;

  virtual void
  do_fill_tlsdesc_entry(unsigned char* pov,
			Address gotplt_address,
			Address plt_address,
			Address got_base,
			unsigned int tlsdesc_got_offset,
			unsigned int plt_offset) = 0;

  void
  do_adjust_output_section(Output_section* os);

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

 private:
  // Set the final size.
  void
  set_final_data_size();

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

  // The reloc section.
  Reloc_section* rel_;

  // The TLSDESC relocs, if necessary.  These must follow the regular
  // PLT relocs.
  Reloc_section* tlsdesc_rel_;

  // The IRELATIVE relocs, if necessary.  These must follow the
  // regular PLT relocations.
  Reloc_section* irelative_rel_;

  // The .got section.
  Output_data_got_aarch64<size, big_endian>* got_;

  // The .got.plt section.
  Output_data_space* got_plt_;

  // The part of the .got.plt section used for IRELATIVE relocs.
  Output_data_space* got_irelative_;

  // The number of PLT entries.
  unsigned int count_;

  // Number of PLT entries with R_AARCH64_IRELATIVE relocs.  These
  // follow the regular PLT entries.
  unsigned int irelative_count_;

  // GOT offset of the reserved TLSDESC_GOT entry for the lazy trampoline.
  // Communicated to the loader via DT_TLSDESC_GOT. The magic value -1
  // indicates an offset is not allocated.
  unsigned int tlsdesc_got_offset_;
};

// Initialize the PLT section.

template<int size, bool big_endian>
void
Output_data_plt_aarch64<size, big_endian>::init(Layout* layout)
{
  this->rel_ = new Reloc_section(false);
  layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
				  elfcpp::SHF_ALLOC, this->rel_,
				  ORDER_DYNAMIC_PLT_RELOCS, false);
}

template<int size, bool big_endian>
void
Output_data_plt_aarch64<size, big_endian>::do_adjust_output_section(
    Output_section* os)
{
  os->set_entsize(this->get_plt_entry_size());
}

// Add an entry to the PLT.

template<int size, bool big_endian>
void
Output_data_plt_aarch64<size, big_endian>::add_entry(Symbol_table* symtab,
    Layout* layout, Symbol* gsym)
{
  gold_assert(!gsym->has_plt_offset());

  unsigned int* pcount;
  unsigned int plt_reserved;
  Output_section_data_build* got;

  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    {
      pcount = &this->irelative_count_;
      plt_reserved = 0;
      got = this->got_irelative_;
    }
  else
    {
      pcount = &this->count_;
      plt_reserved = this->first_plt_entry_offset();
      got = this->got_plt_;
    }

  gsym->set_plt_offset((*pcount) * this->get_plt_entry_size()
		       + plt_reserved);

  ++*pcount;

  section_offset_type got_offset = got->current_data_size();

  // Every PLT entry needs a GOT entry which points back to the PLT
  // entry (this will be changed by the dynamic linker, normally
  // lazily when the function is called).
  got->set_current_data_size(got_offset + size / 8);

  // Every PLT entry needs a reloc.
  this->add_relocation(symtab, layout, gsym, got_offset);

  // Note that we don't need to save the symbol. The contents of the
  // PLT are independent of which symbols are used. The symbols only
  // appear in the relocations.
}

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

template<int size, bool big_endian>
unsigned int
Output_data_plt_aarch64<size, big_endian>::add_local_ifunc_entry(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<size, big_endian>* relobj,
    unsigned int local_sym_index)
{
  unsigned int plt_offset = this->irelative_count_ * this->get_plt_entry_size();
  ++this->irelative_count_;

  section_offset_type got_offset = this->got_irelative_->current_data_size();

  // Every PLT entry needs a GOT entry which points back to the PLT
  // entry.
  this->got_irelative_->set_current_data_size(got_offset + size / 8);

  // Every PLT entry needs a reloc.
  Reloc_section* rela = this->rela_irelative(symtab, layout);
  rela->add_symbolless_local_addend(relobj, local_sym_index,
				    elfcpp::R_AARCH64_IRELATIVE,
				    this->got_irelative_, got_offset, 0);

  return plt_offset;
}

// Add the relocation for a PLT entry.

template<int size, bool big_endian>
void
Output_data_plt_aarch64<size, big_endian>::add_relocation(
    Symbol_table* symtab, Layout* layout, Symbol* gsym, unsigned int got_offset)
{
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    {
      Reloc_section* rela = this->rela_irelative(symtab, layout);
      rela->add_symbolless_global_addend(gsym, elfcpp::R_AARCH64_IRELATIVE,
					 this->got_irelative_, got_offset, 0);
    }
  else
    {
      gsym->set_needs_dynsym_entry();
      this->rel_->add_global(gsym, elfcpp::R_AARCH64_JUMP_SLOT, this->got_plt_,
			     got_offset, 0);
    }
}

// Return where the TLSDESC relocations should go, creating it if
// necessary.  These follow the JUMP_SLOT relocations.

template<int size, bool big_endian>
typename Output_data_plt_aarch64<size, big_endian>::Reloc_section*
Output_data_plt_aarch64<size, big_endian>::rela_tlsdesc(Layout* layout)
{
  if (this->tlsdesc_rel_ == NULL)
    {
      this->tlsdesc_rel_ = new Reloc_section(false);
      layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
				      elfcpp::SHF_ALLOC, this->tlsdesc_rel_,
				      ORDER_DYNAMIC_PLT_RELOCS, false);
      gold_assert(this->tlsdesc_rel_->output_section()
		  == this->rel_->output_section());
    }
  return this->tlsdesc_rel_;
}

// Return where the IRELATIVE relocations should go in the PLT.  These
// follow the JUMP_SLOT and the TLSDESC relocations.

template<int size, bool big_endian>
typename Output_data_plt_aarch64<size, big_endian>::Reloc_section*
Output_data_plt_aarch64<size, big_endian>::rela_irelative(Symbol_table* symtab,
							  Layout* layout)
{
  if (this->irelative_rel_ == NULL)
    {
      // Make sure we have a place for the TLSDESC relocations, in
      // case we see any later on.
      this->rela_tlsdesc(layout);
      this->irelative_rel_ = new Reloc_section(false);
      layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA,
				      elfcpp::SHF_ALLOC, this->irelative_rel_,
				      ORDER_DYNAMIC_PLT_RELOCS, false);
      gold_assert(this->irelative_rel_->output_section()
		  == this->rel_->output_section());

      if (parameters->doing_static_link())
	{
	  // A statically linked executable will only have a .rela.plt
	  // section to hold R_AARCH64_IRELATIVE relocs for
	  // STT_GNU_IFUNC symbols.  The library will use these
	  // symbols to locate the IRELATIVE relocs at program startup
	  // time.
	  symtab->define_in_output_data("__rela_iplt_start", NULL,
					Symbol_table::PREDEFINED,
					this->irelative_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,
					this->irelative_rel_, 0, 0,
					elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
					elfcpp::STV_HIDDEN, 0, true, true);
	}
    }
  return this->irelative_rel_;
}

// Return the PLT address to use for a global symbol.

template<int size, bool big_endian>
uint64_t
Output_data_plt_aarch64<size, big_endian>::address_for_global(
  const Symbol* gsym)
{
  uint64_t offset = 0;
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && gsym->can_use_relative_reloc(false))
    offset = (this->first_plt_entry_offset() +
	      this->count_ * this->get_plt_entry_size());
  return this->address() + offset + gsym->plt_offset();
}

// Return the PLT address to use for a local symbol.  These are always
// IRELATIVE relocs.

template<int size, bool big_endian>
uint64_t
Output_data_plt_aarch64<size, big_endian>::address_for_local(
    const Relobj* object,
    unsigned int r_sym)
{
  return (this->address()
	  + this->first_plt_entry_offset()
	  + this->count_ * this->get_plt_entry_size()
	  + object->local_plt_offset(r_sym));
}

// Set the final size.

template<int size, bool big_endian>
void
Output_data_plt_aarch64<size, big_endian>::set_final_data_size()
{
  unsigned int count = this->count_ + this->irelative_count_;
  unsigned int extra_size = 0;
  if (this->has_tlsdesc_entry())
    extra_size += this->get_plt_tlsdesc_entry_size();
  this->set_data_size(this->first_plt_entry_offset()
		      + count * this->get_plt_entry_size()
		      + extra_size);
}

template<int size, bool big_endian>
class Output_data_plt_aarch64_standard :
  public Output_data_plt_aarch64<size, big_endian>
{
 public:
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  Output_data_plt_aarch64_standard(
      Layout* layout,
      Output_data_got_aarch64<size, big_endian>* got,
      Output_data_space* got_plt,
      Output_data_space* got_irelative)
    : Output_data_plt_aarch64<size, big_endian>(layout,
						size == 32 ? 4 : 8,
						got, got_plt,
						got_irelative)
  { }

 protected:
  // Return the offset of the first non-reserved PLT entry.
  virtual unsigned int
  do_first_plt_entry_offset() const
  { return this->first_plt_entry_size; }

  // Return the size of a PLT entry
  virtual unsigned int
  do_get_plt_entry_size() const
  { return this->plt_entry_size; }

  // Return the size of a tlsdesc entry
  virtual unsigned int
  do_get_plt_tlsdesc_entry_size() const
  { return this->plt_tlsdesc_entry_size; }

  virtual void
  do_fill_first_plt_entry(unsigned char* pov,
			  Address got_address,
			  Address plt_address);

  virtual void
  do_fill_plt_entry(unsigned char* pov,
		    Address got_address,
		    Address plt_address,
		    unsigned int got_offset,
		    unsigned int plt_offset);

  virtual void
  do_fill_tlsdesc_entry(unsigned char* pov,
			Address gotplt_address,
			Address plt_address,
			Address got_base,
			unsigned int tlsdesc_got_offset,
			unsigned int plt_offset);

 private:
  // The size of the first plt entry size.
  static const int first_plt_entry_size = 32;
  // The size of the plt entry size.
  static const int plt_entry_size = 16;
  // The size of the plt tlsdesc entry size.
  static const int plt_tlsdesc_entry_size = 32;
  // Template for the first PLT entry.
  static const uint32_t first_plt_entry[first_plt_entry_size / 4];
  // Template for subsequent PLT entries.
  static const uint32_t plt_entry[plt_entry_size / 4];
  // The reserved TLSDESC entry in the PLT for an executable.
  static const uint32_t tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4];
};

// The first entry in the PLT for an executable.

template<>
const uint32_t
Output_data_plt_aarch64_standard<32, false>::
    first_plt_entry[first_plt_entry_size / 4] =
{
  0xa9bf7bf0,	/* stp x16, x30, [sp, #-16]!  */
  0x90000010,	/* adrp x16, PLT_GOT+0x8  */
  0xb9400A11,	/* ldr w17, [x16, #PLT_GOT+0x8]  */
  0x11002210,	/* add w16, w16,#PLT_GOT+0x8   */
  0xd61f0220,	/* br x17  */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
};


template<>
const uint32_t
Output_data_plt_aarch64_standard<32, true>::
    first_plt_entry[first_plt_entry_size / 4] =
{
  0xa9bf7bf0,	/* stp x16, x30, [sp, #-16]!  */
  0x90000010,	/* adrp x16, PLT_GOT+0x8  */
  0xb9400A11,	/* ldr w17, [x16, #PLT_GOT+0x8]  */
  0x11002210,	/* add w16, w16,#PLT_GOT+0x8   */
  0xd61f0220,	/* br x17  */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
};


template<>
const uint32_t
Output_data_plt_aarch64_standard<64, false>::
    first_plt_entry[first_plt_entry_size / 4] =
{
  0xa9bf7bf0,	/* stp x16, x30, [sp, #-16]!  */
  0x90000010,	/* adrp x16, PLT_GOT+16  */
  0xf9400A11,	/* ldr x17, [x16, #PLT_GOT+0x10]  */
  0x91004210,	/* add x16, x16,#PLT_GOT+0x10   */
  0xd61f0220,	/* br x17  */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
};


template<>
const uint32_t
Output_data_plt_aarch64_standard<64, true>::
    first_plt_entry[first_plt_entry_size / 4] =
{
  0xa9bf7bf0,	/* stp x16, x30, [sp, #-16]!  */
  0x90000010,	/* adrp x16, PLT_GOT+16  */
  0xf9400A11,	/* ldr x17, [x16, #PLT_GOT+0x10]  */
  0x91004210,	/* add x16, x16,#PLT_GOT+0x10   */
  0xd61f0220,	/* br x17  */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
};


template<>
const uint32_t
Output_data_plt_aarch64_standard<32, false>::
    plt_entry[plt_entry_size / 4] =
{
  0x90000010,	/* adrp x16, PLTGOT + n * 4  */
  0xb9400211,	/* ldr w17, [w16, PLTGOT + n * 4] */
  0x11000210,	/* add w16, w16, :lo12:PLTGOT + n * 4  */
  0xd61f0220,	/* br x17.  */
};


template<>
const uint32_t
Output_data_plt_aarch64_standard<32, true>::
    plt_entry[plt_entry_size / 4] =
{
  0x90000010,	/* adrp x16, PLTGOT + n * 4  */
  0xb9400211,	/* ldr w17, [w16, PLTGOT + n * 4] */
  0x11000210,	/* add w16, w16, :lo12:PLTGOT + n * 4  */
  0xd61f0220,	/* br x17.  */
};


template<>
const uint32_t
Output_data_plt_aarch64_standard<64, false>::
    plt_entry[plt_entry_size / 4] =
{
  0x90000010,	/* adrp x16, PLTGOT + n * 8  */
  0xf9400211,	/* ldr x17, [x16, PLTGOT + n * 8] */
  0x91000210,	/* add x16, x16, :lo12:PLTGOT + n * 8  */
  0xd61f0220,	/* br x17.  */
};


template<>
const uint32_t
Output_data_plt_aarch64_standard<64, true>::
    plt_entry[plt_entry_size / 4] =
{
  0x90000010,	/* adrp x16, PLTGOT + n * 8  */
  0xf9400211,	/* ldr x17, [x16, PLTGOT + n * 8] */
  0x91000210,	/* add x16, x16, :lo12:PLTGOT + n * 8  */
  0xd61f0220,	/* br x17.  */
};


template<int size, bool big_endian>
void
Output_data_plt_aarch64_standard<size, big_endian>::do_fill_first_plt_entry(
    unsigned char* pov,
    Address got_address,
    Address plt_address)
{
  // PLT0 of the small PLT looks like this in ELF64 -
  // stp x16, x30, [sp, #-16]!	 	Save the reloc and lr on stack.
  // adrp x16, PLT_GOT + 16		Get the page base of the GOTPLT
  // ldr  x17, [x16, #:lo12:PLT_GOT+16]	Load the address of the
  // 					symbol resolver
  // add  x16, x16, #:lo12:PLT_GOT+16	Load the lo12 bits of the
  // 					GOTPLT entry for this.
  // br   x17
  // PLT0 will be slightly different in ELF32 due to different got entry
  // size.
  memcpy(pov, this->first_plt_entry, this->first_plt_entry_size);
  Address gotplt_2nd_ent = got_address + (size / 8) * 2;

  // Fill in the top 21 bits for this: ADRP x16, PLT_GOT + 8 * 2.
  // ADRP:  (PG(S+A)-PG(P)) >> 12) & 0x1fffff.
  // FIXME: This only works for 64bit
  AArch64_relocate_functions<size, big_endian>::adrp(pov + 4,
      gotplt_2nd_ent, plt_address + 4);

  // Fill in R_AARCH64_LDST8_LO12
  elfcpp::Swap<32, big_endian>::writeval(
      pov + 8,
      ((this->first_plt_entry[2] & 0xffc003ff)
       | ((gotplt_2nd_ent & 0xff8) << 7)));

  // Fill in R_AARCH64_ADD_ABS_LO12
  elfcpp::Swap<32, big_endian>::writeval(
      pov + 12,
      ((this->first_plt_entry[3] & 0xffc003ff)
       | ((gotplt_2nd_ent & 0xfff) << 10)));
}


// Subsequent entries in the PLT for an executable.
// FIXME: This only works for 64bit

template<int size, bool big_endian>
void
Output_data_plt_aarch64_standard<size, big_endian>::do_fill_plt_entry(
    unsigned char* pov,
    Address got_address,
    Address plt_address,
    unsigned int got_offset,
    unsigned int plt_offset)
{
  memcpy(pov, this->plt_entry, this->plt_entry_size);

  Address gotplt_entry_address = got_address + got_offset;
  Address plt_entry_address = plt_address + plt_offset;

  // Fill in R_AARCH64_PCREL_ADR_HI21
  AArch64_relocate_functions<size, big_endian>::adrp(
      pov,
      gotplt_entry_address,
      plt_entry_address);

  // Fill in R_AARCH64_LDST64_ABS_LO12
  elfcpp::Swap<32, big_endian>::writeval(
      pov + 4,
      ((this->plt_entry[1] & 0xffc003ff)
       | ((gotplt_entry_address & 0xff8) << 7)));

  // Fill in R_AARCH64_ADD_ABS_LO12
  elfcpp::Swap<32, big_endian>::writeval(
      pov + 8,
      ((this->plt_entry[2] & 0xffc003ff)
       | ((gotplt_entry_address & 0xfff) <<10)));

}


template<>
const uint32_t
Output_data_plt_aarch64_standard<32, false>::
    tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4] =
{
  0xa9bf0fe2,	/* stp x2, x3, [sp, #-16]!  */
  0x90000002,	/* adrp x2, 0 */
  0x90000003,	/* adrp x3, 0 */
  0xb9400042,	/* ldr w2, [w2, #0] */
  0x11000063,	/* add w3, w3, 0 */
  0xd61f0040,	/* br x2 */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
};

template<>
const uint32_t
Output_data_plt_aarch64_standard<32, true>::
    tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4] =
{
  0xa9bf0fe2,	/* stp x2, x3, [sp, #-16]!  */
  0x90000002,	/* adrp x2, 0 */
  0x90000003,	/* adrp x3, 0 */
  0xb9400042,	/* ldr w2, [w2, #0] */
  0x11000063,	/* add w3, w3, 0 */
  0xd61f0040,	/* br x2 */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
};

template<>
const uint32_t
Output_data_plt_aarch64_standard<64, false>::
    tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4] =
{
  0xa9bf0fe2,	/* stp x2, x3, [sp, #-16]!  */
  0x90000002,	/* adrp x2, 0 */
  0x90000003,	/* adrp x3, 0 */
  0xf9400042,	/* ldr x2, [x2, #0] */
  0x91000063,	/* add x3, x3, 0 */
  0xd61f0040,	/* br x2 */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
};

template<>
const uint32_t
Output_data_plt_aarch64_standard<64, true>::
    tlsdesc_plt_entry[plt_tlsdesc_entry_size / 4] =
{
  0xa9bf0fe2,	/* stp x2, x3, [sp, #-16]!  */
  0x90000002,	/* adrp x2, 0 */
  0x90000003,	/* adrp x3, 0 */
  0xf9400042,	/* ldr x2, [x2, #0] */
  0x91000063,	/* add x3, x3, 0 */
  0xd61f0040,	/* br x2 */
  0xd503201f,	/* nop */
  0xd503201f,	/* nop */
};

template<int size, bool big_endian>
void
Output_data_plt_aarch64_standard<size, big_endian>::do_fill_tlsdesc_entry(
    unsigned char* pov,
    Address gotplt_address,
    Address plt_address,
    Address got_base,
    unsigned int tlsdesc_got_offset,
    unsigned int plt_offset)
{
  memcpy(pov, tlsdesc_plt_entry, plt_tlsdesc_entry_size);

  // move DT_TLSDESC_GOT address into x2
  // move .got.plt address into x3
  Address tlsdesc_got_entry = got_base + tlsdesc_got_offset;
  Address plt_entry_address = plt_address + plt_offset;

  // R_AARCH64_ADR_PREL_PG_HI21
  AArch64_relocate_functions<size, big_endian>::adrp(
      pov + 4,
      tlsdesc_got_entry,
      plt_entry_address + 4);

  // R_AARCH64_ADR_PREL_PG_HI21
  AArch64_relocate_functions<size, big_endian>::adrp(
      pov + 8,
      gotplt_address,
      plt_entry_address + 8);

  // R_AARCH64_LDST64_ABS_LO12
  elfcpp::Swap<32, big_endian>::writeval(
      pov + 12,
      ((this->tlsdesc_plt_entry[3] & 0xffc003ff)
       | ((tlsdesc_got_entry & 0xff8) << 7)));

  // R_AARCH64_ADD_ABS_LO12
  elfcpp::Swap<32, big_endian>::writeval(
      pov + 16,
      ((this->tlsdesc_plt_entry[4] & 0xffc003ff)
       | ((gotplt_address & 0xfff) << 10)));
}

// Write out the PLT.  This uses the hand-coded instructions above,
// and adjusts them as needed.  This is specified by the AMD64 ABI.

template<int size, bool big_endian>
void
Output_data_plt_aarch64<size, big_endian>::do_write(Output_file* of)
{
  const off_t 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);

  const off_t got_file_offset = this->got_plt_->offset();
  gold_assert(got_file_offset + this->got_plt_->data_size()
	      == this->got_irelative_->offset());

  const section_size_type got_size =
      convert_to_section_size_type(this->got_plt_->data_size()
				   + this->got_irelative_->data_size());
  unsigned char* const got_view = of->get_output_view(got_file_offset,
						      got_size);

  unsigned char* pov = oview;

  // The base address of the .plt section.
  typename elfcpp::Elf_types<size>::Elf_Addr plt_address = this->address();
  // The base address of the PLT portion of the .got section.
  typename elfcpp::Elf_types<size>::Elf_Addr gotplt_address
      = this->got_plt_->address();

  this->fill_first_plt_entry(pov, gotplt_address, plt_address);
  pov += this->first_plt_entry_offset();

  // The first three entries in .got.plt are reserved.
  unsigned char* got_pov = got_view;
  memset(got_pov, 0, size / 8 * AARCH64_GOTPLT_RESERVE_COUNT);
  got_pov += (size / 8) * AARCH64_GOTPLT_RESERVE_COUNT;

  unsigned int plt_offset = this->first_plt_entry_offset();
  unsigned int got_offset = (size / 8) * AARCH64_GOTPLT_RESERVE_COUNT;
  const unsigned int count = this->count_ + this->irelative_count_;
  for (unsigned int plt_index = 0;
       plt_index < count;
       ++plt_index,
	 pov += this->get_plt_entry_size(),
	 got_pov += size / 8,
	 plt_offset += this->get_plt_entry_size(),
	 got_offset += size / 8)
    {
      // Set and adjust the PLT entry itself.
      this->fill_plt_entry(pov, gotplt_address, plt_address,
			   got_offset, plt_offset);

      // Set the entry in the GOT, which points to plt0.
      elfcpp::Swap<size, big_endian>::writeval(got_pov, plt_address);
    }

  if (this->has_tlsdesc_entry())
    {
      // Set and adjust the reserved TLSDESC PLT entry.
      unsigned int tlsdesc_got_offset = this->get_tlsdesc_got_offset();
      // The base address of the .base section.
      typename elfcpp::Elf_types<size>::Elf_Addr got_base =
	  this->got_->address();
      this->fill_tlsdesc_entry(pov, gotplt_address, plt_address, got_base,
			       tlsdesc_got_offset, plt_offset);
      pov += this->get_plt_tlsdesc_entry_size();
    }

  gold_assert(static_cast<section_size_type>(pov - oview) == oview_size);
  gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size);

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

// Telling how to update the immediate field of an instruction.
struct AArch64_howto
{
  // The immediate field mask.
  elfcpp::Elf_Xword dst_mask;

  // The offset to apply relocation immediate
  int doffset;

  // The second part offset, if the immediate field has two parts.
  // -1 if the immediate field has only one part.
  int doffset2;
};

static const AArch64_howto aarch64_howto[AArch64_reloc_property::INST_NUM] =
{
  {0, -1, -1},		// DATA
  {0x1fffe0, 5, -1},	// MOVW  [20:5]-imm16
  {0xffffe0, 5, -1},	// LD    [23:5]-imm19
  {0x60ffffe0, 29, 5},	// ADR   [30:29]-immlo  [23:5]-immhi
  {0x60ffffe0, 29, 5},	// ADRP  [30:29]-immlo  [23:5]-immhi
  {0x3ffc00, 10, -1},	// ADD   [21:10]-imm12
  {0x3ffc00, 10, -1},	// LDST  [21:10]-imm12
  {0x7ffe0, 5, -1},	// TBZNZ [18:5]-imm14
  {0xffffe0, 5, -1},	// CONDB [23:5]-imm19
  {0x3ffffff, 0, -1},	// B     [25:0]-imm26
  {0x3ffffff, 0, -1},	// CALL  [25:0]-imm26
};

// AArch64 relocate function class

template<int size, bool big_endian>
class AArch64_relocate_functions
{
 public:
  typedef enum
  {
    STATUS_OKAY,	// No error during relocation.
    STATUS_OVERFLOW,	// Relocation overflow.
    STATUS_BAD_RELOC,	// Relocation cannot be applied.
  } Status;

  typedef AArch64_relocate_functions<size, big_endian> This;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
  typedef Relocate_info<size, big_endian> The_relocate_info;
  typedef AArch64_relobj<size, big_endian> The_aarch64_relobj;
  typedef Reloc_stub<size, big_endian> The_reloc_stub;
  typedef Stub_table<size, big_endian> The_stub_table;
  typedef elfcpp::Rela<size, big_endian> The_rela;
  typedef typename elfcpp::Swap<size, big_endian>::Valtype AArch64_valtype;

  // Return the page address of the address.
  // Page(address) = address & ~0xFFF

  static inline AArch64_valtype
  Page(Address address)
  {
    return (address & (~static_cast<Address>(0xFFF)));
  }

 private:
  // Update instruction (pointed by view) with selected bits (immed).
  // val = (val & ~dst_mask) | (immed << doffset)

  template<int valsize>
  static inline void
  update_view(unsigned char* view,
	      AArch64_valtype immed,
	      elfcpp::Elf_Xword doffset,
	      elfcpp::Elf_Xword dst_mask)
  {
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);

    // Clear immediate fields.
    val &= ~dst_mask;
    elfcpp::Swap<valsize, big_endian>::writeval(wv,
      static_cast<Valtype>(val | (immed << doffset)));
  }

  // Update two parts of an instruction (pointed by view) with selected
  // bits (immed1 and immed2).
  // val = (val & ~dst_mask) | (immed1 << doffset1) | (immed2 << doffset2)

  template<int valsize>
  static inline void
  update_view_two_parts(
    unsigned char* view,
    AArch64_valtype immed1,
    AArch64_valtype immed2,
    elfcpp::Elf_Xword doffset1,
    elfcpp::Elf_Xword doffset2,
    elfcpp::Elf_Xword dst_mask)
  {
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv);
    val &= ~dst_mask;
    elfcpp::Swap<valsize, big_endian>::writeval(wv,
      static_cast<Valtype>(val | (immed1 << doffset1) |
			   (immed2 << doffset2)));
  }

  // Update adr or adrp instruction with immed.
  // In adr and adrp: [30:29] immlo   [23:5] immhi

  static inline void
  update_adr(unsigned char* view, AArch64_valtype immed)
  {
    elfcpp::Elf_Xword dst_mask = (0x3 << 29) | (0x7ffff << 5);
    This::template update_view_two_parts<32>(
      view,
      immed & 0x3,
      (immed & 0x1ffffc) >> 2,
      29,
      5,
      dst_mask);
  }

  // Update movz/movn instruction with bits immed.
  // Set instruction to movz if is_movz is true, otherwise set instruction
  // to movn.

  static inline void
  update_movnz(unsigned char* view,
	       AArch64_valtype immed,
	       bool is_movz)
  {
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);

    const elfcpp::Elf_Xword doffset =
	aarch64_howto[AArch64_reloc_property::INST_MOVW].doffset;
    const elfcpp::Elf_Xword dst_mask =
	aarch64_howto[AArch64_reloc_property::INST_MOVW].dst_mask;

    // Clear immediate fields and opc code.
    val &= ~(dst_mask | (0x3 << 29));

    // Set instruction to movz or movn.
    // movz: [30:29] is 10   movn: [30:29] is 00
    if (is_movz)
      val |= (0x2 << 29);

    elfcpp::Swap<32, big_endian>::writeval(wv,
      static_cast<Valtype>(val | (immed << doffset)));
  }

 public:

  // Update selected bits in text.

  template<int valsize>
  static inline typename This::Status
  reloc_common(unsigned char* view, Address x,
		const AArch64_reloc_property* reloc_property)
  {
    // Select bits from X.
    Address immed = reloc_property->select_x_value(x);

    // Update view.
    const AArch64_reloc_property::Reloc_inst inst =
      reloc_property->reloc_inst();
    // If it is a data relocation or instruction has 2 parts of immediate
    // fields, you should not call pcrela_general.
    gold_assert(aarch64_howto[inst].doffset2 == -1 &&
		aarch64_howto[inst].doffset != -1);
    This::template update_view<valsize>(view, immed,
					aarch64_howto[inst].doffset,
					aarch64_howto[inst].dst_mask);

    // Do check overflow or alignment if needed.
    return (reloc_property->checkup_x_value(x)
	    ? This::STATUS_OKAY
	    : This::STATUS_OVERFLOW);
  }

  // Construct a B insn. Note, although we group it here with other relocation
  // operation, there is actually no 'relocation' involved here.
  static inline void
  construct_b(unsigned char* view, unsigned int branch_offset)
  {
    update_view_two_parts<32>(view, 0x05, (branch_offset >> 2),
			      26, 0, 0xffffffff);
  }

  // Do a simple rela relocation at unaligned addresses.

  template<int valsize>
  static inline typename This::Status
  rela_ua(unsigned char* view,
	  const Sized_relobj_file<size, big_endian>* object,
	  const Symbol_value<size>* psymval,
	  AArch64_valtype addend,
	  const AArch64_reloc_property* reloc_property)
  {
    typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
      Valtype;
    typename elfcpp::Elf_types<size>::Elf_Addr x =
	psymval->value(object, addend);
    elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view,
      static_cast<Valtype>(x));
    return (reloc_property->checkup_x_value(x)
	    ? This::STATUS_OKAY
	    : This::STATUS_OVERFLOW);
  }

  // Do a simple pc-relative relocation at unaligned addresses.

  template<int valsize>
  static inline typename This::Status
  pcrela_ua(unsigned char* view,
	    const Sized_relobj_file<size, big_endian>* object,
	    const Symbol_value<size>* psymval,
	    AArch64_valtype addend,
	    Address address,
	    const AArch64_reloc_property* reloc_property)
  {
    typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
      Valtype;
    Address x = psymval->value(object, addend) - address;
    elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view,
      static_cast<Valtype>(x));
    return (reloc_property->checkup_x_value(x)
	    ? This::STATUS_OKAY
	    : This::STATUS_OVERFLOW);
  }

  // Do a simple rela relocation at aligned addresses.

  template<int valsize>
  static inline typename This::Status
  rela(
    unsigned char* view,
    const Sized_relobj_file<size, big_endian>* object,
    const Symbol_value<size>* psymval,
    AArch64_valtype addend,
    const AArch64_reloc_property* reloc_property)
  {
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Address x = psymval->value(object, addend);
    elfcpp::Swap<valsize, big_endian>::writeval(wv,static_cast<Valtype>(x));
    return (reloc_property->checkup_x_value(x)
	    ? This::STATUS_OKAY
	    : This::STATUS_OVERFLOW);
  }

  // Do relocate. Update selected bits in text.
  // new_val = (val & ~dst_mask) | (immed << doffset)

  template<int valsize>
  static inline typename This::Status
  rela_general(unsigned char* view,
	       const Sized_relobj_file<size, big_endian>* object,
	       const Symbol_value<size>* psymval,
	       AArch64_valtype addend,
	       const AArch64_reloc_property* reloc_property)
  {
    // Calculate relocation.
    Address x = psymval->value(object, addend);
    return This::template reloc_common<valsize>(view, x, reloc_property);
  }

  // Do relocate. Update selected bits in text.
  // new val = (val & ~dst_mask) | (immed << doffset)

  template<int valsize>
  static inline typename This::Status
  rela_general(
    unsigned char* view,
    AArch64_valtype s,
    AArch64_valtype addend,
    const AArch64_reloc_property* reloc_property)
  {
    // Calculate relocation.
    Address x = s + addend;
    return This::template reloc_common<valsize>(view, x, reloc_property);
  }

  // Do address relative relocate. Update selected bits in text.
  // new val = (val & ~dst_mask) | (immed << doffset)

  template<int valsize>
  static inline typename This::Status
  pcrela_general(
    unsigned char* view,
    const Sized_relobj_file<size, big_endian>* object,
    const Symbol_value<size>* psymval,
    AArch64_valtype addend,
    Address address,
    const AArch64_reloc_property* reloc_property)
  {
    // Calculate relocation.
    Address x = psymval->value(object, addend) - address;
    return This::template reloc_common<valsize>(view, x, reloc_property);
  }


  // Calculate (S + A) - address, update adr instruction.

  static inline typename This::Status
  adr(unsigned char* view,
      const Sized_relobj_file<size, big_endian>* object,
      const Symbol_value<size>* psymval,
      Address addend,
      Address address,
      const AArch64_reloc_property* /* reloc_property */)
  {
    AArch64_valtype x = psymval->value(object, addend) - address;
    // Pick bits [20:0] of X.
    AArch64_valtype immed = x & 0x1fffff;
    update_adr(view, immed);
    // Check -2^20 <= X < 2^20
    return (size == 64 && Bits<21>::has_overflow((x))
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // Calculate PG(S+A) - PG(address), update adrp instruction.
  // R_AARCH64_ADR_PREL_PG_HI21

  static inline typename This::Status
  adrp(
    unsigned char* view,
    Address sa,
    Address address)
  {
    AArch64_valtype x = This::Page(sa) - This::Page(address);
    // Pick [32:12] of X.
    AArch64_valtype immed = (x >> 12) & 0x1fffff;
    update_adr(view, immed);
    // Check -2^32 <= X < 2^32
    return (size == 64 && Bits<33>::has_overflow((x))
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // Calculate PG(S+A) - PG(address), update adrp instruction.
  // R_AARCH64_ADR_PREL_PG_HI21

  static inline typename This::Status
  adrp(unsigned char* view,
       const Sized_relobj_file<size, big_endian>* object,
       const Symbol_value<size>* psymval,
       Address addend,
       Address address,
       const AArch64_reloc_property* reloc_property)
  {
    Address sa = psymval->value(object, addend);
    AArch64_valtype x = This::Page(sa) - This::Page(address);
    // Pick [32:12] of X.
    AArch64_valtype immed = (x >> 12) & 0x1fffff;
    update_adr(view, immed);
    return (reloc_property->checkup_x_value(x)
	    ? This::STATUS_OKAY
	    : This::STATUS_OVERFLOW);
  }

  // Update mov[n/z] instruction. Check overflow if needed.
  // If X >=0, set the instruction to movz and its immediate value to the
  // selected bits S.
  // If X < 0, set the instruction to movn and its immediate value to
  // NOT (selected bits of).

  static inline typename This::Status
  movnz(unsigned char* view,
	AArch64_valtype x,
	const AArch64_reloc_property* reloc_property)
  {
    // Select bits from X.
    Address immed;
    bool is_movz;
    typedef typename elfcpp::Elf_types<size>::Elf_Swxword SignedW;
    if (static_cast<SignedW>(x) >= 0)
      {
	immed = reloc_property->select_x_value(x);
        is_movz = true;
      }
    else
      {
	immed = reloc_property->select_x_value(~x);;
	is_movz = false;
      }

    // Update movnz instruction.
    update_movnz(view, immed, is_movz);

    // Do check overflow or alignment if needed.
    return (reloc_property->checkup_x_value(x)
	    ? This::STATUS_OKAY
	    : This::STATUS_OVERFLOW);
  }

  static inline bool
  maybe_apply_stub(unsigned int,
		   const The_relocate_info*,
		   const The_rela&,
		   unsigned char*,
		   Address,
		   const Sized_symbol<size>*,
		   const Symbol_value<size>*,
		   const Sized_relobj_file<size, big_endian>*,
		   section_size_type);

};  // End of AArch64_relocate_functions


// For a certain relocation type (usually jump/branch), test to see if the
// destination needs a stub to fulfil. If so, re-route the destination of the
// original instruction to the stub, note, at this time, the stub has already
// been generated.

template<int size, bool big_endian>
bool
AArch64_relocate_functions<size, big_endian>::
maybe_apply_stub(unsigned int r_type,
		 const The_relocate_info* relinfo,
		 const The_rela& rela,
		 unsigned char* view,
		 Address address,
		 const Sized_symbol<size>* gsym,
		 const Symbol_value<size>* psymval,
		 const Sized_relobj_file<size, big_endian>* object,
		 section_size_type current_group_size)
{
  if (parameters->options().relocatable())
    return false;

  typename elfcpp::Elf_types<size>::Elf_Swxword addend = rela.get_r_addend();
  Address branch_target = psymval->value(object, 0) + addend;
  int stub_type =
    The_reloc_stub::stub_type_for_reloc(r_type, address, branch_target);
  if (stub_type == ST_NONE)
    return false;

  const The_aarch64_relobj* aarch64_relobj =
      static_cast<const The_aarch64_relobj*>(object);
  The_stub_table* stub_table = aarch64_relobj->stub_table(relinfo->data_shndx);
  gold_assert(stub_table != NULL);

  unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
  typename The_reloc_stub::Key stub_key(stub_type, gsym, object, r_sym, addend);
  The_reloc_stub* stub = stub_table->find_reloc_stub(stub_key);
  gold_assert(stub != NULL);

  Address new_branch_target = stub_table->address() + stub->offset();
  typename elfcpp::Swap<size, big_endian>::Valtype branch_offset =
      new_branch_target - address;
  const AArch64_reloc_property* arp =
      aarch64_reloc_property_table->get_reloc_property(r_type);
  gold_assert(arp != NULL);
  typename This::Status status = This::template
      rela_general<32>(view, branch_offset, 0, arp);
  if (status != This::STATUS_OKAY)
    gold_error(_("Stub is too far away, try a smaller value "
		 "for '--stub-group-size'. The current value is 0x%lx."),
	       static_cast<unsigned long>(current_group_size));
  return true;
}


// Group input sections for stub generation.
//
// We group input sections in an output section so that the total size,
// including any padding space due to alignment is smaller than GROUP_SIZE
// unless the only input section in group is bigger than GROUP_SIZE already.
// Then an ARM stub table is created to follow the last input section
// in group.  For each group an ARM stub table is created an is placed
// after the last group.  If STUB_ALWAYS_AFTER_BRANCH is false, we further
// extend the group after the stub table.

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::group_sections(
    Layout* layout,
    section_size_type group_size,
    bool stubs_always_after_branch,
    const Task* task)
{
  // Group input sections and insert stub table
  Layout::Section_list section_list;
  layout->get_executable_sections(&section_list);
  for (Layout::Section_list::const_iterator p = section_list.begin();
       p != section_list.end();
       ++p)
    {
      AArch64_output_section<size, big_endian>* output_section =
	  static_cast<AArch64_output_section<size, big_endian>*>(*p);
      output_section->group_sections(group_size, stubs_always_after_branch,
				     this, task);
    }
}


// Find the AArch64_input_section object corresponding to the SHNDX-th input
// section of RELOBJ.

template<int size, bool big_endian>
AArch64_input_section<size, big_endian>*
Target_aarch64<size, big_endian>::find_aarch64_input_section(
    Relobj* relobj, unsigned int shndx) const
{
  Section_id sid(relobj, shndx);
  typename AArch64_input_section_map::const_iterator p =
    this->aarch64_input_section_map_.find(sid);
  return (p != this->aarch64_input_section_map_.end()) ? p->second : NULL;
}


// Make a new AArch64_input_section object.

template<int size, bool big_endian>
AArch64_input_section<size, big_endian>*
Target_aarch64<size, big_endian>::new_aarch64_input_section(
    Relobj* relobj, unsigned int shndx)
{
  Section_id sid(relobj, shndx);

  AArch64_input_section<size, big_endian>* input_section =
      new AArch64_input_section<size, big_endian>(relobj, shndx);
  input_section->init();

  // Register new AArch64_input_section in map for look-up.
  std::pair<typename AArch64_input_section_map::iterator,bool> ins =
      this->aarch64_input_section_map_.insert(
	  std::make_pair(sid, input_section));

  // Make sure that it we have not created another AArch64_input_section
  // for this input section already.
  gold_assert(ins.second);

  return input_section;
}


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

template<int size, bool big_endian>
bool
Target_aarch64<size, big_endian>::do_relax(
    int pass,
    const Input_objects* input_objects,
    Symbol_table* symtab,
    Layout* layout ,
    const Task* task)
{
  gold_assert(!parameters->options().relocatable());
  if (pass == 1)
    {
      // We don't handle negative stub_group_size right now.
      this->stub_group_size_ = abs(parameters->options().stub_group_size());
      if (this->stub_group_size_ == 1)
	{
	  // Leave room for 4096 4-byte stub entries. If we exceed that, then we
	  // will fail to link.  The user will have to relink with an explicit
	  // group size option.
	  this->stub_group_size_ = The_reloc_stub::MAX_BRANCH_OFFSET -
				   4096 * 4;
	}
      group_sections(layout, this->stub_group_size_, true, task);
    }
  else
    {
      // If this is not the first pass, addresses and file offsets have
      // been reset at this point, set them here.
      for (Stub_table_iterator sp = this->stub_tables_.begin();
	   sp != this->stub_tables_.end(); ++sp)
	{
	  The_stub_table* stt = *sp;
	  The_aarch64_input_section* owner = stt->owner();
	  off_t off = align_address(owner->original_size(),
				    stt->addralign());
	  stt->set_address_and_file_offset(owner->address() + off,
					   owner->offset() + off);
	}
    }

  // Scan relocs for relocation stubs
  for (Input_objects::Relobj_iterator op = input_objects->relobj_begin();
       op != input_objects->relobj_end();
       ++op)
    {
      The_aarch64_relobj* aarch64_relobj =
	  static_cast<The_aarch64_relobj*>(*op);
      // Lock the object so we can read from it.  This is only called
      // single-threaded from Layout::finalize, so it is OK to lock.
      Task_lock_obj<Object> tl(task, aarch64_relobj);
      aarch64_relobj->scan_sections_for_stubs(this, symtab, layout);
    }

  bool any_stub_table_changed = false;
  for (Stub_table_iterator siter = this->stub_tables_.begin();
       siter != this->stub_tables_.end() && !any_stub_table_changed; ++siter)
    {
      The_stub_table* stub_table = *siter;
      if (stub_table->update_data_size_changed_p())
	{
	  The_aarch64_input_section* owner = stub_table->owner();
	  uint64_t address = owner->address();
	  off_t offset = owner->offset();
	  owner->reset_address_and_file_offset();
	  owner->set_address_and_file_offset(address, offset);

	  any_stub_table_changed = true;
	}
    }

  // Do not continue relaxation.
  bool continue_relaxation = any_stub_table_changed;
  if (!continue_relaxation)
    for (Stub_table_iterator sp = this->stub_tables_.begin();
	 (sp != this->stub_tables_.end());
	 ++sp)
      (*sp)->finalize_stubs();

  return continue_relaxation;
}


// Make a new Stub_table.

template<int size, bool big_endian>
Stub_table<size, big_endian>*
Target_aarch64<size, big_endian>::new_stub_table(
    AArch64_input_section<size, big_endian>* owner)
{
  Stub_table<size, big_endian>* stub_table =
      new Stub_table<size, big_endian>(owner);
  stub_table->set_address(align_address(
      owner->address() + owner->data_size(), 8));
  stub_table->set_file_offset(owner->offset() + owner->data_size());
  stub_table->finalize_data_size();

  this->stub_tables_.push_back(stub_table);

  return stub_table;
}


template<int size, bool big_endian>
uint64_t
Target_aarch64<size, big_endian>::do_reloc_addend(
    void* arg, unsigned int r_type, uint64_t) const
{
  gold_assert(r_type == elfcpp::R_AARCH64_TLSDESC);
  uintptr_t intarg = reinterpret_cast<uintptr_t>(arg);
  gold_assert(intarg < this->tlsdesc_reloc_info_.size());
  const Tlsdesc_info& ti(this->tlsdesc_reloc_info_[intarg]);
  const Symbol_value<size>* psymval = ti.object->local_symbol(ti.r_sym);
  gold_assert(psymval->is_tls_symbol());
  // The value of a TLS symbol is the offset in the TLS segment.
  return psymval->value(ti.object, 0);
}

// Return the number of entries in the PLT.

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

// Return the offset of the first non-reserved PLT entry.

template<int size, bool big_endian>
unsigned int
Target_aarch64<size, big_endian>::first_plt_entry_offset() const
{
  return this->plt_->first_plt_entry_offset();
}

// Return the size of each PLT entry.

template<int size, bool big_endian>
unsigned int
Target_aarch64<size, big_endian>::plt_entry_size() const
{
  return this->plt_->get_plt_entry_size();
}

// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::define_tls_base_symbol(
    Symbol_table* symtab, Layout* layout)
{
  if (this->tls_base_symbol_defined_)
    return;

  Output_segment* tls_segment = layout->tls_segment();
  if (tls_segment != NULL)
    {
      // _TLS_MODULE_BASE_ always points to the beginning of tls segment.
      symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
				       Symbol_table::PREDEFINED,
				       tls_segment, 0, 0,
				       elfcpp::STT_TLS,
				       elfcpp::STB_LOCAL,
				       elfcpp::STV_HIDDEN, 0,
				       Symbol::SEGMENT_START,
				       true);
    }
  this->tls_base_symbol_defined_ = true;
}

// Create the reserved PLT and GOT entries for the TLS descriptor resolver.

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

  if (!this->plt_->has_tlsdesc_entry())
    {
      // Allocate the TLSDESC_GOT entry.
      Output_data_got_aarch64<size, big_endian>* got =
	  this->got_section(symtab, layout);
      unsigned int got_offset = got->add_constant(0);

      // Allocate the TLSDESC_PLT entry.
      this->plt_->reserve_tlsdesc_entry(got_offset);
    }
}

// Create a GOT entry for the TLS module index.

template<int size, bool big_endian>
unsigned int
Target_aarch64<size, big_endian>::got_mod_index_entry(
    Symbol_table* symtab, Layout* layout,
    Sized_relobj_file<size, big_endian>* object)
{
  if (this->got_mod_index_offset_ == -1U)
    {
      gold_assert(symtab != NULL && layout != NULL && object != NULL);
      Reloc_section* rela_dyn = this->rela_dyn_section(layout);
      Output_data_got_aarch64<size, big_endian>* got =
	  this->got_section(symtab, layout);
      unsigned int got_offset = got->add_constant(0);
      rela_dyn->add_local(object, 0, elfcpp::R_AARCH64_TLS_DTPMOD64, got,
			  got_offset, 0);
      got->add_constant(0);
      this->got_mod_index_offset_ = got_offset;
    }
  return this->got_mod_index_offset_;
}

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

template<int size, bool big_endian>
tls::Tls_optimization
Target_aarch64<size, big_endian>::optimize_tls_reloc(bool is_final,
						     int r_type)
{
  // If we are generating a shared library, then we can't do anything
  // in the linker
  if (parameters->options().shared())
    return tls::TLSOPT_NONE;

  switch (r_type)
    {
    case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:
    case elfcpp::R_AARCH64_TLSDESC_LD_PREL19:
    case elfcpp::R_AARCH64_TLSDESC_ADR_PREL21:
    case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
    case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
    case elfcpp::R_AARCH64_TLSDESC_OFF_G1:
    case elfcpp::R_AARCH64_TLSDESC_OFF_G0_NC:
    case elfcpp::R_AARCH64_TLSDESC_LDR:
    case elfcpp::R_AARCH64_TLSDESC_ADD:
    case elfcpp::R_AARCH64_TLSDESC_CALL:
      // These are General-Dynamic which permits fully general TLS
      // access.  Since we know that we are generating an executable,
      // we can convert this to Initial-Exec.  If we also know that
      // this is a local symbol, we can further switch to Local-Exec.
      if (is_final)
	return tls::TLSOPT_TO_LE;
      return tls::TLSOPT_TO_IE;

    case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
      // These are Local-Dynamic, which refer to local symbols in the
      // dynamic TLS block. Since we know that we generating an
      // executable, we can switch to Local-Exec.
      return tls::TLSOPT_TO_LE;

    case elfcpp::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1:
    case elfcpp::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
    case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
    case elfcpp::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19:
      // These are Initial-Exec relocs which get the thread offset
      // from the GOT. If we know that we are linking against the
      // local symbol, we can switch to Local-Exec, which links the
      // thread offset into the instruction.
      if (is_final)
	return tls::TLSOPT_TO_LE;
      return tls::TLSOPT_NONE;

    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
      // When we already have Local-Exec, there is nothing further we
      // can do.
      return tls::TLSOPT_NONE;

    default:
      gold_unreachable();
    }
}

// Returns true if this relocation type could be that of a function pointer.

template<int size, bool big_endian>
inline bool
Target_aarch64<size, big_endian>::Scan::possible_function_pointer_reloc(
  unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_AARCH64_ADR_PREL_PG_HI21:
    case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC:
    case elfcpp::R_AARCH64_ADD_ABS_LO12_NC:
    case elfcpp::R_AARCH64_ADR_GOT_PAGE:
    case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
      {
	return true;
      }
    }
  return false;
}

// For safe ICF, scan a relocation for a local symbol to check if it
// corresponds to a function pointer being taken.  In that case mark
// the function whose pointer was taken as not foldable.

template<int size, bool big_endian>
inline bool
Target_aarch64<size, big_endian>::Scan::local_reloc_may_be_function_pointer(
  Symbol_table* ,
  Layout* ,
  Target_aarch64<size, big_endian>* ,
  Sized_relobj_file<size, big_endian>* ,
  unsigned int ,
  Output_section* ,
  const elfcpp::Rela<size, big_endian>& ,
  unsigned int r_type,
  const elfcpp::Sym<size, big_endian>&)
{
  // When building a shared library, do not fold any local symbols.
  return (parameters->options().shared()
	  || possible_function_pointer_reloc(r_type));
}

// For safe ICF, scan a relocation for a global symbol to check if it
// corresponds to a function pointer being taken.  In that case mark
// the function whose pointer was taken as not foldable.

template<int size, bool big_endian>
inline bool
Target_aarch64<size, big_endian>::Scan::global_reloc_may_be_function_pointer(
  Symbol_table* ,
  Layout* ,
  Target_aarch64<size, big_endian>* ,
  Sized_relobj_file<size, big_endian>* ,
  unsigned int ,
  Output_section* ,
  const elfcpp::Rela<size, big_endian>& ,
  unsigned int r_type,
  Symbol* gsym)
{
  // When building a shared library, do not fold symbols whose visibility
  // is hidden, internal or protected.
  return ((parameters->options().shared()
	   && (gsym->visibility() == elfcpp::STV_INTERNAL
	       || gsym->visibility() == elfcpp::STV_PROTECTED
	       || gsym->visibility() == elfcpp::STV_HIDDEN))
	  || possible_function_pointer_reloc(r_type));
}

// Report an unsupported relocation against a local symbol.

template<int size, bool big_endian>
void
Target_aarch64<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_aarch64<size, big_endian>::Scan::check_non_pic(Relobj* object,
						      unsigned int r_type)
{
  gold_assert(r_type != elfcpp::R_AARCH64_NONE);

  switch (r_type)
    {
    // These are the relocation types supported by glibc for AARCH64.
    case elfcpp::R_AARCH64_NONE:
    case elfcpp::R_AARCH64_COPY:
    case elfcpp::R_AARCH64_GLOB_DAT:
    case elfcpp::R_AARCH64_JUMP_SLOT:
    case elfcpp::R_AARCH64_RELATIVE:
    case elfcpp::R_AARCH64_TLS_DTPREL64:
    case elfcpp::R_AARCH64_TLS_DTPMOD64:
    case elfcpp::R_AARCH64_TLS_TPREL64:
    case elfcpp::R_AARCH64_TLSDESC:
    case elfcpp::R_AARCH64_IRELATIVE:
    case elfcpp::R_AARCH64_ABS32:
    case elfcpp::R_AARCH64_ABS64:
      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_aarch64<size, big_endian>::Scan::reloc_needs_plt_for_ifunc(
    Sized_relobj_file<size, big_endian>* object,
    unsigned int r_type)
{
  const AArch64_reloc_property* arp =
      aarch64_reloc_property_table->get_reloc_property(r_type);
  gold_assert(arp != NULL);

  int flags = arp->reference_flags();
  if (flags & Symbol::TLS_REF)
    {
      gold_error(_("%s: unsupported TLS reloc %s for IFUNC symbol"),
		 object->name().c_str(), arp->name().c_str());
      return false;
    }
  return flags != 0;
}

// Scan a relocation for a local symbol.

template<int size, bool big_endian>
inline void
Target_aarch64<size, big_endian>::Scan::local(
    Symbol_table* symtab,
    Layout* layout,
    Target_aarch64<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>& rela,
    unsigned int r_type,
    const elfcpp::Sym<size, big_endian>& lsym,
    bool is_discarded)
{
  if (is_discarded)
    return;

  typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
      Reloc_section;
  unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());

  // 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(object, r_type))
    target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym);

  switch (r_type)
    {
    case elfcpp::R_AARCH64_NONE:
      break;

    case elfcpp::R_AARCH64_ABS32:
    case elfcpp::R_AARCH64_ABS16:
      if (parameters->options().output_is_position_independent())
	{
	  gold_error(_("%s: unsupported reloc %u in pos independent link."),
		     object->name().c_str(), r_type);
	}
      break;

    case elfcpp::R_AARCH64_ABS64:
      // If building a shared library or pie, we need to mark this as a dynmic
      // reloction, so that the dynamic loader can relocate it.
      if (parameters->options().output_is_position_independent())
	{
	  Reloc_section* rela_dyn = target->rela_dyn_section(layout);
	  rela_dyn->add_local_relative(object, r_sym,
				       elfcpp::R_AARCH64_RELATIVE,
				       output_section,
				       data_shndx,
				       rela.get_r_offset(),
				       rela.get_r_addend(),
				       is_ifunc);
	}
      break;

    case elfcpp::R_AARCH64_PREL64:
    case elfcpp::R_AARCH64_PREL32:
    case elfcpp::R_AARCH64_PREL16:
      break;

    case elfcpp::R_AARCH64_ADR_GOT_PAGE:
    case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
    case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
      // The above relocations are used to access GOT entries.
      {
	Output_data_got_aarch64<size, big_endian>* got =
	    target->got_section(symtab, layout);
	bool is_new = false;
	// This symbol requires a GOT entry.
	if (is_ifunc)
	  is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD);
	else
	  is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD);
	if (is_new && parameters->options().output_is_position_independent())
	  target->rela_dyn_section(layout)->
	    add_local_relative(object,
			       r_sym,
			       elfcpp::R_AARCH64_RELATIVE,
			       got,
			       object->local_got_offset(r_sym,
							GOT_TYPE_STANDARD),
			       0,
			       false);
      }
      break;

    case elfcpp::R_AARCH64_MOVW_UABS_G0:        // 263
    case elfcpp::R_AARCH64_MOVW_UABS_G0_NC:     // 264
    case elfcpp::R_AARCH64_MOVW_UABS_G1:        // 265
    case elfcpp::R_AARCH64_MOVW_UABS_G1_NC:     // 266
    case elfcpp::R_AARCH64_MOVW_UABS_G2:        // 267
    case elfcpp::R_AARCH64_MOVW_UABS_G2_NC:     // 268
    case elfcpp::R_AARCH64_MOVW_UABS_G3:        // 269
    case elfcpp::R_AARCH64_MOVW_SABS_G0:        // 270
    case elfcpp::R_AARCH64_MOVW_SABS_G1:        // 271
    case elfcpp::R_AARCH64_MOVW_SABS_G2:        // 272
      if (parameters->options().output_is_position_independent())
	{
	  gold_error(_("%s: unsupported reloc %u in pos independent link."),
		     object->name().c_str(), r_type);
	}
      break;

    case elfcpp::R_AARCH64_LD_PREL_LO19:        // 273
    case elfcpp::R_AARCH64_ADR_PREL_LO21:       // 274
    case elfcpp::R_AARCH64_ADR_PREL_PG_HI21:    // 275
    case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC: // 276
    case elfcpp::R_AARCH64_ADD_ABS_LO12_NC:     // 277
    case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC:   // 278
    case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC:  // 284
    case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC:  // 285
    case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC:  // 286
    case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC: // 299
       break;

    // Control flow, pc-relative. We don't need to do anything for a relative
    // addressing relocation against a local symbol if it does not reference
    // the GOT.
    case elfcpp::R_AARCH64_TSTBR14:
    case elfcpp::R_AARCH64_CONDBR19:
    case elfcpp::R_AARCH64_JUMP26:
    case elfcpp::R_AARCH64_CALL26:
      break;

    case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
    case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
      {
	tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
	  optimize_tls_reloc(!parameters->options().shared(), r_type);
	if (tlsopt == tls::TLSOPT_TO_LE)
	  break;

	layout->set_has_static_tls();
	// Create a GOT entry for the tp-relative offset.
	if (!parameters->doing_static_link())
	  {
	    Output_data_got_aarch64<size, big_endian>* got =
		target->got_section(symtab, layout);
	    got->add_local_with_rel(object, r_sym, GOT_TYPE_TLS_OFFSET,
				    target->rela_dyn_section(layout),
				    elfcpp::R_AARCH64_TLS_TPREL64);
	  }
	else if (!object->local_has_got_offset(r_sym,
					       GOT_TYPE_TLS_OFFSET))
	  {
	    Output_data_got_aarch64<size, big_endian>* got =
		target->got_section(symtab, layout);
	    got->add_local(object, r_sym, GOT_TYPE_TLS_OFFSET);
	    unsigned int got_offset =
		object->local_got_offset(r_sym, GOT_TYPE_TLS_OFFSET);
	    const elfcpp::Elf_Xword addend = rela.get_r_addend();
	    gold_assert(addend == 0);
	    got->add_static_reloc(got_offset, elfcpp::R_AARCH64_TLS_TPREL64,
				  object, r_sym);
	  }
      }
      break;

    case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:
      {
	tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
	    optimize_tls_reloc(!parameters->options().shared(), r_type);
	if (tlsopt == tls::TLSOPT_TO_LE)
	  {
	    layout->set_has_static_tls();
	    break;
	  }
	gold_assert(tlsopt == tls::TLSOPT_NONE);

	Output_data_got_aarch64<size, big_endian>* got =
	    target->got_section(symtab, layout);
	got->add_local_pair_with_rel(object,r_sym, data_shndx,
				     GOT_TYPE_TLS_PAIR,
				     target->rela_dyn_section(layout),
				     elfcpp::R_AARCH64_TLS_DTPMOD64);
      }
      break;

    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
      {
	layout->set_has_static_tls();
	bool output_is_shared = parameters->options().shared();
	if (output_is_shared)
	  gold_error(_("%s: unsupported TLSLE reloc %u in shared code."),
		     object->name().c_str(), r_type);
      }
      break;

    case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
      {
	tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
	    optimize_tls_reloc(!parameters->options().shared(), r_type);
	if (tlsopt == tls::TLSOPT_NONE)
	  {
	    // Create a GOT entry for the module index.
	    target->got_mod_index_entry(symtab, layout, object);
	  }
	else if (tlsopt != tls::TLSOPT_TO_LE)
	  unsupported_reloc_local(object, r_type);
      }
      break;

    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
      break;

    case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
    case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
      {
	tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
	    optimize_tls_reloc(!parameters->options().shared(), r_type);
	target->define_tls_base_symbol(symtab, layout);
	if (tlsopt == tls::TLSOPT_NONE)
	  {
	    // Create reserved PLT and GOT entries for the resolver.
	    target->reserve_tlsdesc_entries(symtab, layout);

	    // Generate a double GOT entry with an R_AARCH64_TLSDESC reloc.
	    // The R_AARCH64_TLSDESC reloc is resolved lazily, so the GOT
	    // entry needs to be in an area in .got.plt, not .got. Call
	    // got_section to make sure the section has been created.
	    target->got_section(symtab, layout);
	    Output_data_got<size, big_endian>* got =
		target->got_tlsdesc_section();
	    unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
	    if (!object->local_has_got_offset(r_sym, GOT_TYPE_TLS_DESC))
	      {
		unsigned int got_offset = got->add_constant(0);
		got->add_constant(0);
		object->set_local_got_offset(r_sym, GOT_TYPE_TLS_DESC,
					     got_offset);
		Reloc_section* rt = target->rela_tlsdesc_section(layout);
		// We store the arguments we need in a vector, and use
		// the index into the vector as the parameter to pass
		// to the target specific routines.
		uintptr_t intarg = target->add_tlsdesc_info(object, r_sym);
		void* arg = reinterpret_cast<void*>(intarg);
		rt->add_target_specific(elfcpp::R_AARCH64_TLSDESC, arg,
					got, got_offset, 0);
	      }
	  }
	else if (tlsopt != tls::TLSOPT_TO_LE)
	  unsupported_reloc_local(object, r_type);
      }
      break;

    case elfcpp::R_AARCH64_TLSDESC_CALL:
      break;

    default:
      unsupported_reloc_local(object, r_type);
    }
}


// Report an unsupported relocation against a global symbol.

template<int size, bool big_endian>
void
Target_aarch64<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());
}

template<int size, bool big_endian>
inline void
Target_aarch64<size, big_endian>::Scan::global(
    Symbol_table* symtab,
    Layout* layout,
    Target_aarch64<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>& rela,
    unsigned int r_type,
    Symbol* gsym)
{
  // A STT_GNU_IFUNC symbol may require a PLT entry.
  if (gsym->type() == elfcpp::STT_GNU_IFUNC
      && this->reloc_needs_plt_for_ifunc(object, r_type))
    target->make_plt_entry(symtab, layout, gsym);

  typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>
    Reloc_section;
  const AArch64_reloc_property* arp =
      aarch64_reloc_property_table->get_reloc_property(r_type);
  gold_assert(arp != NULL);

  switch (r_type)
    {
    case elfcpp::R_AARCH64_NONE:
      break;

    case elfcpp::R_AARCH64_ABS16:
    case elfcpp::R_AARCH64_ABS32:
    case elfcpp::R_AARCH64_ABS64:
      {
	// Make a PLT entry if necessary.
	if (gsym->needs_plt_entry())
	  {
	    target->make_plt_entry(symtab, layout, gsym);
	    // 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 entry.
	    if (gsym->is_from_dynobj() && !parameters->options().shared())
	      gsym->set_needs_dynsym_value();
	  }
	// Make a dynamic relocation if necessary.
	if (gsym->needs_dynamic_reloc(arp->reference_flags()))
	  {
	    if (!parameters->options().output_is_position_independent()
		&& gsym->may_need_copy_reloc())
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, rela);
	      }
	    else if (r_type == elfcpp::R_AARCH64_ABS64
		     && gsym->type() == elfcpp::STT_GNU_IFUNC
		     && gsym->can_use_relative_reloc(false)
		     && !gsym->is_from_dynobj()
		     && !gsym->is_undefined()
		     && !gsym->is_preemptible())
	      {
		// Use an IRELATIVE reloc for a locally defined STT_GNU_IFUNC
		// symbol. This makes a function address in a PIE executable
		// match the address in a shared library that it links against.
		Reloc_section* rela_dyn =
		    target->rela_irelative_section(layout);
		unsigned int r_type = elfcpp::R_AARCH64_IRELATIVE;
		rela_dyn->add_symbolless_global_addend(gsym, r_type,
						       output_section, object,
						       data_shndx,
						       rela.get_r_offset(),
						       rela.get_r_addend());
	      }
	    else if (r_type == elfcpp::R_AARCH64_ABS64
		     && gsym->can_use_relative_reloc(false))
	      {
		Reloc_section* rela_dyn = target->rela_dyn_section(layout);
		rela_dyn->add_global_relative(gsym,
					      elfcpp::R_AARCH64_RELATIVE,
					      output_section,
					      object,
					      data_shndx,
					      rela.get_r_offset(),
					      rela.get_r_addend(),
					      false);
	      }
	    else
	      {
		check_non_pic(object, r_type);
		Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian>*
		    rela_dyn = target->rela_dyn_section(layout);
		rela_dyn->add_global(
		  gsym, r_type, output_section, object,
		  data_shndx, rela.get_r_offset(),rela.get_r_addend());
	      }
	  }
      }
      break;

    case elfcpp::R_AARCH64_PREL16:
    case elfcpp::R_AARCH64_PREL32:
    case elfcpp::R_AARCH64_PREL64:
      // This is used to fill the GOT absolute address.
      if (gsym->needs_plt_entry())
	{
	  target->make_plt_entry(symtab, layout, gsym);
	}
      break;

    case elfcpp::R_AARCH64_MOVW_UABS_G0:        // 263
    case elfcpp::R_AARCH64_MOVW_UABS_G0_NC:     // 264
    case elfcpp::R_AARCH64_MOVW_UABS_G1:        // 265
    case elfcpp::R_AARCH64_MOVW_UABS_G1_NC:     // 266
    case elfcpp::R_AARCH64_MOVW_UABS_G2:        // 267
    case elfcpp::R_AARCH64_MOVW_UABS_G2_NC:     // 268
    case elfcpp::R_AARCH64_MOVW_UABS_G3:        // 269
    case elfcpp::R_AARCH64_MOVW_SABS_G0:        // 270
    case elfcpp::R_AARCH64_MOVW_SABS_G1:        // 271
    case elfcpp::R_AARCH64_MOVW_SABS_G2:        // 272
      if (parameters->options().output_is_position_independent())
	{
	  gold_error(_("%s: unsupported reloc %u in pos independent link."),
		     object->name().c_str(), r_type);
	}
      break;

    case elfcpp::R_AARCH64_LD_PREL_LO19:        // 273
    case elfcpp::R_AARCH64_ADR_PREL_LO21:       // 274
    case elfcpp::R_AARCH64_ADR_PREL_PG_HI21:    // 275
    case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC: // 276
    case elfcpp::R_AARCH64_ADD_ABS_LO12_NC:     // 277
    case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC:   // 278
    case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC:  // 284
    case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC:  // 285
    case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC:  // 286
    case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC: // 299
      {
	if (gsym->needs_plt_entry())
	  target->make_plt_entry(symtab, layout, gsym);
	// Make a dynamic relocation if necessary.
	if (gsym->needs_dynamic_reloc(arp->reference_flags()))
	  {
	    if (parameters->options().output_is_executable()
		&& gsym->may_need_copy_reloc())
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, rela);
	      }
	  }
	break;
      }

    case elfcpp::R_AARCH64_ADR_GOT_PAGE:
    case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
    case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
      {
	// The above relocations are used to access GOT entries.
	// Note a GOT entry is an *address* to a symbol.
	// The symbol requires a GOT entry
	Output_data_got_aarch64<size, big_endian>* got =
	  target->got_section(symtab, layout);
	if (gsym->final_value_is_known())
	  {
	    // For a STT_GNU_IFUNC symbol we want the PLT address.
	    if (gsym->type() == elfcpp::STT_GNU_IFUNC)
	      got->add_global_plt(gsym, GOT_TYPE_STANDARD);
	    else
	      got->add_global(gsym, GOT_TYPE_STANDARD);
	  }
	else
	  {
	    // If this symbol is not fully resolved, we need to add a dynamic
	    // relocation for it.
	    Reloc_section* rela_dyn = target->rela_dyn_section(layout);

	    // Use a GLOB_DAT rather than a RELATIVE reloc if:
	    //
	    // 1) The symbol may be defined in some other module.
	    // 2) We are building a shared library and this is a protected
	    // symbol; using GLOB_DAT means that the dynamic linker can use
	    // the address of the PLT in the main executable when appropriate
	    // so that function address comparisons work.
	    // 3) This is a STT_GNU_IFUNC symbol in position dependent code,
	    // again so that function address comparisons work.
	    if (gsym->is_from_dynobj()
		|| gsym->is_undefined()
		|| gsym->is_preemptible()
		|| (gsym->visibility() == elfcpp::STV_PROTECTED
		    && parameters->options().shared())
		|| (gsym->type() == elfcpp::STT_GNU_IFUNC
		    && parameters->options().output_is_position_independent()))
	      got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
				       rela_dyn, elfcpp::R_AARCH64_GLOB_DAT);
	    else
	      {
		// For a STT_GNU_IFUNC symbol we want to write the PLT
		// offset into the GOT, so that function pointer
		// comparisons work correctly.
		bool is_new;
		if (gsym->type() != elfcpp::STT_GNU_IFUNC)
		  is_new = got->add_global(gsym, GOT_TYPE_STANDARD);
		else
		  {
		    is_new = got->add_global_plt(gsym, GOT_TYPE_STANDARD);
		    // Tell the dynamic linker to use the PLT address
		    // when resolving relocations.
		    if (gsym->is_from_dynobj()
			&& !parameters->options().shared())
		      gsym->set_needs_dynsym_value();
		  }
		if (is_new)
		  {
		    rela_dyn->add_global_relative(
			gsym, elfcpp::R_AARCH64_RELATIVE,
			got,
			gsym->got_offset(GOT_TYPE_STANDARD),
			0,
			false);
		  }
	      }
	  }
	break;
      }

    case elfcpp::R_AARCH64_TSTBR14:
    case elfcpp::R_AARCH64_CONDBR19:
    case elfcpp::R_AARCH64_JUMP26:
    case elfcpp::R_AARCH64_CALL26:
      {
	if (gsym->final_value_is_known())
	  break;

	if (gsym->is_defined() &&
	    !gsym->is_from_dynobj() &&
	    !gsym->is_preemptible())
	  break;

	// Make plt entry for function call.
	target->make_plt_entry(symtab, layout, gsym);
	break;
      }

    case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:  // General dynamic
      {
	tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
	    optimize_tls_reloc(gsym->final_value_is_known(), r_type);
	if (tlsopt == tls::TLSOPT_TO_LE)
	  {
	    layout->set_has_static_tls();
	    break;
	  }
	gold_assert(tlsopt == tls::TLSOPT_NONE);

	// General dynamic.
	Output_data_got_aarch64<size, big_endian>* got =
	    target->got_section(symtab, layout);
	// Create 2 consecutive entries for module index and offset.
	got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
				      target->rela_dyn_section(layout),
				      elfcpp::R_AARCH64_TLS_DTPMOD64,
				      elfcpp::R_AARCH64_TLS_DTPREL64);
      }
      break;

    case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:  // Local dynamic
      {
	tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
	    optimize_tls_reloc(!parameters->options().shared(), r_type);
	if (tlsopt == tls::TLSOPT_NONE)
	  {
	    // Create a GOT entry for the module index.
	    target->got_mod_index_entry(symtab, layout, object);
	  }
	else if (tlsopt != tls::TLSOPT_TO_LE)
	  unsupported_reloc_local(object, r_type);
      }
      break;

    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:  // Other local dynamic
      break;

    case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
    case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:  // Initial executable
      {
	tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
	  optimize_tls_reloc(gsym->final_value_is_known(), r_type);
	if (tlsopt == tls::TLSOPT_TO_LE)
	  break;

	layout->set_has_static_tls();
	// Create a GOT entry for the tp-relative offset.
	Output_data_got_aarch64<size, big_endian>* got
	  = target->got_section(symtab, layout);
	if (!parameters->doing_static_link())
	  {
	    got->add_global_with_rel(
	      gsym, GOT_TYPE_TLS_OFFSET,
	      target->rela_dyn_section(layout),
	      elfcpp::R_AARCH64_TLS_TPREL64);
	  }
	if (!gsym->has_got_offset(GOT_TYPE_TLS_OFFSET))
	  {
	    got->add_global(gsym, GOT_TYPE_TLS_OFFSET);
	    unsigned int got_offset =
	      gsym->got_offset(GOT_TYPE_TLS_OFFSET);
	    const elfcpp::Elf_Xword addend = rela.get_r_addend();
	    gold_assert(addend == 0);
	    got->add_static_reloc(got_offset,
				  elfcpp::R_AARCH64_TLS_TPREL64, gsym);
	  }
      }
      break;

    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:  // Local executable
      layout->set_has_static_tls();
      if (parameters->options().shared())
	gold_error(_("%s: unsupported TLSLE reloc type %u in shared objects."),
		   object->name().c_str(), r_type);
      break;

    case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
    case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:  // TLS descriptor
      {
	target->define_tls_base_symbol(symtab, layout);
	tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
	    optimize_tls_reloc(gsym->final_value_is_known(), r_type);
	if (tlsopt == tls::TLSOPT_NONE)
	  {
	    // Create reserved PLT and GOT entries for the resolver.
	    target->reserve_tlsdesc_entries(symtab, layout);

	    // Create a double GOT entry with an R_AARCH64_TLSDESC
	    // relocation. The R_AARCH64_TLSDESC is resolved lazily, so the GOT
	    // entry needs to be in an area in .got.plt, not .got. Call
	    // got_section to make sure the section has been created.
	    target->got_section(symtab, layout);
	    Output_data_got<size, big_endian>* got =
		target->got_tlsdesc_section();
	    Reloc_section* rt = target->rela_tlsdesc_section(layout);
	    got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_DESC, rt,
					  elfcpp::R_AARCH64_TLSDESC, 0);
	  }
	else if (tlsopt == tls::TLSOPT_TO_IE)
	  {
	    // Create a GOT entry for the tp-relative offset.
	    Output_data_got<size, big_endian>* got
		= target->got_section(symtab, layout);
	    got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
				     target->rela_dyn_section(layout),
				     elfcpp::R_AARCH64_TLS_TPREL64);
	  }
	else if (tlsopt != tls::TLSOPT_TO_LE)
	  unsupported_reloc_global(object, r_type, gsym);
      }
      break;

    case elfcpp::R_AARCH64_TLSDESC_CALL:
      break;

    default:
      gold_error(_("%s: unsupported reloc type in global scan"),
		 aarch64_reloc_property_table->
		 reloc_name_in_error_message(r_type).c_str());
    }
  return;
}  // End of Scan::global


// Create the PLT section.
template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::make_plt_section(
  Symbol_table* symtab, Layout* layout)
{
  if (this->plt_ == NULL)
    {
      // Create the GOT section first.
      this->got_section(symtab, layout);

      this->plt_ = this->make_data_plt(layout, this->got_, this->got_plt_,
				       this->got_irelative_);

      layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC
				       | elfcpp::SHF_EXECINSTR),
				      this->plt_, ORDER_PLT, false);

      // Make the sh_info field of .rela.plt point to .plt.
      Output_section* rela_plt_os = this->plt_->rela_plt()->output_section();
      rela_plt_os->set_info_section(this->plt_->output_section());
    }
}

// Return the section for TLSDESC relocations.

template<int size, bool big_endian>
typename Target_aarch64<size, big_endian>::Reloc_section*
Target_aarch64<size, big_endian>::rela_tlsdesc_section(Layout* layout) const
{
  return this->plt_section()->rela_tlsdesc(layout);
}

// Create a PLT entry for a global symbol.

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::make_plt_entry(
    Symbol_table* symtab,
    Layout* layout,
    Symbol* gsym)
{
  if (gsym->has_plt_offset())
    return;

  if (this->plt_ == NULL)
    this->make_plt_section(symtab, layout);

  this->plt_->add_entry(symtab, layout, gsym);
}

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

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::make_local_ifunc_plt_entry(
    Symbol_table* symtab, Layout* layout,
    Sized_relobj_file<size, big_endian>* relobj,
    unsigned int local_sym_index)
{
  if (relobj->local_has_plt_offset(local_sym_index))
    return;
  if (this->plt_ == NULL)
    this->make_plt_section(symtab, layout);
  unsigned int plt_offset = this->plt_->add_local_ifunc_entry(symtab, layout,
							      relobj,
							      local_sym_index);
  relobj->set_local_plt_offset(local_sym_index, plt_offset);
}

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::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)
{
  typedef Target_aarch64<size, big_endian> Aarch64;
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
      Classify_reloc;

  if (sh_type == elfcpp::SHT_REL)
    {
      return;
    }

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

// Scan relocations for a section.

template<int size, bool big_endian>
void
Target_aarch64<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_aarch64<size, big_endian> Aarch64;
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
      Classify_reloc;

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

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

// Return the value to use for a dynamic 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_aarch64<size, big_endian>::do_dynsym_value(const Symbol* gsym) const
{
  gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
  return this->plt_address_for_global(gsym);
}


// Finalize the sections.

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::do_finalize_sections(
    Layout* layout,
    const Input_objects*,
    Symbol_table* symtab)
{
  const Reloc_section* rel_plt = (this->plt_ == NULL
				  ? NULL
				  : this->plt_->rela_plt());
  layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt,
				  this->rela_dyn_, true, false);

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

  // Fill in some more dynamic tags.
  Output_data_dynamic* const odyn = layout->dynamic_data();
  if (odyn != NULL)
    {
      if (this->plt_ != NULL
	  && this->plt_->output_section() != NULL
	  && this->plt_ ->has_tlsdesc_entry())
	{
	  unsigned int plt_offset = this->plt_->get_tlsdesc_plt_offset();
	  unsigned int got_offset = this->plt_->get_tlsdesc_got_offset();
	  this->got_->finalize_data_size();
	  odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_PLT,
					this->plt_, plt_offset);
	  odyn->add_section_plus_offset(elfcpp::DT_TLSDESC_GOT,
					this->got_, got_offset);
	}
    }

  // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of
  // the .got.plt section.
  Symbol* sym = this->global_offset_table_;
  if (sym != NULL)
    {
      uint64_t data_size = this->got_plt_->current_data_size();
      symtab->get_sized_symbol<size>(sym)->set_symsize(data_size);

      // If the .got section is more than 0x8000 bytes, we add
      // 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
      // bit relocations have a greater chance of working.
      if (data_size >= 0x8000)
	symtab->get_sized_symbol<size>(sym)->set_value(
	  symtab->get_sized_symbol<size>(sym)->value() + 0x8000);
    }

  if (parameters->doing_static_link()
      && (this->plt_ == NULL || !this->plt_->has_irelative_section()))
    {
      // If linking statically, make sure that the __rela_iplt symbols
      // were defined if necessary, even if we didn't create a PLT.
      static const Define_symbol_in_segment syms[] =
	{
	  {
	    "__rela_iplt_start",	// name
	    elfcpp::PT_LOAD,		// segment_type
	    elfcpp::PF_W,		// segment_flags_set
	    elfcpp::PF(0),		// segment_flags_clear
	    0,				// value
	    0,				// size
	    elfcpp::STT_NOTYPE,		// type
	    elfcpp::STB_GLOBAL,		// binding
	    elfcpp::STV_HIDDEN,		// visibility
	    0,				// nonvis
	    Symbol::SEGMENT_START,	// offset_from_base
	    true			// only_if_ref
	  },
	  {
	    "__rela_iplt_end",		// name
	    elfcpp::PT_LOAD,		// segment_type
	    elfcpp::PF_W,		// segment_flags_set
	    elfcpp::PF(0),		// segment_flags_clear
	    0,				// value
	    0,				// size
	    elfcpp::STT_NOTYPE,		// type
	    elfcpp::STB_GLOBAL,		// binding
	    elfcpp::STV_HIDDEN,		// visibility
	    0,				// nonvis
	    Symbol::SEGMENT_START,	// offset_from_base
	    true			// only_if_ref
	  }
	};

      symtab->define_symbols(layout, 2, syms,
			     layout->script_options()->saw_sections_clause());
    }

  return;
}

// Perform a relocation.

template<int size, bool big_endian>
inline bool
Target_aarch64<size, big_endian>::Relocate::relocate(
    const Relocate_info<size, big_endian>* relinfo,
    unsigned int,
    Target_aarch64<size, big_endian>* target,
    Output_section* ,
    size_t relnum,
    const unsigned char* preloc,
    const Sized_symbol<size>* gsym,
    const Symbol_value<size>* psymval,
    unsigned char* view,
    typename elfcpp::Elf_types<size>::Elf_Addr address,
    section_size_type /* view_size */)
{
  if (view == NULL)
    return true;

  typedef AArch64_relocate_functions<size, big_endian> Reloc;

  const elfcpp::Rela<size, big_endian> rela(preloc);
  unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info());
  const AArch64_reloc_property* reloc_property =
      aarch64_reloc_property_table->get_reloc_property(r_type);

  if (reloc_property == NULL)
    {
      std::string reloc_name =
	  aarch64_reloc_property_table->reloc_name_in_error_message(r_type);
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("cannot relocate %s in object file"),
			     reloc_name.c_str());
      return true;
    }

  const Sized_relobj_file<size, big_endian>* object = relinfo->object;

  // Pick the value to use for symbols defined in the PLT.
  Symbol_value<size> symval;
  if (gsym != NULL
      && gsym->use_plt_offset(reloc_property->reference_flags()))
    {
      symval.set_output_value(target->plt_address_for_global(gsym));
      psymval = &symval;
    }
  else if (gsym == NULL && psymval->is_ifunc_symbol())
    {
      unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
      if (object->local_has_plt_offset(r_sym))
	{
	  symval.set_output_value(target->plt_address_for_local(object, r_sym));
	  psymval = &symval;
	}
    }

  const elfcpp::Elf_Xword addend = rela.get_r_addend();

  // Get the GOT offset if needed.
  // For aarch64, the GOT pointer points to the start of the GOT section.
  bool have_got_offset = false;
  int got_offset = 0;
  int got_base = (target->got_ != NULL
		  ? (target->got_->current_data_size() >= 0x8000
		     ? 0x8000 : 0)
		  : 0);
  switch (r_type)
    {
    case elfcpp::R_AARCH64_MOVW_GOTOFF_G0:
    case elfcpp::R_AARCH64_MOVW_GOTOFF_G0_NC:
    case elfcpp::R_AARCH64_MOVW_GOTOFF_G1:
    case elfcpp::R_AARCH64_MOVW_GOTOFF_G1_NC:
    case elfcpp::R_AARCH64_MOVW_GOTOFF_G2:
    case elfcpp::R_AARCH64_MOVW_GOTOFF_G2_NC:
    case elfcpp::R_AARCH64_MOVW_GOTOFF_G3:
    case elfcpp::R_AARCH64_GOTREL64:
    case elfcpp::R_AARCH64_GOTREL32:
    case elfcpp::R_AARCH64_GOT_LD_PREL19:
    case elfcpp::R_AARCH64_LD64_GOTOFF_LO15:
    case elfcpp::R_AARCH64_ADR_GOT_PAGE:
    case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
    case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
      if (gsym != NULL)
	{
	  gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
	  got_offset = gsym->got_offset(GOT_TYPE_STANDARD) - got_base;
	}
      else
	{
	  unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
	  gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD));
	  got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD)
			- got_base);
	}
      have_got_offset = true;
      break;

    default:
      break;
    }

  typename Reloc::Status reloc_status = Reloc::STATUS_OKAY;
  typename elfcpp::Elf_types<size>::Elf_Addr value;
  switch (r_type)
    {
    case elfcpp::R_AARCH64_NONE:
      break;

    case elfcpp::R_AARCH64_ABS64:
      if (!parameters->options().apply_dynamic_relocs()
          && parameters->options().output_is_position_independent()
          && gsym != NULL
          && gsym->needs_dynamic_reloc(reloc_property->reference_flags())
          && !gsym->can_use_relative_reloc(false))
        // We have generated an absolute dynamic relocation, so do not
        // apply the relocation statically. (Works around bugs in older
        // Android dynamic linkers.)
        break;
      reloc_status = Reloc::template rela_ua<64>(
	view, object, psymval, addend, reloc_property);
      break;

    case elfcpp::R_AARCH64_ABS32:
      if (!parameters->options().apply_dynamic_relocs()
          && parameters->options().output_is_position_independent()
          && gsym != NULL
          && gsym->needs_dynamic_reloc(reloc_property->reference_flags()))
        // We have generated an absolute dynamic relocation, so do not
        // apply the relocation statically. (Works around bugs in older
        // Android dynamic linkers.)
        break;
      reloc_status = Reloc::template rela_ua<32>(
	view, object, psymval, addend, reloc_property);
      break;

    case elfcpp::R_AARCH64_ABS16:
      if (!parameters->options().apply_dynamic_relocs()
          && parameters->options().output_is_position_independent()
          && gsym != NULL
          && gsym->needs_dynamic_reloc(reloc_property->reference_flags()))
        // We have generated an absolute dynamic relocation, so do not
        // apply the relocation statically. (Works around bugs in older
        // Android dynamic linkers.)
        break;
      reloc_status = Reloc::template rela_ua<16>(
	view, object, psymval, addend, reloc_property);
      break;

    case elfcpp::R_AARCH64_PREL64:
      reloc_status = Reloc::template pcrela_ua<64>(
	view, object, psymval, addend, address, reloc_property);
      break;

    case elfcpp::R_AARCH64_PREL32:
      reloc_status = Reloc::template pcrela_ua<32>(
	view, object, psymval, addend, address, reloc_property);
      break;

    case elfcpp::R_AARCH64_PREL16:
      reloc_status = Reloc::template pcrela_ua<16>(
	view, object, psymval, addend, address, reloc_property);
      break;

    case elfcpp::R_AARCH64_MOVW_UABS_G0:
    case elfcpp::R_AARCH64_MOVW_UABS_G0_NC:
    case elfcpp::R_AARCH64_MOVW_UABS_G1:
    case elfcpp::R_AARCH64_MOVW_UABS_G1_NC:
    case elfcpp::R_AARCH64_MOVW_UABS_G2:
    case elfcpp::R_AARCH64_MOVW_UABS_G2_NC:
    case elfcpp::R_AARCH64_MOVW_UABS_G3:
      reloc_status = Reloc::template rela_general<32>(
	view, object, psymval, addend, reloc_property);
      break;
    case elfcpp::R_AARCH64_MOVW_SABS_G0:
    case elfcpp::R_AARCH64_MOVW_SABS_G1:
    case elfcpp::R_AARCH64_MOVW_SABS_G2:
      reloc_status = Reloc::movnz(view, psymval->value(object, addend),
				  reloc_property);
      break;

    case elfcpp::R_AARCH64_LD_PREL_LO19:
      reloc_status = Reloc::template pcrela_general<32>(
	  view, object, psymval, addend, address, reloc_property);
      break;

    case elfcpp::R_AARCH64_ADR_PREL_LO21:
      reloc_status = Reloc::adr(view, object, psymval, addend,
				address, reloc_property);
      break;

    case elfcpp::R_AARCH64_ADR_PREL_PG_HI21_NC:
    case elfcpp::R_AARCH64_ADR_PREL_PG_HI21:
      reloc_status = Reloc::adrp(view, object, psymval, addend, address,
				 reloc_property);
      break;

    case elfcpp::R_AARCH64_LDST8_ABS_LO12_NC:
    case elfcpp::R_AARCH64_LDST16_ABS_LO12_NC:
    case elfcpp::R_AARCH64_LDST32_ABS_LO12_NC:
    case elfcpp::R_AARCH64_LDST64_ABS_LO12_NC:
    case elfcpp::R_AARCH64_LDST128_ABS_LO12_NC:
    case elfcpp::R_AARCH64_ADD_ABS_LO12_NC:
      reloc_status = Reloc::template rela_general<32>(
	view, object, psymval, addend, reloc_property);
      break;

    case elfcpp::R_AARCH64_CALL26:
      if (this->skip_call_tls_get_addr_)
	{
	  // Double check that the TLSGD insn has been optimized away.
	  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
	  Insntype insn = elfcpp::Swap<32, big_endian>::readval(
	      reinterpret_cast<Insntype*>(view));
	  gold_assert((insn & 0xff000000) == 0x91000000);

	  reloc_status = Reloc::STATUS_OKAY;
	  this->skip_call_tls_get_addr_ = false;
	  // Return false to stop further processing this reloc.
	  return false;
	}
      // Fall through.
    case elfcpp::R_AARCH64_JUMP26:
      if (Reloc::maybe_apply_stub(r_type, relinfo, rela, view, address,
				  gsym, psymval, object,
				  target->stub_group_size_))
	break;
      // Fall through.
    case elfcpp::R_AARCH64_TSTBR14:
    case elfcpp::R_AARCH64_CONDBR19:
      reloc_status = Reloc::template pcrela_general<32>(
	view, object, psymval, addend, address, reloc_property);
      break;

    case elfcpp::R_AARCH64_ADR_GOT_PAGE:
      gold_assert(have_got_offset);
      value = target->got_->address() + got_base + got_offset;
      reloc_status = Reloc::adrp(view, value + addend, address);
      break;

    case elfcpp::R_AARCH64_LD64_GOT_LO12_NC:
      gold_assert(have_got_offset);
      value = target->got_->address() + got_base + got_offset;
      reloc_status = Reloc::template rela_general<32>(
	view, value, addend, reloc_property);
      break;

    case elfcpp::R_AARCH64_LD64_GOTPAGE_LO15:
      {
	gold_assert(have_got_offset);
	value = target->got_->address() + got_base + got_offset + addend -
	  Reloc::Page(target->got_->address() + got_base);
	if ((value & 7) != 0)
	  reloc_status = Reloc::STATUS_OVERFLOW;
	else
	  reloc_status = Reloc::template reloc_common<32>(
	    view, value, reloc_property);
	break;
      }

    case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:
    case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
    case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
    case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
    case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
    case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
    case elfcpp::R_AARCH64_TLSDESC_CALL:
      reloc_status = relocate_tls(relinfo, target, relnum, rela, r_type,
				  gsym, psymval, view, address);
      break;

    // These are dynamic relocations, which are unexpected when linking.
    case elfcpp::R_AARCH64_COPY:
    case elfcpp::R_AARCH64_GLOB_DAT:
    case elfcpp::R_AARCH64_JUMP_SLOT:
    case elfcpp::R_AARCH64_RELATIVE:
    case elfcpp::R_AARCH64_IRELATIVE:
    case elfcpp::R_AARCH64_TLS_DTPREL64:
    case elfcpp::R_AARCH64_TLS_DTPMOD64:
    case elfcpp::R_AARCH64_TLS_TPREL64:
    case elfcpp::R_AARCH64_TLSDESC:
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unexpected reloc %u in object file"),
			     r_type);
      break;

    default:
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("unsupported reloc %s"),
			     reloc_property->name().c_str());
      break;
    }

  // Report any errors.
  switch (reloc_status)
    {
    case Reloc::STATUS_OKAY:
      break;
    case Reloc::STATUS_OVERFLOW:
      gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			     _("relocation overflow in %s"),
			     reloc_property->name().c_str());
      break;
    case Reloc::STATUS_BAD_RELOC:
      gold_error_at_location(
	  relinfo,
	  relnum,
	  rela.get_r_offset(),
	  _("unexpected opcode while processing relocation %s"),
	  reloc_property->name().c_str());
      break;
    default:
      gold_unreachable();
    }

  return true;
}


template<int size, bool big_endian>
inline
typename AArch64_relocate_functions<size, big_endian>::Status
Target_aarch64<size, big_endian>::Relocate::relocate_tls(
    const Relocate_info<size, big_endian>* relinfo,
    Target_aarch64<size, big_endian>* target,
    size_t relnum,
    const elfcpp::Rela<size, big_endian>& rela,
    unsigned int r_type, const Sized_symbol<size>* gsym,
    const Symbol_value<size>* psymval,
    unsigned char* view,
    typename elfcpp::Elf_types<size>::Elf_Addr address)
{
  typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;

  Output_segment* tls_segment = relinfo->layout->tls_segment();
  const elfcpp::Elf_Xword addend = rela.get_r_addend();
  const AArch64_reloc_property* reloc_property =
      aarch64_reloc_property_table->get_reloc_property(r_type);
  gold_assert(reloc_property != NULL);

  const bool is_final = (gsym == NULL
			 ? !parameters->options().shared()
			 : gsym->final_value_is_known());
  tls::Tls_optimization tlsopt = Target_aarch64<size, big_endian>::
      optimize_tls_reloc(is_final, r_type);

  Sized_relobj_file<size, big_endian>* object = relinfo->object;
  int tls_got_offset_type;
  switch (r_type)
    {
    case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:  // Global-dynamic
      {
	if (tlsopt == tls::TLSOPT_TO_LE)
	  {
	    if (tls_segment == NULL)
	      {
		gold_assert(parameters->errors()->error_count() > 0
			    || issue_undefined_symbol_error(gsym));
		return aarch64_reloc_funcs::STATUS_BAD_RELOC;
	      }
	    return tls_gd_to_le(relinfo, target, rela, r_type, view,
				psymval);
	  }
	else if (tlsopt == tls::TLSOPT_NONE)
	  {
	    tls_got_offset_type = GOT_TYPE_TLS_PAIR;
	    // Firstly get the address for the got entry.
	    typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address;
	    if (gsym != NULL)
	      {
		gold_assert(gsym->has_got_offset(tls_got_offset_type));
		got_entry_address = target->got_->address() +
				    gsym->got_offset(tls_got_offset_type);
	      }
	    else
	      {
		unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
		gold_assert(
		  object->local_has_got_offset(r_sym, tls_got_offset_type));
		got_entry_address = target->got_->address() +
		  object->local_got_offset(r_sym, tls_got_offset_type);
	      }

	    // Relocate the address into adrp/ld, adrp/add pair.
	    switch (r_type)
	      {
	      case elfcpp::R_AARCH64_TLSGD_ADR_PAGE21:
		return aarch64_reloc_funcs::adrp(
		  view, got_entry_address + addend, address);

		break;

	      case elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC:
		return aarch64_reloc_funcs::template rela_general<32>(
		  view, got_entry_address, addend, reloc_property);
		break;

	      default:
		gold_unreachable();
	      }
	  }
	gold_error_at_location(relinfo, relnum, rela.get_r_offset(),
			       _("unsupported gd_to_ie relaxation on %u"),
			       r_type);
      }
      break;

    case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:  // Local-dynamic
      {
	if (tlsopt == tls::TLSOPT_TO_LE)
	  {
	    if (tls_segment == NULL)
	      {
		gold_assert(parameters->errors()->error_count() > 0
			    || issue_undefined_symbol_error(gsym));
		return aarch64_reloc_funcs::STATUS_BAD_RELOC;
	      }
	    return this->tls_ld_to_le(relinfo, target, rela, r_type, view,
				      psymval);
	  }

	gold_assert(tlsopt == tls::TLSOPT_NONE);
	// Relocate the field with the offset of the GOT entry for
	// the module index.
	typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address;
	got_entry_address = (target->got_mod_index_entry(NULL, NULL, NULL) +
			     target->got_->address());

	switch (r_type)
	  {
	  case elfcpp::R_AARCH64_TLSLD_ADR_PAGE21:
	    return aarch64_reloc_funcs::adrp(
	      view, got_entry_address + addend, address);
	    break;

	  case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
	    return aarch64_reloc_funcs::template rela_general<32>(
	      view, got_entry_address, addend, reloc_property);
	    break;

	  default:
	    gold_unreachable();
	  }
      }
      break;

    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:  // Other local-dynamic
      {
	AArch64_address value = psymval->value(object, 0);
	if (tlsopt == tls::TLSOPT_TO_LE)
	  {
	    if (tls_segment == NULL)
	      {
		gold_assert(parameters->errors()->error_count() > 0
			    || issue_undefined_symbol_error(gsym));
		return aarch64_reloc_funcs::STATUS_BAD_RELOC;
	      }
	  }
	switch (r_type)
	  {
	  case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
	    return aarch64_reloc_funcs::movnz(view, value + addend,
					      reloc_property);
	    break;

	  case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
	  case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
	  case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
	    return aarch64_reloc_funcs::template rela_general<32>(
		view, value, addend, reloc_property);
	    break;

	  default:
	    gold_unreachable();
	  }
	// We should never reach here.
      }
      break;

    case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
    case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:  // Initial-exec
      {
	if (tlsopt == tls::TLSOPT_TO_LE)
	  {
	    if (tls_segment == NULL)
	      {
		gold_assert(parameters->errors()->error_count() > 0
			    || issue_undefined_symbol_error(gsym));
		return aarch64_reloc_funcs::STATUS_BAD_RELOC;
	      }
	    return tls_ie_to_le(relinfo, target, rela, r_type, view,
				psymval);
	  }
	tls_got_offset_type = GOT_TYPE_TLS_OFFSET;

	// Firstly get the address for the got entry.
	typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address;
	if (gsym != NULL)
	  {
	    gold_assert(gsym->has_got_offset(tls_got_offset_type));
	    got_entry_address = target->got_->address() +
				gsym->got_offset(tls_got_offset_type);
	  }
	else
	  {
	    unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
	    gold_assert(
		object->local_has_got_offset(r_sym, tls_got_offset_type));
	    got_entry_address = target->got_->address() +
		object->local_got_offset(r_sym, tls_got_offset_type);
	  }
	// Relocate the address into adrp/ld, adrp/add pair.
	switch (r_type)
	  {
	  case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
	    return aarch64_reloc_funcs::adrp(view, got_entry_address + addend,
					     address);
	    break;
	  case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
	    return aarch64_reloc_funcs::template rela_general<32>(
	      view, got_entry_address, addend, reloc_property);
	  default:
	    gold_unreachable();
	  }
      }
      // We shall never reach here.
      break;

    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
    case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
      {
	gold_assert(tls_segment != NULL);
	AArch64_address value = psymval->value(object, 0);

	if (!parameters->options().shared())
	  {
	    AArch64_address aligned_tcb_size =
		align_address(target->tcb_size(),
			      tls_segment->maximum_alignment());
	    value += aligned_tcb_size;
	    switch (r_type)
	      {
	      case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
	      case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
	      case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
		return aarch64_reloc_funcs::movnz(view, value + addend,
						  reloc_property);
	      default:
		return aarch64_reloc_funcs::template
		  rela_general<32>(view,
				   value,
				   addend,
				   reloc_property);
	      }
	  }
	else
	  gold_error(_("%s: unsupported reloc %u "
		       "in non-static TLSLE mode."),
		     object->name().c_str(), r_type);
      }
      break;

    case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
    case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
    case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
    case elfcpp::R_AARCH64_TLSDESC_CALL:
      {
	if (tlsopt == tls::TLSOPT_TO_LE)
	  {
	    if (tls_segment == NULL)
	      {
		gold_assert(parameters->errors()->error_count() > 0
			    || issue_undefined_symbol_error(gsym));
		return aarch64_reloc_funcs::STATUS_BAD_RELOC;
	      }
	    return tls_desc_gd_to_le(relinfo, target, rela, r_type,
				     view, psymval);
	  }
	else
	  {
	    tls_got_offset_type = (tlsopt == tls::TLSOPT_TO_IE
				   ? GOT_TYPE_TLS_OFFSET
				   : GOT_TYPE_TLS_DESC);
	    unsigned int got_tlsdesc_offset = 0;
	    if (r_type != elfcpp::R_AARCH64_TLSDESC_CALL
		&& tlsopt == tls::TLSOPT_NONE)
	      {
		// We created GOT entries in the .got.tlsdesc portion of the
		// .got.plt section, but the offset stored in the symbol is the
		// offset within .got.tlsdesc.
		got_tlsdesc_offset = (target->got_->data_size()
				      + target->got_plt_section()->data_size());
	      }
	    typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address;
	    if (gsym != NULL)
	      {
		gold_assert(gsym->has_got_offset(tls_got_offset_type));
		got_entry_address = target->got_->address()
				    + got_tlsdesc_offset
				    + gsym->got_offset(tls_got_offset_type);
	      }
	    else
	      {
		unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info());
		gold_assert(
		    object->local_has_got_offset(r_sym, tls_got_offset_type));
		got_entry_address = target->got_->address() +
		  got_tlsdesc_offset +
		  object->local_got_offset(r_sym, tls_got_offset_type);
	      }
	    if (tlsopt == tls::TLSOPT_TO_IE)
	      {
		return tls_desc_gd_to_ie(relinfo, target, rela, r_type,
					 view, psymval, got_entry_address,
					 address);
	      }

	    // Now do tlsdesc relocation.
	    switch (r_type)
	      {
	      case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
		return aarch64_reloc_funcs::adrp(view,
						 got_entry_address + addend,
						 address);
		break;
	      case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
	      case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
		return aarch64_reloc_funcs::template rela_general<32>(
		  view, got_entry_address, addend, reloc_property);
		break;
	      case elfcpp::R_AARCH64_TLSDESC_CALL:
		return aarch64_reloc_funcs::STATUS_OKAY;
		break;
	      default:
		gold_unreachable();
	      }
	  }
	}
      break;

    default:
      gold_error(_("%s: unsupported TLS reloc %u."),
		 object->name().c_str(), r_type);
    }
  return aarch64_reloc_funcs::STATUS_BAD_RELOC;
}  // End of relocate_tls.


template<int size, bool big_endian>
inline
typename AArch64_relocate_functions<size, big_endian>::Status
Target_aarch64<size, big_endian>::Relocate::tls_gd_to_le(
	     const Relocate_info<size, big_endian>* relinfo,
	     Target_aarch64<size, big_endian>* target,
	     const elfcpp::Rela<size, big_endian>& rela,
	     unsigned int r_type,
	     unsigned char* view,
	     const Symbol_value<size>* psymval)
{
  typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;

  Insntype* ip = reinterpret_cast<Insntype*>(view);
  Insntype insn1 = elfcpp::Swap<32, big_endian>::readval(ip);
  Insntype insn2 = elfcpp::Swap<32, big_endian>::readval(ip + 1);
  Insntype insn3 = elfcpp::Swap<32, big_endian>::readval(ip + 2);

  if (r_type == elfcpp::R_AARCH64_TLSGD_ADD_LO12_NC)
    {
      // This is the 2nd relocs, optimization should already have been
      // done.
      gold_assert((insn1 & 0xfff00000) == 0x91400000);
      return aarch64_reloc_funcs::STATUS_OKAY;
    }

  // The original sequence is -
  //   90000000        adrp    x0, 0 <main>
  //   91000000        add     x0, x0, #0x0
  //   94000000        bl      0 <__tls_get_addr>
  // optimized to sequence -
  //   d53bd040        mrs     x0, tpidr_el0
  //   91400000        add     x0, x0, #0x0, lsl #12
  //   91000000        add     x0, x0, #0x0

  // Unlike tls_ie_to_le, we change the 3 insns in one function call when we
  // encounter the first relocation "R_AARCH64_TLSGD_ADR_PAGE21". Because we
  // have to change "bl tls_get_addr", which does not have a corresponding tls
  // relocation type. So before proceeding, we need to make sure compiler
  // does not change the sequence.
  if(!(insn1 == 0x90000000      // adrp x0,0
       && insn2 == 0x91000000   // add x0, x0, #0x0
       && insn3 == 0x94000000)) // bl 0
    {
      // Ideally we should give up gd_to_le relaxation and do gd access.
      // However the gd_to_le relaxation decision has been made early
      // in the scan stage, where we did not allocate any GOT entry for
      // this symbol. Therefore we have to exit and report error now.
      gold_error(_("unexpected reloc insn sequence while relaxing "
		   "tls gd to le for reloc %u."), r_type);
      return aarch64_reloc_funcs::STATUS_BAD_RELOC;
    }

  // Write new insns.
  insn1 = 0xd53bd040;  // mrs x0, tpidr_el0
  insn2 = 0x91400000;  // add x0, x0, #0x0, lsl #12
  insn3 = 0x91000000;  // add x0, x0, #0x0
  elfcpp::Swap<32, big_endian>::writeval(ip, insn1);
  elfcpp::Swap<32, big_endian>::writeval(ip + 1, insn2);
  elfcpp::Swap<32, big_endian>::writeval(ip + 2, insn3);

  // Calculate tprel value.
  Output_segment* tls_segment = relinfo->layout->tls_segment();
  gold_assert(tls_segment != NULL);
  AArch64_address value = psymval->value(relinfo->object, 0);
  const elfcpp::Elf_Xword addend = rela.get_r_addend();
  AArch64_address aligned_tcb_size =
      align_address(target->tcb_size(), tls_segment->maximum_alignment());
  AArch64_address x = value + aligned_tcb_size;

  // After new insns are written, apply TLSLE relocs.
  const AArch64_reloc_property* rp1 =
      aarch64_reloc_property_table->get_reloc_property(
	  elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12);
  const AArch64_reloc_property* rp2 =
      aarch64_reloc_property_table->get_reloc_property(
	  elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12);
  gold_assert(rp1 != NULL && rp2 != NULL);

  typename aarch64_reloc_funcs::Status s1 =
      aarch64_reloc_funcs::template rela_general<32>(view + 4,
						     x,
						     addend,
						     rp1);
  if (s1 != aarch64_reloc_funcs::STATUS_OKAY)
    return s1;

  typename aarch64_reloc_funcs::Status s2 =
      aarch64_reloc_funcs::template rela_general<32>(view + 8,
						     x,
						     addend,
						     rp2);

  this->skip_call_tls_get_addr_ = true;
  return s2;
}  // End of tls_gd_to_le


template<int size, bool big_endian>
inline
typename AArch64_relocate_functions<size, big_endian>::Status
Target_aarch64<size, big_endian>::Relocate::tls_ld_to_le(
	     const Relocate_info<size, big_endian>* relinfo,
	     Target_aarch64<size, big_endian>* target,
	     const elfcpp::Rela<size, big_endian>& rela,
	     unsigned int r_type,
	     unsigned char* view,
	     const Symbol_value<size>* psymval)
{
  typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;

  Insntype* ip = reinterpret_cast<Insntype*>(view);
  Insntype insn1 = elfcpp::Swap<32, big_endian>::readval(ip);
  Insntype insn2 = elfcpp::Swap<32, big_endian>::readval(ip + 1);
  Insntype insn3 = elfcpp::Swap<32, big_endian>::readval(ip + 2);

  if (r_type == elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC)
    {
      // This is the 2nd relocs, optimization should already have been
      // done.
      gold_assert((insn1 & 0xfff00000) == 0x91400000);
      return aarch64_reloc_funcs::STATUS_OKAY;
    }

  // The original sequence is -
  //   90000000        adrp    x0, 0 <main>
  //   91000000        add     x0, x0, #0x0
  //   94000000        bl      0 <__tls_get_addr>
  // optimized to sequence -
  //   d53bd040        mrs     x0, tpidr_el0
  //   91400000        add     x0, x0, #0x0, lsl #12
  //   91000000        add     x0, x0, #0x0

  // Unlike tls_ie_to_le, we change the 3 insns in one function call when we
  // encounter the first relocation "R_AARCH64_TLSLD_ADR_PAGE21". Because we
  // have to change "bl tls_get_addr", which does not have a corresponding tls
  // relocation type. So before proceeding, we need to make sure compiler
  // does not change the sequence.
  if(!(insn1 == 0x90000000      // adrp x0,0
       && insn2 == 0x91000000   // add x0, x0, #0x0
       && insn3 == 0x94000000)) // bl 0
    {
      // Ideally we should give up gd_to_le relaxation and do gd access.
      // However the gd_to_le relaxation decision has been made early
      // in the scan stage, where we did not allocate any GOT entry for
      // this symbol. Therefore we have to exit and report error now.
      gold_error(_("unexpected reloc insn sequence while relaxing "
		   "tls gd to le for reloc %u."), r_type);
      return aarch64_reloc_funcs::STATUS_BAD_RELOC;
    }

  // Write new insns.
  insn1 = 0xd53bd040;  // mrs x0, tpidr_el0
  insn2 = 0x91400000;  // add x0, x0, #0x0, lsl #12
  insn3 = 0x91000000;  // add x0, x0, #0x0
  elfcpp::Swap<32, big_endian>::writeval(ip, insn1);
  elfcpp::Swap<32, big_endian>::writeval(ip + 1, insn2);
  elfcpp::Swap<32, big_endian>::writeval(ip + 2, insn3);

  // Calculate tprel value.
  Output_segment* tls_segment = relinfo->layout->tls_segment();
  gold_assert(tls_segment != NULL);
  AArch64_address value = psymval->value(relinfo->object, 0);
  const elfcpp::Elf_Xword addend = rela.get_r_addend();
  AArch64_address aligned_tcb_size =
      align_address(target->tcb_size(), tls_segment->maximum_alignment());
  AArch64_address x = value + aligned_tcb_size;

  // After new insns are written, apply TLSLE relocs.
  const AArch64_reloc_property* rp1 =
      aarch64_reloc_property_table->get_reloc_property(
	  elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12);
  const AArch64_reloc_property* rp2 =
      aarch64_reloc_property_table->get_reloc_property(
	  elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12);
  gold_assert(rp1 != NULL && rp2 != NULL);

  typename aarch64_reloc_funcs::Status s1 =
      aarch64_reloc_funcs::template rela_general<32>(view + 4,
						     x,
						     addend,
						     rp1);
  if (s1 != aarch64_reloc_funcs::STATUS_OKAY)
    return s1;

  typename aarch64_reloc_funcs::Status s2 =
      aarch64_reloc_funcs::template rela_general<32>(view + 8,
						     x,
						     addend,
						     rp2);

  this->skip_call_tls_get_addr_ = true;
  return s2;

}  // End of tls_ld_to_le

template<int size, bool big_endian>
inline
typename AArch64_relocate_functions<size, big_endian>::Status
Target_aarch64<size, big_endian>::Relocate::tls_ie_to_le(
	     const Relocate_info<size, big_endian>* relinfo,
	     Target_aarch64<size, big_endian>* target,
	     const elfcpp::Rela<size, big_endian>& rela,
	     unsigned int r_type,
	     unsigned char* view,
	     const Symbol_value<size>* psymval)
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
  typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;

  AArch64_address value = psymval->value(relinfo->object, 0);
  Output_segment* tls_segment = relinfo->layout->tls_segment();
  AArch64_address aligned_tcb_address =
      align_address(target->tcb_size(), tls_segment->maximum_alignment());
  const elfcpp::Elf_Xword addend = rela.get_r_addend();
  AArch64_address x = value + addend + aligned_tcb_address;
  // "x" is the offset to tp, we can only do this if x is within
  // range [0, 2^32-1]
  if (!(size == 32 || (size == 64 && (static_cast<uint64_t>(x) >> 32) == 0)))
    {
      gold_error(_("TLS variable referred by reloc %u is too far from TP."),
		 r_type);
      return aarch64_reloc_funcs::STATUS_BAD_RELOC;
    }

  Insntype* ip = reinterpret_cast<Insntype*>(view);
  Insntype insn = elfcpp::Swap<32, big_endian>::readval(ip);
  unsigned int regno;
  Insntype newinsn;
  if (r_type == elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21)
    {
      // Generate movz.
      regno = (insn & 0x1f);
      newinsn = (0xd2a00000 | regno) | (((x >> 16) & 0xffff) << 5);
    }
  else if (r_type == elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
    {
      // Generate movk.
      regno = (insn & 0x1f);
      gold_assert(regno == ((insn >> 5) & 0x1f));
      newinsn = (0xf2800000 | regno) | ((x & 0xffff) << 5);
    }
  else
    gold_unreachable();

  elfcpp::Swap<32, big_endian>::writeval(ip, newinsn);
  return aarch64_reloc_funcs::STATUS_OKAY;
}  // End of tls_ie_to_le


template<int size, bool big_endian>
inline
typename AArch64_relocate_functions<size, big_endian>::Status
Target_aarch64<size, big_endian>::Relocate::tls_desc_gd_to_le(
	     const Relocate_info<size, big_endian>* relinfo,
	     Target_aarch64<size, big_endian>* target,
	     const elfcpp::Rela<size, big_endian>& rela,
	     unsigned int r_type,
	     unsigned char* view,
	     const Symbol_value<size>* psymval)
{
  typedef typename elfcpp::Elf_types<size>::Elf_Addr AArch64_address;
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
  typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;

  // TLSDESC-GD sequence is like:
  //   adrp  x0, :tlsdesc:v1
  //   ldr   x1, [x0, #:tlsdesc_lo12:v1]
  //   add   x0, x0, :tlsdesc_lo12:v1
  //   .tlsdesccall    v1
  //   blr   x1
  // After desc_gd_to_le optimization, the sequence will be like:
  //   movz  x0, #0x0, lsl #16
  //   movk  x0, #0x10
  //   nop
  //   nop

  // Calculate tprel value.
  Output_segment* tls_segment = relinfo->layout->tls_segment();
  gold_assert(tls_segment != NULL);
  Insntype* ip = reinterpret_cast<Insntype*>(view);
  const elfcpp::Elf_Xword addend = rela.get_r_addend();
  AArch64_address value = psymval->value(relinfo->object, addend);
  AArch64_address aligned_tcb_size =
      align_address(target->tcb_size(), tls_segment->maximum_alignment());
  AArch64_address x = value + aligned_tcb_size;
  // x is the offset to tp, we can only do this if x is within range
  // [0, 2^32-1]. If x is out of range, fail and exit.
  if (size == 64 && (static_cast<uint64_t>(x) >> 32) != 0)
    {
      gold_error(_("TLS variable referred by reloc %u is too far from TP. "
		   "We Can't do gd_to_le relaxation.\n"), r_type);
      return aarch64_reloc_funcs::STATUS_BAD_RELOC;
    }
  Insntype newinsn;
  switch (r_type)
    {
    case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
    case elfcpp::R_AARCH64_TLSDESC_CALL:
      // Change to nop
      newinsn = 0xd503201f;
      break;

    case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
      // Change to movz.
      newinsn = 0xd2a00000 | (((x >> 16) & 0xffff) << 5);
      break;

    case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
      // Change to movk.
      newinsn = 0xf2800000 | ((x & 0xffff) << 5);
      break;

    default:
      gold_error(_("unsupported tlsdesc gd_to_le optimization on reloc %u"),
		 r_type);
      gold_unreachable();
    }
  elfcpp::Swap<32, big_endian>::writeval(ip, newinsn);
  return aarch64_reloc_funcs::STATUS_OKAY;
}  // End of tls_desc_gd_to_le


template<int size, bool big_endian>
inline
typename AArch64_relocate_functions<size, big_endian>::Status
Target_aarch64<size, big_endian>::Relocate::tls_desc_gd_to_ie(
	     const Relocate_info<size, big_endian>* /* relinfo */,
	     Target_aarch64<size, big_endian>* /* target */,
	     const elfcpp::Rela<size, big_endian>& rela,
	     unsigned int r_type,
	     unsigned char* view,
	     const Symbol_value<size>* /* psymval */,
	     typename elfcpp::Elf_types<size>::Elf_Addr got_entry_address,
	     typename elfcpp::Elf_types<size>::Elf_Addr address)
{
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype;
  typedef AArch64_relocate_functions<size, big_endian> aarch64_reloc_funcs;

  // TLSDESC-GD sequence is like:
  //   adrp  x0, :tlsdesc:v1
  //   ldr   x1, [x0, #:tlsdesc_lo12:v1]
  //   add   x0, x0, :tlsdesc_lo12:v1
  //   .tlsdesccall    v1
  //   blr   x1
  // After desc_gd_to_ie optimization, the sequence will be like:
  //   adrp  x0, :tlsie:v1
  //   ldr   x0, [x0, :tlsie_lo12:v1]
  //   nop
  //   nop

  Insntype* ip = reinterpret_cast<Insntype*>(view);
  const elfcpp::Elf_Xword addend = rela.get_r_addend();
  Insntype newinsn;
  switch (r_type)
    {
    case elfcpp::R_AARCH64_TLSDESC_ADD_LO12:
    case elfcpp::R_AARCH64_TLSDESC_CALL:
      // Change to nop
      newinsn = 0xd503201f;
      elfcpp::Swap<32, big_endian>::writeval(ip, newinsn);
      break;

    case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
      {
	return aarch64_reloc_funcs::adrp(view, got_entry_address + addend,
					 address);
      }
      break;

    case elfcpp::R_AARCH64_TLSDESC_LD64_LO12:
      {
       // Set ldr target register to be x0.
       Insntype insn = elfcpp::Swap<32, big_endian>::readval(ip);
       insn &= 0xffffffe0;
       elfcpp::Swap<32, big_endian>::writeval(ip, insn);
       // Do relocation.
	const AArch64_reloc_property* reloc_property =
	    aarch64_reloc_property_table->get_reloc_property(
	      elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
	return aarch64_reloc_funcs::template rela_general<32>(
		 view, got_entry_address, addend, reloc_property);
      }
      break;

    default:
      gold_error(_("Don't support tlsdesc gd_to_ie optimization on reloc %u"),
		 r_type);
      gold_unreachable();
    }
  return aarch64_reloc_funcs::STATUS_OKAY;
}  // End of tls_desc_gd_to_ie

// Relocate section data.

template<int size, bool big_endian>
void
Target_aarch64<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,
    typename elfcpp::Elf_types<size>::Elf_Addr address,
    section_size_type view_size,
    const Reloc_symbol_changes* reloc_symbol_changes)
{
  typedef Target_aarch64<size, big_endian> Aarch64;
  typedef typename Target_aarch64<size, big_endian>::Relocate AArch64_relocate;
  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, Aarch64, AArch64_relocate,
			 gold::Default_comdat_behavior, Classify_reloc>(
    relinfo,
    this,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    view,
    address,
    view_size,
    reloc_symbol_changes);
}

// Scan the relocs during a relocatable link.

template<int size, bool big_endian>
void
Target_aarch64<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 gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
      Classify_reloc;
  typedef gold::Default_scan_relocatable_relocs<Classify_reloc>
      Scan_relocatable_relocs;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>(
    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_aarch64<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);
}

// Relocate a section during a relocatable link.

template<int size, bool big_endian>
void
Target_aarch64<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* view,
    typename elfcpp::Elf_types<size>::Elf_Addr view_address,
    section_size_type view_size,
    unsigned char* reloc_view,
    section_size_type reloc_view_size)
{
  typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian>
      Classify_reloc;

  gold_assert(sh_type == elfcpp::SHT_RELA);

  gold::relocate_relocs<size, big_endian, Classify_reloc>(
    relinfo,
    prelocs,
    reloc_count,
    output_section,
    offset_in_output_section,
    view,
    view_address,
    view_size,
    reloc_view,
    reloc_view_size);
}


// Return whether this is a 3-insn erratum sequence.

template<int size, bool big_endian>
bool
Target_aarch64<size, big_endian>::is_erratum_843419_sequence(
    typename elfcpp::Swap<32,big_endian>::Valtype insn1,
    typename elfcpp::Swap<32,big_endian>::Valtype insn2,
    typename elfcpp::Swap<32,big_endian>::Valtype insn3)
{
  unsigned rt1, rt2;
  bool load, pair;

  // The 2nd insn is a single register load or store; or register pair
  // store.
  if (Insn_utilities::aarch64_mem_op_p(insn2, &rt1, &rt2, &pair, &load)
      && (!pair || (pair && !load)))
    {
      // The 3rd insn is a load or store instruction from the "Load/store
      // register (unsigned immediate)" encoding class, using Rn as the
      // base address register.
      if (Insn_utilities::aarch64_ldst_uimm(insn3)
	  && (Insn_utilities::aarch64_rn(insn3)
	      == Insn_utilities::aarch64_rd(insn1)))
	return true;
    }
  return false;
}


// Return whether this is a 835769 sequence.
// (Similarly implemented as in elfnn-aarch64.c.)

template<int size, bool big_endian>
bool
Target_aarch64<size, big_endian>::is_erratum_835769_sequence(
    typename elfcpp::Swap<32,big_endian>::Valtype insn1,
    typename elfcpp::Swap<32,big_endian>::Valtype insn2)
{
  uint32_t rt;
  uint32_t rt2 = 0;
  uint32_t rn;
  uint32_t rm;
  uint32_t ra;
  bool pair;
  bool load;

  if (Insn_utilities::aarch64_mlxl(insn2)
      && Insn_utilities::aarch64_mem_op_p (insn1, &rt, &rt2, &pair, &load))
    {
      /* Any SIMD memory op is independent of the subsequent MLA
	 by definition of the erratum.  */
      if (Insn_utilities::aarch64_bit(insn1, 26))
	return true;

      /* If not SIMD, check for integer memory ops and MLA relationship.  */
      rn = Insn_utilities::aarch64_rn(insn2);
      ra = Insn_utilities::aarch64_ra(insn2);
      rm = Insn_utilities::aarch64_rm(insn2);

      /* If this is a load and there's a true(RAW) dependency, we are safe
	 and this is not an erratum sequence.  */
      if (load &&
	  (rt == rn || rt == rm || rt == ra
	   || (pair && (rt2 == rn || rt2 == rm || rt2 == ra))))
	return false;

      /* We conservatively put out stubs for all other cases (including
	 writebacks).  */
      return true;
    }

  return false;
}


// Helper method to create erratum stub for ST_E_843419 and ST_E_835769.

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::create_erratum_stub(
    AArch64_relobj<size, big_endian>* relobj,
    unsigned int shndx,
    section_size_type erratum_insn_offset,
    Address erratum_address,
    typename Insn_utilities::Insntype erratum_insn,
    int erratum_type,
    unsigned int e843419_adrp_offset)
{
  gold_assert(erratum_type == ST_E_843419 || erratum_type == ST_E_835769);
  The_stub_table* stub_table = relobj->stub_table(shndx);
  gold_assert(stub_table != NULL);
  if (stub_table->find_erratum_stub(relobj,
				    shndx,
				    erratum_insn_offset) == NULL)
    {
      const int BPI = AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;
      The_erratum_stub* stub;
      if (erratum_type == ST_E_835769)
	stub = new The_erratum_stub(relobj, erratum_type, shndx,
				    erratum_insn_offset);
      else if (erratum_type == ST_E_843419)
	stub = new E843419_stub<size, big_endian>(
	    relobj, shndx, erratum_insn_offset, e843419_adrp_offset);
      else
	gold_unreachable();
      stub->set_erratum_insn(erratum_insn);
      stub->set_erratum_address(erratum_address);
      // For erratum ST_E_843419 and ST_E_835769, the destination address is
      // always the next insn after erratum insn.
      stub->set_destination_address(erratum_address + BPI);
      stub_table->add_erratum_stub(stub);
    }
}


// Scan erratum for section SHNDX range [output_address + span_start,
// output_address + span_end). Note here we do not share the code with
// scan_erratum_843419_span function, because for 843419 we optimize by only
// scanning the last few insns of a page, whereas for 835769, we need to scan
// every insn.

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::scan_erratum_835769_span(
    AArch64_relobj<size, big_endian>*  relobj,
    unsigned int shndx,
    const section_size_type span_start,
    const section_size_type span_end,
    unsigned char* input_view,
    Address output_address)
{
  typedef typename Insn_utilities::Insntype Insntype;

  const int BPI = AArch64_insn_utilities<big_endian>::BYTES_PER_INSN;

  // Adjust output_address and view to the start of span.
  output_address += span_start;
  input_view += span_start;

  section_size_type span_length = span_end - span_start;
  section_size_type offset = 0;
  for (offset = 0; offset + BPI < span_length; offset += BPI)
    {
      Insntype* ip = reinterpret_cast<Insntype*>(input_view + offset);
      Insntype insn1 = ip[0];
      Insntype insn2 = ip[1];
      if (is_erratum_835769_sequence(insn1, insn2))
	{
	  Insntype erratum_insn = insn2;
	  // "span_start + offset" is the offset for insn1. So for insn2, it is
	  // "span_start + offset + BPI".
	  section_size_type erratum_insn_offset = span_start + offset + BPI;
	  Address erratum_address = output_address + offset + BPI;
	  gold_info(_("Erratum 835769 found and fixed at \"%s\", "
			 "section %d, offset 0x%08x."),
		       relobj->name().c_str(), shndx,
		       (unsigned int)(span_start + offset));

	  this->create_erratum_stub(relobj, shndx,
				    erratum_insn_offset, erratum_address,
				    erratum_insn, ST_E_835769);
	  offset += BPI;  // Skip mac insn.
	}
    }
}  // End of "Target_aarch64::scan_erratum_835769_span".


// Scan erratum for section SHNDX range
// [output_address + span_start, output_address + span_end).

template<int size, bool big_endian>
void
Target_aarch64<size, big_endian>::scan_erratum_843419_span(
    AArch64_relobj<size, big_endian>*  relobj,
    unsigned int shndx,
    const section_size_type span_start,
    const section_size_type span_end,
    unsigned char* input_view,
    Address output_address)
{
  typedef typename Insn_utilities::Insntype Insntype;

  // Adjust output_address and view to the start of span.
  output_address += span_start;
  input_view += span_start;

  if ((output_address & 0x03) != 0)
    return;

  section_size_type offset = 0;
  section_size_type span_length = span_end - span_start;
  // The first instruction must be ending at 0xFF8 or 0xFFC.
  unsigned int page_offset = output_address & 0xFFF;
  // Make sure starting position, that is "output_address+offset",
  // starts at page position 0xff8 or 0xffc.
  if (page_offset < 0xff8)
    offset = 0xff8 - page_offset;
  while (offset + 3 * Insn_utilities::BYTES_PER_INSN <= span_length)
    {
      Insntype* ip = reinterpret_cast<Insntype*>(input_view + offset);
      Insntype insn1 = ip[0];
      if (Insn_utilities::is_adrp(insn1))
	{
	  Insntype insn2 = ip[1];
	  Insntype insn3 = ip[2];
	  Insntype erratum_insn;
	  unsigned insn_offset;
	  bool do_report = false;
	  if (is_erratum_843419_sequence(insn1, insn2, insn3))
	    {
	      do_report = true;
	      erratum_insn = insn3;
	      insn_offset = 2 * Insn_utilities::BYTES_PER_INSN;
	    }
	  else if (offset + 4 * Insn_utilities::BYTES_PER_INSN <= span_length)
	    {
	      // Optionally we can have an insn between ins2 and ins3
	      Insntype insn_opt = ip[2];
	      // And insn_opt must not be a branch.
	      if (!Insn_utilities::aarch64_b(insn_opt)
		  && !Insn_utilities::aarch64_bl(insn_opt)
		  && !Insn_utilities::aarch64_blr(insn_opt)
		  && !Insn_utilities::aarch64_br(insn_opt))
		{
		  // And insn_opt must not write to dest reg in insn1. However
		  // we do a conservative scan, which means we may fix/report
		  // more than necessary, but it doesn't hurt.

		  Insntype insn4 = ip[3];
		  if (is_erratum_843419_sequence(insn1, insn2, insn4))
		    {
		      do_report = true;
		      erratum_insn = insn4;
		      insn_offset = 3 * Insn_utilities::BYTES_PER_INSN;
		    }
		}
	    }
	  if (do_report)
	    {
	      unsigned int erratum_insn_offset =
		span_start + offset + insn_offset;
	      Address erratum_address =
		output_address + offset + insn_offset;
	      create_erratum_stub(relobj, shndx,
				  erratum_insn_offset, erratum_address,
				  erratum_insn, ST_E_843419,
				  span_start + offset);
	    }
	}

      // Advance to next candidate instruction. We only consider instruction
      // sequences starting at a page offset of 0xff8 or 0xffc.
      page_offset = (output_address + offset) & 0xfff;
      if (page_offset == 0xff8)
	offset += 4;
      else  // (page_offset == 0xffc), we move to next page's 0xff8.
	offset += 0xffc;
    }
}  // End of "Target_aarch64::scan_erratum_843419_span".


// The selector for aarch64 object files.

template<int size, bool big_endian>
class Target_selector_aarch64 : public Target_selector
{
 public:
  Target_selector_aarch64();

  virtual Target*
  do_instantiate_target()
  { return new Target_aarch64<size, big_endian>(); }
};

template<>
Target_selector_aarch64<32, true>::Target_selector_aarch64()
  : Target_selector(elfcpp::EM_AARCH64, 32, true,
		    "elf32-bigaarch64", "aarch64_elf32_be_vec")
{ }

template<>
Target_selector_aarch64<32, false>::Target_selector_aarch64()
  : Target_selector(elfcpp::EM_AARCH64, 32, false,
		    "elf32-littleaarch64", "aarch64_elf32_le_vec")
{ }

template<>
Target_selector_aarch64<64, true>::Target_selector_aarch64()
  : Target_selector(elfcpp::EM_AARCH64, 64, true,
		    "elf64-bigaarch64", "aarch64_elf64_be_vec")
{ }

template<>
Target_selector_aarch64<64, false>::Target_selector_aarch64()
  : Target_selector(elfcpp::EM_AARCH64, 64, false,
		    "elf64-littleaarch64", "aarch64_elf64_le_vec")
{ }

Target_selector_aarch64<32, true> target_selector_aarch64elf32b;
Target_selector_aarch64<32, false> target_selector_aarch64elf32;
Target_selector_aarch64<64, true> target_selector_aarch64elfb;
Target_selector_aarch64<64, false> target_selector_aarch64elf;

} // End anonymous namespace.
