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

// Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
// Written by Doug Kwan <dougkwan@google.com> based on the i386 code
// by Ian Lance Taylor <iant@google.com>.
// This file also contains borrowed and adapted code from
// bfd/elf32-arm.c.

// 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 <limits>
#include <cstdio>
#include <string>
#include <algorithm>
#include <map>
#include <utility>
#include <set>

#include "elfcpp.h"
#include "parameters.h"
#include "reloc.h"
#include "arm.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 "defstd.h"
#include "gc.h"
#include "attributes.h"
#include "arm-reloc-property.h"
#include "nacl.h"

namespace
{

using namespace gold;

template<bool big_endian>
class Output_data_plt_arm;

template<bool big_endian>
class Output_data_plt_arm_standard;

template<bool big_endian>
class Stub_table;

template<bool big_endian>
class Arm_input_section;

class Arm_exidx_cantunwind;

class Arm_exidx_merged_section;

class Arm_exidx_fixup;

template<bool big_endian>
class Arm_output_section;

class Arm_exidx_input_section;

template<bool big_endian>
class Arm_relobj;

template<bool big_endian>
class Arm_relocate_functions;

template<bool big_endian>
class Arm_output_data_got;

template<bool big_endian>
class Target_arm;

// For convenience.
typedef elfcpp::Elf_types<32>::Elf_Addr Arm_address;

// Maximum branch offsets for ARM, THUMB and THUMB2.
const int32_t ARM_MAX_FWD_BRANCH_OFFSET = ((((1 << 23) - 1) << 2) + 8);
const int32_t ARM_MAX_BWD_BRANCH_OFFSET = ((-((1 << 23) << 2)) + 8);
const int32_t THM_MAX_FWD_BRANCH_OFFSET = ((1 << 22) -2 + 4);
const int32_t THM_MAX_BWD_BRANCH_OFFSET = (-(1 << 22) + 4);
const int32_t THM2_MAX_FWD_BRANCH_OFFSET = (((1 << 24) - 2) + 4);
const int32_t THM2_MAX_BWD_BRANCH_OFFSET = (-(1 << 24) + 4);

// Thread Control Block size.
const size_t ARM_TCB_SIZE = 8;

// The arm target class.
//
// This is a very simple port of gold for ARM-EABI.  It is intended for
// supporting Android only for the time being.
//
// TODOs:
// - Implement all static relocation types documented in arm-reloc.def.
// - Make PLTs more flexible for different architecture features like
//   Thumb-2 and BE8.
// There are probably a lot more.

// Ideally we would like to avoid using global variables but this is used
// very in many places and sometimes in loops.  If we use a function
// returning a static instance of Arm_reloc_property_table, it will be very
// slow in an threaded environment since the static instance needs to be
// locked.  The pointer is below initialized in the
// Target::do_select_as_default_target() hook so that we do not spend time
// building the table if we are not linking ARM objects.
//
// An alternative is to to process the information in arm-reloc.def in
// compilation time and generate a representation of it in PODs only.  That
// way we can avoid initialization when the linker starts.

Arm_reloc_property_table* arm_reloc_property_table = NULL;

// Instruction template class.  This class is similar to the insn_sequence
// struct in bfd/elf32-arm.c.

class Insn_template
{
 public:
  // Types of instruction templates.
  enum Type
    {
      THUMB16_TYPE = 1,
      // THUMB16_SPECIAL_TYPE is used by sub-classes of Stub for instruction
      // templates with class-specific semantics.  Currently this is used
      // only by the Cortex_a8_stub class for handling condition codes in
      // conditional branches.
      THUMB16_SPECIAL_TYPE,
      THUMB32_TYPE,
      ARM_TYPE,
      DATA_TYPE
    };

  // Factory methods to create instruction templates in different formats.

  static const Insn_template
  thumb16_insn(uint32_t data)
  { return Insn_template(data, THUMB16_TYPE, elfcpp::R_ARM_NONE, 0); }

  // A Thumb conditional branch, in which the proper condition is inserted
  // when we build the stub.
  static const Insn_template
  thumb16_bcond_insn(uint32_t data)
  { return Insn_template(data, THUMB16_SPECIAL_TYPE, elfcpp::R_ARM_NONE, 1); }

  static const Insn_template
  thumb32_insn(uint32_t data)
  { return Insn_template(data, THUMB32_TYPE, elfcpp::R_ARM_NONE, 0); }

  static const Insn_template
  thumb32_b_insn(uint32_t data, int reloc_addend)
  {
    return Insn_template(data, THUMB32_TYPE, elfcpp::R_ARM_THM_JUMP24,
			 reloc_addend);
  }

  static const Insn_template
  arm_insn(uint32_t data)
  { return Insn_template(data, ARM_TYPE, elfcpp::R_ARM_NONE, 0); }

  static const Insn_template
  arm_rel_insn(unsigned data, int reloc_addend)
  { return Insn_template(data, ARM_TYPE, elfcpp::R_ARM_JUMP24, reloc_addend); }

  static const Insn_template
  data_word(unsigned data, unsigned int r_type, int reloc_addend)
  { return Insn_template(data, DATA_TYPE, r_type, reloc_addend); }

  // Accessors.  This class is used for read-only objects so no modifiers
  // are provided.

  uint32_t
  data() const
  { return this->data_; }

  // Return the instruction sequence type of this.
  Type
  type() const
  { return this->type_; }

  // Return the ARM relocation type of this.
  unsigned int
  r_type() const
  { return this->r_type_; }

  int32_t
  reloc_addend() const
  { return this->reloc_addend_; }

  // Return size of instruction template in bytes.
  size_t
  size() const;

  // Return byte-alignment of instruction template.
  unsigned
  alignment() const;

 private:
  // We make the constructor private to ensure that only the factory
  // methods are used.
  inline
  Insn_template(unsigned data, Type type, unsigned int r_type, int reloc_addend)
    : data_(data), type_(type), r_type_(r_type), reloc_addend_(reloc_addend)
  { }

  // Instruction specific data.  This is used to store information like
  // some of the instruction bits.
  uint32_t data_;
  // Instruction template type.
  Type type_;
  // Relocation type if there is a relocation or R_ARM_NONE otherwise.
  unsigned int r_type_;
  // Relocation addend.
  int32_t reloc_addend_;
};

// Macro for generating code to stub types. One entry per long/short
// branch stub

#define DEF_STUBS \
  DEF_STUB(long_branch_any_any) \
  DEF_STUB(long_branch_v4t_arm_thumb) \
  DEF_STUB(long_branch_thumb_only) \
  DEF_STUB(long_branch_v4t_thumb_thumb) \
  DEF_STUB(long_branch_v4t_thumb_arm) \
  DEF_STUB(short_branch_v4t_thumb_arm) \
  DEF_STUB(long_branch_any_arm_pic) \
  DEF_STUB(long_branch_any_thumb_pic) \
  DEF_STUB(long_branch_v4t_thumb_thumb_pic) \
  DEF_STUB(long_branch_v4t_arm_thumb_pic) \
  DEF_STUB(long_branch_v4t_thumb_arm_pic) \
  DEF_STUB(long_branch_thumb_only_pic) \
  DEF_STUB(a8_veneer_b_cond) \
  DEF_STUB(a8_veneer_b) \
  DEF_STUB(a8_veneer_bl) \
  DEF_STUB(a8_veneer_blx) \
  DEF_STUB(v4_veneer_bx)

// Stub types.

#define DEF_STUB(x) arm_stub_##x,
typedef enum
  {
    arm_stub_none,
    DEF_STUBS

    // First reloc stub type.
    arm_stub_reloc_first = arm_stub_long_branch_any_any,
    // Last  reloc stub type.
    arm_stub_reloc_last = arm_stub_long_branch_thumb_only_pic,

    // First Cortex-A8 stub type.
    arm_stub_cortex_a8_first = arm_stub_a8_veneer_b_cond,
    // Last Cortex-A8 stub type.
    arm_stub_cortex_a8_last = arm_stub_a8_veneer_blx,

    // Last stub type.
    arm_stub_type_last = arm_stub_v4_veneer_bx
  } Stub_type;
#undef DEF_STUB

// Stub template class.  Templates are meant to be read-only objects.
// A stub template for a stub type contains all read-only attributes
// common to all stubs of the same type.

class Stub_template
{
 public:
  Stub_template(Stub_type, const Insn_template*, size_t);

  ~Stub_template()
  { }

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

  // Return an array of instruction templates.
  const Insn_template*
  insns() const
  { return this->insns_; }

  // Return size of template in number of instructions.
  size_t
  insn_count() const
  { return this->insn_count_; }

  // Return size of template in bytes.
  size_t
  size() const
  { return this->size_; }

  // Return alignment of the stub template.
  unsigned
  alignment() const
  { return this->alignment_; }

  // Return whether entry point is in thumb mode.
  bool
  entry_in_thumb_mode() const
  { return this->entry_in_thumb_mode_; }

  // Return number of relocations in this template.
  size_t
  reloc_count() const
  { return this->relocs_.size(); }

  // Return index of the I-th instruction with relocation.
  size_t
  reloc_insn_index(size_t i) const
  {
    gold_assert(i < this->relocs_.size());
    return this->relocs_[i].first;
  }

  // Return the offset of the I-th instruction with relocation from the
  // beginning of the stub.
  section_size_type
  reloc_offset(size_t i) const
  {
    gold_assert(i < this->relocs_.size());
    return this->relocs_[i].second;
  }

 private:
  // This contains information about an instruction template with a relocation
  // and its offset from start of stub.
  typedef std::pair<size_t, section_size_type> Reloc;

  // A Stub_template may not be copied.  We want to share templates as much
  // as possible.
  Stub_template(const Stub_template&);
  Stub_template& operator=(const Stub_template&);

  // Stub type.
  Stub_type type_;
  // Points to an array of Insn_templates.
  const Insn_template* insns_;
  // Number of Insn_templates in insns_[].
  size_t insn_count_;
  // Size of templated instructions in bytes.
  size_t size_;
  // Alignment of templated instructions.
  unsigned alignment_;
  // Flag to indicate if entry is in thumb mode.
  bool entry_in_thumb_mode_;
  // A table of reloc instruction indices and offsets.  We can find these by
  // looking at the instruction templates but we pre-compute and then stash
  // them here for speed.
  std::vector<Reloc> relocs_;
};

//
// A class for code stubs.  This is a base class for different type of
// stubs used in the ARM target.
//

class Stub
{
 private:
  static const section_offset_type invalid_offset =
    static_cast<section_offset_type>(-1);

 public:
  Stub(const Stub_template* stub_template)
    : stub_template_(stub_template), offset_(invalid_offset)
  { }

  virtual
   ~Stub()
  { }

  // Return the stub template.
  const Stub_template*
  stub_template() const
  { return this->stub_template_; }

  // Return offset of code stub from beginning of its containing stub table.
  section_offset_type
  offset() const
  {
    gold_assert(this->offset_ != invalid_offset);
    return this->offset_;
  }

  // Set offset of code stub from beginning of its containing stub table.
  void
  set_offset(section_offset_type offset)
  { this->offset_ = offset; }

  // Return the relocation target address of the i-th relocation in the
  // stub.  This must be defined in a child class.
  Arm_address
  reloc_target(size_t i)
  { return this->do_reloc_target(i); }

  // Write a stub at output VIEW.  BIG_ENDIAN select how a stub is written.
  void
  write(unsigned char* view, section_size_type view_size, bool big_endian)
  { this->do_write(view, view_size, big_endian); }

  // Return the instruction for THUMB16_SPECIAL_TYPE instruction template
  // for the i-th instruction.
  uint16_t
  thumb16_special(size_t i)
  { return this->do_thumb16_special(i); }

 protected:
  // This must be defined in the child class.
  virtual Arm_address
  do_reloc_target(size_t) = 0;

  // This may be overridden in the child class.
  virtual void
  do_write(unsigned char* view, section_size_type view_size, bool big_endian)
  {
    if (big_endian)
      this->do_fixed_endian_write<true>(view, view_size);
    else
      this->do_fixed_endian_write<false>(view, view_size);
  }

  // This must be overridden if a child class uses the THUMB16_SPECIAL_TYPE
  // instruction template.
  virtual uint16_t
  do_thumb16_special(size_t)
  { gold_unreachable(); }

 private:
  // A template to implement do_write.
  template<bool big_endian>
  void inline
  do_fixed_endian_write(unsigned char*, section_size_type);

  // Its template.
  const Stub_template* stub_template_;
  // Offset within the section of containing this stub.
  section_offset_type offset_;
};

// Reloc stub class.  These are stubs we use to fix up relocation because
// of limited branch ranges.

class Reloc_stub : public Stub
{
 public:
  static const unsigned int invalid_index = static_cast<unsigned int>(-1);
  // We assume we never jump to this address.
  static const Arm_address invalid_address = static_cast<Arm_address>(-1);

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

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

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

  // Determine stub type for a branch of a relocation of R_TYPE going
  // from BRANCH_ADDRESS to BRANCH_TARGET.  If TARGET_IS_THUMB is set,
  // the branch target is a thumb instruction.  TARGET is used for look
  // up ARM-specific linker settings.
  static Stub_type
  stub_type_for_reloc(unsigned int r_type, Arm_address branch_address,
		      Arm_address branch_target, bool target_is_thumb);

  // Reloc_stub key.  A key is logically a triplet of a stub type, a symbol
  // and an addend.  Since we treat global and local symbol differently, we
  // use a Symbol object for a global symbol and a object-index pair for
  // a local symbol.
  class Key
  {
   public:
    // If SYMBOL is not null, this is a global symbol, we ignore RELOBJ and
    // R_SYM.  Otherwise, this is a local symbol and RELOBJ must non-NULL
    // and R_SYM must not be invalid_index.
    Key(Stub_type stub_type, const Symbol* symbol, const Relobj* relobj,
	unsigned int r_sym, int32_t addend)
      : stub_type_(stub_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()
    { }

    // Accessors: Keys are meant to be read-only object so no modifiers are
    // provided.

    // Return stub type.
    Stub_type
    stub_type() const
    { return this->stub_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->stub_type_ == k.stub_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
    {
      return (this->stub_type_
	      ^ this->r_sym_
	      ^ gold::string_hash<char>(
		    (this->r_sym_ != Reloc_stub::invalid_index)
		    ? this->u_.relobj->name().c_str()
		    : this->u_.symbol->name())
	      ^ this->addend_);
    }

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

    // Name of key.  This is mainly for debugging.
    std::string
    name() const;

   private:
    // Stub type.
    Stub_type stub_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_;
  };

 protected:
  // Reloc_stubs are created via a stub factory.  So these are protected.
  Reloc_stub(const Stub_template* stub_template)
    : Stub(stub_template), destination_address_(invalid_address)
  { }

  ~Reloc_stub()
  { }

  friend class Stub_factory;

  // Return the relocation target address of the i-th relocation in the
  // stub.
  Arm_address
  do_reloc_target(size_t i)
  {
    // All reloc stub have only one relocation.
    gold_assert(i == 0);
    return this->destination_address_;
  }

 private:
  // Address of destination.
  Arm_address destination_address_;
};

// Cortex-A8 stub class.  We need a Cortex-A8 stub to redirect any 32-bit
// THUMB branch that meets the following conditions:
//
// 1. The branch straddles across a page boundary. i.e. lower 12-bit of
//    branch address is 0xffe.
// 2. The branch target address is in the same page as the first word of the
//    branch.
// 3. The branch follows a 32-bit instruction which is not a branch.
//
// To do the fix up, we need to store the address of the branch instruction
// and its target at least.  We also need to store the original branch
// instruction bits for the condition code in a conditional branch.  The
// condition code is used in a special instruction template.  We also want
// to identify input sections needing Cortex-A8 workaround quickly.  We store
// extra information about object and section index of the code section
// containing a branch being fixed up.  The information is used to mark
// the code section when we finalize the Cortex-A8 stubs.
//

class Cortex_a8_stub : public Stub
{
 public:
  ~Cortex_a8_stub()
  { }

  // Return the object of the code section containing the branch being fixed
  // up.
  Relobj*
  relobj() const
  { return this->relobj_; }

  // Return the section index of the code section containing the branch being
  // fixed up.
  unsigned int
  shndx() const
  { return this->shndx_; }

  // Return the source address of stub.  This is the address of the original
  // branch instruction.  LSB is 1 always set to indicate that it is a THUMB
  // instruction.
  Arm_address
  source_address() const
  { return this->source_address_; }

  // Return the destination address of the stub.  This is the branch taken
  // address of the original branch instruction.  LSB is 1 if it is a THUMB
  // instruction address.
  Arm_address
  destination_address() const
  { return this->destination_address_; }

  // Return the instruction being fixed up.
  uint32_t
  original_insn() const
  { return this->original_insn_; }

 protected:
  // Cortex_a8_stubs are created via a stub factory.  So these are protected.
  Cortex_a8_stub(const Stub_template* stub_template, Relobj* relobj,
		 unsigned int shndx, Arm_address source_address,
		 Arm_address destination_address, uint32_t original_insn)
    : Stub(stub_template), relobj_(relobj), shndx_(shndx),
      source_address_(source_address | 1U),
      destination_address_(destination_address),
      original_insn_(original_insn)
  { }

  friend class Stub_factory;

  // Return the relocation target address of the i-th relocation in the
  // stub.
  Arm_address
  do_reloc_target(size_t i)
  {
    if (this->stub_template()->type() == arm_stub_a8_veneer_b_cond)
      {
	// The conditional branch veneer has two relocations.
	gold_assert(i < 2);
	return i == 0 ? this->source_address_ + 4 : this->destination_address_;
      }
    else
      {
	// All other Cortex-A8 stubs have only one relocation.
	gold_assert(i == 0);
	return this->destination_address_;
      }
  }

  // Return an instruction for the THUMB16_SPECIAL_TYPE instruction template.
  uint16_t
  do_thumb16_special(size_t);

 private:
  // Object of the code section containing the branch being fixed up.
  Relobj* relobj_;
  // Section index of the code section containing the branch begin fixed up.
  unsigned int shndx_;
  // Source address of original branch.
  Arm_address source_address_;
  // Destination address of the original branch.
  Arm_address destination_address_;
  // Original branch instruction.  This is needed for copying the condition
  // code from a condition branch to its stub.
  uint32_t original_insn_;
};

// ARMv4 BX Rx branch relocation stub class.
class Arm_v4bx_stub : public Stub
{
 public:
  ~Arm_v4bx_stub()
  { }

  // Return the associated register.
  uint32_t
  reg() const
  { return this->reg_; }

 protected:
  // Arm V4BX stubs are created via a stub factory.  So these are protected.
  Arm_v4bx_stub(const Stub_template* stub_template, const uint32_t reg)
    : Stub(stub_template), reg_(reg)
  { }

  friend class Stub_factory;

  // Return the relocation target address of the i-th relocation in the
  // stub.
  Arm_address
  do_reloc_target(size_t)
  { gold_unreachable(); }

  // This may be overridden in the child class.
  virtual void
  do_write(unsigned char* view, section_size_type view_size, bool big_endian)
  {
    if (big_endian)
      this->do_fixed_endian_v4bx_write<true>(view, view_size);
    else
      this->do_fixed_endian_v4bx_write<false>(view, view_size);
  }

 private:
  // A template to implement do_write.
  template<bool big_endian>
  void inline
  do_fixed_endian_v4bx_write(unsigned char* view, section_size_type)
  {
    const Insn_template* insns = this->stub_template()->insns();
    elfcpp::Swap<32, big_endian>::writeval(view,
					   (insns[0].data()
					   + (this->reg_ << 16)));
    view += insns[0].size();
    elfcpp::Swap<32, big_endian>::writeval(view,
					   (insns[1].data() + this->reg_));
    view += insns[1].size();
    elfcpp::Swap<32, big_endian>::writeval(view,
					   (insns[2].data() + this->reg_));
  }

  // A register index (r0-r14), which is associated with the stub.
  uint32_t reg_;
};

// Stub factory class.

class Stub_factory
{
 public:
  // Return the unique instance of this class.
  static const Stub_factory&
  get_instance()
  {
    static Stub_factory singleton;
    return singleton;
  }

  // Make a relocation stub.
  Reloc_stub*
  make_reloc_stub(Stub_type stub_type) const
  {
    gold_assert(stub_type >= arm_stub_reloc_first
		&& stub_type <= arm_stub_reloc_last);
    return new Reloc_stub(this->stub_templates_[stub_type]);
  }

  // Make a Cortex-A8 stub.
  Cortex_a8_stub*
  make_cortex_a8_stub(Stub_type stub_type, Relobj* relobj, unsigned int shndx,
		      Arm_address source, Arm_address destination,
		      uint32_t original_insn) const
  {
    gold_assert(stub_type >= arm_stub_cortex_a8_first
		&& stub_type <= arm_stub_cortex_a8_last);
    return new Cortex_a8_stub(this->stub_templates_[stub_type], relobj, shndx,
			      source, destination, original_insn);
  }

  // Make an ARM V4BX relocation stub.
  // This method creates a stub from the arm_stub_v4_veneer_bx template only.
  Arm_v4bx_stub*
  make_arm_v4bx_stub(uint32_t reg) const
  {
    gold_assert(reg < 0xf);
    return new Arm_v4bx_stub(this->stub_templates_[arm_stub_v4_veneer_bx],
			     reg);
  }

 private:
  // Constructor and destructor are protected since we only return a single
  // instance created in Stub_factory::get_instance().

  Stub_factory();

  // A Stub_factory may not be copied since it is a singleton.
  Stub_factory(const Stub_factory&);
  Stub_factory& operator=(Stub_factory&);

  // Stub templates.  These are initialized in the constructor.
  const Stub_template* stub_templates_[arm_stub_type_last+1];
};

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

template<bool big_endian>
class Stub_table : public Output_data
{
 public:
  Stub_table(Arm_input_section<big_endian>* owner)
    : Output_data(), owner_(owner), reloc_stubs_(), reloc_stubs_size_(0),
      reloc_stubs_addralign_(1), cortex_a8_stubs_(), arm_v4bx_stubs_(0xf),
      prev_data_size_(0), prev_addralign_(1)
  { }

  ~Stub_table()
  { }

  // Owner of this stub table.
  Arm_input_section<big_endian>*
  owner() const
  { return this->owner_; }

  // Whether this stub table is empty.
  bool
  empty() const
  {
    return (this->reloc_stubs_.empty()
	    && this->cortex_a8_stubs_.empty()
	    && this->arm_v4bx_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(Reloc_stub* stub, const Reloc_stub::Key& key)
  {
    const Stub_template* stub_template = stub->stub_template();
    gold_assert(stub_template->type() == key.stub_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.
    uint64_t align = stub_template->alignment();
    this->reloc_stubs_size_ = align_address(this->reloc_stubs_size_, align);
    stub->set_offset(this->reloc_stubs_size_);
    this->reloc_stubs_size_ += stub_template->size();
    this->reloc_stubs_addralign_ =
      std::max(this->reloc_stubs_addralign_, align);
  }

  // Add a Cortex-A8 STUB that fixes up a THUMB branch at ADDRESS.
  // The caller is responsible for avoiding addition if a STUB with the same
  // address has already been added.
  void
  add_cortex_a8_stub(Arm_address address, Cortex_a8_stub* stub)
  {
    std::pair<Arm_address, Cortex_a8_stub*> value(address, stub);
    this->cortex_a8_stubs_.insert(value);
  }

  // Add an ARM V4BX relocation stub. A register index will be retrieved
  // from the stub.
  void
  add_arm_v4bx_stub(Arm_v4bx_stub* stub)
  {
    gold_assert(stub != NULL && this->arm_v4bx_stubs_[stub->reg()] == NULL);
    this->arm_v4bx_stubs_[stub->reg()] = stub;
  }

  // Remove all Cortex-A8 stubs.
  void
  remove_all_cortex_a8_stubs();

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

  // Look up an arm v4bx relocation stub using the register index.
  // Return NULL if there is none.
  Arm_v4bx_stub*
  find_arm_v4bx_stub(const uint32_t reg) const
  {
    gold_assert(reg < 0xf);
    return this->arm_v4bx_stubs_[reg];
  }

  // Relocate stubs in this stub table.
  void
  relocate_stubs(const Relocate_info<32, big_endian>*,
		 Target_arm<big_endian>*, Output_section*,
		 unsigned char*, Arm_address, section_size_type);

  // Update data size and alignment at the end of a relaxation pass.  Return
  // true if either data size or alignment is different from that of the
  // previous relaxation pass.
  bool
  update_data_size_and_addralign();

  // Finalize stubs.  Set the offsets of all stubs and mark input sections
  // needing the Cortex-A8 workaround.
  void
  finalize_stubs();

  // Apply Cortex-A8 workaround to an address range.
  void
  apply_cortex_a8_workaround_to_address_range(Target_arm<big_endian>*,
					      unsigned char*, Arm_address,
					      section_size_type);

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

  // Return the required alignment.
  uint64_t
  do_addralign() const
  { return this->prev_addralign_; }

  // 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(Stub*, const Relocate_info<32, big_endian>*,
		Target_arm<big_endian>*, Output_section*,
		unsigned char*, Arm_address, section_size_type);

  // Unordered map of relocation stubs.
  typedef
    Unordered_map<Reloc_stub::Key, Reloc_stub*, Reloc_stub::Key::hash,
		  Reloc_stub::Key::equal_to>
    Reloc_stub_map;

  // List of Cortex-A8 stubs ordered by addresses of branches being
  // fixed up in output.
  typedef std::map<Arm_address, Cortex_a8_stub*> Cortex_a8_stub_list;
  // List of Arm V4BX relocation stubs ordered by associated registers.
  typedef std::vector<Arm_v4bx_stub*> Arm_v4bx_stub_list;

  // Owner of this stub table.
  Arm_input_section<big_endian>* owner_;
  // The relocation stubs.
  Reloc_stub_map reloc_stubs_;
  // Size of reloc stubs.
  off_t reloc_stubs_size_;
  // Maximum address alignment of reloc stubs.
  uint64_t reloc_stubs_addralign_;
  // The cortex_a8_stubs.
  Cortex_a8_stub_list cortex_a8_stubs_;
  // The Arm V4BX relocation stubs.
  Arm_v4bx_stub_list arm_v4bx_stubs_;
  // data size of this in the previous pass.
  off_t prev_data_size_;
  // address alignment of this in the previous pass.
  uint64_t prev_addralign_;
};

// Arm_exidx_cantunwind class.  This represents an EXIDX_CANTUNWIND entry
// we add to the end of an EXIDX input section that goes into the output.

class Arm_exidx_cantunwind : public Output_section_data
{
 public:
  Arm_exidx_cantunwind(Relobj* relobj, unsigned int shndx)
    : Output_section_data(8, 4, true), relobj_(relobj), shndx_(shndx)
  { }

  // Return the object containing the section pointed by this.
  Relobj*
  relobj() const
  { return this->relobj_; }

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

 protected:
  void
  do_write(Output_file* of)
  {
    if (parameters->target().is_big_endian())
      this->do_fixed_endian_write<true>(of);
    else
      this->do_fixed_endian_write<false>(of);
  }

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

 private:
  // Implement do_write for a given endianness.
  template<bool big_endian>
  void inline
  do_fixed_endian_write(Output_file*);

  // The object containing the section pointed by this.
  Relobj* relobj_;
  // The section index of the section pointed by this.
  unsigned int shndx_;
};

// During EXIDX coverage fix-up, we compact an EXIDX section.  The
// Offset map is used to map input section offset within the EXIDX section
// to the output offset from the start of this EXIDX section.

typedef std::map<section_offset_type, section_offset_type>
	Arm_exidx_section_offset_map;

// Arm_exidx_merged_section class.  This represents an EXIDX input section
// with some of its entries merged.

class Arm_exidx_merged_section : public Output_relaxed_input_section
{
 public:
  // Constructor for Arm_exidx_merged_section.
  // EXIDX_INPUT_SECTION points to the unmodified EXIDX input section.
  // SECTION_OFFSET_MAP points to a section offset map describing how
  // parts of the input section are mapped to output.  DELETED_BYTES is
  // the number of bytes deleted from the EXIDX input section.
  Arm_exidx_merged_section(
      const Arm_exidx_input_section& exidx_input_section,
      const Arm_exidx_section_offset_map& section_offset_map,
      uint32_t deleted_bytes);

  // Build output contents.
  void
  build_contents(const unsigned char*, section_size_type);

  // Return the original EXIDX input section.
  const Arm_exidx_input_section&
  exidx_input_section() const
  { return this->exidx_input_section_; }

  // Return the section offset map.
  const Arm_exidx_section_offset_map&
  section_offset_map() const
  { return this->section_offset_map_; }

 protected:
  // Write merged section into file OF.
  void
  do_write(Output_file* of);

  bool
  do_output_offset(const Relobj*, unsigned int, section_offset_type,
		  section_offset_type*) const;

 private:
  // Original EXIDX input section.
  const Arm_exidx_input_section& exidx_input_section_;
  // Section offset map.
  const Arm_exidx_section_offset_map& section_offset_map_;
  // Merged section contents.  We need to keep build the merged section
  // and save it here to avoid accessing the original EXIDX section when
  // we cannot lock the sections' object.
  unsigned char* section_contents_;
};

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

template<bool big_endian>
class Arm_input_section : public Output_relaxed_input_section
{
 public:
  Arm_input_section(Relobj* relobj, unsigned int shndx)
    : Output_relaxed_input_section(relobj, shndx, 1),
      original_addralign_(1), original_size_(0), stub_table_(NULL),
      original_contents_(NULL)
  { }

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

  // Initialize.
  void
  init();

  // 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 stub table.
  Stub_table<big_endian>*
  stub_table() const
  { return this->stub_table_; }

  // Set the stub_table.
  void
  set_stub_table(Stub_table<big_endian>* stub_table)
  { this->stub_table_ = stub_table; }

  // Downcast a base pointer to an Arm_input_section pointer.  This is
  // not type-safe but we only use Arm_input_section not the base class.
  static Arm_input_section<big_endian>*
  as_arm_input_section(Output_relaxed_input_section* poris)
  { return static_cast<Arm_input_section<big_endian>*>(poris); }

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

 protected:
  // Write data to output file.
  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.
  Arm_input_section(const Arm_input_section&);
  Arm_input_section& operator=(const Arm_input_section&);

  // Address alignment of the original input section.
  uint32_t original_addralign_;
  // Section size of the original input section.
  uint32_t original_size_;
  // Stub table.
  Stub_table<big_endian>* 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_;
};

// Arm_exidx_fixup class.  This is used to define a number of methods
// and keep states for fixing up EXIDX coverage.

class Arm_exidx_fixup
{
 public:
  Arm_exidx_fixup(Output_section* exidx_output_section,
		  bool merge_exidx_entries = true)
    : exidx_output_section_(exidx_output_section), last_unwind_type_(UT_NONE),
      last_inlined_entry_(0), last_input_section_(NULL),
      section_offset_map_(NULL), first_output_text_section_(NULL),
      merge_exidx_entries_(merge_exidx_entries)
  { }

  ~Arm_exidx_fixup()
  { delete this->section_offset_map_; }

  // Process an EXIDX section for entry merging.  SECTION_CONTENTS points
  // to the EXIDX contents and SECTION_SIZE is the size of the contents. Return
  // number of bytes to be deleted in output.  If parts of the input EXIDX
  // section are merged a heap allocated Arm_exidx_section_offset_map is store
  // in the located PSECTION_OFFSET_MAP.   The caller owns the map and is
  // responsible for releasing it.
  template<bool big_endian>
  uint32_t
  process_exidx_section(const Arm_exidx_input_section* exidx_input_section,
			const unsigned char* section_contents,
			section_size_type section_size,
			Arm_exidx_section_offset_map** psection_offset_map);

  // Append an EXIDX_CANTUNWIND entry pointing at the end of the last
  // input section, if there is not one already.
  void
  add_exidx_cantunwind_as_needed();

  // Return the output section for the text section which is linked to the
  // first exidx input in output.
  Output_section*
  first_output_text_section() const
  { return this->first_output_text_section_; }

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

  // Type of EXIDX unwind entry.
  enum Unwind_type
  {
    // No type.
    UT_NONE,
    // EXIDX_CANTUNWIND.
    UT_EXIDX_CANTUNWIND,
    // Inlined entry.
    UT_INLINED_ENTRY,
    // Normal entry.
    UT_NORMAL_ENTRY,
  };

  // Process an EXIDX entry.  We only care about the second word of the
  // entry.  Return true if the entry can be deleted.
  bool
  process_exidx_entry(uint32_t second_word);

  // Update the current section offset map during EXIDX section fix-up.
  // If there is no map, create one.  INPUT_OFFSET is the offset of a
  // reference point, DELETED_BYTES is the number of deleted by in the
  // section so far.  If DELETE_ENTRY is true, the reference point and
  // all offsets after the previous reference point are discarded.
  void
  update_offset_map(section_offset_type input_offset,
		    section_size_type deleted_bytes, bool delete_entry);

  // EXIDX output section.
  Output_section* exidx_output_section_;
  // Unwind type of the last EXIDX entry processed.
  Unwind_type last_unwind_type_;
  // Last seen inlined EXIDX entry.
  uint32_t last_inlined_entry_;
  // Last processed EXIDX input section.
  const Arm_exidx_input_section* last_input_section_;
  // Section offset map created in process_exidx_section.
  Arm_exidx_section_offset_map* section_offset_map_;
  // Output section for the text section which is linked to the first exidx
  // input in output.
  Output_section* first_output_text_section_;

  bool merge_exidx_entries_;
};

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

template<bool big_endian>
class Arm_output_section : public Output_section
{
 public:
  typedef std::vector<std::pair<Relobj*, unsigned int> > Text_section_list;

  // We need to force SHF_LINK_ORDER in a SHT_ARM_EXIDX section.
  Arm_output_section(const char* name, elfcpp::Elf_Word type,
		     elfcpp::Elf_Xword flags)
    : Output_section(name, type,
		     (type == elfcpp::SHT_ARM_EXIDX
		      ? flags | elfcpp::SHF_LINK_ORDER
		      : flags))
  {
    if (type == elfcpp::SHT_ARM_EXIDX)
      this->set_always_keeps_input_sections();
  }

  ~Arm_output_section()
  { }

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

  // Downcast a base pointer to an Arm_output_section pointer.  This is
  // not type-safe but we only use Arm_output_section not the base class.
  static Arm_output_section<big_endian>*
  as_arm_output_section(Output_section* os)
  { return static_cast<Arm_output_section<big_endian>*>(os); }

  // Append all input text sections in this into LIST.
  void
  append_text_sections_to_list(Text_section_list* list);

  // Fix EXIDX coverage of this EXIDX output section.  SORTED_TEXT_SECTION
  // is a list of text input sections sorted in ascending order of their
  // output addresses.
  void
  fix_exidx_coverage(Layout* layout,
		     const Text_section_list& sorted_text_section,
		     Symbol_table* symtab,
		     bool merge_exidx_entries,
		     const Task* task);

  // Link an EXIDX section into its corresponding text section.
  void
  set_exidx_section_link();

 private:
  // For convenience.
  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,
			 Target_arm<big_endian>*,
			 std::vector<Output_relaxed_input_section*>*,
			 const Task* task);
};

// Arm_exidx_input_section class.  This represents an EXIDX input section.

class Arm_exidx_input_section
{
 public:
  static const section_offset_type invalid_offset =
    static_cast<section_offset_type>(-1);

  Arm_exidx_input_section(Relobj* relobj, unsigned int shndx,
			  unsigned int link, uint32_t size,
			  uint32_t addralign, uint32_t text_size)
    : relobj_(relobj), shndx_(shndx), link_(link), size_(size),
      addralign_(addralign), text_size_(text_size), has_errors_(false)
  { }

  ~Arm_exidx_input_section()
  { }

  // Accessors:  This is a read-only class.

  // Return the object containing this EXIDX input section.
  Relobj*
  relobj() const
  { return this->relobj_; }

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

  // Return the section index of linked text section in the same object.
  unsigned int
  link() const
  { return this->link_; }

  // Return size of the EXIDX input section.
  uint32_t
  size() const
  { return this->size_; }

  // Return address alignment of EXIDX input section.
  uint32_t
  addralign() const
  { return this->addralign_; }

  // Return size of the associated text input section.
  uint32_t
  text_size() const
  { return this->text_size_; }

  // Whether there are any errors in the EXIDX input section.
  bool
  has_errors() const
  { return this->has_errors_; }

  // Set has-errors flag.
  void
  set_has_errors()
  { this->has_errors_ = true; }

 private:
  // Object containing this.
  Relobj* relobj_;
  // Section index of this.
  unsigned int shndx_;
  // text section linked to this in the same object.
  unsigned int link_;
  // Size of this.  For ARM 32-bit is sufficient.
  uint32_t size_;
  // Address alignment of this.  For ARM 32-bit is sufficient.
  uint32_t addralign_;
  // Size of associated text section.
  uint32_t text_size_;
  // Whether this has any errors.
  bool has_errors_;
};

// Arm_relobj class.

template<bool big_endian>
class Arm_relobj : public Sized_relobj_file<32, big_endian>
{
 public:
  static const Arm_address invalid_address = static_cast<Arm_address>(-1);

  Arm_relobj(const std::string& name, Input_file* input_file, off_t offset,
	     const typename elfcpp::Ehdr<32, big_endian>& ehdr)
    : Sized_relobj_file<32, big_endian>(name, input_file, offset, ehdr),
      stub_tables_(), local_symbol_is_thumb_function_(),
      attributes_section_data_(NULL), mapping_symbols_info_(),
      section_has_cortex_a8_workaround_(NULL), exidx_section_map_(),
      output_local_symbol_count_needs_update_(false),
      merge_flags_and_attributes_(true)
  { }

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

  // Return the stub table of the SHNDX-th section if there is one.
  Stub_table<big_endian>*
  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, Stub_table<big_endian>* stub_table)
  {
    gold_assert(shndx < this->stub_tables_.size());
    this->stub_tables_[shndx] = stub_table;
  }

  // Whether a local symbol is a THUMB function.  R_SYM is the symbol table
  // index.  This is only valid after do_count_local_symbol is called.
  bool
  local_symbol_is_thumb_function(unsigned int r_sym) const
  {
    gold_assert(r_sym < this->local_symbol_is_thumb_function_.size());
    return this->local_symbol_is_thumb_function_[r_sym];
  }

  // Scan all relocation sections for stub generation.
  void
  scan_sections_for_stubs(Target_arm<big_endian>*, const Symbol_table*,
			  const Layout*);

  // 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_section_offset(shndx, -1ULL);
    this->set_relocs_must_follow_section_writes();
  }

  // Downcast a base pointer to an Arm_relobj pointer.  This is
  // not type-safe but we only use Arm_relobj not the base class.
  static Arm_relobj<big_endian>*
  as_arm_relobj(Relobj* relobj)
  { return static_cast<Arm_relobj<big_endian>*>(relobj); }

  // Processor-specific flags in ELF file header.  This is valid only after
  // reading symbols.
  elfcpp::Elf_Word
  processor_specific_flags() const
  { return this->processor_specific_flags_; }

  // Attribute section data  This is the contents of the .ARM.attribute section
  // if there is one.
  const Attributes_section_data*
  attributes_section_data() const
  { return this->attributes_section_data_; }

  // Mapping symbol location.
  typedef std::pair<unsigned int, Arm_address> Mapping_symbol_position;

  // Functor for STL container.
  struct Mapping_symbol_position_less
  {
    bool
    operator()(const Mapping_symbol_position& p1,
	       const Mapping_symbol_position& p2) const
    {
      return (p1.first < p2.first
	      || (p1.first == p2.first && p1.second < p2.second));
    }
  };

  // We only care about the first character of a mapping symbol, so
  // we only store that instead of the whole symbol name.
  typedef std::map<Mapping_symbol_position, char,
		   Mapping_symbol_position_less> Mapping_symbols_info;

  // Whether a section contains any Cortex-A8 workaround.
  bool
  section_has_cortex_a8_workaround(unsigned int shndx) const
  {
    return (this->section_has_cortex_a8_workaround_ != NULL
	    && (*this->section_has_cortex_a8_workaround_)[shndx]);
  }

  // Mark a section that has Cortex-A8 workaround.
  void
  mark_section_for_cortex_a8_workaround(unsigned int shndx)
  {
    if (this->section_has_cortex_a8_workaround_ == NULL)
      this->section_has_cortex_a8_workaround_ =
	new std::vector<bool>(this->shnum(), false);
    (*this->section_has_cortex_a8_workaround_)[shndx] = true;
  }

  // Return the EXIDX section of an text section with index SHNDX or NULL
  // if the text section has no associated EXIDX section.
  const Arm_exidx_input_section*
  exidx_input_section_by_link(unsigned int shndx) const
  {
    Exidx_section_map::const_iterator p = this->exidx_section_map_.find(shndx);
    return ((p != this->exidx_section_map_.end()
	     && p->second->link() == shndx)
	    ? p->second
	    : NULL);
  }

  // Return the EXIDX section with index SHNDX or NULL if there is none.
  const Arm_exidx_input_section*
  exidx_input_section_by_shndx(unsigned shndx) const
  {
    Exidx_section_map::const_iterator p = this->exidx_section_map_.find(shndx);
    return ((p != this->exidx_section_map_.end()
	     && p->second->shndx() == shndx)
	    ? p->second
	    : NULL);
  }

  // Whether output local symbol count needs updating.
  bool
  output_local_symbol_count_needs_update() const
  { return this->output_local_symbol_count_needs_update_; }

  // Set output_local_symbol_count_needs_update flag to be true.
  void
  set_output_local_symbol_count_needs_update()
  { this->output_local_symbol_count_needs_update_ = true; }

  // Update output local symbol count at the end of relaxation.
  void
  update_output_local_symbol_count();

  // Whether we want to merge processor-specific flags and attributes.
  bool
  merge_flags_and_attributes() const
  { return this->merge_flags_and_attributes_; }

  // Export list of EXIDX section indices.
  void
  get_exidx_shndx_list(std::vector<unsigned int>* list) const
  {
    list->clear();
    for (Exidx_section_map::const_iterator p = this->exidx_section_map_.begin();
	 p != this->exidx_section_map_.end();
	 ++p)
      {
	if (p->second->shndx() == p->first)
	  list->push_back(p->first);
      }
    // Sort list to make result independent of implementation of map.
    std::sort(list->begin(), list->end());
  }

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

    // Initialize look-up tables.
    Stub_table_list empty_stub_table_list(this->shnum(), NULL);
    this->stub_tables_.swap(empty_stub_table_list);
  }

  // Count the local symbols.
  void
  do_count_local_symbols(Stringpool_template<char>*,
			 Stringpool_template<char>*);

  void
  do_relocate_sections(
      const Symbol_table* symtab, const Layout* layout,
      const unsigned char* pshdrs, Output_file* of,
      typename Sized_relobj_file<32, big_endian>::Views* pivews);

  // Read the symbol information.
  void
  do_read_symbols(Read_symbols_data* sd);

  // Process relocs for garbage collection.
  void
  do_gc_process_relocs(Symbol_table*, Layout*, Read_relocs_data*);

 private:

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

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

  // Whether a section needs to be scanned for the Cortex-A8 erratum.
  bool
  section_needs_cortex_a8_stub_scanning(const elfcpp::Shdr<32, big_endian>&,
					unsigned int, Output_section*,
					const Symbol_table*);

  // Scan a section for the Cortex-A8 erratum.
  void
  scan_section_for_cortex_a8_erratum(const elfcpp::Shdr<32, big_endian>&,
				     unsigned int, Output_section*,
				     Target_arm<big_endian>*);

  // Find the linked text section of an EXIDX section by looking at the
  // first relocation of the EXIDX section.  PSHDR points to the section
  // headers of a relocation section and PSYMS points to the local symbols.
  // PSHNDX points to a location storing the text section index if found.
  // Return whether we can find the linked section.
  bool
  find_linked_text_section(const unsigned char* pshdr,
			   const unsigned char* psyms, unsigned int* pshndx);

  //
  // Make a new Arm_exidx_input_section object for EXIDX section with
  // index SHNDX and section header SHDR.  TEXT_SHNDX is the section
  // index of the linked text section.
  void
  make_exidx_input_section(unsigned int shndx,
			   const elfcpp::Shdr<32, big_endian>& shdr,
			   unsigned int text_shndx,
			   const elfcpp::Shdr<32, big_endian>& text_shdr);

  // Return the output address of either a plain input section or a
  // relaxed input section.  SHNDX is the section index.
  Arm_address
  simple_input_section_output_address(unsigned int, Output_section*);

  typedef std::vector<Stub_table<big_endian>*> Stub_table_list;
  typedef Unordered_map<unsigned int, const Arm_exidx_input_section*>
    Exidx_section_map;

  // List of stub tables.
  Stub_table_list stub_tables_;
  // Bit vector to tell if a local symbol is a thumb function or not.
  // This is only valid after do_count_local_symbol is called.
  std::vector<bool> local_symbol_is_thumb_function_;
  // processor-specific flags in ELF file header.
  elfcpp::Elf_Word processor_specific_flags_;
  // Object attributes if there is an .ARM.attributes section or NULL.
  Attributes_section_data* attributes_section_data_;
  // Mapping symbols information.
  Mapping_symbols_info mapping_symbols_info_;
  // Bitmap to indicate sections with Cortex-A8 workaround or NULL.
  std::vector<bool>* section_has_cortex_a8_workaround_;
  // Map a text section to its associated .ARM.exidx section, if there is one.
  Exidx_section_map exidx_section_map_;
  // Whether output local symbol count needs updating.
  bool output_local_symbol_count_needs_update_;
  // Whether we merge processor flags and attributes of this object to
  // output.
  bool merge_flags_and_attributes_;
};

// Arm_dynobj class.

template<bool big_endian>
class Arm_dynobj : public Sized_dynobj<32, big_endian>
{
 public:
  Arm_dynobj(const std::string& name, Input_file* input_file, off_t offset,
	     const elfcpp::Ehdr<32, big_endian>& ehdr)
    : Sized_dynobj<32, big_endian>(name, input_file, offset, ehdr),
      processor_specific_flags_(0), attributes_section_data_(NULL)
  { }

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

  // Downcast a base pointer to an Arm_relobj pointer.  This is
  // not type-safe but we only use Arm_relobj not the base class.
  static Arm_dynobj<big_endian>*
  as_arm_dynobj(Dynobj* dynobj)
  { return static_cast<Arm_dynobj<big_endian>*>(dynobj); }

  // Processor-specific flags in ELF file header.  This is valid only after
  // reading symbols.
  elfcpp::Elf_Word
  processor_specific_flags() const
  { return this->processor_specific_flags_; }

  // Attributes section data.
  const Attributes_section_data*
  attributes_section_data() const
  { return this->attributes_section_data_; }

 protected:
  // Read the symbol information.
  void
  do_read_symbols(Read_symbols_data* sd);

 private:
  // processor-specific flags in ELF file header.
  elfcpp::Elf_Word processor_specific_flags_;
  // Object attributes if there is an .ARM.attributes section or NULL.
  Attributes_section_data* attributes_section_data_;
};

// Functor to read reloc addends during stub generation.

template<int sh_type, bool big_endian>
struct Stub_addend_reader
{
  // Return the addend for a relocation of a particular type.  Depending
  // on whether this is a REL or RELA relocation, read the addend from a
  // view or from a Reloc object.
  elfcpp::Elf_types<32>::Elf_Swxword
  operator()(
    unsigned int /* r_type */,
    const unsigned char* /* view */,
    const typename Reloc_types<sh_type,
			       32, big_endian>::Reloc& /* reloc */) const;
};

// Specialized Stub_addend_reader for SHT_REL type relocation sections.

template<bool big_endian>
struct Stub_addend_reader<elfcpp::SHT_REL, big_endian>
{
  elfcpp::Elf_types<32>::Elf_Swxword
  operator()(
    unsigned int,
    const unsigned char*,
    const typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc&) const;
};

// Specialized Stub_addend_reader for RELA type relocation sections.
// We currently do not handle RELA type relocation sections but it is trivial
// to implement the addend reader.  This is provided for completeness and to
// make it easier to add support for RELA relocation sections in the future.

template<bool big_endian>
struct Stub_addend_reader<elfcpp::SHT_RELA, big_endian>
{
  elfcpp::Elf_types<32>::Elf_Swxword
  operator()(
    unsigned int,
    const unsigned char*,
    const typename Reloc_types<elfcpp::SHT_RELA, 32,
			       big_endian>::Reloc& reloc) const
  { return reloc.get_r_addend(); }
};

// Cortex_a8_reloc class.  We keep record of relocation that may need
// the Cortex-A8 erratum workaround.

class Cortex_a8_reloc
{
 public:
  Cortex_a8_reloc(Reloc_stub* reloc_stub, unsigned r_type,
		  Arm_address destination)
    : reloc_stub_(reloc_stub), r_type_(r_type), destination_(destination)
  { }

  ~Cortex_a8_reloc()
  { }

  // Accessors:  This is a read-only class.

  // Return the relocation stub associated with this relocation if there is
  // one.
  const Reloc_stub*
  reloc_stub() const
  { return this->reloc_stub_; }

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

  // Return the destination address of the relocation.  LSB stores the THUMB
  // bit.
  Arm_address
  destination() const
  { return this->destination_; }

 private:
  // Associated relocation stub if there is one, or NULL.
  const Reloc_stub* reloc_stub_;
  // Relocation type.
  unsigned int r_type_;
  // Destination address of this relocation.  LSB is used to distinguish
  // ARM/THUMB mode.
  Arm_address destination_;
};

// Arm_output_data_got class.  We derive this from Output_data_got to add
// extra methods to handle TLS relocations in a static link.

template<bool big_endian>
class Arm_output_data_got : public Output_data_got<32, big_endian>
{
 public:
  Arm_output_data_got(Symbol_table* symtab, Layout* layout)
    : Output_data_got<32, 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<32, big_endian>* relobj,
		   unsigned int index)
  {
    this->static_relocs_.push_back(Static_reloc(got_offset, r_type, relobj,
						index));
  }

  // Add a GOT pair for R_ARM_TLS_GD32.  The creates a pair of GOT entries.
  // The first one is initialized to be 1, which is the module index for
  // the main executable and the second one 0.  A reloc of the type
  // R_ARM_TLS_DTPOFF32 will be created for the second GOT entry and will
  // be applied by gold.  GSYM is a global symbol.
  void
  add_tls_gd32_with_static_reloc(unsigned int got_type, Symbol* gsym);

  // Same as the above but for a local symbol in OBJECT with INDEX.
  void
  add_tls_gd32_with_static_reloc(unsigned int got_type,
				 Sized_relobj_file<32, big_endian>* object,
				 unsigned int index);

 protected:
  // Write out the GOT table.
  void
  do_write(Output_file*);

 private:
  // 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<32, 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<32, 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 object.
	Sized_relobj_file<32, big_endian>* relobj;
	// For a local symbol, the symbol index.
	unsigned int index;
      } local;
    } u_;
  };

  // Symbol table of the output object.
  Symbol_table* symbol_table_;
  // Layout of the output object.
  Layout* layout_;
  // Static relocs to be applied to the GOT.
  std::vector<Static_reloc> static_relocs_;
};

// The ARM target has many relocation types with odd-sizes or noncontiguous
// bits.  The default handling of relocatable relocation cannot process these
// relocations.  So we have to extend the default code.

template<bool big_endian, int sh_type, typename Classify_reloc>
class Arm_scan_relocatable_relocs :
  public Default_scan_relocatable_relocs<sh_type, Classify_reloc>
{
 public:
  // Return the strategy to use for a local symbol which is a section
  // symbol, given the relocation type.
  inline Relocatable_relocs::Reloc_strategy
  local_section_strategy(unsigned int r_type, Relobj*)
  {
    if (sh_type == elfcpp::SHT_RELA)
      return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_RELA;
    else
      {
	if (r_type == elfcpp::R_ARM_TARGET1
	    || r_type == elfcpp::R_ARM_TARGET2)
	  {
	    const Target_arm<big_endian>* arm_target =
	      Target_arm<big_endian>::default_target();
	    r_type = arm_target->get_real_reloc_type(r_type);
	  }

	switch(r_type)
	  {
	  // Relocations that write nothing.  These exclude R_ARM_TARGET1
	  // and R_ARM_TARGET2.
	  case elfcpp::R_ARM_NONE:
	  case elfcpp::R_ARM_V4BX:
	  case elfcpp::R_ARM_TLS_GOTDESC:
	  case elfcpp::R_ARM_TLS_CALL:
	  case elfcpp::R_ARM_TLS_DESCSEQ:
	  case elfcpp::R_ARM_THM_TLS_CALL:
	  case elfcpp::R_ARM_GOTRELAX:
	  case elfcpp::R_ARM_GNU_VTENTRY:
	  case elfcpp::R_ARM_GNU_VTINHERIT:
	  case elfcpp::R_ARM_THM_TLS_DESCSEQ16:
	  case elfcpp::R_ARM_THM_TLS_DESCSEQ32:
	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_0;
	  // These should have been converted to something else above.
	  case elfcpp::R_ARM_TARGET1:
	  case elfcpp::R_ARM_TARGET2:
	    gold_unreachable();
	  // Relocations that write full 32 bits and
	  // have alignment of 1.
	  case elfcpp::R_ARM_ABS32:
	  case elfcpp::R_ARM_REL32:
	  case elfcpp::R_ARM_SBREL32:
	  case elfcpp::R_ARM_GOTOFF32:
	  case elfcpp::R_ARM_BASE_PREL:
	  case elfcpp::R_ARM_GOT_BREL:
	  case elfcpp::R_ARM_BASE_ABS:
	  case elfcpp::R_ARM_ABS32_NOI:
	  case elfcpp::R_ARM_REL32_NOI:
	  case elfcpp::R_ARM_PLT32_ABS:
	  case elfcpp::R_ARM_GOT_ABS:
	  case elfcpp::R_ARM_GOT_PREL:
	  case elfcpp::R_ARM_TLS_GD32:
	  case elfcpp::R_ARM_TLS_LDM32:
	  case elfcpp::R_ARM_TLS_LDO32:
	  case elfcpp::R_ARM_TLS_IE32:
	  case elfcpp::R_ARM_TLS_LE32:
	    return Relocatable_relocs::RELOC_ADJUST_FOR_SECTION_4_UNALIGNED;
	  default:
	    // For all other static relocations, return RELOC_SPECIAL.
	    return Relocatable_relocs::RELOC_SPECIAL;
	  }
      }
  }
};

template<bool big_endian>
class Target_arm : public Sized_target<32, big_endian>
{
 public:
  typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
    Reloc_section;

  // When were are relocating a stub, we pass this as the relocation number.
  static const size_t fake_relnum_for_stubs = static_cast<size_t>(-1);

  Target_arm(const Target::Target_info* info = &arm_info)
    : Sized_target<32, big_endian>(info),
      got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL),
      copy_relocs_(elfcpp::R_ARM_COPY), dynbss_(NULL),
      got_mod_index_offset_(-1U), tls_base_symbol_defined_(false),
      stub_tables_(), stub_factory_(Stub_factory::get_instance()),
      should_force_pic_veneer_(false),
      arm_input_section_map_(), attributes_section_data_(NULL),
      fix_cortex_a8_(false), cortex_a8_relocs_info_()
  { }

  // Whether we force PCI branch veneers.
  bool
  should_force_pic_veneer() const
  { return this->should_force_pic_veneer_; }

  // Set PIC veneer flag.
  void
  set_should_force_pic_veneer(bool value)
  { this->should_force_pic_veneer_ = value; }

  // Whether we use THUMB-2 instructions.
  bool
  using_thumb2() const
  {
    Object_attribute* attr =
      this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
    int arch = attr->int_value();
    return arch == elfcpp::TAG_CPU_ARCH_V6T2 || arch >= elfcpp::TAG_CPU_ARCH_V7;
  }

  // Whether we use THUMB/THUMB-2 instructions only.
  bool
  using_thumb_only() const
  {
    Object_attribute* attr =
      this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);

    if (attr->int_value() == elfcpp::TAG_CPU_ARCH_V6_M
	|| attr->int_value() == elfcpp::TAG_CPU_ARCH_V6S_M)
      return true;
    if (attr->int_value() != elfcpp::TAG_CPU_ARCH_V7
	&& attr->int_value() != elfcpp::TAG_CPU_ARCH_V7E_M)
      return false;
    attr = this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch_profile);
    return attr->int_value() == 'M';
  }

  // Whether we have an NOP instruction.  If not, use mov r0, r0 instead.
  bool
  may_use_arm_nop() const
  {
    Object_attribute* attr =
      this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
    int arch = attr->int_value();
    return (arch == elfcpp::TAG_CPU_ARCH_V6T2
	    || arch == elfcpp::TAG_CPU_ARCH_V6K
	    || arch == elfcpp::TAG_CPU_ARCH_V7
	    || arch == elfcpp::TAG_CPU_ARCH_V7E_M);
  }

  // Whether we have THUMB-2 NOP.W instruction.
  bool
  may_use_thumb2_nop() const
  {
    Object_attribute* attr =
      this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
    int arch = attr->int_value();
    return (arch == elfcpp::TAG_CPU_ARCH_V6T2
	    || arch == elfcpp::TAG_CPU_ARCH_V7
	    || arch == elfcpp::TAG_CPU_ARCH_V7E_M);
  }

  // Whether we have v4T interworking instructions available.
  bool
  may_use_v4t_interworking() const
  {
    Object_attribute* attr =
      this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
    int arch = attr->int_value();
    return (arch != elfcpp::TAG_CPU_ARCH_PRE_V4
	    && arch != elfcpp::TAG_CPU_ARCH_V4);
  }

  // Whether we have v5T interworking instructions available.
  bool
  may_use_v5t_interworking() const
  {
    Object_attribute* attr =
      this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
    int arch = attr->int_value();
    if (parameters->options().fix_arm1176())
      return (arch == elfcpp::TAG_CPU_ARCH_V6T2
	      || arch == elfcpp::TAG_CPU_ARCH_V7
	      || arch == elfcpp::TAG_CPU_ARCH_V6_M
	      || arch == elfcpp::TAG_CPU_ARCH_V6S_M
	      || arch == elfcpp::TAG_CPU_ARCH_V7E_M);
    else
      return (arch != elfcpp::TAG_CPU_ARCH_PRE_V4
	      && arch != elfcpp::TAG_CPU_ARCH_V4
	      && arch != elfcpp::TAG_CPU_ARCH_V4T);
  }

  // Process the relocations to determine unreferenced sections for
  // garbage collection.
  void
  gc_process_relocs(Symbol_table* symtab,
		    Layout* layout,
		    Sized_relobj_file<32, 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<32, 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 symbol which requires special
  // treatment.
  uint64_t
  do_dynsym_value(const Symbol*) const;

  // Relocate a section.
  void
  relocate_section(const Relocate_info<32, 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,
		   Arm_address view_address,
		   section_size_type view_size,
		   const Reloc_symbol_changes*);

  // Scan the relocs during a relocatable link.
  void
  scan_relocatable_relocs(Symbol_table* symtab,
			  Layout* layout,
			  Sized_relobj_file<32, 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*);

  // Relocate a section during a relocatable link.
  void
  relocate_for_relocatable(const Relocate_info<32, big_endian>*,
			   unsigned int sh_type,
			   const unsigned char* prelocs,
			   size_t reloc_count,
			   Output_section* output_section,
			   typename elfcpp::Elf_types<32>::Elf_Off
                             offset_in_output_section,
			   const Relocatable_relocs*,
			   unsigned char* view,
			   Arm_address view_address,
			   section_size_type view_size,
			   unsigned char* reloc_view,
			   section_size_type reloc_view_size);

  // Perform target-specific processing in a relocatable link.  This is
  // only used if we use the relocation strategy RELOC_SPECIAL.
  void
  relocate_special_relocatable(const Relocate_info<32, big_endian>* relinfo,
			       unsigned int sh_type,
			       const unsigned char* preloc_in,
			       size_t relnum,
			       Output_section* output_section,
			       typename elfcpp::Elf_types<32>::Elf_Off
                                 offset_in_output_section,
			       unsigned char* view,
			       typename elfcpp::Elf_types<32>::Elf_Addr
				 view_address,
			       section_size_type view_size,
			       unsigned char* preloc_out);

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

  // Return whether there is a GOT section.
  bool
  has_got_section() const
  { return this->got_ != NULL; }

  // Return the size of the GOT section.
  section_size_type
  got_size() const
  {
    gold_assert(this->got_ != NULL);
    return this->got_->data_size();
  }

  // Return the number of entries in the GOT.
  unsigned int
  got_entry_count() const
  {
    if (!this->has_got_section())
      return 0;
    return this->got_size() / 4;
  }

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

  // Map platform-specific reloc types
  static unsigned int
  get_real_reloc_type(unsigned int r_type);

  //
  // Methods to support stub-generations.
  //

  // Return the stub factory
  const Stub_factory&
  stub_factory() const
  { return this->stub_factory_; }

  // Make a new Arm_input_section object.
  Arm_input_section<big_endian>*
  new_arm_input_section(Relobj*, unsigned int);

  // Find the Arm_input_section object corresponding to the SHNDX-th input
  // section of RELOBJ.
  Arm_input_section<big_endian>*
  find_arm_input_section(Relobj* relobj, unsigned int shndx) const;

  // Make a new Stub_table
  Stub_table<big_endian>*
  new_stub_table(Arm_input_section<big_endian>*);

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

  // Relocate a stub.
  void
  relocate_stub(Stub*, const Relocate_info<32, big_endian>*,
		Output_section*, unsigned char*, Arm_address,
		section_size_type);

  // Get the default ARM target.
  static Target_arm<big_endian>*
  default_target()
  {
    gold_assert(parameters->target().machine_code() == elfcpp::EM_ARM
		&& parameters->target().is_big_endian() == big_endian);
    return static_cast<Target_arm<big_endian>*>(
	     parameters->sized_target<32, big_endian>());
  }

  // Whether NAME belongs to a mapping symbol.
  static bool
  is_mapping_symbol_name(const char* name)
  {
    return (name
	    && name[0] == '$'
	    && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
	    && (name[2] == '\0' || name[2] == '.'));
  }

  // Whether we work around the Cortex-A8 erratum.
  bool
  fix_cortex_a8() const
  { return this->fix_cortex_a8_; }

  // Whether we merge exidx entries in debuginfo.
  bool
  merge_exidx_entries() const
  { return parameters->options().merge_exidx_entries(); }

  // Whether we fix R_ARM_V4BX relocation.
  // 0 - do not fix
  // 1 - replace with MOV instruction (armv4 target)
  // 2 - make interworking veneer (>= armv4t targets only)
  General_options::Fix_v4bx
  fix_v4bx() const
  { return parameters->options().fix_v4bx(); }

  // Scan a span of THUMB code section for Cortex-A8 erratum.
  void
  scan_span_for_cortex_a8_erratum(Arm_relobj<big_endian>*, unsigned int,
				  section_size_type, section_size_type,
				  const unsigned char*, Arm_address);

  // Apply Cortex-A8 workaround to a branch.
  void
  apply_cortex_a8_workaround(const Cortex_a8_stub*, Arm_address,
			     unsigned char*, Arm_address);

 protected:
  // Make the PLT-generator object.
  Output_data_plt_arm<big_endian>*
  make_data_plt(Layout* layout, Output_data_space* got_plt)
  { return this->do_make_data_plt(layout, got_plt); }

  // Make an ELF object.
  Object*
  do_make_elf_object(const std::string&, Input_file*, off_t,
		     const elfcpp::Ehdr<32, big_endian>& ehdr);

  Object*
  do_make_elf_object(const std::string&, Input_file*, off_t,
		     const elfcpp::Ehdr<32, !big_endian>&)
  { gold_unreachable(); }

  Object*
  do_make_elf_object(const std::string&, Input_file*, off_t,
		      const elfcpp::Ehdr<64, false>&)
  { gold_unreachable(); }

  Object*
  do_make_elf_object(const std::string&, Input_file*, off_t,
		     const elfcpp::Ehdr<64, true>&)
  { gold_unreachable(); }

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

  void
  do_adjust_elf_header(unsigned char* view, int len) const;

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

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

  // Determine whether an object attribute tag takes an integer, a
  // string or both.
  int
  do_attribute_arg_type(int tag) const;

  // Reorder tags during output.
  int
  do_attributes_order(int num) const;

  // This is called when the target is selected as the default.
  void
  do_select_as_default_target()
  {
    // No locking is required since there should only be one default target.
    // We cannot have both the big-endian and little-endian ARM targets
    // as the default.
    gold_assert(arm_reloc_property_table == NULL);
    arm_reloc_property_table = new Arm_reloc_property_table();
  }

  // Virtual function which is set to return true by a target if
  // it can use relocation types to determine if a function's
  // pointer is taken.
  virtual bool
  do_can_check_for_function_pointers() const
  { return true; }

  // Whether a section called SECTION_NAME may have function pointers to
  // sections not eligible for safe ICF folding.
  virtual bool
  do_section_may_have_icf_unsafe_pointers(const char* section_name) const
  {
    return (!is_prefix_of(".ARM.exidx", section_name)
	    && !is_prefix_of(".ARM.extab", section_name)
	    && Target::do_section_may_have_icf_unsafe_pointers(section_name));
  }

  virtual void
  do_define_standard_symbols(Symbol_table*, Layout*);

  virtual Output_data_plt_arm<big_endian>*
  do_make_data_plt(Layout* layout, Output_data_space* got_plt)
  {
    return new Output_data_plt_arm_standard<big_endian>(layout, got_plt);
  }

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

    static inline int
    get_reference_flags(unsigned int r_type);

    inline void
    local(Symbol_table* symtab, Layout* layout, Target_arm* target,
	  Sized_relobj_file<32, big_endian>* object,
	  unsigned int data_shndx,
	  Output_section* output_section,
	  const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type,
	  const elfcpp::Sym<32, big_endian>& lsym);

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

    inline bool
    local_reloc_may_be_function_pointer(Symbol_table* , Layout* , Target_arm* ,
					Sized_relobj_file<32, big_endian>* ,
					unsigned int ,
					Output_section* ,
					const elfcpp::Rel<32, big_endian>& ,
					unsigned int ,
					const elfcpp::Sym<32, big_endian>&);

    inline bool
    global_reloc_may_be_function_pointer(Symbol_table* , Layout* , Target_arm* ,
					 Sized_relobj_file<32, big_endian>* ,
					 unsigned int ,
					 Output_section* ,
					 const elfcpp::Rel<32, big_endian>& ,
					 unsigned int , Symbol*);

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

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

    void
    check_non_pic(Relobj*, unsigned int r_type);

    // Almost identical to Symbol::needs_plt_entry except that it also
    // handles STT_ARM_TFUNC.
    static bool
    symbol_needs_plt_entry(const Symbol* sym)
    {
      // An undefined symbol from an executable does not need a PLT entry.
      if (sym->is_undefined() && !parameters->options().shared())
	return false;

      return (!parameters->doing_static_link()
	      && (sym->type() == elfcpp::STT_FUNC
		  || sym->type() == elfcpp::STT_ARM_TFUNC)
	      && (sym->is_from_dynobj()
		  || sym->is_undefined()
		  || sym->is_preemptible()));
    }

    inline bool
    possible_function_pointer_reloc(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()
    { }

    ~Relocate()
    { }

    // Return whether the static relocation needs to be applied.
    inline bool
    should_apply_static_reloc(const Sized_symbol<32>* gsym,
			      unsigned int r_type,
			      bool is_32bit,
			      Output_section* output_section);

    // Do a relocation.  Return false if the caller should not issue
    // any warnings about this relocation.
    inline bool
    relocate(const Relocate_info<32, big_endian>*, Target_arm*,
	     Output_section*,  size_t relnum,
	     const elfcpp::Rel<32, big_endian>&,
	     unsigned int r_type, const Sized_symbol<32>*,
	     const Symbol_value<32>*,
	     unsigned char*, Arm_address,
	     section_size_type);

    // Return whether we want to pass flag NON_PIC_REF for this
    // reloc.  This means the relocation type accesses a symbol not via
    // GOT or PLT.
    static inline bool
    reloc_is_non_pic(unsigned int r_type)
    {
      switch (r_type)
	{
	// These relocation types reference GOT or PLT entries explicitly.
	case elfcpp::R_ARM_GOT_BREL:
	case elfcpp::R_ARM_GOT_ABS:
	case elfcpp::R_ARM_GOT_PREL:
	case elfcpp::R_ARM_GOT_BREL12:
	case elfcpp::R_ARM_PLT32_ABS:
	case elfcpp::R_ARM_TLS_GD32:
	case elfcpp::R_ARM_TLS_LDM32:
	case elfcpp::R_ARM_TLS_IE32:
	case elfcpp::R_ARM_TLS_IE12GP:

	// These relocate types may use PLT entries.
	case elfcpp::R_ARM_CALL:
	case elfcpp::R_ARM_THM_CALL:
	case elfcpp::R_ARM_JUMP24:
	case elfcpp::R_ARM_THM_JUMP24:
	case elfcpp::R_ARM_THM_JUMP19:
	case elfcpp::R_ARM_PLT32:
	case elfcpp::R_ARM_THM_XPC22:
	case elfcpp::R_ARM_PREL31:
	case elfcpp::R_ARM_SBREL31:
	  return false;

	default:
	  return true;
	}
    }

   private:
    // Do a TLS relocation.
    inline typename Arm_relocate_functions<big_endian>::Status
    relocate_tls(const Relocate_info<32, big_endian>*, Target_arm<big_endian>*,
		 size_t, const elfcpp::Rel<32, big_endian>&, unsigned int,
		 const Sized_symbol<32>*, const Symbol_value<32>*,
		 unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
		 section_size_type);

  };

  // A class which returns the size required for a relocation type,
  // used while scanning relocs during a relocatable link.
  class Relocatable_size_for_reloc
  {
   public:
    unsigned int
    get_size_for_reloc(unsigned int, Relobj*);
  };

  // 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.
  Arm_output_data_got<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_;
  }

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

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

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

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

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

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

  // Return true if the symbol may need a COPY relocation.
  // References from an executable object to non-function symbols
  // defined in a dynamic object may need a COPY relocation.
  bool
  may_need_copy_reloc(Symbol* gsym)
  {
    return (gsym->type() != elfcpp::STT_ARM_TFUNC
	    && gsym->may_need_copy_reloc());
  }

  // Add a potential copy relocation.
  void
  copy_reloc(Symbol_table* symtab, Layout* layout,
	     Sized_relobj_file<32, big_endian>* object,
	     unsigned int shndx, Output_section* output_section,
	     Symbol* sym, const elfcpp::Rel<32, big_endian>& reloc)
  {
    this->copy_relocs_.copy_reloc(symtab, layout,
				  symtab->get_sized_symbol<32>(sym),
				  object, shndx, output_section, reloc,
				  this->rel_dyn_section(layout));
  }

  // Whether two EABI versions are compatible.
  static bool
  are_eabi_versions_compatible(elfcpp::Elf_Word v1, elfcpp::Elf_Word v2);

  // Merge processor-specific flags from input object and those in the ELF
  // header of the output.
  void
  merge_processor_specific_flags(const std::string&, elfcpp::Elf_Word);

  // Get the secondary compatible architecture.
  static int
  get_secondary_compatible_arch(const Attributes_section_data*);

  // Set the secondary compatible architecture.
  static void
  set_secondary_compatible_arch(Attributes_section_data*, int);

  static int
  tag_cpu_arch_combine(const char*, int, int*, int, int);

  // Helper to print AEABI enum tag value.
  static std::string
  aeabi_enum_name(unsigned int);

  // Return string value for TAG_CPU_name.
  static std::string
  tag_cpu_name_value(unsigned int);

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

  // Helper to get an AEABI object attribute
  Object_attribute*
  get_aeabi_object_attribute(int tag) const
  {
    Attributes_section_data* pasd = this->attributes_section_data_;
    gold_assert(pasd != NULL);
    Object_attribute* attr =
      pasd->get_attribute(Object_attribute::OBJ_ATTR_PROC, tag);
    gold_assert(attr != NULL);
    return attr;
  }

  //
  // Methods to support stub-generations.
  //

  // Group input sections for stub generation.
  void
  group_sections(Layout*, section_size_type, bool, const Task*);

  // Scan a relocation for stub generation.
  void
  scan_reloc_for_stub(const Relocate_info<32, big_endian>*, unsigned int,
		      const Sized_symbol<32>*, unsigned int,
		      const Symbol_value<32>*,
		      elfcpp::Elf_types<32>::Elf_Swxword, Arm_address);

  // Scan a relocation section for stub.
  template<int sh_type>
  void
  scan_reloc_section_for_stubs(
      const Relocate_info<32, big_endian>* relinfo,
      const unsigned char* prelocs,
      size_t reloc_count,
      Output_section* output_section,
      bool needs_special_offset_handling,
      const unsigned char* view,
      elfcpp::Elf_types<32>::Elf_Addr view_address,
      section_size_type);

  // Fix .ARM.exidx section coverage.
  void
  fix_exidx_coverage(Layout*, const Input_objects*,
		     Arm_output_section<big_endian>*, Symbol_table*,
		     const Task*);

  // Functors for STL set.
  struct output_section_address_less_than
  {
    bool
    operator()(const Output_section* s1, const Output_section* s2) const
    { return s1->address() < s2->address(); }
  };

  // Information about this specific target which we pass to the
  // general Target structure.
  static const Target::Target_info arm_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_NOFFSET = 1,   // GOT entry for negative TLS offset
    GOT_TYPE_TLS_OFFSET = 2,    // GOT entry for positive TLS offset
    GOT_TYPE_TLS_PAIR = 3,      // GOT entry for TLS module/offset pair
    GOT_TYPE_TLS_DESC = 4       // GOT entry for TLS_DESC pair
  };

  typedef typename std::vector<Stub_table<big_endian>*> Stub_table_list;

  // Map input section to Arm_input_section.
  typedef Unordered_map<Section_id,
			Arm_input_section<big_endian>*,
			Section_id_hash>
	  Arm_input_section_map;

  // Map output addresses to relocs for Cortex-A8 erratum.
  typedef Unordered_map<Arm_address, const Cortex_a8_reloc*>
	  Cortex_a8_relocs_info;

  // The GOT section.
  Arm_output_data_got<big_endian>* got_;
  // The PLT section.
  Output_data_plt_arm<big_endian>* plt_;
  // The GOT PLT section.
  Output_data_space* got_plt_;
  // The dynamic reloc section.
  Reloc_section* rel_dyn_;
  // Relocs saved to avoid a COPY reloc.
  Copy_relocs<elfcpp::SHT_REL, 32, big_endian> copy_relocs_;
  // Space for variables copied with a COPY reloc.
  Output_data_space* dynbss_;
  // Offset of the GOT entry for the TLS module index.
  unsigned int got_mod_index_offset_;
  // True if the _TLS_MODULE_BASE_ symbol has been defined.
  bool tls_base_symbol_defined_;
  // Vector of Stub_tables created.
  Stub_table_list stub_tables_;
  // Stub factory.
  const Stub_factory &stub_factory_;
  // Whether we force PIC branch veneers.
  bool should_force_pic_veneer_;
  // Map for locating Arm_input_sections.
  Arm_input_section_map arm_input_section_map_;
  // Attributes section data in output.
  Attributes_section_data* attributes_section_data_;
  // Whether we want to fix code for Cortex-A8 erratum.
  bool fix_cortex_a8_;
  // Map addresses to relocs for Cortex-A8 erratum.
  Cortex_a8_relocs_info cortex_a8_relocs_info_;
};

template<bool big_endian>
const Target::Target_info Target_arm<big_endian>::arm_info =
{
  32,			// size
  big_endian,		// is_big_endian
  elfcpp::EM_ARM,	// machine_code
  false,		// has_make_symbol
  false,		// has_resolve
  false,		// has_code_fill
  true,			// is_default_stack_executable
  false,		// can_icf_inline_merge_sections
  '\0',			// wrap_char
  "/usr/lib/libc.so.1",	// dynamic_linker
  0x8000,		// default_text_segment_address
  0x1000,		// 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
  ".ARM.attributes",	// attributes_section
  "aeabi"		// attributes_vendor
};

// Arm relocate functions class
//

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

 private:
  typedef Relocate_functions<32, big_endian> Base;
  typedef Arm_relocate_functions<big_endian> This;

  // Encoding of imm16 argument for movt and movw ARM instructions
  // from ARM ARM:
  //
  //     imm16 := imm4 | imm12
  //
  //  f e d c b a 9 8 7 6 5 4 3 2 1 0 f e d c b a 9 8 7 6 5 4 3 2 1 0
  // +-------+---------------+-------+-------+-----------------------+
  // |       |               |imm4   |       |imm12                  |
  // +-------+---------------+-------+-------+-----------------------+

  // Extract the relocation addend from VAL based on the ARM
  // instruction encoding described above.
  static inline typename elfcpp::Swap<32, big_endian>::Valtype
  extract_arm_movw_movt_addend(
      typename elfcpp::Swap<32, big_endian>::Valtype val)
  {
    // According to the Elf ABI for ARM Architecture the immediate
    // field is sign-extended to form the addend.
    return Bits<16>::sign_extend32(((val >> 4) & 0xf000) | (val & 0xfff));
  }

  // Insert X into VAL based on the ARM instruction encoding described
  // above.
  static inline typename elfcpp::Swap<32, big_endian>::Valtype
  insert_val_arm_movw_movt(
      typename elfcpp::Swap<32, big_endian>::Valtype val,
      typename elfcpp::Swap<32, big_endian>::Valtype x)
  {
    val &= 0xfff0f000;
    val |= x & 0x0fff;
    val |= (x & 0xf000) << 4;
    return val;
  }

  // Encoding of imm16 argument for movt and movw Thumb2 instructions
  // from ARM ARM:
  //
  //     imm16 := imm4 | i | imm3 | imm8
  //
  //  f e d c b a 9 8 7 6 5 4 3 2 1 0  f e d c b a 9 8 7 6 5 4 3 2 1 0
  // +---------+-+-----------+-------++-+-----+-------+---------------+
  // |         |i|           |imm4   || |imm3 |       |imm8           |
  // +---------+-+-----------+-------++-+-----+-------+---------------+

  // Extract the relocation addend from VAL based on the Thumb2
  // instruction encoding described above.
  static inline typename elfcpp::Swap<32, big_endian>::Valtype
  extract_thumb_movw_movt_addend(
      typename elfcpp::Swap<32, big_endian>::Valtype val)
  {
    // According to the Elf ABI for ARM Architecture the immediate
    // field is sign-extended to form the addend.
    return Bits<16>::sign_extend32(((val >> 4) & 0xf000)
				   | ((val >> 15) & 0x0800)
				   | ((val >> 4) & 0x0700)
				   | (val & 0x00ff));
  }

  // Insert X into VAL based on the Thumb2 instruction encoding
  // described above.
  static inline typename elfcpp::Swap<32, big_endian>::Valtype
  insert_val_thumb_movw_movt(
      typename elfcpp::Swap<32, big_endian>::Valtype val,
      typename elfcpp::Swap<32, big_endian>::Valtype x)
  {
    val &= 0xfbf08f00;
    val |= (x & 0xf000) << 4;
    val |= (x & 0x0800) << 15;
    val |= (x & 0x0700) << 4;
    val |= (x & 0x00ff);
    return val;
  }

  // Calculate the smallest constant Kn for the specified residual.
  // (see (AAELF 4.6.1.4 Static ARM relocations, Group Relocations, p.32)
  static uint32_t
  calc_grp_kn(typename elfcpp::Swap<32, big_endian>::Valtype residual)
  {
    int32_t msb;

    if (residual == 0)
      return 0;
    // Determine the most significant bit in the residual and
    // align the resulting value to a 2-bit boundary.
    for (msb = 30; (msb >= 0) && !(residual & (3 << msb)); msb -= 2)
      ;
    // The desired shift is now (msb - 6), or zero, whichever
    // is the greater.
    return (((msb - 6) < 0) ? 0 : (msb - 6));
  }

  // Calculate the final residual for the specified group index.
  // If the passed group index is less than zero, the method will return
  // the value of the specified residual without any change.
  // (see (AAELF 4.6.1.4 Static ARM relocations, Group Relocations, p.32)
  static typename elfcpp::Swap<32, big_endian>::Valtype
  calc_grp_residual(typename elfcpp::Swap<32, big_endian>::Valtype residual,
		    const int group)
  {
    for (int n = 0; n <= group; n++)
      {
	// Calculate which part of the value to mask.
	uint32_t shift = calc_grp_kn(residual);
	// Calculate the residual for the next time around.
	residual &= ~(residual & (0xff << shift));
      }

    return residual;
  }

  // Calculate the value of Gn for the specified group index.
  // We return it in the form of an encoded constant-and-rotation.
  // (see (AAELF 4.6.1.4 Static ARM relocations, Group Relocations, p.32)
  static typename elfcpp::Swap<32, big_endian>::Valtype
  calc_grp_gn(typename elfcpp::Swap<32, big_endian>::Valtype residual,
	      const int group)
  {
    typename elfcpp::Swap<32, big_endian>::Valtype gn = 0;
    uint32_t shift = 0;

    for (int n = 0; n <= group; n++)
      {
	// Calculate which part of the value to mask.
	shift = calc_grp_kn(residual);
	// Calculate Gn in 32-bit as well as encoded constant-and-rotation form.
	gn = residual & (0xff << shift);
	// Calculate the residual for the next time around.
	residual &= ~gn;
      }
    // Return Gn in the form of an encoded constant-and-rotation.
    return ((gn >> shift) | ((gn <= 0xff ? 0 : (32 - shift) / 2) << 8));
  }

 public:
  // Handle ARM long branches.
  static typename This::Status
  arm_branch_common(unsigned int, const Relocate_info<32, big_endian>*,
		    unsigned char*, const Sized_symbol<32>*,
		    const Arm_relobj<big_endian>*, unsigned int,
		    const Symbol_value<32>*, Arm_address, Arm_address, bool);

  // Handle THUMB long branches.
  static typename This::Status
  thumb_branch_common(unsigned int, const Relocate_info<32, big_endian>*,
		      unsigned char*, const Sized_symbol<32>*,
		      const Arm_relobj<big_endian>*, unsigned int,
		      const Symbol_value<32>*, Arm_address, Arm_address, bool);


  // Return the branch offset of a 32-bit THUMB branch.
  static inline int32_t
  thumb32_branch_offset(uint16_t upper_insn, uint16_t lower_insn)
  {
    // We use the Thumb-2 encoding (backwards compatible with Thumb-1)
    // involving the J1 and J2 bits.
    uint32_t s = (upper_insn & (1U << 10)) >> 10;
    uint32_t upper = upper_insn & 0x3ffU;
    uint32_t lower = lower_insn & 0x7ffU;
    uint32_t j1 = (lower_insn & (1U << 13)) >> 13;
    uint32_t j2 = (lower_insn & (1U << 11)) >> 11;
    uint32_t i1 = j1 ^ s ? 0 : 1;
    uint32_t i2 = j2 ^ s ? 0 : 1;

    return Bits<25>::sign_extend32((s << 24) | (i1 << 23) | (i2 << 22)
				   | (upper << 12) | (lower << 1));
  }

  // Insert OFFSET to a 32-bit THUMB branch and return the upper instruction.
  // UPPER_INSN is the original upper instruction of the branch.  Caller is
  // responsible for overflow checking and BLX offset adjustment.
  static inline uint16_t
  thumb32_branch_upper(uint16_t upper_insn, int32_t offset)
  {
    uint32_t s = offset < 0 ? 1 : 0;
    uint32_t bits = static_cast<uint32_t>(offset);
    return (upper_insn & ~0x7ffU) | ((bits >> 12) & 0x3ffU) | (s << 10);
  }

  // Insert OFFSET to a 32-bit THUMB branch and return the lower instruction.
  // LOWER_INSN is the original lower instruction of the branch.  Caller is
  // responsible for overflow checking and BLX offset adjustment.
  static inline uint16_t
  thumb32_branch_lower(uint16_t lower_insn, int32_t offset)
  {
    uint32_t s = offset < 0 ? 1 : 0;
    uint32_t bits = static_cast<uint32_t>(offset);
    return ((lower_insn & ~0x2fffU)
	    | ((((bits >> 23) & 1) ^ !s) << 13)
	    | ((((bits >> 22) & 1) ^ !s) << 11)
	    | ((bits >> 1) & 0x7ffU));
  }

  // Return the branch offset of a 32-bit THUMB conditional branch.
  static inline int32_t
  thumb32_cond_branch_offset(uint16_t upper_insn, uint16_t lower_insn)
  {
    uint32_t s = (upper_insn & 0x0400U) >> 10;
    uint32_t j1 = (lower_insn & 0x2000U) >> 13;
    uint32_t j2 = (lower_insn & 0x0800U) >> 11;
    uint32_t lower = (lower_insn & 0x07ffU);
    uint32_t upper = (s << 8) | (j2 << 7) | (j1 << 6) | (upper_insn & 0x003fU);

    return Bits<21>::sign_extend32((upper << 12) | (lower << 1));
  }

  // Insert OFFSET to a 32-bit THUMB conditional branch and return the upper
  // instruction.  UPPER_INSN is the original upper instruction of the branch.
  // Caller is responsible for overflow checking.
  static inline uint16_t
  thumb32_cond_branch_upper(uint16_t upper_insn, int32_t offset)
  {
    uint32_t s = offset < 0 ? 1 : 0;
    uint32_t bits = static_cast<uint32_t>(offset);
    return (upper_insn & 0xfbc0U) | (s << 10) | ((bits & 0x0003f000U) >> 12);
  }

  // Insert OFFSET to a 32-bit THUMB conditional branch and return the lower
  // instruction.  LOWER_INSN is the original lower instruction of the branch.
  // The caller is responsible for overflow checking.
  static inline uint16_t
  thumb32_cond_branch_lower(uint16_t lower_insn, int32_t offset)
  {
    uint32_t bits = static_cast<uint32_t>(offset);
    uint32_t j2 = (bits & 0x00080000U) >> 19;
    uint32_t j1 = (bits & 0x00040000U) >> 18;
    uint32_t lo = (bits & 0x00000ffeU) >> 1;

    return (lower_insn & 0xd000U) | (j1 << 13) | (j2 << 11) | lo;
  }

  // R_ARM_ABS8: S + A
  static inline typename This::Status
  abs8(unsigned char* view,
       const Sized_relobj_file<32, big_endian>* object,
       const Symbol_value<32>* psymval)
  {
    typedef typename elfcpp::Swap<8, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<8, big_endian>::readval(wv);
    int32_t addend = Bits<8>::sign_extend32(val);
    Arm_address x = psymval->value(object, addend);
    val = Bits<32>::bit_select32(val, x, 0xffU);
    elfcpp::Swap<8, big_endian>::writeval(wv, val);

    // R_ARM_ABS8 permits signed or unsigned results.
    return (Bits<8>::has_signed_unsigned_overflow32(x)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_THM_ABS5: S + A
  static inline typename This::Status
  thm_abs5(unsigned char* view,
       const Sized_relobj_file<32, big_endian>* object,
       const Symbol_value<32>* psymval)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<16, big_endian>::readval(wv);
    Reltype addend = (val & 0x7e0U) >> 6;
    Reltype x = psymval->value(object, addend);
    val = Bits<32>::bit_select32(val, x << 6, 0x7e0U);
    elfcpp::Swap<16, big_endian>::writeval(wv, val);
    return (Bits<5>::has_overflow32(x)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_ABS12: S + A
  static inline typename This::Status
  abs12(unsigned char* view,
	const Sized_relobj_file<32, big_endian>* object,
	const Symbol_value<32>* psymval)
  {
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
    Reltype addend = val & 0x0fffU;
    Reltype x = psymval->value(object, addend);
    val = Bits<32>::bit_select32(val, x, 0x0fffU);
    elfcpp::Swap<32, big_endian>::writeval(wv, val);
    return (Bits<12>::has_overflow32(x)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_ABS16: S + A
  static inline typename This::Status
  abs16(unsigned char* view,
	const Sized_relobj_file<32, big_endian>* object,
	const Symbol_value<32>* psymval)
  {
    typedef typename elfcpp::Swap_unaligned<16, big_endian>::Valtype Valtype;
    Valtype val = elfcpp::Swap_unaligned<16, big_endian>::readval(view);
    int32_t addend = Bits<16>::sign_extend32(val);
    Arm_address x = psymval->value(object, addend);
    val = Bits<32>::bit_select32(val, x, 0xffffU);
    elfcpp::Swap_unaligned<16, big_endian>::writeval(view, val);

    // R_ARM_ABS16 permits signed or unsigned results.
    return (Bits<16>::has_signed_unsigned_overflow32(x)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_ABS32: (S + A) | T
  static inline typename This::Status
  abs32(unsigned char* view,
	const Sized_relobj_file<32, big_endian>* object,
	const Symbol_value<32>* psymval,
	Arm_address thumb_bit)
  {
    typedef typename elfcpp::Swap_unaligned<32, big_endian>::Valtype Valtype;
    Valtype addend = elfcpp::Swap_unaligned<32, big_endian>::readval(view);
    Valtype x = psymval->value(object, addend) | thumb_bit;
    elfcpp::Swap_unaligned<32, big_endian>::writeval(view, x);
    return This::STATUS_OKAY;
  }

  // R_ARM_REL32: (S + A) | T - P
  static inline typename This::Status
  rel32(unsigned char* view,
	const Sized_relobj_file<32, big_endian>* object,
	const Symbol_value<32>* psymval,
	Arm_address address,
	Arm_address thumb_bit)
  {
    typedef typename elfcpp::Swap_unaligned<32, big_endian>::Valtype Valtype;
    Valtype addend = elfcpp::Swap_unaligned<32, big_endian>::readval(view);
    Valtype x = (psymval->value(object, addend) | thumb_bit) - address;
    elfcpp::Swap_unaligned<32, big_endian>::writeval(view, x);
    return This::STATUS_OKAY;
  }

  // R_ARM_THM_JUMP24: (S + A) | T - P
  static typename This::Status
  thm_jump19(unsigned char* view, const Arm_relobj<big_endian>* object,
	     const Symbol_value<32>* psymval, Arm_address address,
	     Arm_address thumb_bit);

  // R_ARM_THM_JUMP6: S + A – P
  static inline typename This::Status
  thm_jump6(unsigned char* view,
	    const Sized_relobj_file<32, big_endian>* object,
	    const Symbol_value<32>* psymval,
	    Arm_address address)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<16, big_endian>::readval(wv);
    // bit[9]:bit[7:3]:’0’ (mask: 0x02f8)
    Reltype addend = (((val & 0x0200) >> 3) | ((val & 0x00f8) >> 2));
    Reltype x = (psymval->value(object, addend) - address);
    val = (val & 0xfd07) | ((x  & 0x0040) << 3) | ((val & 0x003e) << 2);
    elfcpp::Swap<16, big_endian>::writeval(wv, val);
    // CZB does only forward jumps.
    return ((x > 0x007e)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_THM_JUMP8: S + A – P
  static inline typename This::Status
  thm_jump8(unsigned char* view,
	    const Sized_relobj_file<32, big_endian>* object,
	    const Symbol_value<32>* psymval,
	    Arm_address address)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<16, big_endian>::readval(wv);
    int32_t addend = Bits<8>::sign_extend32((val & 0x00ff) << 1);
    int32_t x = (psymval->value(object, addend) - address);
    elfcpp::Swap<16, big_endian>::writeval(wv, ((val & 0xff00)
						| ((x & 0x01fe) >> 1)));
    // We do a 9-bit overflow check because x is right-shifted by 1 bit.
    return (Bits<9>::has_overflow32(x)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_THM_JUMP11: S + A – P
  static inline typename This::Status
  thm_jump11(unsigned char* view,
	    const Sized_relobj_file<32, big_endian>* object,
	    const Symbol_value<32>* psymval,
	    Arm_address address)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<16, big_endian>::readval(wv);
    int32_t addend = Bits<11>::sign_extend32((val & 0x07ff) << 1);
    int32_t x = (psymval->value(object, addend) - address);
    elfcpp::Swap<16, big_endian>::writeval(wv, ((val & 0xf800)
						| ((x & 0x0ffe) >> 1)));
    // We do a 12-bit overflow check because x is right-shifted by 1 bit.
    return (Bits<12>::has_overflow32(x)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_BASE_PREL: B(S) + A - P
  static inline typename This::Status
  base_prel(unsigned char* view,
	    Arm_address origin,
	    Arm_address address)
  {
    Base::rel32(view, origin - address);
    return STATUS_OKAY;
  }

  // R_ARM_BASE_ABS: B(S) + A
  static inline typename This::Status
  base_abs(unsigned char* view,
	   Arm_address origin)
  {
    Base::rel32(view, origin);
    return STATUS_OKAY;
  }

  // R_ARM_GOT_BREL: GOT(S) + A - GOT_ORG
  static inline typename This::Status
  got_brel(unsigned char* view,
	   typename elfcpp::Swap<32, big_endian>::Valtype got_offset)
  {
    Base::rel32(view, got_offset);
    return This::STATUS_OKAY;
  }

  // R_ARM_GOT_PREL: GOT(S) + A - P
  static inline typename This::Status
  got_prel(unsigned char* view,
	   Arm_address got_entry,
	   Arm_address address)
  {
    Base::rel32(view, got_entry - address);
    return This::STATUS_OKAY;
  }

  // R_ARM_PREL: (S + A) | T - P
  static inline typename This::Status
  prel31(unsigned char* view,
	 const Sized_relobj_file<32, big_endian>* object,
	 const Symbol_value<32>* psymval,
	 Arm_address address,
	 Arm_address thumb_bit)
  {
    typedef typename elfcpp::Swap_unaligned<32, big_endian>::Valtype Valtype;
    Valtype val = elfcpp::Swap_unaligned<32, big_endian>::readval(view);
    Valtype addend = Bits<31>::sign_extend32(val);
    Valtype x = (psymval->value(object, addend) | thumb_bit) - address;
    val = Bits<32>::bit_select32(val, x, 0x7fffffffU);
    elfcpp::Swap_unaligned<32, big_endian>::writeval(view, val);
    return (Bits<31>::has_overflow32(x)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_MOVW_ABS_NC: (S + A) | T	(relative address base is )
  // R_ARM_MOVW_PREL_NC: (S + A) | T - P
  // R_ARM_MOVW_BREL_NC: ((S + A) | T) - B(S)
  // R_ARM_MOVW_BREL: ((S + A) | T) - B(S)
  static inline typename This::Status
  movw(unsigned char* view,
       const Sized_relobj_file<32, big_endian>* object,
       const Symbol_value<32>* psymval,
       Arm_address relative_address_base,
       Arm_address thumb_bit,
       bool check_overflow)
  {
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype addend = This::extract_arm_movw_movt_addend(val);
    Valtype x = ((psymval->value(object, addend) | thumb_bit)
		 - relative_address_base);
    val = This::insert_val_arm_movw_movt(val, x);
    elfcpp::Swap<32, big_endian>::writeval(wv, val);
    return ((check_overflow && Bits<16>::has_overflow32(x))
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_MOVT_ABS: S + A	(relative address base is 0)
  // R_ARM_MOVT_PREL: S + A - P
  // R_ARM_MOVT_BREL: S + A - B(S)
  static inline typename This::Status
  movt(unsigned char* view,
       const Sized_relobj_file<32, big_endian>* object,
       const Symbol_value<32>* psymval,
       Arm_address relative_address_base)
  {
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype addend = This::extract_arm_movw_movt_addend(val);
    Valtype x = (psymval->value(object, addend) - relative_address_base) >> 16;
    val = This::insert_val_arm_movw_movt(val, x);
    elfcpp::Swap<32, big_endian>::writeval(wv, val);
    // FIXME: IHI0044D says that we should check for overflow.
    return This::STATUS_OKAY;
  }

  // R_ARM_THM_MOVW_ABS_NC: S + A | T		(relative_address_base is 0)
  // R_ARM_THM_MOVW_PREL_NC: (S + A) | T - P
  // R_ARM_THM_MOVW_BREL_NC: ((S + A) | T) - B(S)
  // R_ARM_THM_MOVW_BREL: ((S + A) | T) - B(S)
  static inline typename This::Status
  thm_movw(unsigned char* view,
	   const Sized_relobj_file<32, big_endian>* object,
	   const Symbol_value<32>* psymval,
	   Arm_address relative_address_base,
	   Arm_address thumb_bit,
	   bool check_overflow)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Reltype val = (elfcpp::Swap<16, big_endian>::readval(wv) << 16)
		  | elfcpp::Swap<16, big_endian>::readval(wv + 1);
    Reltype addend = This::extract_thumb_movw_movt_addend(val);
    Reltype x =
      (psymval->value(object, addend) | thumb_bit) - relative_address_base;
    val = This::insert_val_thumb_movw_movt(val, x);
    elfcpp::Swap<16, big_endian>::writeval(wv, val >> 16);
    elfcpp::Swap<16, big_endian>::writeval(wv + 1, val & 0xffff);
    return ((check_overflow && Bits<16>::has_overflow32(x))
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_THM_MOVT_ABS: S + A		(relative address base is 0)
  // R_ARM_THM_MOVT_PREL: S + A - P
  // R_ARM_THM_MOVT_BREL: S + A - B(S)
  static inline typename This::Status
  thm_movt(unsigned char* view,
	   const Sized_relobj_file<32, big_endian>* object,
	   const Symbol_value<32>* psymval,
	   Arm_address relative_address_base)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Reltype val = (elfcpp::Swap<16, big_endian>::readval(wv) << 16)
		  | elfcpp::Swap<16, big_endian>::readval(wv + 1);
    Reltype addend = This::extract_thumb_movw_movt_addend(val);
    Reltype x = (psymval->value(object, addend) - relative_address_base) >> 16;
    val = This::insert_val_thumb_movw_movt(val, x);
    elfcpp::Swap<16, big_endian>::writeval(wv, val >> 16);
    elfcpp::Swap<16, big_endian>::writeval(wv + 1, val & 0xffff);
    return This::STATUS_OKAY;
  }

  // R_ARM_THM_ALU_PREL_11_0: ((S + A) | T) - Pa (Thumb32)
  static inline typename This::Status
  thm_alu11(unsigned char* view,
	    const Sized_relobj_file<32, big_endian>* object,
	    const Symbol_value<32>* psymval,
	    Arm_address address,
	    Arm_address thumb_bit)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Reltype insn = (elfcpp::Swap<16, big_endian>::readval(wv) << 16)
		   | elfcpp::Swap<16, big_endian>::readval(wv + 1);

    //	      f e d c b|a|9|8 7 6 5|4|3 2 1 0||f|e d c|b a 9 8|7 6 5 4 3 2 1 0
    // -----------------------------------------------------------------------
    // ADD{S} 1 1 1 1 0|i|0|1 0 0 0|S|1 1 0 1||0|imm3 |Rd     |imm8
    // ADDW   1 1 1 1 0|i|1|0 0 0 0|0|1 1 0 1||0|imm3 |Rd     |imm8
    // ADR[+] 1 1 1 1 0|i|1|0 0 0 0|0|1 1 1 1||0|imm3 |Rd     |imm8
    // SUB{S} 1 1 1 1 0|i|0|1 1 0 1|S|1 1 0 1||0|imm3 |Rd     |imm8
    // SUBW   1 1 1 1 0|i|1|0 1 0 1|0|1 1 0 1||0|imm3 |Rd     |imm8
    // ADR[-] 1 1 1 1 0|i|1|0 1 0 1|0|1 1 1 1||0|imm3 |Rd     |imm8

    // Determine a sign for the addend.
    const int sign = ((insn & 0xf8ef0000) == 0xf0ad0000
		      || (insn & 0xf8ef0000) == 0xf0af0000) ? -1 : 1;
    // Thumb2 addend encoding:
    // imm12 := i | imm3 | imm8
    int32_t addend = (insn & 0xff)
		     | ((insn & 0x00007000) >> 4)
		     | ((insn & 0x04000000) >> 15);
    // Apply a sign to the added.
    addend *= sign;

    int32_t x = (psymval->value(object, addend) | thumb_bit)
		- (address & 0xfffffffc);
    Reltype val = abs(x);
    // Mask out the value and a distinct part of the ADD/SUB opcode
    // (bits 7:5 of opword).
    insn = (insn & 0xfb0f8f00)
	   | (val & 0xff)
	   | ((val & 0x700) << 4)
	   | ((val & 0x800) << 15);
    // Set the opcode according to whether the value to go in the
    // place is negative.
    if (x < 0)
      insn |= 0x00a00000;

    elfcpp::Swap<16, big_endian>::writeval(wv, insn >> 16);
    elfcpp::Swap<16, big_endian>::writeval(wv + 1, insn & 0xffff);
    return ((val > 0xfff) ?
	    This::STATUS_OVERFLOW : This::STATUS_OKAY);
  }

  // R_ARM_THM_PC8: S + A - Pa (Thumb)
  static inline typename This::Status
  thm_pc8(unsigned char* view,
	  const Sized_relobj_file<32, big_endian>* object,
	  const Symbol_value<32>* psymval,
	  Arm_address address)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype insn = elfcpp::Swap<16, big_endian>::readval(wv);
    Reltype addend = ((insn & 0x00ff) << 2);
    int32_t x = (psymval->value(object, addend) - (address & 0xfffffffc));
    Reltype val = abs(x);
    insn = (insn & 0xff00) | ((val & 0x03fc) >> 2);

    elfcpp::Swap<16, big_endian>::writeval(wv, insn);
    return ((val > 0x03fc)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_THM_PC12: S + A - Pa (Thumb32)
  static inline typename This::Status
  thm_pc12(unsigned char* view,
	   const Sized_relobj_file<32, big_endian>* object,
	   const Symbol_value<32>* psymval,
	   Arm_address address)
  {
    typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Reltype insn = (elfcpp::Swap<16, big_endian>::readval(wv) << 16)
		   | elfcpp::Swap<16, big_endian>::readval(wv + 1);
    // Determine a sign for the addend (positive if the U bit is 1).
    const int sign = (insn & 0x00800000) ? 1 : -1;
    int32_t addend = (insn & 0xfff);
    // Apply a sign to the added.
    addend *= sign;

    int32_t x = (psymval->value(object, addend) - (address & 0xfffffffc));
    Reltype val = abs(x);
    // Mask out and apply the value and the U bit.
    insn = (insn & 0xff7ff000) | (val & 0xfff);
    // Set the U bit according to whether the value to go in the
    // place is positive.
    if (x >= 0)
      insn |= 0x00800000;

    elfcpp::Swap<16, big_endian>::writeval(wv, insn >> 16);
    elfcpp::Swap<16, big_endian>::writeval(wv + 1, insn & 0xffff);
    return ((val > 0xfff) ?
	    This::STATUS_OVERFLOW : This::STATUS_OKAY);
  }

  // R_ARM_V4BX
  static inline typename This::Status
  v4bx(const Relocate_info<32, big_endian>* relinfo,
       unsigned char* view,
       const Arm_relobj<big_endian>* object,
       const Arm_address address,
       const bool is_interworking)
  {

    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);

    // Ensure that we have a BX instruction.
    gold_assert((val & 0x0ffffff0) == 0x012fff10);
    const uint32_t reg = (val & 0xf);
    if (is_interworking && reg != 0xf)
      {
	Stub_table<big_endian>* stub_table =
	    object->stub_table(relinfo->data_shndx);
	gold_assert(stub_table != NULL);

	Arm_v4bx_stub* stub = stub_table->find_arm_v4bx_stub(reg);
	gold_assert(stub != NULL);

	int32_t veneer_address =
	    stub_table->address() + stub->offset() - 8 - address;
	gold_assert((veneer_address <= ARM_MAX_FWD_BRANCH_OFFSET)
		    && (veneer_address >= ARM_MAX_BWD_BRANCH_OFFSET));
	// Replace with a branch to veneer (B <addr>)
	val = (val & 0xf0000000) | 0x0a000000
	      | ((veneer_address >> 2) & 0x00ffffff);
      }
    else
      {
	// Preserve Rm (lowest four bits) and the condition code
	// (highest four bits). Other bits encode MOV PC,Rm.
	val = (val & 0xf000000f) | 0x01a0f000;
      }
    elfcpp::Swap<32, big_endian>::writeval(wv, val);
    return This::STATUS_OKAY;
  }

  // R_ARM_ALU_PC_G0_NC: ((S + A) | T) - P
  // R_ARM_ALU_PC_G0:    ((S + A) | T) - P
  // R_ARM_ALU_PC_G1_NC: ((S + A) | T) - P
  // R_ARM_ALU_PC_G1:    ((S + A) | T) - P
  // R_ARM_ALU_PC_G2:    ((S + A) | T) - P
  // R_ARM_ALU_SB_G0_NC: ((S + A) | T) - B(S)
  // R_ARM_ALU_SB_G0:    ((S + A) | T) - B(S)
  // R_ARM_ALU_SB_G1_NC: ((S + A) | T) - B(S)
  // R_ARM_ALU_SB_G1:    ((S + A) | T) - B(S)
  // R_ARM_ALU_SB_G2:    ((S + A) | T) - B(S)
  static inline typename This::Status
  arm_grp_alu(unsigned char* view,
	const Sized_relobj_file<32, big_endian>* object,
	const Symbol_value<32>* psymval,
	const int group,
	Arm_address address,
	Arm_address thumb_bit,
	bool check_overflow)
  {
    gold_assert(group >= 0 && group < 3);
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype insn = elfcpp::Swap<32, big_endian>::readval(wv);

    // ALU group relocations are allowed only for the ADD/SUB instructions.
    // (0x00800000 - ADD, 0x00400000 - SUB)
    const Valtype opcode = insn & 0x01e00000;
    if (opcode != 0x00800000 && opcode != 0x00400000)
      return This::STATUS_BAD_RELOC;

    // Determine a sign for the addend.
    const int sign = (opcode == 0x00800000) ? 1 : -1;
    // shifter = rotate_imm * 2
    const uint32_t shifter = (insn & 0xf00) >> 7;
    // Initial addend value.
    int32_t addend = insn & 0xff;
    // Rotate addend right by shifter.
    addend = (addend >> shifter) | (addend << (32 - shifter));
    // Apply a sign to the added.
    addend *= sign;

    int32_t x = ((psymval->value(object, addend) | thumb_bit) - address);
    Valtype gn = Arm_relocate_functions::calc_grp_gn(abs(x), group);
    // Check for overflow if required
    if (check_overflow
	&& (Arm_relocate_functions::calc_grp_residual(abs(x), group) != 0))
      return This::STATUS_OVERFLOW;

    // Mask out the value and the ADD/SUB part of the opcode; take care
    // not to destroy the S bit.
    insn &= 0xff1ff000;
    // Set the opcode according to whether the value to go in the
    // place is negative.
    insn |= ((x < 0) ? 0x00400000 : 0x00800000);
    // Encode the offset (encoded Gn).
    insn |= gn;

    elfcpp::Swap<32, big_endian>::writeval(wv, insn);
    return This::STATUS_OKAY;
  }

  // R_ARM_LDR_PC_G0: S + A - P
  // R_ARM_LDR_PC_G1: S + A - P
  // R_ARM_LDR_PC_G2: S + A - P
  // R_ARM_LDR_SB_G0: S + A - B(S)
  // R_ARM_LDR_SB_G1: S + A - B(S)
  // R_ARM_LDR_SB_G2: S + A - B(S)
  static inline typename This::Status
  arm_grp_ldr(unsigned char* view,
	const Sized_relobj_file<32, big_endian>* object,
	const Symbol_value<32>* psymval,
	const int group,
	Arm_address address)
  {
    gold_assert(group >= 0 && group < 3);
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype insn = elfcpp::Swap<32, big_endian>::readval(wv);

    const int sign = (insn & 0x00800000) ? 1 : -1;
    int32_t addend = (insn & 0xfff) * sign;
    int32_t x = (psymval->value(object, addend) - address);
    // Calculate the relevant G(n-1) value to obtain this stage residual.
    Valtype residual =
	Arm_relocate_functions::calc_grp_residual(abs(x), group - 1);
    if (residual >= 0x1000)
      return This::STATUS_OVERFLOW;

    // Mask out the value and U bit.
    insn &= 0xff7ff000;
    // Set the U bit for non-negative values.
    if (x >= 0)
      insn |= 0x00800000;
    insn |= residual;

    elfcpp::Swap<32, big_endian>::writeval(wv, insn);
    return This::STATUS_OKAY;
  }

  // R_ARM_LDRS_PC_G0: S + A - P
  // R_ARM_LDRS_PC_G1: S + A - P
  // R_ARM_LDRS_PC_G2: S + A - P
  // R_ARM_LDRS_SB_G0: S + A - B(S)
  // R_ARM_LDRS_SB_G1: S + A - B(S)
  // R_ARM_LDRS_SB_G2: S + A - B(S)
  static inline typename This::Status
  arm_grp_ldrs(unsigned char* view,
	const Sized_relobj_file<32, big_endian>* object,
	const Symbol_value<32>* psymval,
	const int group,
	Arm_address address)
  {
    gold_assert(group >= 0 && group < 3);
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype insn = elfcpp::Swap<32, big_endian>::readval(wv);

    const int sign = (insn & 0x00800000) ? 1 : -1;
    int32_t addend = (((insn & 0xf00) >> 4) + (insn & 0xf)) * sign;
    int32_t x = (psymval->value(object, addend) - address);
    // Calculate the relevant G(n-1) value to obtain this stage residual.
    Valtype residual =
	Arm_relocate_functions::calc_grp_residual(abs(x), group - 1);
   if (residual >= 0x100)
      return This::STATUS_OVERFLOW;

    // Mask out the value and U bit.
    insn &= 0xff7ff0f0;
    // Set the U bit for non-negative values.
    if (x >= 0)
      insn |= 0x00800000;
    insn |= ((residual & 0xf0) << 4) | (residual & 0xf);

    elfcpp::Swap<32, big_endian>::writeval(wv, insn);
    return This::STATUS_OKAY;
  }

  // R_ARM_LDC_PC_G0: S + A - P
  // R_ARM_LDC_PC_G1: S + A - P
  // R_ARM_LDC_PC_G2: S + A - P
  // R_ARM_LDC_SB_G0: S + A - B(S)
  // R_ARM_LDC_SB_G1: S + A - B(S)
  // R_ARM_LDC_SB_G2: S + A - B(S)
  static inline typename This::Status
  arm_grp_ldc(unsigned char* view,
      const Sized_relobj_file<32, big_endian>* object,
      const Symbol_value<32>* psymval,
      const int group,
      Arm_address address)
  {
    gold_assert(group >= 0 && group < 3);
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype insn = elfcpp::Swap<32, big_endian>::readval(wv);

    const int sign = (insn & 0x00800000) ? 1 : -1;
    int32_t addend = ((insn & 0xff) << 2) * sign;
    int32_t x = (psymval->value(object, addend) - address);
    // Calculate the relevant G(n-1) value to obtain this stage residual.
    Valtype residual =
      Arm_relocate_functions::calc_grp_residual(abs(x), group - 1);
    if ((residual & 0x3) != 0 || residual >= 0x400)
      return This::STATUS_OVERFLOW;

    // Mask out the value and U bit.
    insn &= 0xff7fff00;
    // Set the U bit for non-negative values.
    if (x >= 0)
      insn |= 0x00800000;
    insn |= (residual >> 2);

    elfcpp::Swap<32, big_endian>::writeval(wv, insn);
    return This::STATUS_OKAY;
  }
};

// Relocate ARM long branches.  This handles relocation types
// R_ARM_CALL, R_ARM_JUMP24, R_ARM_PLT32 and R_ARM_XPC25.
// If IS_WEAK_UNDEFINED_WITH_PLT is true.  The target symbol is weakly
// undefined and we do not use PLT in this relocation.  In such a case,
// the branch is converted into an NOP.

template<bool big_endian>
typename Arm_relocate_functions<big_endian>::Status
Arm_relocate_functions<big_endian>::arm_branch_common(
    unsigned int r_type,
    const Relocate_info<32, big_endian>* relinfo,
    unsigned char* view,
    const Sized_symbol<32>* gsym,
    const Arm_relobj<big_endian>* object,
    unsigned int r_sym,
    const Symbol_value<32>* psymval,
    Arm_address address,
    Arm_address thumb_bit,
    bool is_weakly_undefined_without_plt)
{
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
  Valtype* wv = reinterpret_cast<Valtype*>(view);
  Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);

  bool insn_is_b = (((val >> 28) & 0xf) <= 0xe)
		    && ((val & 0x0f000000UL) == 0x0a000000UL);
  bool insn_is_uncond_bl = (val & 0xff000000UL) == 0xeb000000UL;
  bool insn_is_cond_bl = (((val >> 28) & 0xf) < 0xe)
			  && ((val & 0x0f000000UL) == 0x0b000000UL);
  bool insn_is_blx = (val & 0xfe000000UL) == 0xfa000000UL;
  bool insn_is_any_branch = (val & 0x0e000000UL) == 0x0a000000UL;

  // Check that the instruction is valid.
  if (r_type == elfcpp::R_ARM_CALL)
    {
      if (!insn_is_uncond_bl && !insn_is_blx)
	return This::STATUS_BAD_RELOC;
    }
  else if (r_type == elfcpp::R_ARM_JUMP24)
    {
      if (!insn_is_b && !insn_is_cond_bl)
	return This::STATUS_BAD_RELOC;
    }
  else if (r_type == elfcpp::R_ARM_PLT32)
    {
      if (!insn_is_any_branch)
	return This::STATUS_BAD_RELOC;
    }
  else if (r_type == elfcpp::R_ARM_XPC25)
    {
      // FIXME: AAELF document IH0044C does not say much about it other
      // than it being obsolete.
      if (!insn_is_any_branch)
	return This::STATUS_BAD_RELOC;
    }
  else
    gold_unreachable();

  // A branch to an undefined weak symbol is turned into a jump to
  // the next instruction unless a PLT entry will be created.
  // Do the same for local undefined symbols.
  // The jump to the next instruction is optimized as a NOP depending
  // on the architecture.
  const Target_arm<big_endian>* arm_target =
    Target_arm<big_endian>::default_target();
  if (is_weakly_undefined_without_plt)
    {
      gold_assert(!parameters->options().relocatable());
      Valtype cond = val & 0xf0000000U;
      if (arm_target->may_use_arm_nop())
	val = cond | 0x0320f000;
      else
	val = cond | 0x01a00000;	// Using pre-UAL nop: mov r0, r0.
      elfcpp::Swap<32, big_endian>::writeval(wv, val);
      return This::STATUS_OKAY;
    }

  Valtype addend = Bits<26>::sign_extend32(val << 2);
  Valtype branch_target = psymval->value(object, addend);
  int32_t branch_offset = branch_target - address;

  // We need a stub if the branch offset is too large or if we need
  // to switch mode.
  bool may_use_blx = arm_target->may_use_v5t_interworking();
  Reloc_stub* stub = NULL;

  if (!parameters->options().relocatable()
      && (Bits<26>::has_overflow32(branch_offset)
	  || ((thumb_bit != 0)
	      && !(may_use_blx && r_type == elfcpp::R_ARM_CALL))))
    {
      Valtype unadjusted_branch_target = psymval->value(object, 0);

      Stub_type stub_type =
	Reloc_stub::stub_type_for_reloc(r_type, address,
					unadjusted_branch_target,
					(thumb_bit != 0));
      if (stub_type != arm_stub_none)
	{
	  Stub_table<big_endian>* stub_table =
	    object->stub_table(relinfo->data_shndx);
	  gold_assert(stub_table != NULL);

	  Reloc_stub::Key stub_key(stub_type, gsym, object, r_sym, addend);
	  stub = stub_table->find_reloc_stub(stub_key);
	  gold_assert(stub != NULL);
	  thumb_bit = stub->stub_template()->entry_in_thumb_mode() ? 1 : 0;
	  branch_target = stub_table->address() + stub->offset() + addend;
	  branch_offset = branch_target - address;
	  gold_assert(!Bits<26>::has_overflow32(branch_offset));
	}
    }

  // At this point, if we still need to switch mode, the instruction
  // must either be a BLX or a BL that can be converted to a BLX.
  if (thumb_bit != 0)
    {
      // Turn BL to BLX.
      gold_assert(may_use_blx && r_type == elfcpp::R_ARM_CALL);
      val = (val & 0xffffff) | 0xfa000000 | ((branch_offset & 2) << 23);
    }

  val = Bits<32>::bit_select32(val, (branch_offset >> 2), 0xffffffUL);
  elfcpp::Swap<32, big_endian>::writeval(wv, val);
  return (Bits<26>::has_overflow32(branch_offset)
	  ? This::STATUS_OVERFLOW
	  : This::STATUS_OKAY);
}

// Relocate THUMB long branches.  This handles relocation types
// R_ARM_THM_CALL, R_ARM_THM_JUMP24 and R_ARM_THM_XPC22.
// If IS_WEAK_UNDEFINED_WITH_PLT is true.  The target symbol is weakly
// undefined and we do not use PLT in this relocation.  In such a case,
// the branch is converted into an NOP.

template<bool big_endian>
typename Arm_relocate_functions<big_endian>::Status
Arm_relocate_functions<big_endian>::thumb_branch_common(
    unsigned int r_type,
    const Relocate_info<32, big_endian>* relinfo,
    unsigned char* view,
    const Sized_symbol<32>* gsym,
    const Arm_relobj<big_endian>* object,
    unsigned int r_sym,
    const Symbol_value<32>* psymval,
    Arm_address address,
    Arm_address thumb_bit,
    bool is_weakly_undefined_without_plt)
{
  typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
  Valtype* wv = reinterpret_cast<Valtype*>(view);
  uint32_t upper_insn = elfcpp::Swap<16, big_endian>::readval(wv);
  uint32_t lower_insn = elfcpp::Swap<16, big_endian>::readval(wv + 1);

  // FIXME: These tests are too loose and do not take THUMB/THUMB-2 difference
  // into account.
  bool is_bl_insn = (lower_insn & 0x1000U) == 0x1000U;
  bool is_blx_insn = (lower_insn & 0x1000U) == 0x0000U;

  // Check that the instruction is valid.
  if (r_type == elfcpp::R_ARM_THM_CALL)
    {
      if (!is_bl_insn && !is_blx_insn)
	return This::STATUS_BAD_RELOC;
    }
  else if (r_type == elfcpp::R_ARM_THM_JUMP24)
    {
      // This cannot be a BLX.
      if (!is_bl_insn)
	return This::STATUS_BAD_RELOC;
    }
  else if (r_type == elfcpp::R_ARM_THM_XPC22)
    {
      // Check for Thumb to Thumb call.
      if (!is_blx_insn)
	return This::STATUS_BAD_RELOC;
      if (thumb_bit != 0)
	{
	  gold_warning(_("%s: Thumb BLX instruction targets "
			 "thumb function '%s'."),
			 object->name().c_str(),
			 (gsym ? gsym->name() : "(local)"));
	  // Convert BLX to BL.
	  lower_insn |= 0x1000U;
	}
    }
  else
    gold_unreachable();

  // A branch to an undefined weak symbol is turned into a jump to
  // the next instruction unless a PLT entry will be created.
  // The jump to the next instruction is optimized as a NOP.W for
  // Thumb-2 enabled architectures.
  const Target_arm<big_endian>* arm_target =
    Target_arm<big_endian>::default_target();
  if (is_weakly_undefined_without_plt)
    {
      gold_assert(!parameters->options().relocatable());
      if (arm_target->may_use_thumb2_nop())
	{
	  elfcpp::Swap<16, big_endian>::writeval(wv, 0xf3af);
	  elfcpp::Swap<16, big_endian>::writeval(wv + 1, 0x8000);
	}
      else
	{
	  elfcpp::Swap<16, big_endian>::writeval(wv, 0xe000);
	  elfcpp::Swap<16, big_endian>::writeval(wv + 1, 0xbf00);
	}
      return This::STATUS_OKAY;
    }

  int32_t addend = This::thumb32_branch_offset(upper_insn, lower_insn);
  Arm_address branch_target = psymval->value(object, addend);

  // For BLX, bit 1 of target address comes from bit 1 of base address.
  bool may_use_blx = arm_target->may_use_v5t_interworking();
  if (thumb_bit == 0 && may_use_blx)
    branch_target = Bits<32>::bit_select32(branch_target, address, 0x2);

  int32_t branch_offset = branch_target - address;

  // We need a stub if the branch offset is too large or if we need
  // to switch mode.
  bool thumb2 = arm_target->using_thumb2();
  if (!parameters->options().relocatable()
      && ((!thumb2 && Bits<23>::has_overflow32(branch_offset))
	  || (thumb2 && Bits<25>::has_overflow32(branch_offset))
	  || ((thumb_bit == 0)
	      && (((r_type == elfcpp::R_ARM_THM_CALL) && !may_use_blx)
		  || r_type == elfcpp::R_ARM_THM_JUMP24))))
    {
      Arm_address unadjusted_branch_target = psymval->value(object, 0);

      Stub_type stub_type =
	Reloc_stub::stub_type_for_reloc(r_type, address,
					unadjusted_branch_target,
					(thumb_bit != 0));

      if (stub_type != arm_stub_none)
	{
	  Stub_table<big_endian>* stub_table =
	    object->stub_table(relinfo->data_shndx);
	  gold_assert(stub_table != NULL);

	  Reloc_stub::Key stub_key(stub_type, gsym, object, r_sym, addend);
	  Reloc_stub* stub = stub_table->find_reloc_stub(stub_key);
	  gold_assert(stub != NULL);
	  thumb_bit = stub->stub_template()->entry_in_thumb_mode() ? 1 : 0;
	  branch_target = stub_table->address() + stub->offset() + addend;
	  if (thumb_bit == 0 && may_use_blx)
	    branch_target = Bits<32>::bit_select32(branch_target, address, 0x2);
	  branch_offset = branch_target - address;
	}
    }

  // At this point, if we still need to switch mode, the instruction
  // must either be a BLX or a BL that can be converted to a BLX.
  if (thumb_bit == 0)
    {
      gold_assert(may_use_blx
		  && (r_type == elfcpp::R_ARM_THM_CALL
		      || r_type == elfcpp::R_ARM_THM_XPC22));
      // Make sure this is a BLX.
      lower_insn &= ~0x1000U;
    }
  else
    {
      // Make sure this is a BL.
      lower_insn |= 0x1000U;
    }

  // For a BLX instruction, make sure that the relocation is rounded up
  // to a word boundary.  This follows the semantics of the instruction
  // which specifies that bit 1 of the target address will come from bit
  // 1 of the base address.
  if ((lower_insn & 0x5000U) == 0x4000U)
    gold_assert((branch_offset & 3) == 0);

  // Put BRANCH_OFFSET back into the insn.  Assumes two's complement.
  // We use the Thumb-2 encoding, which is safe even if dealing with
  // a Thumb-1 instruction by virtue of our overflow check above.  */
  upper_insn = This::thumb32_branch_upper(upper_insn, branch_offset);
  lower_insn = This::thumb32_branch_lower(lower_insn, branch_offset);

  elfcpp::Swap<16, big_endian>::writeval(wv, upper_insn);
  elfcpp::Swap<16, big_endian>::writeval(wv + 1, lower_insn);

  gold_assert(!Bits<25>::has_overflow32(branch_offset));

  return ((thumb2
	   ? Bits<25>::has_overflow32(branch_offset)
	   : Bits<23>::has_overflow32(branch_offset))
	  ? This::STATUS_OVERFLOW
	  : This::STATUS_OKAY);
}

// Relocate THUMB-2 long conditional branches.
// If IS_WEAK_UNDEFINED_WITH_PLT is true.  The target symbol is weakly
// undefined and we do not use PLT in this relocation.  In such a case,
// the branch is converted into an NOP.

template<bool big_endian>
typename Arm_relocate_functions<big_endian>::Status
Arm_relocate_functions<big_endian>::thm_jump19(
    unsigned char* view,
    const Arm_relobj<big_endian>* object,
    const Symbol_value<32>* psymval,
    Arm_address address,
    Arm_address thumb_bit)
{
  typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
  Valtype* wv = reinterpret_cast<Valtype*>(view);
  uint32_t upper_insn = elfcpp::Swap<16, big_endian>::readval(wv);
  uint32_t lower_insn = elfcpp::Swap<16, big_endian>::readval(wv + 1);
  int32_t addend = This::thumb32_cond_branch_offset(upper_insn, lower_insn);

  Arm_address branch_target = psymval->value(object, addend);
  int32_t branch_offset = branch_target - address;

  // ??? Should handle interworking?  GCC might someday try to
  // use this for tail calls.
  // FIXME: We do support thumb entry to PLT yet.
  if (thumb_bit == 0)
    {
      gold_error(_("conditional branch to PLT in THUMB-2 not supported yet."));
      return This::STATUS_BAD_RELOC;
    }

  // Put RELOCATION back into the insn.
  upper_insn = This::thumb32_cond_branch_upper(upper_insn, branch_offset);
  lower_insn = This::thumb32_cond_branch_lower(lower_insn, branch_offset);

  // Put the relocated value back in the object file:
  elfcpp::Swap<16, big_endian>::writeval(wv, upper_insn);
  elfcpp::Swap<16, big_endian>::writeval(wv + 1, lower_insn);

  return (Bits<21>::has_overflow32(branch_offset)
	  ? This::STATUS_OVERFLOW
	  : This::STATUS_OKAY);
}

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

template<bool big_endian>
Arm_output_data_got<big_endian>*
Target_arm<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 as a relro section.
      // Without -z now, it is modified after program startup by lazy
      // PLT relocations.
      bool is_got_relro = parameters->options().now();
      Output_section_order got_order = (is_got_relro
					? ORDER_RELRO_LAST
					: ORDER_DATA);

      // Unlike some targets (.e.g x86), ARM does not use separate .got and
      // .got.plt sections in output.  The output .got section contains both
      // PLT and non-PLT GOT entries.
      this->got_ = new Arm_output_data_got<big_endian>(symtab, layout);

      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
				      this->got_, got_order, is_got_relro);

      // The old GNU linker creates a .got.plt section.  We just
      // create another set of data in the .got section.  Note that we
      // always create a PLT if we create a GOT, although the PLT
      // might be empty.
      this->got_plt_ = new Output_data_space(4, "** GOT PLT");
      layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
				      (elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE),
				      this->got_plt_, got_order, is_got_relro);

      // The first three entries are reserved.
      this->got_plt_->set_current_data_size(3 * 4);

      // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT.
      symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL,
				    Symbol_table::PREDEFINED,
				    this->got_plt_,
				    0, 0, elfcpp::STT_OBJECT,
				    elfcpp::STB_LOCAL,
				    elfcpp::STV_HIDDEN, 0,
				    false, false);
    }
  return this->got_;
}

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

template<bool big_endian>
typename Target_arm<big_endian>::Reloc_section*
Target_arm<big_endian>::rel_dyn_section(Layout* layout)
{
  if (this->rel_dyn_ == NULL)
    {
      gold_assert(layout != NULL);
      this->rel_dyn_ = new Reloc_section(parameters->options().combreloc());
      layout->add_output_section_data(".rel.dyn", elfcpp::SHT_REL,
				      elfcpp::SHF_ALLOC, this->rel_dyn_,
				      ORDER_DYNAMIC_RELOCS, false);
    }
  return this->rel_dyn_;
}

// Insn_template methods.

// Return byte size of an instruction template.

size_t
Insn_template::size() const
{
  switch (this->type())
    {
    case THUMB16_TYPE:
    case THUMB16_SPECIAL_TYPE:
      return 2;
    case ARM_TYPE:
    case THUMB32_TYPE:
    case DATA_TYPE:
      return 4;
    default:
      gold_unreachable();
    }
}

// Return alignment of an instruction template.

unsigned
Insn_template::alignment() const
{
  switch (this->type())
    {
    case THUMB16_TYPE:
    case THUMB16_SPECIAL_TYPE:
    case THUMB32_TYPE:
      return 2;
    case ARM_TYPE:
    case DATA_TYPE:
      return 4;
    default:
      gold_unreachable();
    }
}

// Stub_template methods.

Stub_template::Stub_template(
    Stub_type type, const Insn_template* insns,
     size_t insn_count)
  : type_(type), insns_(insns), insn_count_(insn_count), alignment_(1),
    entry_in_thumb_mode_(false), relocs_()
{
  off_t offset = 0;

  // Compute byte size and alignment of stub template.
  for (size_t i = 0; i < insn_count; i++)
    {
      unsigned insn_alignment = insns[i].alignment();
      size_t insn_size = insns[i].size();
      gold_assert((offset & (insn_alignment - 1)) == 0);
      this->alignment_ = std::max(this->alignment_, insn_alignment);
      switch (insns[i].type())
	{
	case Insn_template::THUMB16_TYPE:
	case Insn_template::THUMB16_SPECIAL_TYPE:
	  if (i == 0)
	    this->entry_in_thumb_mode_ = true;
	  break;

	case Insn_template::THUMB32_TYPE:
	  if (insns[i].r_type() != elfcpp::R_ARM_NONE)
	    this->relocs_.push_back(Reloc(i, offset));
	  if (i == 0)
	    this->entry_in_thumb_mode_ = true;
	  break;

	case Insn_template::ARM_TYPE:
	  // Handle cases where the target is encoded within the
	  // instruction.
	  if (insns[i].r_type() == elfcpp::R_ARM_JUMP24)
	    this->relocs_.push_back(Reloc(i, offset));
	  break;

	case Insn_template::DATA_TYPE:
	  // Entry point cannot be data.
	  gold_assert(i != 0);
	  this->relocs_.push_back(Reloc(i, offset));
	  break;

	default:
	  gold_unreachable();
	}
      offset += insn_size;
    }
  this->size_ = offset;
}

// Stub methods.

// Template to implement do_write for a specific target endianness.

template<bool big_endian>
void inline
Stub::do_fixed_endian_write(unsigned char* view, section_size_type view_size)
{
  const Stub_template* stub_template = this->stub_template();
  const Insn_template* insns = stub_template->insns();

  // FIXME:  We do not handle BE8 encoding yet.
  unsigned char* pov = view;
  for (size_t i = 0; i < stub_template->insn_count(); i++)
    {
      switch (insns[i].type())
	{
	case Insn_template::THUMB16_TYPE:
	  elfcpp::Swap<16, big_endian>::writeval(pov, insns[i].data() & 0xffff);
	  break;
	case Insn_template::THUMB16_SPECIAL_TYPE:
	  elfcpp::Swap<16, big_endian>::writeval(
	      pov,
	      this->thumb16_special(i));
	  break;
	case Insn_template::THUMB32_TYPE:
	  {
	    uint32_t hi = (insns[i].data() >> 16) & 0xffff;
	    uint32_t lo = insns[i].data() & 0xffff;
	    elfcpp::Swap<16, big_endian>::writeval(pov, hi);
	    elfcpp::Swap<16, big_endian>::writeval(pov + 2, lo);
	  }
	  break;
	case Insn_template::ARM_TYPE:
	case Insn_template::DATA_TYPE:
	  elfcpp::Swap<32, big_endian>::writeval(pov, insns[i].data());
	  break;
	default:
	  gold_unreachable();
	}
      pov += insns[i].size();
    }
  gold_assert(static_cast<section_size_type>(pov - view) == view_size);
}

// Reloc_stub::Key methods.

// Dump a Key as a string for debugging.

std::string
Reloc_stub::Key::name() const
{
  if (this->r_sym_ == invalid_index)
    {
      // Global symbol key name
      // <stub-type>:<symbol name>:<addend>.
      const std::string sym_name = this->u_.symbol->name();
      // We need to print two hex number and two colons.  So just add 100 bytes
      // to the symbol name size.
      size_t len = sym_name.size() + 100;
      char* buffer = new char[len];
      int c = snprintf(buffer, len, "%d:%s:%x", this->stub_type_,
		       sym_name.c_str(), this->addend_);
      gold_assert(c > 0 && c < static_cast<int>(len));
      delete[] buffer;
      return std::string(buffer);
    }
  else
    {
      // local symbol key name
      // <stub-type>:<object>:<r_sym>:<addend>.
      const size_t len = 200;
      char buffer[len];
      int c = snprintf(buffer, len, "%d:%p:%u:%x", this->stub_type_,
		       this->u_.relobj, this->r_sym_, this->addend_);
      gold_assert(c > 0 && c < static_cast<int>(len));
      return std::string(buffer);
    }
}

// Reloc_stub methods.

// Determine the type of stub needed, if any, for a relocation of R_TYPE at
// LOCATION to DESTINATION.
// This code is based on the arm_type_of_stub function in
// bfd/elf32-arm.c.  We have changed the interface a little to keep the Stub
// class simple.

Stub_type
Reloc_stub::stub_type_for_reloc(
   unsigned int r_type,
   Arm_address location,
   Arm_address destination,
   bool target_is_thumb)
{
  Stub_type stub_type = arm_stub_none;

  // This is a bit ugly but we want to avoid using a templated class for
  // big and little endianities.
  bool may_use_blx;
  bool should_force_pic_veneer;
  bool thumb2;
  bool thumb_only;
  if (parameters->target().is_big_endian())
    {
      const Target_arm<true>* big_endian_target =
	Target_arm<true>::default_target();
      may_use_blx = big_endian_target->may_use_v5t_interworking();
      should_force_pic_veneer = big_endian_target->should_force_pic_veneer();
      thumb2 = big_endian_target->using_thumb2();
      thumb_only = big_endian_target->using_thumb_only();
    }
  else
    {
      const Target_arm<false>* little_endian_target =
	Target_arm<false>::default_target();
      may_use_blx = little_endian_target->may_use_v5t_interworking();
      should_force_pic_veneer = little_endian_target->should_force_pic_veneer();
      thumb2 = little_endian_target->using_thumb2();
      thumb_only = little_endian_target->using_thumb_only();
    }

  int64_t branch_offset;
  bool output_is_position_independent =
      parameters->options().output_is_position_independent();
  if (r_type == elfcpp::R_ARM_THM_CALL || r_type == elfcpp::R_ARM_THM_JUMP24)
    {
      // For THUMB BLX instruction, bit 1 of target comes from bit 1 of the
      // base address (instruction address + 4).
      if ((r_type == elfcpp::R_ARM_THM_CALL) && may_use_blx && !target_is_thumb)
	destination = Bits<32>::bit_select32(destination, location, 0x2);
      branch_offset = static_cast<int64_t>(destination) - location;

      // Handle cases where:
      // - this call goes too far (different Thumb/Thumb2 max
      //   distance)
      // - it's a Thumb->Arm call and blx is not available, or it's a
      //   Thumb->Arm branch (not bl). A stub is needed in this case.
      if ((!thumb2
	    && (branch_offset > THM_MAX_FWD_BRANCH_OFFSET
		|| (branch_offset < THM_MAX_BWD_BRANCH_OFFSET)))
	  || (thumb2
	      && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
		  || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
	  || ((!target_is_thumb)
	      && (((r_type == elfcpp::R_ARM_THM_CALL) && !may_use_blx)
		  || (r_type == elfcpp::R_ARM_THM_JUMP24))))
	{
	  if (target_is_thumb)
	    {
	      // Thumb to thumb.
	      if (!thumb_only)
		{
		  stub_type = (output_is_position_independent
			       || should_force_pic_veneer)
		    // PIC stubs.
		    ? ((may_use_blx
			&& (r_type == elfcpp::R_ARM_THM_CALL))
		       // V5T and above. Stub starts with ARM code, so
		       // we must be able to switch mode before
		       // reaching it, which is only possible for 'bl'
		       // (ie R_ARM_THM_CALL relocation).
		       ? arm_stub_long_branch_any_thumb_pic
		       // On V4T, use Thumb code only.
		       : arm_stub_long_branch_v4t_thumb_thumb_pic)

		    // non-PIC stubs.
		    : ((may_use_blx
			&& (r_type == elfcpp::R_ARM_THM_CALL))
		       ? arm_stub_long_branch_any_any // V5T and above.
		       : arm_stub_long_branch_v4t_thumb_thumb);	// V4T.
		}
	      else
		{
		  stub_type = (output_is_position_independent
			       || should_force_pic_veneer)
		    ? arm_stub_long_branch_thumb_only_pic	// PIC stub.
		    : arm_stub_long_branch_thumb_only;	// non-PIC stub.
		}
	    }
	  else
	    {
	      // Thumb to arm.

	      // FIXME: We should check that the input section is from an
	      // object that has interwork enabled.

	      stub_type = (output_is_position_independent
			   || should_force_pic_veneer)
		// PIC stubs.
		? ((may_use_blx
		    && (r_type == elfcpp::R_ARM_THM_CALL))
		   ? arm_stub_long_branch_any_arm_pic	// V5T and above.
		   : arm_stub_long_branch_v4t_thumb_arm_pic)	// V4T.

		// non-PIC stubs.
		: ((may_use_blx
		    && (r_type == elfcpp::R_ARM_THM_CALL))
		   ? arm_stub_long_branch_any_any	// V5T and above.
		   : arm_stub_long_branch_v4t_thumb_arm);	// V4T.

	      // Handle v4t short branches.
	      if ((stub_type == arm_stub_long_branch_v4t_thumb_arm)
		  && (branch_offset <= THM_MAX_FWD_BRANCH_OFFSET)
		  && (branch_offset >= THM_MAX_BWD_BRANCH_OFFSET))
		stub_type = arm_stub_short_branch_v4t_thumb_arm;
	    }
	}
    }
  else if (r_type == elfcpp::R_ARM_CALL
	   || r_type == elfcpp::R_ARM_JUMP24
	   || r_type == elfcpp::R_ARM_PLT32)
    {
      branch_offset = static_cast<int64_t>(destination) - location;
      if (target_is_thumb)
	{
	  // Arm to thumb.

	  // FIXME: We should check that the input section is from an
	  // object that has interwork enabled.

	  // We have an extra 2-bytes reach because of
	  // the mode change (bit 24 (H) of BLX encoding).
	  if (branch_offset > (ARM_MAX_FWD_BRANCH_OFFSET + 2)
	      || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET)
	      || ((r_type == elfcpp::R_ARM_CALL) && !may_use_blx)
	      || (r_type == elfcpp::R_ARM_JUMP24)
	      || (r_type == elfcpp::R_ARM_PLT32))
	    {
	      stub_type = (output_is_position_independent
			   || should_force_pic_veneer)
		// PIC stubs.
		? (may_use_blx
		   ? arm_stub_long_branch_any_thumb_pic// V5T and above.
		   : arm_stub_long_branch_v4t_arm_thumb_pic)	// V4T stub.

		// non-PIC stubs.
		: (may_use_blx
		   ? arm_stub_long_branch_any_any	// V5T and above.
		   : arm_stub_long_branch_v4t_arm_thumb);	// V4T.
	    }
	}
      else
	{
	  // Arm to arm.
	  if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
	      || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
	    {
	      stub_type = (output_is_position_independent
			   || should_force_pic_veneer)
		? arm_stub_long_branch_any_arm_pic	// PIC stubs.
		: arm_stub_long_branch_any_any;		/// non-PIC.
	    }
	}
    }

  return stub_type;
}

// Cortex_a8_stub methods.

// Return the instruction for a THUMB16_SPECIAL_TYPE instruction template.
// I is the position of the instruction template in the stub template.

uint16_t
Cortex_a8_stub::do_thumb16_special(size_t i)
{
  // The only use of this is to copy condition code from a conditional
  // branch being worked around to the corresponding conditional branch in
  // to the stub.
  gold_assert(this->stub_template()->type() == arm_stub_a8_veneer_b_cond
	      && i == 0);
  uint16_t data = this->stub_template()->insns()[i].data();
  gold_assert((data & 0xff00U) == 0xd000U);
  data |= ((this->original_insn_ >> 22) & 0xf) << 8;
  return data;
}

// Stub_factory methods.

Stub_factory::Stub_factory()
{
  // The instruction template sequences are declared as static
  // objects and initialized first time the constructor runs.

  // Arm/Thumb -> Arm/Thumb long branch stub. On V5T and above, use blx
  // to reach the stub if necessary.
  static const Insn_template elf32_arm_stub_long_branch_any_any[] =
    {
      Insn_template::arm_insn(0xe51ff004),	// ldr   pc, [pc, #-4]
      Insn_template::data_word(0, elfcpp::R_ARM_ABS32, 0),
						// dcd   R_ARM_ABS32(X)
    };

  // V4T Arm -> Thumb long branch stub. Used on V4T where blx is not
  // available.
  static const Insn_template elf32_arm_stub_long_branch_v4t_arm_thumb[] =
    {
      Insn_template::arm_insn(0xe59fc000),	// ldr   ip, [pc, #0]
      Insn_template::arm_insn(0xe12fff1c),	// bx    ip
      Insn_template::data_word(0, elfcpp::R_ARM_ABS32, 0),
						// dcd   R_ARM_ABS32(X)
    };

  // Thumb -> Thumb long branch stub. Used on M-profile architectures.
  static const Insn_template elf32_arm_stub_long_branch_thumb_only[] =
    {
      Insn_template::thumb16_insn(0xb401),	// push {r0}
      Insn_template::thumb16_insn(0x4802),	// ldr  r0, [pc, #8]
      Insn_template::thumb16_insn(0x4684),	// mov  ip, r0
      Insn_template::thumb16_insn(0xbc01),	// pop  {r0}
      Insn_template::thumb16_insn(0x4760),	// bx   ip
      Insn_template::thumb16_insn(0xbf00),	// nop
      Insn_template::data_word(0, elfcpp::R_ARM_ABS32, 0),
						// dcd  R_ARM_ABS32(X)
    };

  // V4T Thumb -> Thumb long branch stub. Using the stack is not
  // allowed.
  static const Insn_template elf32_arm_stub_long_branch_v4t_thumb_thumb[] =
    {
      Insn_template::thumb16_insn(0x4778),	// bx   pc
      Insn_template::thumb16_insn(0x46c0),	// nop
      Insn_template::arm_insn(0xe59fc000),	// ldr  ip, [pc, #0]
      Insn_template::arm_insn(0xe12fff1c),	// bx   ip
      Insn_template::data_word(0, elfcpp::R_ARM_ABS32, 0),
						// dcd  R_ARM_ABS32(X)
    };

  // V4T Thumb -> ARM long branch stub. Used on V4T where blx is not
  // available.
  static const Insn_template elf32_arm_stub_long_branch_v4t_thumb_arm[] =
    {
      Insn_template::thumb16_insn(0x4778),	// bx   pc
      Insn_template::thumb16_insn(0x46c0),	// nop
      Insn_template::arm_insn(0xe51ff004),	// ldr   pc, [pc, #-4]
      Insn_template::data_word(0, elfcpp::R_ARM_ABS32, 0),
						// dcd   R_ARM_ABS32(X)
    };

  // V4T Thumb -> ARM short branch stub. Shorter variant of the above
  // one, when the destination is close enough.
  static const Insn_template elf32_arm_stub_short_branch_v4t_thumb_arm[] =
    {
      Insn_template::thumb16_insn(0x4778),		// bx   pc
      Insn_template::thumb16_insn(0x46c0),		// nop
      Insn_template::arm_rel_insn(0xea000000, -8),	// b    (X-8)
    };

  // ARM/Thumb -> ARM long branch stub, PIC.  On V5T and above, use
  // blx to reach the stub if necessary.
  static const Insn_template elf32_arm_stub_long_branch_any_arm_pic[] =
    {
      Insn_template::arm_insn(0xe59fc000),	// ldr   r12, [pc]
      Insn_template::arm_insn(0xe08ff00c),	// add   pc, pc, ip
      Insn_template::data_word(0, elfcpp::R_ARM_REL32, -4),
						// dcd   R_ARM_REL32(X-4)
    };

  // ARM/Thumb -> Thumb long branch stub, PIC.  On V5T and above, use
  // blx to reach the stub if necessary.  We can not add into pc;
  // it is not guaranteed to mode switch (different in ARMv6 and
  // ARMv7).
  static const Insn_template elf32_arm_stub_long_branch_any_thumb_pic[] =
    {
      Insn_template::arm_insn(0xe59fc004),	// ldr   r12, [pc, #4]
      Insn_template::arm_insn(0xe08fc00c),	// add   ip, pc, ip
      Insn_template::arm_insn(0xe12fff1c),	// bx    ip
      Insn_template::data_word(0, elfcpp::R_ARM_REL32, 0),
						// dcd   R_ARM_REL32(X)
    };

  // V4T ARM -> ARM long branch stub, PIC.
  static const Insn_template elf32_arm_stub_long_branch_v4t_arm_thumb_pic[] =
    {
      Insn_template::arm_insn(0xe59fc004),	// ldr   ip, [pc, #4]
      Insn_template::arm_insn(0xe08fc00c),	// add   ip, pc, ip
      Insn_template::arm_insn(0xe12fff1c),	// bx    ip
      Insn_template::data_word(0, elfcpp::R_ARM_REL32, 0),
						// dcd   R_ARM_REL32(X)
    };

  // V4T Thumb -> ARM long branch stub, PIC.
  static const Insn_template elf32_arm_stub_long_branch_v4t_thumb_arm_pic[] =
    {
      Insn_template::thumb16_insn(0x4778),	// bx   pc
      Insn_template::thumb16_insn(0x46c0),	// nop
      Insn_template::arm_insn(0xe59fc000),	// ldr  ip, [pc, #0]
      Insn_template::arm_insn(0xe08cf00f),	// add  pc, ip, pc
      Insn_template::data_word(0, elfcpp::R_ARM_REL32, -4),
						// dcd  R_ARM_REL32(X)
    };

  // Thumb -> Thumb long branch stub, PIC. Used on M-profile
  // architectures.
  static const Insn_template elf32_arm_stub_long_branch_thumb_only_pic[] =
    {
      Insn_template::thumb16_insn(0xb401),	// push {r0}
      Insn_template::thumb16_insn(0x4802),	// ldr  r0, [pc, #8]
      Insn_template::thumb16_insn(0x46fc),	// mov  ip, pc
      Insn_template::thumb16_insn(0x4484),	// add  ip, r0
      Insn_template::thumb16_insn(0xbc01),	// pop  {r0}
      Insn_template::thumb16_insn(0x4760),	// bx   ip
      Insn_template::data_word(0, elfcpp::R_ARM_REL32, 4),
						// dcd  R_ARM_REL32(X)
    };

  // V4T Thumb -> Thumb long branch stub, PIC. Using the stack is not
  // allowed.
  static const Insn_template elf32_arm_stub_long_branch_v4t_thumb_thumb_pic[] =
    {
      Insn_template::thumb16_insn(0x4778),	// bx   pc
      Insn_template::thumb16_insn(0x46c0),	// nop
      Insn_template::arm_insn(0xe59fc004),	// ldr  ip, [pc, #4]
      Insn_template::arm_insn(0xe08fc00c),	// add   ip, pc, ip
      Insn_template::arm_insn(0xe12fff1c),	// bx   ip
      Insn_template::data_word(0, elfcpp::R_ARM_REL32, 0),
						// dcd  R_ARM_REL32(X)
    };

  // Cortex-A8 erratum-workaround stubs.

  // Stub used for conditional branches (which may be beyond +/-1MB away,
  // so we can't use a conditional branch to reach this stub).

  // original code:
  //
  // 	b<cond> X
  // after:
  //
  static const Insn_template elf32_arm_stub_a8_veneer_b_cond[] =
    {
      Insn_template::thumb16_bcond_insn(0xd001),	//	b<cond>.n true
      Insn_template::thumb32_b_insn(0xf000b800, -4),	//	b.w after
      Insn_template::thumb32_b_insn(0xf000b800, -4)	// true:
							//	b.w X
    };

  // Stub used for b.w and bl.w instructions.

  static const Insn_template elf32_arm_stub_a8_veneer_b[] =
    {
      Insn_template::thumb32_b_insn(0xf000b800, -4)	// b.w dest
    };

  static const Insn_template elf32_arm_stub_a8_veneer_bl[] =
    {
      Insn_template::thumb32_b_insn(0xf000b800, -4)	// b.w dest
    };

  // Stub used for Thumb-2 blx.w instructions.  We modified the original blx.w
  // instruction (which switches to ARM mode) to point to this stub.  Jump to
  // the real destination using an ARM-mode branch.
  static const Insn_template elf32_arm_stub_a8_veneer_blx[] =
    {
      Insn_template::arm_rel_insn(0xea000000, -8)	// b dest
    };

  // Stub used to provide an interworking for R_ARM_V4BX relocation
  // (bx r[n] instruction).
  static const Insn_template elf32_arm_stub_v4_veneer_bx[] =
    {
      Insn_template::arm_insn(0xe3100001),		// tst   r<n>, #1
      Insn_template::arm_insn(0x01a0f000),		// moveq pc, r<n>
      Insn_template::arm_insn(0xe12fff10)		// bx    r<n>
    };

  // Fill in the stub template look-up table.  Stub templates are constructed
  // per instance of Stub_factory for fast look-up without locking
  // in a thread-enabled environment.

  this->stub_templates_[arm_stub_none] =
    new Stub_template(arm_stub_none, NULL, 0);

#define DEF_STUB(x)	\
  do \
    { \
      size_t array_size \
	= sizeof(elf32_arm_stub_##x) / sizeof(elf32_arm_stub_##x[0]); \
      Stub_type type = arm_stub_##x; \
      this->stub_templates_[type] = \
	new Stub_template(type, elf32_arm_stub_##x, array_size); \
    } \
  while (0);

  DEF_STUBS
#undef DEF_STUB
}

// Stub_table methods.

// Remove all Cortex-A8 stub.

template<bool big_endian>
void
Stub_table<big_endian>::remove_all_cortex_a8_stubs()
{
  for (Cortex_a8_stub_list::iterator p = this->cortex_a8_stubs_.begin();
       p != this->cortex_a8_stubs_.end();
       ++p)
    delete p->second;
  this->cortex_a8_stubs_.clear();
}

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

template<bool big_endian>
void
Stub_table<big_endian>::relocate_stub(
    Stub* stub,
    const Relocate_info<32, big_endian>* relinfo,
    Target_arm<big_endian>* arm_target,
    Output_section* output_section,
    unsigned char* view,
    Arm_address address,
    section_size_type view_size)
{
  const Stub_template* stub_template = stub->stub_template();
  if (stub_template->reloc_count() != 0)
    {
      // Adjust view to cover the stub only.
      section_size_type offset = stub->offset();
      section_size_type stub_size = stub_template->size();
      gold_assert(offset + stub_size <= view_size);

      arm_target->relocate_stub(stub, relinfo, output_section, view + offset,
				address + offset, stub_size);
    }
}

// Relocate all stubs in this stub table.

template<bool big_endian>
void
Stub_table<big_endian>::relocate_stubs(
    const Relocate_info<32, big_endian>* relinfo,
    Target_arm<big_endian>* arm_target,
    Output_section* output_section,
    unsigned char* view,
    Arm_address address,
    section_size_type view_size)
{
  // If we are passed a view bigger than the stub table's.  we need to
  // adjust the view.
  gold_assert(address == this->address()
	      && (view_size
		  == static_cast<section_size_type>(this->data_size())));

  // Relocate all relocation stubs.
  for (typename Reloc_stub_map::const_iterator p = this->reloc_stubs_.begin();
      p != this->reloc_stubs_.end();
      ++p)
    this->relocate_stub(p->second, relinfo, arm_target, output_section, view,
			address, view_size);

  // Relocate all Cortex-A8 stubs.
  for (Cortex_a8_stub_list::iterator p = this->cortex_a8_stubs_.begin();
       p != this->cortex_a8_stubs_.end();
       ++p)
    this->relocate_stub(p->second, relinfo, arm_target, output_section, view,
			address, view_size);

  // Relocate all ARM V4BX stubs.
  for (Arm_v4bx_stub_list::iterator p = this->arm_v4bx_stubs_.begin();
       p != this->arm_v4bx_stubs_.end();
       ++p)
    {
      if (*p != NULL)
	this->relocate_stub(*p, relinfo, arm_target, output_section, view,
			    address, view_size);
    }
}

// Write out the stubs to file.

template<bool big_endian>
void
Stub_table<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)
    {
      Reloc_stub* stub = p->second;
      Arm_address address = this->address() + stub->offset();
      gold_assert(address
		  == align_address(address,
				   stub->stub_template()->alignment()));
      stub->write(oview + stub->offset(), stub->stub_template()->size(),
		  big_endian);
    }

  // Write Cortex-A8 stubs.
  for (Cortex_a8_stub_list::const_iterator p = this->cortex_a8_stubs_.begin();
       p != this->cortex_a8_stubs_.end();
       ++p)
    {
      Cortex_a8_stub* stub = p->second;
      Arm_address address = this->address() + stub->offset();
      gold_assert(address
		  == align_address(address,
				   stub->stub_template()->alignment()));
      stub->write(oview + stub->offset(), stub->stub_template()->size(),
		  big_endian);
    }

  // Write ARM V4BX relocation stubs.
  for (Arm_v4bx_stub_list::const_iterator p = this->arm_v4bx_stubs_.begin();
       p != this->arm_v4bx_stubs_.end();
       ++p)
    {
      if (*p == NULL)
	continue;

      Arm_address address = this->address() + (*p)->offset();
      gold_assert(address
		  == align_address(address,
				   (*p)->stub_template()->alignment()));
      (*p)->write(oview + (*p)->offset(), (*p)->stub_template()->size(),
		  big_endian);
    }

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

// Update the data size and address alignment of the stub table at the end
// of a relaxation pass.   Return true if either the data size or the
// alignment changed in this relaxation pass.

template<bool big_endian>
bool
Stub_table<big_endian>::update_data_size_and_addralign()
{
  // Go over all stubs in table to compute data size and address alignment.
  off_t size = this->reloc_stubs_size_;
  unsigned addralign = this->reloc_stubs_addralign_;

  for (Cortex_a8_stub_list::const_iterator p = this->cortex_a8_stubs_.begin();
       p != this->cortex_a8_stubs_.end();
       ++p)
    {
      const Stub_template* stub_template = p->second->stub_template();
      addralign = std::max(addralign, stub_template->alignment());
      size = (align_address(size, stub_template->alignment())
	      + stub_template->size());
    }

  for (Arm_v4bx_stub_list::const_iterator p = this->arm_v4bx_stubs_.begin();
       p != this->arm_v4bx_stubs_.end();
       ++p)
    {
      if (*p == NULL)
	continue;

      const Stub_template* stub_template = (*p)->stub_template();
      addralign = std::max(addralign, stub_template->alignment());
      size = (align_address(size, stub_template->alignment())
	      + stub_template->size());
    }

  // Check if either data size or alignment changed in this pass.
  // Update prev_data_size_ and prev_addralign_.  These will be used
  // as the current data size and address alignment for the next pass.
  bool changed = size != this->prev_data_size_;
  this->prev_data_size_ = size;

  if (addralign != this->prev_addralign_)
    changed = true;
  this->prev_addralign_ = addralign;

  return changed;
}

// Finalize the stubs.  This sets the offsets of the stubs within the stub
// table.  It also marks all input sections needing Cortex-A8 workaround.

template<bool big_endian>
void
Stub_table<big_endian>::finalize_stubs()
{
  off_t off = this->reloc_stubs_size_;
  for (Cortex_a8_stub_list::const_iterator p = this->cortex_a8_stubs_.begin();
       p != this->cortex_a8_stubs_.end();
       ++p)
    {
      Cortex_a8_stub* stub = p->second;
      const Stub_template* stub_template = stub->stub_template();
      uint64_t stub_addralign = stub_template->alignment();
      off = align_address(off, stub_addralign);
      stub->set_offset(off);
      off += stub_template->size();

      // Mark input section so that we can determine later if a code section
      // needs the Cortex-A8 workaround quickly.
      Arm_relobj<big_endian>* arm_relobj =
	Arm_relobj<big_endian>::as_arm_relobj(stub->relobj());
      arm_relobj->mark_section_for_cortex_a8_workaround(stub->shndx());
    }

  for (Arm_v4bx_stub_list::const_iterator p = this->arm_v4bx_stubs_.begin();
      p != this->arm_v4bx_stubs_.end();
      ++p)
    {
      if (*p == NULL)
	continue;

      const Stub_template* stub_template = (*p)->stub_template();
      uint64_t stub_addralign = stub_template->alignment();
      off = align_address(off, stub_addralign);
      (*p)->set_offset(off);
      off += stub_template->size();
    }

  gold_assert(off <= this->prev_data_size_);
}

// Apply Cortex-A8 workaround to an address range between VIEW_ADDRESS
// and VIEW_ADDRESS + VIEW_SIZE - 1.  VIEW points to the mapped address
// of the address range seen by the linker.

template<bool big_endian>
void
Stub_table<big_endian>::apply_cortex_a8_workaround_to_address_range(
    Target_arm<big_endian>* arm_target,
    unsigned char* view,
    Arm_address view_address,
    section_size_type view_size)
{
  // Cortex-A8 stubs are sorted by addresses of branches being fixed up.
  for (Cortex_a8_stub_list::const_iterator p =
	 this->cortex_a8_stubs_.lower_bound(view_address);
       ((p != this->cortex_a8_stubs_.end())
	&& (p->first < (view_address + view_size)));
       ++p)
    {
      // We do not store the THUMB bit in the LSB of either the branch address
      // or the stub offset.  There is no need to strip the LSB.
      Arm_address branch_address = p->first;
      const Cortex_a8_stub* stub = p->second;
      Arm_address stub_address = this->address() + stub->offset();

      // Offset of the branch instruction relative to this view.
      section_size_type offset =
	convert_to_section_size_type(branch_address - view_address);
      gold_assert((offset + 4) <= view_size);

      arm_target->apply_cortex_a8_workaround(stub, stub_address,
					     view + offset, branch_address);
    }
}

// Arm_input_section methods.

// Initialize an Arm_input_section.

template<bool big_endian>
void
Arm_input_section<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();
}

template<bool big_endian>
void
Arm_input_section<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);
}

// Finalize data size.

template<bool big_endian>
void
Arm_input_section<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<bool big_endian>
void
Arm_input_section<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())
    {
      Stub_table<big_endian>* 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);
}

// Arm_exidx_cantunwind methods.

// Write this to Output file OF for a fixed endianness.

template<bool big_endian>
void
Arm_exidx_cantunwind::do_fixed_endian_write(Output_file* of)
{
  off_t offset = this->offset();
  const section_size_type oview_size = 8;
  unsigned char* const oview = of->get_output_view(offset, oview_size);

  Output_section* os = this->relobj_->output_section(this->shndx_);
  gold_assert(os != NULL);

  Arm_relobj<big_endian>* arm_relobj =
    Arm_relobj<big_endian>::as_arm_relobj(this->relobj_);
  Arm_address output_offset =
    arm_relobj->get_output_section_offset(this->shndx_);
  Arm_address section_start;
  section_size_type section_size;

  // Find out the end of the text section referred by this.
  if (output_offset != Arm_relobj<big_endian>::invalid_address)
    {
      section_start = os->address() + output_offset;
      const Arm_exidx_input_section* exidx_input_section =
	arm_relobj->exidx_input_section_by_link(this->shndx_);
      gold_assert(exidx_input_section != NULL);
      section_size =
	convert_to_section_size_type(exidx_input_section->text_size());
    }
  else
    {
      // Currently this only happens for a relaxed section.
      const Output_relaxed_input_section* poris =
	os->find_relaxed_input_section(this->relobj_, this->shndx_);
      gold_assert(poris != NULL);
      section_start = poris->address();
      section_size = convert_to_section_size_type(poris->data_size());
    }

  // We always append this to the end of an EXIDX section.
  Arm_address output_address = section_start + section_size;

  // Write out the entry.  The first word either points to the beginning
  // or after the end of a text section.  The second word is the special
  // EXIDX_CANTUNWIND value.
  uint32_t prel31_offset = output_address - this->address();
  if (Bits<31>::has_overflow32(offset))
    gold_error(_("PREL31 overflow in EXIDX_CANTUNWIND entry"));
  elfcpp::Swap_unaligned<32, big_endian>::writeval(oview,
						   prel31_offset & 0x7fffffffU);
  elfcpp::Swap_unaligned<32, big_endian>::writeval(oview + 4,
						   elfcpp::EXIDX_CANTUNWIND);

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

// Arm_exidx_merged_section methods.

// Constructor for Arm_exidx_merged_section.
// EXIDX_INPUT_SECTION points to the unmodified EXIDX input section.
// SECTION_OFFSET_MAP points to a section offset map describing how
// parts of the input section are mapped to output.  DELETED_BYTES is
// the number of bytes deleted from the EXIDX input section.

Arm_exidx_merged_section::Arm_exidx_merged_section(
    const Arm_exidx_input_section& exidx_input_section,
    const Arm_exidx_section_offset_map& section_offset_map,
    uint32_t deleted_bytes)
  : Output_relaxed_input_section(exidx_input_section.relobj(),
				 exidx_input_section.shndx(),
				 exidx_input_section.addralign()),
    exidx_input_section_(exidx_input_section),
    section_offset_map_(section_offset_map)
{
  // If we retain or discard the whole EXIDX input section,  we would
  // not be here.
  gold_assert(deleted_bytes != 0
	      && deleted_bytes != this->exidx_input_section_.size());

  // Fix size here so that we do not need to implement set_final_data_size.
  uint32_t size = exidx_input_section.size() - deleted_bytes;
  this->set_data_size(size);
  this->fix_data_size();

  // Allocate buffer for section contents and build contents.
  this->section_contents_ = new unsigned char[size];
}

// Build the contents of a merged EXIDX output section.

void
Arm_exidx_merged_section::build_contents(
    const unsigned char* original_contents,
    section_size_type original_size)
{
  // Go over spans of input offsets and write only those that are not
  // discarded.
  section_offset_type in_start = 0;
  section_offset_type out_start = 0;
  section_offset_type in_max =
    convert_types<section_offset_type>(original_size);
  section_offset_type out_max =
    convert_types<section_offset_type>(this->data_size());
  for (Arm_exidx_section_offset_map::const_iterator p =
	this->section_offset_map_.begin();
      p != this->section_offset_map_.end();
      ++p)
    {
      section_offset_type in_end = p->first;
      gold_assert(in_end >= in_start);
      section_offset_type out_end = p->second;
      size_t in_chunk_size = convert_types<size_t>(in_end - in_start + 1);
      if (out_end != -1)
	{
	  size_t out_chunk_size =
	    convert_types<size_t>(out_end - out_start + 1);

	  gold_assert(out_chunk_size == in_chunk_size
		      && in_end < in_max && out_end < out_max);

	  memcpy(this->section_contents_ + out_start,
		 original_contents + in_start,
		 out_chunk_size);
	  out_start += out_chunk_size;
	}
      in_start += in_chunk_size;
    }
}

// Given an input OBJECT, an input section index SHNDX within that
// object, and an OFFSET relative to the start of that input
// section, return whether or not the corresponding offset within
// the output section is known.  If this function returns true, it
// sets *POUTPUT to the output offset.  The value -1 indicates that
// this input offset is being discarded.

bool
Arm_exidx_merged_section::do_output_offset(
    const Relobj* relobj,
    unsigned int shndx,
    section_offset_type offset,
    section_offset_type* poutput) const
{
  // We only handle offsets for the original EXIDX input section.
  if (relobj != this->exidx_input_section_.relobj()
      || shndx != this->exidx_input_section_.shndx())
    return false;

  section_offset_type section_size =
    convert_types<section_offset_type>(this->exidx_input_section_.size());
  if (offset < 0 || offset >= section_size)
    // Input offset is out of valid range.
    *poutput = -1;
  else
    {
      // We need to look up the section offset map to determine the output
      // offset.  Find the reference point in map that is first offset
      // bigger than or equal to this offset.
      Arm_exidx_section_offset_map::const_iterator p =
	this->section_offset_map_.lower_bound(offset);

      // The section offset maps are build such that this should not happen if
      // input offset is in the valid range.
      gold_assert(p != this->section_offset_map_.end());

      // We need to check if this is dropped.
     section_offset_type ref = p->first;
     section_offset_type mapped_ref = p->second;

      if (mapped_ref != Arm_exidx_input_section::invalid_offset)
	// Offset is present in output.
	*poutput = mapped_ref + (offset - ref);
      else
	// Offset is discarded owing to EXIDX entry merging.
	*poutput = -1;
    }

  return true;
}

// Write this to output file OF.

void
Arm_exidx_merged_section::do_write(Output_file* of)
{
  off_t offset = this->offset();
  const section_size_type oview_size = this->data_size();
  unsigned char* const oview = of->get_output_view(offset, oview_size);

  Output_section* os = this->relobj()->output_section(this->shndx());
  gold_assert(os != NULL);

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

// Arm_exidx_fixup methods.

// Append an EXIDX_CANTUNWIND in the current output section if the last entry
// is not an EXIDX_CANTUNWIND entry already.  The new EXIDX_CANTUNWIND entry
// points to the end of the last seen EXIDX section.

void
Arm_exidx_fixup::add_exidx_cantunwind_as_needed()
{
  if (this->last_unwind_type_ != UT_EXIDX_CANTUNWIND
      && this->last_input_section_ != NULL)
    {
      Relobj* relobj = this->last_input_section_->relobj();
      unsigned int text_shndx = this->last_input_section_->link();
      Arm_exidx_cantunwind* cantunwind =
	new Arm_exidx_cantunwind(relobj, text_shndx);
      this->exidx_output_section_->add_output_section_data(cantunwind);
      this->last_unwind_type_ = UT_EXIDX_CANTUNWIND;
    }
}

// Process an EXIDX section entry in input.  Return whether this entry
// can be deleted in the output.  SECOND_WORD in the second word of the
// EXIDX entry.

bool
Arm_exidx_fixup::process_exidx_entry(uint32_t second_word)
{
  bool delete_entry;
  if (second_word == elfcpp::EXIDX_CANTUNWIND)
    {
      // Merge if previous entry is also an EXIDX_CANTUNWIND.
      delete_entry = this->last_unwind_type_ == UT_EXIDX_CANTUNWIND;
      this->last_unwind_type_ = UT_EXIDX_CANTUNWIND;
    }
  else if ((second_word & 0x80000000) != 0)
    {
      // Inlined unwinding data.  Merge if equal to previous.
      delete_entry = (merge_exidx_entries_
		      && this->last_unwind_type_ == UT_INLINED_ENTRY
		      && this->last_inlined_entry_ == second_word);
      this->last_unwind_type_ = UT_INLINED_ENTRY;
      this->last_inlined_entry_ = second_word;
    }
  else
    {
      // Normal table entry.  In theory we could merge these too,
      // but duplicate entries are likely to be much less common.
      delete_entry = false;
      this->last_unwind_type_ = UT_NORMAL_ENTRY;
    }
  return delete_entry;
}

// Update the current section offset map during EXIDX section fix-up.
// If there is no map, create one.  INPUT_OFFSET is the offset of a
// reference point, DELETED_BYTES is the number of deleted by in the
// section so far.  If DELETE_ENTRY is true, the reference point and
// all offsets after the previous reference point are discarded.

void
Arm_exidx_fixup::update_offset_map(
    section_offset_type input_offset,
    section_size_type deleted_bytes,
    bool delete_entry)
{
  if (this->section_offset_map_ == NULL)
    this->section_offset_map_ = new Arm_exidx_section_offset_map();
  section_offset_type output_offset;
  if (delete_entry)
    output_offset = Arm_exidx_input_section::invalid_offset;
  else
    output_offset = input_offset - deleted_bytes;
  (*this->section_offset_map_)[input_offset] = output_offset;
}

// Process EXIDX_INPUT_SECTION for EXIDX entry merging.  Return the number of
// bytes deleted.  SECTION_CONTENTS points to the contents of the EXIDX
// section and SECTION_SIZE is the number of bytes pointed by SECTION_CONTENTS.
// If some entries are merged, also store a pointer to a newly created
// Arm_exidx_section_offset_map object in *PSECTION_OFFSET_MAP.  The caller
// owns the map and is responsible for releasing it after use.

template<bool big_endian>
uint32_t
Arm_exidx_fixup::process_exidx_section(
    const Arm_exidx_input_section* exidx_input_section,
    const unsigned char* section_contents,
    section_size_type section_size,
    Arm_exidx_section_offset_map** psection_offset_map)
{
  Relobj* relobj = exidx_input_section->relobj();
  unsigned shndx = exidx_input_section->shndx();

  if ((section_size % 8) != 0)
    {
      // Something is wrong with this section.  Better not touch it.
      gold_error(_("uneven .ARM.exidx section size in %s section %u"),
		 relobj->name().c_str(), shndx);
      this->last_input_section_ = exidx_input_section;
      this->last_unwind_type_ = UT_NONE;
      return 0;
    }

  uint32_t deleted_bytes = 0;
  bool prev_delete_entry = false;
  gold_assert(this->section_offset_map_ == NULL);

  for (section_size_type i = 0; i < section_size; i += 8)
    {
      typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
      const Valtype* wv =
	  reinterpret_cast<const Valtype*>(section_contents + i + 4);
      uint32_t second_word = elfcpp::Swap<32, big_endian>::readval(wv);

      bool delete_entry = this->process_exidx_entry(second_word);

      // Entry deletion causes changes in output offsets.  We use a std::map
      // to record these.  And entry (x, y) means input offset x
      // is mapped to output offset y.  If y is invalid_offset, then x is
      // dropped in the output.  Because of the way std::map::lower_bound
      // works, we record the last offset in a region w.r.t to keeping or
      // dropping.  If there is no entry (x0, y0) for an input offset x0,
      // the output offset y0 of it is determined by the output offset y1 of
      // the smallest input offset x1 > x0 that there is an (x1, y1) entry
      // in the map.  If y1 is not -1, then y0 = y1 + x0 - x1.  Otherwise, y1
      // y0 is also -1.
      if (delete_entry != prev_delete_entry && i != 0)
	this->update_offset_map(i - 1, deleted_bytes, prev_delete_entry);

      // Update total deleted bytes for this entry.
      if (delete_entry)
	deleted_bytes += 8;

      prev_delete_entry = delete_entry;
    }

  // If section offset map is not NULL, make an entry for the end of
  // section.
  if (this->section_offset_map_ != NULL)
    update_offset_map(section_size - 1, deleted_bytes, prev_delete_entry);

  *psection_offset_map = this->section_offset_map_;
  this->section_offset_map_ = NULL;
  this->last_input_section_ = exidx_input_section;

  // Set the first output text section so that we can link the EXIDX output
  // section to it.  Ignore any EXIDX input section that is completely merged.
  if (this->first_output_text_section_ == NULL
      && deleted_bytes != section_size)
    {
      unsigned int link = exidx_input_section->link();
      Output_section* os = relobj->output_section(link);
      gold_assert(os != NULL);
      this->first_output_text_section_ = os;
    }

  return deleted_bytes;
}

// Arm_output_section methods.

// Create a stub group for input sections from BEGIN to END.  OWNER
// points to the input section to be the owner a new stub table.

template<bool big_endian>
void
Arm_output_section<big_endian>::create_stub_group(
  Input_section_list::const_iterator begin,
  Input_section_list::const_iterator end,
  Input_section_list::const_iterator owner,
  Target_arm<big_endian>* target,
  std::vector<Output_relaxed_input_section*>* new_relaxed_sections,
  const Task* task)
{
  // We use a different kind of relaxed section in an EXIDX section.
  // The static casting from Output_relaxed_input_section to
  // Arm_input_section is invalid in an EXIDX section.  We are okay
  // because we should not be calling this for an EXIDX section.
  gold_assert(this->type() != elfcpp::SHT_ARM_EXIDX);

  // Currently we convert ordinary input sections into relaxed sections only
  // at this point but we may want to support creating relaxed input section
  // very early.  So we check here to see if owner is already a relaxed
  // section.

  Arm_input_section<big_endian>* arm_input_section;
  if (owner->is_relaxed_input_section())
    {
      arm_input_section =
	Arm_input_section<big_endian>::as_arm_input_section(
	  owner->relaxed_input_section());
    }
  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());
      arm_input_section =
	target->new_arm_input_section(owner->relobj(), owner->shndx());
      new_relaxed_sections->push_back(arm_input_section);
    }

  // Create a stub table.
  Stub_table<big_endian>* stub_table =
    target->new_stub_table(arm_input_section);

  arm_input_section->set_stub_table(stub_table);

  Input_section_list::const_iterator p = begin;
  Input_section_list::const_iterator prev_p;

  // Look for input sections or relaxed input sections in [begin ... end].
  do
    {
      if (p->is_input_section() || p->is_relaxed_input_section())
	{
	  // The stub table information for input sections live
	  // in their objects.
	  Arm_relobj<big_endian>* arm_relobj =
	    Arm_relobj<big_endian>::as_arm_relobj(p->relobj());
	  arm_relobj->set_stub_table(p->shndx(), stub_table);
	}
      prev_p = p++;
    }
  while (prev_p != end);
}

// 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.  If STUB_ALWAYS_AFTER_BRANCH is false, we also add
// input section after the stub table, effectively double the group size.
//
// This is similar to the group_sections() function in elf32-arm.c but is
// implemented differently.

template<bool big_endian>
void
Arm_output_section<big_endian>::group_sections(
    section_size_type group_size,
    bool stubs_always_after_branch,
    Target_arm<big_endian>* target,
    const Task* task)
{
  // We only care about sections containing code.
  if ((this->flags() & elfcpp::SHF_EXECINSTR) == 0)
    return;

  // States for grouping.
  typedef enum
  {
    // No group is being built.
    NO_GROUP,
    // A group is being built but the stub table is not found yet.
    // We keep group a stub group until the size is just under GROUP_SIZE.
    // The last input section in the group will be used as the stub table.
    FINDING_STUB_SECTION,
    // A group is being built and we have already found a stub table.
    // We enter this state to grow a stub group by adding input section
    // after the stub table.  This effectively doubles the group size.
    HAS_STUB_SECTION
  } State;

  // Any newly created relaxed sections are stored here.
  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
		{
		  // But wait, there's more!  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.
	  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);
    }

  // Convert input section into relaxed input section in a batch.
  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)
    {
      Arm_relobj<big_endian>* arm_relobj =
	Arm_relobj<big_endian>::as_arm_relobj(
	  new_relaxed_sections[i]->relobj());
      unsigned int shndx = new_relaxed_sections[i]->shndx();
      // Tell Arm_relobj that this input section is converted.
      arm_relobj->convert_input_section_to_relaxed_section(shndx);
    }
}

// Append non empty text sections in this to LIST in ascending
// order of their position in this.

template<bool big_endian>
void
Arm_output_section<big_endian>::append_text_sections_to_list(
    Text_section_list* list)
{
  gold_assert((this->flags() & elfcpp::SHF_ALLOC) != 0);

  for (Input_section_list::const_iterator p = this->input_sections().begin();
       p != this->input_sections().end();
       ++p)
    {
      // We only care about plain or relaxed input sections.  We also
      // ignore any merged sections.
      if (p->is_input_section() || p->is_relaxed_input_section())
	list->push_back(Text_section_list::value_type(p->relobj(),
						      p->shndx()));
    }
}

template<bool big_endian>
void
Arm_output_section<big_endian>::fix_exidx_coverage(
    Layout* layout,
    const Text_section_list& sorted_text_sections,
    Symbol_table* symtab,
    bool merge_exidx_entries,
    const Task* task)
{
  // We should only do this for the EXIDX output section.
  gold_assert(this->type() == elfcpp::SHT_ARM_EXIDX);

  // We don't want the relaxation loop to undo these changes, so we discard
  // the current saved states and take another one after the fix-up.
  this->discard_states();

  // Remove all input sections.
  uint64_t address = this->address();
  typedef std::list<Output_section::Input_section> Input_section_list;
  Input_section_list input_sections;
  this->reset_address_and_file_offset();
  this->get_input_sections(address, std::string(""), &input_sections);

  if (!this->input_sections().empty())
    gold_error(_("Found non-EXIDX input sections in EXIDX output section"));

  // Go through all the known input sections and record them.
  typedef Unordered_set<Section_id, Section_id_hash> Section_id_set;
  typedef Unordered_map<Section_id, const Output_section::Input_section*,
			Section_id_hash> Text_to_exidx_map;
  Text_to_exidx_map text_to_exidx_map;
  for (Input_section_list::const_iterator p = input_sections.begin();
       p != input_sections.end();
       ++p)
    {
      // This should never happen.  At this point, we should only see
      // plain EXIDX input sections.
      gold_assert(!p->is_relaxed_input_section());
      text_to_exidx_map[Section_id(p->relobj(), p->shndx())] = &(*p);
    }

  Arm_exidx_fixup exidx_fixup(this, merge_exidx_entries);

  // Go over the sorted text sections.
  typedef Unordered_set<Section_id, Section_id_hash> Section_id_set;
  Section_id_set processed_input_sections;
  for (Text_section_list::const_iterator p = sorted_text_sections.begin();
       p != sorted_text_sections.end();
       ++p)
    {
      Relobj* relobj = p->first;
      unsigned int shndx = p->second;

      Arm_relobj<big_endian>* arm_relobj =
	 Arm_relobj<big_endian>::as_arm_relobj(relobj);
      const Arm_exidx_input_section* exidx_input_section =
	 arm_relobj->exidx_input_section_by_link(shndx);

      // If this text section has no EXIDX section or if the EXIDX section
      // has errors, force an EXIDX_CANTUNWIND entry pointing to the end
      // of the last seen EXIDX section.
      if (exidx_input_section == NULL || exidx_input_section->has_errors())
	{
	  exidx_fixup.add_exidx_cantunwind_as_needed();
	  continue;
	}

      Relobj* exidx_relobj = exidx_input_section->relobj();
      unsigned int exidx_shndx = exidx_input_section->shndx();
      Section_id sid(exidx_relobj, exidx_shndx);
      Text_to_exidx_map::const_iterator iter = text_to_exidx_map.find(sid);
      if (iter == text_to_exidx_map.end())
	{
	  // This is odd.  We have not seen this EXIDX input section before.
	  // We cannot do fix-up.  If we saw a SECTIONS clause in a script,
	  // issue a warning instead.  We assume the user knows what he
	  // or she is doing.  Otherwise, this is an error.
	  if (layout->script_options()->saw_sections_clause())
	    gold_warning(_("unwinding may not work because EXIDX input section"
			   " %u of %s is not in EXIDX output section"),
			 exidx_shndx, exidx_relobj->name().c_str());
	  else
	    gold_error(_("unwinding may not work because EXIDX input section"
			 " %u of %s is not in EXIDX output section"),
		       exidx_shndx, exidx_relobj->name().c_str());

	  exidx_fixup.add_exidx_cantunwind_as_needed();
	  continue;
	}

      // We need to access the contents of the EXIDX section, lock the
      // object here.
      Task_lock_obj<Object> tl(task, exidx_relobj);
      section_size_type exidx_size;
      const unsigned char* exidx_contents =
	exidx_relobj->section_contents(exidx_shndx, &exidx_size, false);

      // Fix up coverage and append input section to output data list.
      Arm_exidx_section_offset_map* section_offset_map = NULL;
      uint32_t deleted_bytes =
	exidx_fixup.process_exidx_section<big_endian>(exidx_input_section,
						      exidx_contents,
						      exidx_size,
						      &section_offset_map);

      if (deleted_bytes == exidx_input_section->size())
	{
	  // The whole EXIDX section got merged.  Remove it from output.
	  gold_assert(section_offset_map == NULL);
	  exidx_relobj->set_output_section(exidx_shndx, NULL);

	  // All local symbols defined in this input section will be dropped.
	  // We need to adjust output local symbol count.
	  arm_relobj->set_output_local_symbol_count_needs_update();
	}
      else if (deleted_bytes > 0)
	{
	  // Some entries are merged.  We need to convert this EXIDX input
	  // section into a relaxed section.
	  gold_assert(section_offset_map != NULL);

	  Arm_exidx_merged_section* merged_section =
	    new Arm_exidx_merged_section(*exidx_input_section,
					 *section_offset_map, deleted_bytes);
	  merged_section->build_contents(exidx_contents, exidx_size);

	  const std::string secname = exidx_relobj->section_name(exidx_shndx);
	  this->add_relaxed_input_section(layout, merged_section, secname);
	  arm_relobj->convert_input_section_to_relaxed_section(exidx_shndx);

	  // All local symbols defined in discarded portions of this input
	  // section will be dropped.  We need to adjust output local symbol
	  // count.
	  arm_relobj->set_output_local_symbol_count_needs_update();
	}
      else
	{
	  // Just add back the EXIDX input section.
	  gold_assert(section_offset_map == NULL);
	  const Output_section::Input_section* pis = iter->second;
	  gold_assert(pis->is_input_section());
	  this->add_script_input_section(*pis);
	}

      processed_input_sections.insert(Section_id(exidx_relobj, exidx_shndx));
    }

  // Insert an EXIDX_CANTUNWIND entry at the end of output if necessary.
  exidx_fixup.add_exidx_cantunwind_as_needed();

  // Remove any known EXIDX input sections that are not processed.
  for (Input_section_list::const_iterator p = input_sections.begin();
       p != input_sections.end();
       ++p)
    {
      if (processed_input_sections.find(Section_id(p->relobj(), p->shndx()))
	  == processed_input_sections.end())
	{
	  // We discard a known EXIDX section because its linked
	  // text section has been folded by ICF.  We also discard an
	  // EXIDX section with error, the output does not matter in this
	  // case.  We do this to avoid triggering asserts.
	  Arm_relobj<big_endian>* arm_relobj =
	    Arm_relobj<big_endian>::as_arm_relobj(p->relobj());
	  const Arm_exidx_input_section* exidx_input_section =
	    arm_relobj->exidx_input_section_by_shndx(p->shndx());
	  gold_assert(exidx_input_section != NULL);
	  if (!exidx_input_section->has_errors())
	    {
	      unsigned int text_shndx = exidx_input_section->link();
	      gold_assert(symtab->is_section_folded(p->relobj(), text_shndx));
	    }

	  // Remove this from link.  We also need to recount the
	  // local symbols.
	  p->relobj()->set_output_section(p->shndx(), NULL);
	  arm_relobj->set_output_local_symbol_count_needs_update();
	}
    }

  // Link exidx output section to the first seen output section and
  // set correct entry size.
  this->set_link_section(exidx_fixup.first_output_text_section());
  this->set_entsize(8);

  // Make changes permanent.
  this->save_states();
  this->set_section_offsets_need_adjustment();
}

// Link EXIDX output sections to text output sections.

template<bool big_endian>
void
Arm_output_section<big_endian>::set_exidx_section_link()
{
  gold_assert(this->type() == elfcpp::SHT_ARM_EXIDX);
  if (!this->input_sections().empty())
    {
      Input_section_list::const_iterator p = this->input_sections().begin();
      Arm_relobj<big_endian>* arm_relobj =
	Arm_relobj<big_endian>::as_arm_relobj(p->relobj());
      unsigned exidx_shndx = p->shndx();
      const Arm_exidx_input_section* exidx_input_section =
	arm_relobj->exidx_input_section_by_shndx(exidx_shndx);
      gold_assert(exidx_input_section != NULL);
      unsigned int text_shndx = exidx_input_section->link();
      Output_section* os = arm_relobj->output_section(text_shndx);
      this->set_link_section(os);
    }
}

// Arm_relobj methods.

// 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<bool big_endian>
bool
Arm_relobj<big_endian>::section_is_scannable(
    const elfcpp::Shdr<32, big_endian>& shdr,
    unsigned int shndx,
    const Output_section* os,
    const Symbol_table* symtab)
{
  // Skip any empty sections, unallocated sections or sections whose
  // type are not SHT_PROGBITS.
  if (shdr.get_sh_size() == 0
      || (shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0
      || shdr.get_sh_type() != elfcpp::SHT_PROGBITS)
    return false;

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

  // If this requires special offset handling, check to see if it is
  // a relaxed section.  If this is not, then it is a merged section that
  // we cannot handle.
  if (this->is_output_section_offset_invalid(shndx))
    {
      const Output_relaxed_input_section* poris =
	os->find_relaxed_input_section(this, shndx);
      if (poris == NULL)
	return false;
    }

  return true;
}

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

template<bool big_endian>
bool
Arm_relobj<big_endian>::section_needs_reloc_stub_scanning(
    const elfcpp::Shdr<32, 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_REL && 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;

  unsigned int reloc_size;
  if (sh_type == elfcpp::SHT_REL)
    reloc_size = elfcpp::Elf_sizes<32>::rel_size;
  else
    reloc_size = elfcpp::Elf_sizes<32>::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 index = this->adjust_shndx(shdr.get_sh_info());
  if (index >= this->shnum())
    return false;

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

// Return the output address of either a plain input section or a relaxed
// input section.  SHNDX is the section index.  We define and use this
// instead of calling Output_section::output_address because that is slow
// for large output.

template<bool big_endian>
Arm_address
Arm_relobj<big_endian>::simple_input_section_output_address(
    unsigned int shndx,
    Output_section* os)
{
  if (this->is_output_section_offset_invalid(shndx))
    {
      const Output_relaxed_input_section* poris =
	os->find_relaxed_input_section(this, shndx);
      // We do not handle merged sections here.
      gold_assert(poris != NULL);
      return poris->address();
    }
  else
    return os->address() + this->get_output_section_offset(shndx);
}

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

template<bool big_endian>
bool
Arm_relobj<big_endian>::section_needs_cortex_a8_stub_scanning(
    const elfcpp::Shdr<32, big_endian>& shdr,
    unsigned int shndx,
    Output_section* os,
    const Symbol_table* symtab)
{
  if (!this->section_is_scannable(shdr, shndx, os, symtab))
    return false;

  // If the section does not cross any 4K-boundaries, it does not need to
  // be scanned.
  Arm_address address = this->simple_input_section_output_address(shndx, os);
  if ((address & ~0xfffU) == ((address + shdr.get_sh_size() - 1) & ~0xfffU))
    return false;

  return true;
}

// Scan a section for Cortex-A8 workaround.

template<bool big_endian>
void
Arm_relobj<big_endian>::scan_section_for_cortex_a8_erratum(
    const elfcpp::Shdr<32, big_endian>& shdr,
    unsigned int shndx,
    Output_section* os,
    Target_arm<big_endian>* arm_target)
{
  // Look for the first mapping symbol in this section.  It should be
  // at (shndx, 0).
  Mapping_symbol_position section_start(shndx, 0);
  typename Mapping_symbols_info::const_iterator p =
    this->mapping_symbols_info_.lower_bound(section_start);

  // There are no mapping symbols for this section.  Treat it as a data-only
  // section.  Issue a warning if section is marked as containing
  // instructions.
  if (p == this->mapping_symbols_info_.end() || p->first.first != shndx)
    {
      if ((this->section_flags(shndx) & elfcpp::SHF_EXECINSTR) != 0)
	gold_warning(_("cannot scan executable section %u of %s for Cortex-A8 "
		       "erratum because it has no mapping symbols."),
		     shndx, this->name().c_str());
      return;
    }

  Arm_address output_address =
    this->simple_input_section_output_address(shndx, os);

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

  // We need to go through the mapping symbols to determine what to
  // scan.  There are two reasons.  First, we should look at THUMB code and
  // THUMB code only.  Second, we only want to look at the 4K-page boundary
  // to speed up the scanning.

  while (p != this->mapping_symbols_info_.end()
	&& p->first.first == shndx)
    {
      typename Mapping_symbols_info::const_iterator next =
	this->mapping_symbols_info_.upper_bound(p->first);

      // Only scan part of a section with THUMB code.
      if (p->second == 't')
	{
	  // Determine the end of this range.
	  section_size_type span_start =
	    convert_to_section_size_type(p->first.second);
	  section_size_type span_end;
	  if (next != this->mapping_symbols_info_.end()
	      && next->first.first == shndx)
	    span_end = convert_to_section_size_type(next->first.second);
	  else
	    span_end = convert_to_section_size_type(shdr.get_sh_size());

	  if (((span_start + output_address) & ~0xfffUL)
	      != ((span_end + output_address - 1) & ~0xfffUL))
	    {
	      arm_target->scan_span_for_cortex_a8_erratum(this, shndx,
							  span_start, span_end,
							  input_view,
							  output_address);
	    }
	}

      p = next;
    }
}

// Scan relocations for stub generation.

template<bool big_endian>
void
Arm_relobj<big_endian>::scan_sections_for_stubs(
    Target_arm<big_endian>* arm_target,
    const Symbol_table* symtab,
    const Layout* layout)
{
  unsigned int shnum = this->shnum();
  const unsigned int shdr_size = elfcpp::Elf_sizes<32>::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<32, 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<32, big_endian> shdr(p);
      if (this->section_needs_reloc_stub_scanning(shdr, out_sections, symtab,
						  pshdrs))
	{
	  unsigned int index = this->adjust_shndx(shdr.get_sh_info());
	  Arm_address output_offset = this->get_output_section_offset(index);
	  Arm_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.  This does work for the case in which
	  // we modify the contents of an input section.  We need to pass the
	  // output view under such circumstances.
	  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;
	  if (sh_type == elfcpp::SHT_REL)
	    reloc_size = elfcpp::Elf_sizes<32>::rel_size;
	  else
	    reloc_size = elfcpp::Elf_sizes<32>::rela_size;

	  Output_section* os = out_sections[index];
	  arm_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);
	}
    }

  // Do Cortex-A8 erratum stubs scanning.  This has to be done for a section
  // after its relocation section, if there is one, is processed for
  // relocation stubs.  Merging this loop with the one above would have been
  // complicated since we would have had to make sure that relocation stub
  // scanning is done first.
  if (arm_target->fix_cortex_a8())
    {
      const unsigned char* p = pshdrs + shdr_size;
      for (unsigned int i = 1; i < shnum; ++i, p += shdr_size)
	{
	  const elfcpp::Shdr<32, big_endian> shdr(p);
	  if (this->section_needs_cortex_a8_stub_scanning(shdr, i,
							  out_sections[i],
							  symtab))
	    this->scan_section_for_cortex_a8_erratum(shdr, i, out_sections[i],
						     arm_target);
	}
    }

  // After we've done the relocations, we release the hash tables,
  // since we no longer need them.
  this->free_input_to_output_maps();
}

// Count the local symbols.  The ARM backend needs to know if a symbol
// is a THUMB function or not.  For global symbols, it is easy because
// the Symbol object keeps the ELF symbol type.  For local symbol it is
// harder because we cannot access this information.   So we override the
// do_count_local_symbol in parent and scan local symbols to mark
// THUMB functions.  This is not the most efficient way but I do not want to
// slow down other ports by calling a per symbol target hook inside
// Sized_relobj_file<size, big_endian>::do_count_local_symbols.

template<bool big_endian>
void
Arm_relobj<big_endian>::do_count_local_symbols(
    Stringpool_template<char>* pool,
    Stringpool_template<char>* dynpool)
{
  // We need to fix-up the values of any local symbols whose type are
  // STT_ARM_TFUNC.

  // Ask parent to count the local symbols.
  Sized_relobj_file<32, big_endian>::do_count_local_symbols(pool, dynpool);
  const unsigned int loccount = this->local_symbol_count();
  if (loccount == 0)
    return;

  // Initialize the thumb function bit-vector.
  std::vector<bool> empty_vector(loccount, false);
  this->local_symbol_is_thumb_function_.swap(empty_vector);

  // Read the symbol table section header.
  const unsigned int symtab_shndx = this->symtab_shndx();
  elfcpp::Shdr<32, 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<32>::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<32, 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));

  // Loop over the local symbols and mark any local symbols pointing
  // to THUMB functions.

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

      // Check to see if this is a mapping symbol.
      const char* sym_name = pnames + sym.get_st_name();
      if (Target_arm<big_endian>::is_mapping_symbol_name(sym_name))
	{
	  bool is_ordinary;
	  unsigned int input_shndx =
	    this->adjust_sym_shndx(i, sym.get_st_shndx(), &is_ordinary);
	  gold_assert(is_ordinary);

	  // Strip of LSB in case this is a THUMB symbol.
	  Mapping_symbol_position msp(input_shndx, input_value & ~1U);
	  this->mapping_symbols_info_[msp] = sym_name[1];
	}

      if (st_type == elfcpp::STT_ARM_TFUNC
	  || (st_type == elfcpp::STT_FUNC && ((input_value & 1) != 0)))
	{
	  // This is a THUMB function.  Mark this and canonicalize the
	  // symbol value by setting LSB.
	  this->local_symbol_is_thumb_function_[i] = true;
	  if ((input_value & 1) == 0)
	    lv.set_input_value(input_value | 1);
	}
    }
}

// Relocate sections.
template<bool big_endian>
void
Arm_relobj<big_endian>::do_relocate_sections(
    const Symbol_table* symtab,
    const Layout* layout,
    const unsigned char* pshdrs,
    Output_file* of,
    typename Sized_relobj_file<32, big_endian>::Views* pviews)
{
  // Call parent to relocate sections.
  Sized_relobj_file<32, 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;

  // Relocate stub tables.
  unsigned int shnum = this->shnum();

  Target_arm<big_endian>* arm_target =
    Target_arm<big_endian>::default_target();

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

  for (unsigned int i = 1; i < shnum; ++i)
    {
      Arm_input_section<big_endian>* arm_input_section =
	arm_target->find_arm_input_section(this, i);

      if (arm_input_section != NULL
	  && arm_input_section->is_stub_table_owner()
	  && !arm_input_section->stub_table()->empty())
	{
	  // We cannot discard a section if it owns a stub table.
	  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<32>::shdr_size;

	  gold_assert((*pviews)[i].view != NULL);

	  // We are passed the output section view.  Adjust it to cover the
	  // stub table only.
	  Stub_table<big_endian>* stub_table = arm_input_section->stub_table();
	  gold_assert((stub_table->address() >= (*pviews)[i].address)
		      && ((stub_table->address() + stub_table->data_size())
			  <= (*pviews)[i].address + (*pviews)[i].view_size));

	  off_t offset = stub_table->address() - (*pviews)[i].address;
	  unsigned char* view = (*pviews)[i].view + offset;
	  Arm_address address = stub_table->address();
	  section_size_type view_size = stub_table->data_size();

	  stub_table->relocate_stubs(&relinfo, arm_target, os, view, address,
				     view_size);
	}

      // Apply Cortex A8 workaround if applicable.
      if (this->section_has_cortex_a8_workaround(i))
	{
	  unsigned char* view = (*pviews)[i].view;
	  Arm_address view_address = (*pviews)[i].address;
	  section_size_type view_size = (*pviews)[i].view_size;
	  Stub_table<big_endian>* stub_table = this->stub_tables_[i];

	  // Adjust view to cover section.
	  Output_section* os = this->output_section(i);
	  gold_assert(os != NULL);
	  Arm_address section_address =
	    this->simple_input_section_output_address(i, os);
	  uint64_t section_size = this->section_size(i);

	  gold_assert(section_address >= view_address
		      && ((section_address + section_size)
			  <= (view_address + view_size)));

	  unsigned char* section_view = view + (section_address - view_address);

	  // Apply the Cortex-A8 workaround to the output address range
	  // corresponding to this input section.
	  stub_table->apply_cortex_a8_workaround_to_address_range(
	      arm_target,
	      section_view,
	      section_address,
	      section_size);
	}
    }
}

// Find the linked text section of an EXIDX section by looking at the first
// relocation.  4.4.1 of the EHABI specifications says that an EXIDX section
// must be linked to its associated code section via the sh_link field of
// its section header.  However, some tools are broken and the link is not
// always set.  LD just drops such an EXIDX section silently, causing the
// associated code not unwindabled.   Here we try a little bit harder to
// discover the linked code section.
//
// PSHDR points to the section header of a relocation section of an EXIDX
// section.  If we can find a linked text section, return true and
// store the text section index in the location PSHNDX.  Otherwise
// return false.

template<bool big_endian>
bool
Arm_relobj<big_endian>::find_linked_text_section(
    const unsigned char* pshdr,
    const unsigned char* psyms,
    unsigned int* pshndx)
{
  elfcpp::Shdr<32, big_endian> shdr(pshdr);

  // If there is no relocation, we cannot find the linked text section.
  size_t reloc_size;
  if (shdr.get_sh_type() == elfcpp::SHT_REL)
      reloc_size = elfcpp::Elf_sizes<32>::rel_size;
  else
      reloc_size = elfcpp::Elf_sizes<32>::rela_size;
  size_t reloc_count = shdr.get_sh_size() / reloc_size;

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

  // Find the REL31 relocation for the first word of the first EXIDX entry.
  for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
    {
      Arm_address r_offset;
      typename elfcpp::Elf_types<32>::Elf_WXword r_info;
      if (shdr.get_sh_type() == elfcpp::SHT_REL)
	{
	  typename elfcpp::Rel<32, big_endian> reloc(prelocs);
	  r_info = reloc.get_r_info();
	  r_offset = reloc.get_r_offset();
	}
      else
	{
	  typename elfcpp::Rela<32, big_endian> reloc(prelocs);
	  r_info = reloc.get_r_info();
	  r_offset = reloc.get_r_offset();
	}

      unsigned int r_type = elfcpp::elf_r_type<32>(r_info);
      if (r_type != elfcpp::R_ARM_PREL31 && r_type != elfcpp::R_ARM_SBREL31)
	continue;

      unsigned int r_sym = elfcpp::elf_r_sym<32>(r_info);
      if (r_sym == 0
	  || r_sym >= this->local_symbol_count()
	  || r_offset != 0)
	continue;

      // This is the relocation for the first word of the first EXIDX entry.
      // We expect to see a local section symbol.
      const int sym_size = elfcpp::Elf_sizes<32>::sym_size;
      elfcpp::Sym<32, big_endian> sym(psyms + r_sym * sym_size);
      if (sym.get_st_type() == elfcpp::STT_SECTION)
	{
	  bool is_ordinary;
	  *pshndx =
	    this->adjust_sym_shndx(r_sym, sym.get_st_shndx(), &is_ordinary);
	  gold_assert(is_ordinary);
	  return true;
	}
      else
	return false;
    }

  return false;
}

// Make an EXIDX input section object for an EXIDX section whose index is
// SHNDX.  SHDR is the section header of the EXIDX section and TEXT_SHNDX
// is the section index of the linked text section.

template<bool big_endian>
void
Arm_relobj<big_endian>::make_exidx_input_section(
    unsigned int shndx,
    const elfcpp::Shdr<32, big_endian>& shdr,
    unsigned int text_shndx,
    const elfcpp::Shdr<32, big_endian>& text_shdr)
{
  // Create an Arm_exidx_input_section object for this EXIDX section.
  Arm_exidx_input_section* exidx_input_section =
    new Arm_exidx_input_section(this, shndx, text_shndx, shdr.get_sh_size(),
				shdr.get_sh_addralign(),
				text_shdr.get_sh_size());

  gold_assert(this->exidx_section_map_[shndx] == NULL);
  this->exidx_section_map_[shndx] = exidx_input_section;

  if (text_shndx == elfcpp::SHN_UNDEF || text_shndx >= this->shnum())
    {
      gold_error(_("EXIDX section %s(%u) links to invalid section %u in %s"),
		 this->section_name(shndx).c_str(), shndx, text_shndx,
		 this->name().c_str());
      exidx_input_section->set_has_errors();
    }
  else if (this->exidx_section_map_[text_shndx] != NULL)
    {
      unsigned other_exidx_shndx =
	this->exidx_section_map_[text_shndx]->shndx();
      gold_error(_("EXIDX sections %s(%u) and %s(%u) both link to text section"
		   "%s(%u) in %s"),
		 this->section_name(shndx).c_str(), shndx,
		 this->section_name(other_exidx_shndx).c_str(),
		 other_exidx_shndx, this->section_name(text_shndx).c_str(),
		 text_shndx, this->name().c_str());
      exidx_input_section->set_has_errors();
    }
  else
     this->exidx_section_map_[text_shndx] = exidx_input_section;

  // Check section flags of text section.
  if ((text_shdr.get_sh_flags() & elfcpp::SHF_ALLOC) == 0)
    {
      gold_error(_("EXIDX section %s(%u) links to non-allocated section %s(%u) "
		   " in %s"),
		 this->section_name(shndx).c_str(), shndx,
		 this->section_name(text_shndx).c_str(), text_shndx,
		 this->name().c_str());
      exidx_input_section->set_has_errors();
    }
  else if ((text_shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) == 0)
    // I would like to make this an error but currently ld just ignores
    // this.
    gold_warning(_("EXIDX section %s(%u) links to non-executable section "
		   "%s(%u) in %s"),
		 this->section_name(shndx).c_str(), shndx,
		 this->section_name(text_shndx).c_str(), text_shndx,
		 this->name().c_str());
}

// Read the symbol information.

template<bool big_endian>
void
Arm_relobj<big_endian>::do_read_symbols(Read_symbols_data* sd)
{
  // Call parent class to read symbol information.
  Sized_relobj_file<32, big_endian>::do_read_symbols(sd);

  // If this input file is a binary file, it has no processor
  // specific flags and attributes section.
  Input_file::Format format = this->input_file()->format();
  if (format != Input_file::FORMAT_ELF)
    {
      gold_assert(format == Input_file::FORMAT_BINARY);
      this->merge_flags_and_attributes_ = false;
      return;
    }

  // Read processor-specific flags in ELF file header.
  const unsigned char* pehdr = this->get_view(elfcpp::file_header_offset,
					      elfcpp::Elf_sizes<32>::ehdr_size,
					      true, false);
  elfcpp::Ehdr<32, big_endian> ehdr(pehdr);
  this->processor_specific_flags_ = ehdr.get_e_flags();

  // Go over the section headers and look for .ARM.attributes and .ARM.exidx
  // sections.
  std::vector<unsigned int> deferred_exidx_sections;
  const size_t shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
  const unsigned char* pshdrs = sd->section_headers->data();
  const unsigned char* ps = pshdrs + shdr_size;
  bool must_merge_flags_and_attributes = false;
  for (unsigned int i = 1; i < this->shnum(); ++i, ps += shdr_size)
    {
      elfcpp::Shdr<32, big_endian> shdr(ps);

      // Sometimes an object has no contents except the section name string
      // table and an empty symbol table with the undefined symbol.  We
      // don't want to merge processor-specific flags from such an object.
      if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
	{
	  // Symbol table is not empty.
	  const elfcpp::Elf_types<32>::Elf_WXword sym_size =
	     elfcpp::Elf_sizes<32>::sym_size;
	  if (shdr.get_sh_size() > sym_size)
	    must_merge_flags_and_attributes = true;
	}
      else if (shdr.get_sh_type() != elfcpp::SHT_STRTAB)
	// If this is neither an empty symbol table nor a string table,
	// be conservative.
	must_merge_flags_and_attributes = true;

      if (shdr.get_sh_type() == elfcpp::SHT_ARM_ATTRIBUTES)
	{
	  gold_assert(this->attributes_section_data_ == NULL);
	  section_offset_type section_offset = shdr.get_sh_offset();
	  section_size_type section_size =
	    convert_to_section_size_type(shdr.get_sh_size());
	  const unsigned char* view =
	     this->get_view(section_offset, section_size, true, false);
	  this->attributes_section_data_ =
	    new Attributes_section_data(view, section_size);
	}
      else if (shdr.get_sh_type() == elfcpp::SHT_ARM_EXIDX)
	{
	  unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_link());
	  if (text_shndx == elfcpp::SHN_UNDEF)
	    deferred_exidx_sections.push_back(i);
	  else
	    {
	      elfcpp::Shdr<32, big_endian> text_shdr(pshdrs
						     + text_shndx * shdr_size);
	      this->make_exidx_input_section(i, shdr, text_shndx, text_shdr);
	    }
	  // EHABI 4.4.1 requires that SHF_LINK_ORDER flag to be set.
	  if ((shdr.get_sh_flags() & elfcpp::SHF_LINK_ORDER) == 0)
	    gold_warning(_("SHF_LINK_ORDER not set in EXIDX section %s of %s"),
			 this->section_name(i).c_str(), this->name().c_str());
	}
    }

  // This is rare.
  if (!must_merge_flags_and_attributes)
    {
      gold_assert(deferred_exidx_sections.empty());
      this->merge_flags_and_attributes_ = false;
      return;
    }

  // Some tools are broken and they do not set the link of EXIDX sections.
  // We look at the first relocation to figure out the linked sections.
  if (!deferred_exidx_sections.empty())
    {
      // We need to go over the section headers again to find the mapping
      // from sections being relocated to their relocation sections.  This is
      // a bit inefficient as we could do that in the loop above.  However,
      // we do not expect any deferred EXIDX sections normally.  So we do not
      // want to slow down the most common path.
      typedef Unordered_map<unsigned int, unsigned int> Reloc_map;
      Reloc_map reloc_map;
      ps = pshdrs + shdr_size;
      for (unsigned int i = 1; i < this->shnum(); ++i, ps += shdr_size)
	{
	  elfcpp::Shdr<32, big_endian> shdr(ps);
	  elfcpp::Elf_Word sh_type = shdr.get_sh_type();
	  if (sh_type == elfcpp::SHT_REL || sh_type == elfcpp::SHT_RELA)
	    {
	      unsigned int info_shndx = this->adjust_shndx(shdr.get_sh_info());
	      if (info_shndx >= this->shnum())
		gold_error(_("relocation section %u has invalid info %u"),
			   i, info_shndx);
	      Reloc_map::value_type value(info_shndx, i);
	      std::pair<Reloc_map::iterator, bool> result =
		reloc_map.insert(value);
	      if (!result.second)
		gold_error(_("section %u has multiple relocation sections "
			     "%u and %u"),
			   info_shndx, i, reloc_map[info_shndx]);
	    }
	}

      // Read the symbol table section header.
      const unsigned int symtab_shndx = this->symtab_shndx();
      elfcpp::Shdr<32, 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<32>::sym_size;
      const unsigned int loccount = this->local_symbol_count();
      gold_assert(loccount == symtabshdr.get_sh_info());
      off_t locsize = loccount * sym_size;
      const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
						  locsize, true, true);

      // Process the deferred EXIDX sections.
      for (unsigned int i = 0; i < deferred_exidx_sections.size(); ++i)
	{
	  unsigned int shndx = deferred_exidx_sections[i];
	  elfcpp::Shdr<32, big_endian> shdr(pshdrs + shndx * shdr_size);
	  unsigned int text_shndx = elfcpp::SHN_UNDEF;
	  Reloc_map::const_iterator it = reloc_map.find(shndx);
	  if (it != reloc_map.end())
	    find_linked_text_section(pshdrs + it->second * shdr_size,
				     psyms, &text_shndx);
	  elfcpp::Shdr<32, big_endian> text_shdr(pshdrs
						 + text_shndx * shdr_size);
	  this->make_exidx_input_section(shndx, shdr, text_shndx, text_shdr);
	}
    }
}

// Process relocations for garbage collection.  The ARM target uses .ARM.exidx
// sections for unwinding.  These sections are referenced implicitly by
// text sections linked in the section headers.  If we ignore these implicit
// references, the .ARM.exidx sections and any .ARM.extab sections they use
// will be garbage-collected incorrectly.  Hence we override the same function
// in the base class to handle these implicit references.

template<bool big_endian>
void
Arm_relobj<big_endian>::do_gc_process_relocs(Symbol_table* symtab,
					     Layout* layout,
					     Read_relocs_data* rd)
{
  // First, call base class method to process relocations in this object.
  Sized_relobj_file<32, big_endian>::do_gc_process_relocs(symtab, layout, rd);

  // If --gc-sections is not specified, there is nothing more to do.
  // This happens when --icf is used but --gc-sections is not.
  if (!parameters->options().gc_sections())
    return;

  unsigned int shnum = this->shnum();
  const unsigned int shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
  const unsigned char* pshdrs = this->get_view(this->elf_file()->shoff(),
					       shnum * shdr_size,
					       true, true);

  // Scan section headers for sections of type SHT_ARM_EXIDX.  Add references
  // to these from the linked text sections.
  const unsigned char* ps = pshdrs + shdr_size;
  for (unsigned int i = 1; i < shnum; ++i, ps += shdr_size)
    {
      elfcpp::Shdr<32, big_endian> shdr(ps);
      if (shdr.get_sh_type() == elfcpp::SHT_ARM_EXIDX)
	{
	  // Found an .ARM.exidx section, add it to the set of reachable
	  // sections from its linked text section.
	  unsigned int text_shndx = this->adjust_shndx(shdr.get_sh_link());
	  symtab->gc()->add_reference(this, text_shndx, this, i);
	}
    }
}

// Update output local symbol count.  Owing to EXIDX entry merging, some local
// symbols  will be removed in output.  Adjust output local symbol count
// accordingly.  We can only changed the static output local symbol count.  It
// is too late to change the dynamic symbols.

template<bool big_endian>
void
Arm_relobj<big_endian>::update_output_local_symbol_count()
{
  // Caller should check that this needs updating.  We want caller checking
  // because output_local_symbol_count_needs_update() is most likely inlined.
  gold_assert(this->output_local_symbol_count_needs_update_);

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

  // Read the symbol table section header.
  const unsigned int symtab_shndx = this->symtab_shndx();
  elfcpp::Shdr<32, 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<32>::sym_size;
  const unsigned int loccount = this->local_symbol_count();
  gold_assert(loccount == symtabshdr.get_sh_info());
  off_t locsize = loccount * sym_size;
  const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
					      locsize, true, true);

  // Loop over the local symbols.

  typedef typename Sized_relobj_file<32, big_endian>::Output_sections
     Output_sections;
  const Output_sections& out_sections(this->output_sections());
  unsigned int shnum = this->shnum();
  unsigned int count = 0;
  // Skip the first, dummy, symbol.
  psyms += sym_size;
  for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
    {
      elfcpp::Sym<32, big_endian> sym(psyms);

      Symbol_value<32>& lv((*this->local_values())[i]);

      // This local symbol was already discarded by do_count_local_symbols.
      if (lv.is_output_symtab_index_set() && !lv.has_output_symtab_entry())
	continue;

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

      if (shndx < shnum)
	{
	  Output_section* os = out_sections[shndx];

	  // This local symbol no longer has an output section.  Discard it.
	  if (os == NULL)
	    {
	      lv.set_no_output_symtab_entry();
	      continue;
	    }

	  // Currently we only discard parts of EXIDX input sections.
	  // We explicitly check for a merged EXIDX input section to avoid
	  // calling Output_section_data::output_offset unless necessary.
	  if ((this->get_output_section_offset(shndx) == invalid_address)
	      && (this->exidx_input_section_by_shndx(shndx) != NULL))
	    {
	      section_offset_type output_offset =
		os->output_offset(this, shndx, lv.input_value());
	      if (output_offset == -1)
		{
		  // This symbol is defined in a part of an EXIDX input section
		  // that is discarded due to entry merging.
		  lv.set_no_output_symtab_entry();
		  continue;
		}
	    }
	}

      ++count;
    }

  this->set_output_local_symbol_count(count);
  this->output_local_symbol_count_needs_update_ = false;
}

// Arm_dynobj methods.

// Read the symbol information.

template<bool big_endian>
void
Arm_dynobj<big_endian>::do_read_symbols(Read_symbols_data* sd)
{
  // Call parent class to read symbol information.
  Sized_dynobj<32, big_endian>::do_read_symbols(sd);

  // Read processor-specific flags in ELF file header.
  const unsigned char* pehdr = this->get_view(elfcpp::file_header_offset,
					      elfcpp::Elf_sizes<32>::ehdr_size,
					      true, false);
  elfcpp::Ehdr<32, big_endian> ehdr(pehdr);
  this->processor_specific_flags_ = ehdr.get_e_flags();

  // Read the attributes section if there is one.
  // We read from the end because gas seems to put it near the end of
  // the section headers.
  const size_t shdr_size = elfcpp::Elf_sizes<32>::shdr_size;
  const unsigned char* ps =
    sd->section_headers->data() + shdr_size * (this->shnum() - 1);
  for (unsigned int i = this->shnum(); i > 0; --i, ps -= shdr_size)
    {
      elfcpp::Shdr<32, big_endian> shdr(ps);
      if (shdr.get_sh_type() == elfcpp::SHT_ARM_ATTRIBUTES)
	{
	  section_offset_type section_offset = shdr.get_sh_offset();
	  section_size_type section_size =
	    convert_to_section_size_type(shdr.get_sh_size());
	  const unsigned char* view =
	    this->get_view(section_offset, section_size, true, false);
	  this->attributes_section_data_ =
	    new Attributes_section_data(view, section_size);
	  break;
	}
    }
}

// Stub_addend_reader methods.

// Read the addend of a REL relocation of type R_TYPE at VIEW.

template<bool big_endian>
elfcpp::Elf_types<32>::Elf_Swxword
Stub_addend_reader<elfcpp::SHT_REL, big_endian>::operator()(
    unsigned int r_type,
    const unsigned char* view,
    const typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc&) const
{
  typedef class Arm_relocate_functions<big_endian> RelocFuncs;

  switch (r_type)
    {
    case elfcpp::R_ARM_CALL:
    case elfcpp::R_ARM_JUMP24:
    case elfcpp::R_ARM_PLT32:
      {
	typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
	const Valtype* wv = reinterpret_cast<const Valtype*>(view);
	Valtype val = elfcpp::Swap<32, big_endian>::readval(wv);
	return Bits<26>::sign_extend32(val << 2);
      }

    case elfcpp::R_ARM_THM_CALL:
    case elfcpp::R_ARM_THM_JUMP24:
    case elfcpp::R_ARM_THM_XPC22:
      {
	typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
	const Valtype* wv = reinterpret_cast<const Valtype*>(view);
	Valtype upper_insn = elfcpp::Swap<16, big_endian>::readval(wv);
	Valtype lower_insn = elfcpp::Swap<16, big_endian>::readval(wv + 1);
	return RelocFuncs::thumb32_branch_offset(upper_insn, lower_insn);
      }

    case elfcpp::R_ARM_THM_JUMP19:
      {
	typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
	const Valtype* wv = reinterpret_cast<const Valtype*>(view);
	Valtype upper_insn = elfcpp::Swap<16, big_endian>::readval(wv);
	Valtype lower_insn = elfcpp::Swap<16, big_endian>::readval(wv + 1);
	return RelocFuncs::thumb32_cond_branch_offset(upper_insn, lower_insn);
      }

    default:
      gold_unreachable();
    }
}

// Arm_output_data_got methods.

// Add a GOT pair for R_ARM_TLS_GD32.  The creates a pair of GOT entries.
// The first one is initialized to be 1, which is the module index for
// the main executable and the second one 0.  A reloc of the type
// R_ARM_TLS_DTPOFF32 will be created for the second GOT entry and will
// be applied by gold.  GSYM is a global symbol.
//
template<bool big_endian>
void
Arm_output_data_got<big_endian>::add_tls_gd32_with_static_reloc(
    unsigned int got_type,
    Symbol* gsym)
{
  if (gsym->has_got_offset(got_type))
    return;

  // We are doing a static link.  Just mark it as belong to module 1,
  // the executable.
  unsigned int got_offset = this->add_constant(1);
  gsym->set_got_offset(got_type, got_offset);
  got_offset = this->add_constant(0);
  this->static_relocs_.push_back(Static_reloc(got_offset,
					      elfcpp::R_ARM_TLS_DTPOFF32,
					      gsym));
}

// Same as the above but for a local symbol.

template<bool big_endian>
void
Arm_output_data_got<big_endian>::add_tls_gd32_with_static_reloc(
  unsigned int got_type,
  Sized_relobj_file<32, big_endian>* object,
  unsigned int index)
{
  if (object->local_has_got_offset(index, got_type))
    return;

  // We are doing a static link.  Just mark it as belong to module 1,
  // the executable.
  unsigned int got_offset = this->add_constant(1);
  object->set_local_got_offset(index, got_type, got_offset);
  got_offset = this->add_constant(0);
  this->static_relocs_.push_back(Static_reloc(got_offset,
					      elfcpp::R_ARM_TLS_DTPOFF32,
					      object, index));
}

template<bool big_endian>
void
Arm_output_data_got<big_endian>::do_write(Output_file* of)
{
  // Call parent to write out GOT.
  Output_data_got<32, big_endian>::do_write(of);

  // We are done if there is no fix up.
  if (this->static_relocs_.empty())
    return;

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

  // The thread pointer $tp points to the TCB, which is followed by the
  // TLS.  So we need to adjust $tp relative addressing by this amount.
  Arm_address aligned_tcb_size =
    align_address(ARM_TCB_SIZE, tls_segment->maximum_alignment());

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

      Arm_address value;
      if (!reloc.symbol_is_global())
	{
	  Sized_relobj_file<32, big_endian>* object = reloc.relobj();
	  const Symbol_value<32>* 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<32>* sym =
		static_cast<const Sized_symbol<32>*>(gsym);
	      value = sym->value();
	    }
	  else
	      value = 0;
	}

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

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

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

// 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<bool big_endian>
class Output_data_plt_arm : public Output_section_data
{
 public:
  typedef Output_data_reloc<elfcpp::SHT_REL, true, 32, big_endian>
    Reloc_section;

  Output_data_plt_arm(Layout*, uint64_t addralign, Output_data_space*);

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

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

  // Return the number of PLT entries.
  unsigned int
  entry_count() const
  { return this->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(); }

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

  void
  fill_plt_entry(unsigned char* pov,
		 Arm_address got_address,
		 Arm_address plt_address,
		 unsigned int got_offset,
		 unsigned int plt_offset)
  { do_fill_plt_entry(pov, got_address, plt_address, 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 void
  do_fill_first_plt_entry(unsigned char* pov,
			  Arm_address got_address,
			  Arm_address plt_address) = 0;

  virtual void
  do_fill_plt_entry(unsigned char* pov,
		    Arm_address got_address,
		    Arm_address plt_address,
		    unsigned int 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()
  {
    this->set_data_size(this->first_plt_entry_offset()
			+ this->count_ * this->get_plt_entry_size());
  }

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

  // The reloc section.
  Reloc_section* rel_;
  // The .got.plt section.
  Output_data_space* got_plt_;
  // The number of PLT entries.
  unsigned int count_;
};

// Create the PLT section.  The ordinary .got section is an argument,
// since we need to refer to the start.  We also create our own .got
// section just for PLT entries.

template<bool big_endian>
Output_data_plt_arm<big_endian>::Output_data_plt_arm(Layout* layout,
						     uint64_t addralign,
						     Output_data_space* got_plt)
  : Output_section_data(addralign), got_plt_(got_plt), count_(0)
{
  this->rel_ = new Reloc_section(false);
  layout->add_output_section_data(".rel.plt", elfcpp::SHT_REL,
				  elfcpp::SHF_ALLOC, this->rel_,
				  ORDER_DYNAMIC_PLT_RELOCS, false);
}

template<bool big_endian>
void
Output_data_plt_arm<big_endian>::do_adjust_output_section(Output_section* os)
{
  os->set_entsize(0);
}

// Add an entry to the PLT.

template<bool big_endian>
void
Output_data_plt_arm<big_endian>::add_entry(Symbol* gsym)
{
  gold_assert(!gsym->has_plt_offset());

  // Note that when setting the PLT offset we skip the initial
  // reserved PLT entry.
  gsym->set_plt_offset((this->count_) * this->get_plt_entry_size()
		       + this->first_plt_entry_offset());

  ++this->count_;

  section_offset_type got_offset = this->got_plt_->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).
  this->got_plt_->set_current_data_size(got_offset + 4);

  // Every PLT entry needs a reloc.
  gsym->set_needs_dynsym_entry();
  this->rel_->add_global(gsym, elfcpp::R_ARM_JUMP_SLOT, this->got_plt_,
			 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.
}

template<bool big_endian>
class Output_data_plt_arm_standard : public Output_data_plt_arm<big_endian>
{
 public:
  Output_data_plt_arm_standard(Layout* layout, Output_data_space* got_plt)
    : Output_data_plt_arm<big_endian>(layout, 4, got_plt)
  { }

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

  // Return the size of a PLT entry.
  virtual unsigned int
  do_get_plt_entry_size() const
  { return sizeof(plt_entry); }

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

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

 private:
  // Template for the first PLT entry.
  static const uint32_t first_plt_entry[5];

  // Template for subsequent PLT entries.
  static const uint32_t plt_entry[3];
};

// ARM PLTs.
// FIXME:  This is not very flexible.  Right now this has only been tested
// on armv5te.  If we are to support additional architecture features like
// Thumb-2 or BE8, we need to make this more flexible like GNU ld.

// The first entry in the PLT.
template<bool big_endian>
const uint32_t Output_data_plt_arm_standard<big_endian>::first_plt_entry[5] =
{
  0xe52de004,	// str   lr, [sp, #-4]!
  0xe59fe004,   // ldr   lr, [pc, #4]
  0xe08fe00e,	// add   lr, pc, lr
  0xe5bef008,	// ldr   pc, [lr, #8]!
  0x00000000,	// &GOT[0] - .
};

template<bool big_endian>
void
Output_data_plt_arm_standard<big_endian>::do_fill_first_plt_entry(
    unsigned char* pov,
    Arm_address got_address,
    Arm_address plt_address)
{
  // Write first PLT entry.  All but the last word are constants.
  const size_t num_first_plt_words = (sizeof(first_plt_entry)
				      / sizeof(plt_entry[0]));
  for (size_t i = 0; i < num_first_plt_words - 1; i++)
    elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]);
  // Last word in first PLT entry is &GOT[0] - .
  elfcpp::Swap<32, big_endian>::writeval(pov + 16,
					 got_address - (plt_address + 16));
}

// Subsequent entries in the PLT.

template<bool big_endian>
const uint32_t Output_data_plt_arm_standard<big_endian>::plt_entry[3] =
{
  0xe28fc600,	// add   ip, pc, #0xNN00000
  0xe28cca00,	// add   ip, ip, #0xNN000
  0xe5bcf000,	// ldr   pc, [ip, #0xNNN]!
};

template<bool big_endian>
void
Output_data_plt_arm_standard<big_endian>::do_fill_plt_entry(
    unsigned char* pov,
    Arm_address got_address,
    Arm_address plt_address,
    unsigned int got_offset,
    unsigned int plt_offset)
{
  int32_t offset = ((got_address + got_offset)
		    - (plt_address + plt_offset + 8));

  gold_assert(offset >= 0 && offset < 0x0fffffff);
  uint32_t plt_insn0 = plt_entry[0] | ((offset >> 20) & 0xff);
  elfcpp::Swap<32, big_endian>::writeval(pov, plt_insn0);
  uint32_t plt_insn1 = plt_entry[1] | ((offset >> 12) & 0xff);
  elfcpp::Swap<32, big_endian>::writeval(pov + 4, plt_insn1);
  uint32_t plt_insn2 = plt_entry[2] | (offset & 0xfff);
  elfcpp::Swap<32, big_endian>::writeval(pov + 8, plt_insn2);
}

// Write out the PLT.  This uses the hand-coded instructions above,
// and adjusts them as needed.  This is all specified by the arm ELF
// Processor Supplement.

template<bool big_endian>
void
Output_data_plt_arm<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();
  const section_size_type got_size =
    convert_to_section_size_type(this->got_plt_->data_size());
  unsigned char* const got_view = of->get_output_view(got_file_offset,
						      got_size);
  unsigned char* pov = oview;

  Arm_address plt_address = this->address();
  Arm_address got_address = this->got_plt_->address();

  // Write first PLT entry.
  this->fill_first_plt_entry(pov, got_address, plt_address);
  pov += this->first_plt_entry_offset();

  unsigned char* got_pov = got_view;

  memset(got_pov, 0, 12);
  got_pov += 12;

  unsigned int plt_offset = this->first_plt_entry_offset();
  unsigned int got_offset = 12;
  const unsigned int count = this->count_;
  for (unsigned int i = 0;
       i < count;
       ++i,
	 pov += this->get_plt_entry_size(),
	 got_pov += 4,
	 plt_offset += this->get_plt_entry_size(),
	 got_offset += 4)
    {
      // Set and adjust the PLT entry itself.
      this->fill_plt_entry(pov, got_address, plt_address,
			   got_offset, plt_offset);

      // Set the entry in the GOT.
      elfcpp::Swap<32, big_endian>::writeval(got_pov, plt_address);
    }

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

// Create a PLT entry for a global symbol.

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

  if (this->plt_ == NULL)
    {
      // Create the GOT sections first.
      this->got_section(symtab, layout);

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

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

// Return the number of entries in the PLT.

template<bool big_endian>
unsigned int
Target_arm<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<bool big_endian>
unsigned int
Target_arm<big_endian>::first_plt_entry_offset() const
{
  return this->plt_->first_plt_entry_offset();
}

// Return the size of each PLT entry.

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

// Get the section to use for TLS_DESC relocations.

template<bool big_endian>
typename Target_arm<big_endian>::Reloc_section*
Target_arm<big_endian>::rel_tls_desc_section(Layout* layout) const
{
  return this->plt_section()->rel_tls_desc(layout);
}

// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.

template<bool big_endian>
void
Target_arm<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)
    {
      bool is_exec = parameters->options().output_is_executable();
      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,
				       (is_exec
					? Symbol::SEGMENT_END
					: Symbol::SEGMENT_START),
				       true);
    }
  this->tls_base_symbol_defined_ = true;
}

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

template<bool big_endian>
unsigned int
Target_arm<big_endian>::got_mod_index_entry(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<32, big_endian>* object)
{
  if (this->got_mod_index_offset_ == -1U)
    {
      gold_assert(symtab != NULL && layout != NULL && object != NULL);
      Arm_output_data_got<big_endian>* got = this->got_section(symtab, layout);
      unsigned int got_offset;
      if (!parameters->doing_static_link())
	{
	  got_offset = got->add_constant(0);
	  Reloc_section* rel_dyn = this->rel_dyn_section(layout);
	  rel_dyn->add_local(object, 0, elfcpp::R_ARM_TLS_DTPMOD32, got,
			     got_offset);
	}
      else
	{
	  // We are doing a static link.  Just mark it as belong to module 1,
	  // the executable.
	  got_offset = got->add_constant(1);
	}

      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<bool big_endian>
tls::Tls_optimization
Target_arm<big_endian>::optimize_tls_reloc(bool, int)
{
  // FIXME: Currently we do not do any TLS optimization.
  return tls::TLSOPT_NONE;
}

// Get the Reference_flags for a particular relocation.

template<bool big_endian>
int
Target_arm<big_endian>::Scan::get_reference_flags(unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_ARM_NONE:
    case elfcpp::R_ARM_V4BX:
    case elfcpp::R_ARM_GNU_VTENTRY:
    case elfcpp::R_ARM_GNU_VTINHERIT:
      // No symbol reference.
      return 0;

    case elfcpp::R_ARM_ABS32:
    case elfcpp::R_ARM_ABS16:
    case elfcpp::R_ARM_ABS12:
    case elfcpp::R_ARM_THM_ABS5:
    case elfcpp::R_ARM_ABS8:
    case elfcpp::R_ARM_BASE_ABS:
    case elfcpp::R_ARM_MOVW_ABS_NC:
    case elfcpp::R_ARM_MOVT_ABS:
    case elfcpp::R_ARM_THM_MOVW_ABS_NC:
    case elfcpp::R_ARM_THM_MOVT_ABS:
    case elfcpp::R_ARM_ABS32_NOI:
      return Symbol::ABSOLUTE_REF;

    case elfcpp::R_ARM_REL32:
    case elfcpp::R_ARM_LDR_PC_G0:
    case elfcpp::R_ARM_SBREL32:
    case elfcpp::R_ARM_THM_PC8:
    case elfcpp::R_ARM_BASE_PREL:
    case elfcpp::R_ARM_MOVW_PREL_NC:
    case elfcpp::R_ARM_MOVT_PREL:
    case elfcpp::R_ARM_THM_MOVW_PREL_NC:
    case elfcpp::R_ARM_THM_MOVT_PREL:
    case elfcpp::R_ARM_THM_ALU_PREL_11_0:
    case elfcpp::R_ARM_THM_PC12:
    case elfcpp::R_ARM_REL32_NOI:
    case elfcpp::R_ARM_ALU_PC_G0_NC:
    case elfcpp::R_ARM_ALU_PC_G0:
    case elfcpp::R_ARM_ALU_PC_G1_NC:
    case elfcpp::R_ARM_ALU_PC_G1:
    case elfcpp::R_ARM_ALU_PC_G2:
    case elfcpp::R_ARM_LDR_PC_G1:
    case elfcpp::R_ARM_LDR_PC_G2:
    case elfcpp::R_ARM_LDRS_PC_G0:
    case elfcpp::R_ARM_LDRS_PC_G1:
    case elfcpp::R_ARM_LDRS_PC_G2:
    case elfcpp::R_ARM_LDC_PC_G0:
    case elfcpp::R_ARM_LDC_PC_G1:
    case elfcpp::R_ARM_LDC_PC_G2:
    case elfcpp::R_ARM_ALU_SB_G0_NC:
    case elfcpp::R_ARM_ALU_SB_G0:
    case elfcpp::R_ARM_ALU_SB_G1_NC:
    case elfcpp::R_ARM_ALU_SB_G1:
    case elfcpp::R_ARM_ALU_SB_G2:
    case elfcpp::R_ARM_LDR_SB_G0:
    case elfcpp::R_ARM_LDR_SB_G1:
    case elfcpp::R_ARM_LDR_SB_G2:
    case elfcpp::R_ARM_LDRS_SB_G0:
    case elfcpp::R_ARM_LDRS_SB_G1:
    case elfcpp::R_ARM_LDRS_SB_G2:
    case elfcpp::R_ARM_LDC_SB_G0:
    case elfcpp::R_ARM_LDC_SB_G1:
    case elfcpp::R_ARM_LDC_SB_G2:
    case elfcpp::R_ARM_MOVW_BREL_NC:
    case elfcpp::R_ARM_MOVT_BREL:
    case elfcpp::R_ARM_MOVW_BREL:
    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
    case elfcpp::R_ARM_THM_MOVT_BREL:
    case elfcpp::R_ARM_THM_MOVW_BREL:
    case elfcpp::R_ARM_GOTOFF32:
    case elfcpp::R_ARM_GOTOFF12:
    case elfcpp::R_ARM_SBREL31:
      return Symbol::RELATIVE_REF;

    case elfcpp::R_ARM_PLT32:
    case elfcpp::R_ARM_CALL:
    case elfcpp::R_ARM_JUMP24:
    case elfcpp::R_ARM_THM_CALL:
    case elfcpp::R_ARM_THM_JUMP24:
    case elfcpp::R_ARM_THM_JUMP19:
    case elfcpp::R_ARM_THM_JUMP6:
    case elfcpp::R_ARM_THM_JUMP11:
    case elfcpp::R_ARM_THM_JUMP8:
    // R_ARM_PREL31 is not used to relocate call/jump instructions but
    // in unwind tables. It may point to functions via PLTs.
    // So we treat it like call/jump relocations above.
    case elfcpp::R_ARM_PREL31:
      return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF;

    case elfcpp::R_ARM_GOT_BREL:
    case elfcpp::R_ARM_GOT_ABS:
    case elfcpp::R_ARM_GOT_PREL:
      // Absolute in GOT.
      return Symbol::ABSOLUTE_REF;

    case elfcpp::R_ARM_TLS_GD32:	// Global-dynamic
    case elfcpp::R_ARM_TLS_LDM32:	// Local-dynamic
    case elfcpp::R_ARM_TLS_LDO32:	// Alternate local-dynamic
    case elfcpp::R_ARM_TLS_IE32:	// Initial-exec
    case elfcpp::R_ARM_TLS_LE32:	// Local-exec
      return Symbol::TLS_REF;

    case elfcpp::R_ARM_TARGET1:
    case elfcpp::R_ARM_TARGET2:
    case elfcpp::R_ARM_COPY:
    case elfcpp::R_ARM_GLOB_DAT:
    case elfcpp::R_ARM_JUMP_SLOT:
    case elfcpp::R_ARM_RELATIVE:
    case elfcpp::R_ARM_PC24:
    case elfcpp::R_ARM_LDR_SBREL_11_0_NC:
    case elfcpp::R_ARM_ALU_SBREL_19_12_NC:
    case elfcpp::R_ARM_ALU_SBREL_27_20_CK:
    default:
      // Not expected.  We will give an error later.
      return 0;
    }
}

// Report an unsupported relocation against a local symbol.

template<bool big_endian>
void
Target_arm<big_endian>::Scan::unsupported_reloc_local(
    Sized_relobj_file<32, 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.  The GNU linker
// only issues a non-PIC error for an allocated read-only section.
// Here we know the section is allocated, but we don't know that it is
// read-only.  But we check for all the relocation types which the
// glibc dynamic linker supports, so it seems appropriate to issue an
// error even if the section is not read-only.

template<bool big_endian>
void
Target_arm<big_endian>::Scan::check_non_pic(Relobj* object,
					    unsigned int r_type)
{
  switch (r_type)
    {
    // These are the relocation types supported by glibc for ARM.
    case elfcpp::R_ARM_RELATIVE:
    case elfcpp::R_ARM_COPY:
    case elfcpp::R_ARM_GLOB_DAT:
    case elfcpp::R_ARM_JUMP_SLOT:
    case elfcpp::R_ARM_ABS32:
    case elfcpp::R_ARM_ABS32_NOI:
    case elfcpp::R_ARM_PC24:
    // FIXME: The following 3 types are not supported by Android's dynamic
    // linker.
    case elfcpp::R_ARM_TLS_DTPMOD32:
    case elfcpp::R_ARM_TLS_DTPOFF32:
    case elfcpp::R_ARM_TLS_TPOFF32:
      return;

    default:
      {
	// 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;
	const Arm_reloc_property* reloc_property =
	  arm_reloc_property_table->get_reloc_property(r_type);
	gold_assert(reloc_property != NULL);
	object->error(_("requires unsupported dynamic reloc %s; "
		      "recompile with -fPIC"),
		      reloc_property->name().c_str());
	this->issued_non_pic_error_ = true;
	return;
      }

    case elfcpp::R_ARM_NONE:
      gold_unreachable();
    }
}

// Scan a relocation for a local symbol.
// FIXME: This only handles a subset of relocation types used by Android
// on ARM v5te devices.

template<bool big_endian>
inline void
Target_arm<big_endian>::Scan::local(Symbol_table* symtab,
				    Layout* layout,
				    Target_arm* target,
				    Sized_relobj_file<32, big_endian>* object,
				    unsigned int data_shndx,
				    Output_section* output_section,
				    const elfcpp::Rel<32, big_endian>& reloc,
				    unsigned int r_type,
				    const elfcpp::Sym<32, big_endian>& lsym)
{
  r_type = get_real_reloc_type(r_type);
  switch (r_type)
    {
    case elfcpp::R_ARM_NONE:
    case elfcpp::R_ARM_V4BX:
    case elfcpp::R_ARM_GNU_VTENTRY:
    case elfcpp::R_ARM_GNU_VTINHERIT:
      break;

    case elfcpp::R_ARM_ABS32:
    case elfcpp::R_ARM_ABS32_NOI:
      // If building a shared library (or a position-independent
      // executable), we need to create a dynamic relocation for
      // this location. The relocation applied at link time will
      // apply the link-time value, so we flag the location with
      // an R_ARM_RELATIVE relocation so the dynamic loader can
      // relocate it easily.
      if (parameters->options().output_is_position_independent())
	{
	  Reloc_section* rel_dyn = target->rel_dyn_section(layout);
	  unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
	  // If we are to add more other reloc types than R_ARM_ABS32,
	  // we need to add check_non_pic(object, r_type) here.
	  rel_dyn->add_local_relative(object, r_sym, elfcpp::R_ARM_RELATIVE,
				      output_section, data_shndx,
				      reloc.get_r_offset());
	}
      break;

    case elfcpp::R_ARM_ABS16:
    case elfcpp::R_ARM_ABS12:
    case elfcpp::R_ARM_THM_ABS5:
    case elfcpp::R_ARM_ABS8:
    case elfcpp::R_ARM_BASE_ABS:
    case elfcpp::R_ARM_MOVW_ABS_NC:
    case elfcpp::R_ARM_MOVT_ABS:
    case elfcpp::R_ARM_THM_MOVW_ABS_NC:
    case elfcpp::R_ARM_THM_MOVT_ABS:
      // If building a shared library (or a position-independent
      // executable), we need to create a dynamic relocation for
      // this location. Because the addend needs to remain in the
      // data section, we need to be careful not to apply this
      // relocation statically.
      if (parameters->options().output_is_position_independent())
	{
	  check_non_pic(object, r_type);
	  Reloc_section* rel_dyn = target->rel_dyn_section(layout);
	  unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
	  if (lsym.get_st_type() != elfcpp::STT_SECTION)
	    rel_dyn->add_local(object, r_sym, r_type, output_section,
			       data_shndx, reloc.get_r_offset());
	  else
	    {
	      gold_assert(lsym.get_st_value() == 0);
	      unsigned int shndx = lsym.get_st_shndx();
	      bool is_ordinary;
	      shndx = object->adjust_sym_shndx(r_sym, shndx,
					       &is_ordinary);
	      if (!is_ordinary)
		object->error(_("section symbol %u has bad shndx %u"),
			      r_sym, shndx);
	      else
		rel_dyn->add_local_section(object, shndx,
					   r_type, output_section,
					   data_shndx, reloc.get_r_offset());
	    }
	}
      break;

    case elfcpp::R_ARM_REL32:
    case elfcpp::R_ARM_LDR_PC_G0:
    case elfcpp::R_ARM_SBREL32:
    case elfcpp::R_ARM_THM_CALL:
    case elfcpp::R_ARM_THM_PC8:
    case elfcpp::R_ARM_BASE_PREL:
    case elfcpp::R_ARM_PLT32:
    case elfcpp::R_ARM_CALL:
    case elfcpp::R_ARM_JUMP24:
    case elfcpp::R_ARM_THM_JUMP24:
    case elfcpp::R_ARM_SBREL31:
    case elfcpp::R_ARM_PREL31:
    case elfcpp::R_ARM_MOVW_PREL_NC:
    case elfcpp::R_ARM_MOVT_PREL:
    case elfcpp::R_ARM_THM_MOVW_PREL_NC:
    case elfcpp::R_ARM_THM_MOVT_PREL:
    case elfcpp::R_ARM_THM_JUMP19:
    case elfcpp::R_ARM_THM_JUMP6:
    case elfcpp::R_ARM_THM_ALU_PREL_11_0:
    case elfcpp::R_ARM_THM_PC12:
    case elfcpp::R_ARM_REL32_NOI:
    case elfcpp::R_ARM_ALU_PC_G0_NC:
    case elfcpp::R_ARM_ALU_PC_G0:
    case elfcpp::R_ARM_ALU_PC_G1_NC:
    case elfcpp::R_ARM_ALU_PC_G1:
    case elfcpp::R_ARM_ALU_PC_G2:
    case elfcpp::R_ARM_LDR_PC_G1:
    case elfcpp::R_ARM_LDR_PC_G2:
    case elfcpp::R_ARM_LDRS_PC_G0:
    case elfcpp::R_ARM_LDRS_PC_G1:
    case elfcpp::R_ARM_LDRS_PC_G2:
    case elfcpp::R_ARM_LDC_PC_G0:
    case elfcpp::R_ARM_LDC_PC_G1:
    case elfcpp::R_ARM_LDC_PC_G2:
    case elfcpp::R_ARM_ALU_SB_G0_NC:
    case elfcpp::R_ARM_ALU_SB_G0:
    case elfcpp::R_ARM_ALU_SB_G1_NC:
    case elfcpp::R_ARM_ALU_SB_G1:
    case elfcpp::R_ARM_ALU_SB_G2:
    case elfcpp::R_ARM_LDR_SB_G0:
    case elfcpp::R_ARM_LDR_SB_G1:
    case elfcpp::R_ARM_LDR_SB_G2:
    case elfcpp::R_ARM_LDRS_SB_G0:
    case elfcpp::R_ARM_LDRS_SB_G1:
    case elfcpp::R_ARM_LDRS_SB_G2:
    case elfcpp::R_ARM_LDC_SB_G0:
    case elfcpp::R_ARM_LDC_SB_G1:
    case elfcpp::R_ARM_LDC_SB_G2:
    case elfcpp::R_ARM_MOVW_BREL_NC:
    case elfcpp::R_ARM_MOVT_BREL:
    case elfcpp::R_ARM_MOVW_BREL:
    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
    case elfcpp::R_ARM_THM_MOVT_BREL:
    case elfcpp::R_ARM_THM_MOVW_BREL:
    case elfcpp::R_ARM_THM_JUMP11:
    case elfcpp::R_ARM_THM_JUMP8:
      // We don't need to do anything for a relative addressing relocation
      // against a local symbol if it does not reference the GOT.
      break;

    case elfcpp::R_ARM_GOTOFF32:
    case elfcpp::R_ARM_GOTOFF12:
      // We need a GOT section:
      target->got_section(symtab, layout);
      break;

    case elfcpp::R_ARM_GOT_BREL:
    case elfcpp::R_ARM_GOT_PREL:
      {
	// The symbol requires a GOT entry.
	Arm_output_data_got<big_endian>* got =
	  target->got_section(symtab, layout);
	unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
	if (got->add_local(object, r_sym, GOT_TYPE_STANDARD))
	  {
	    // If we are generating a shared object, we need to add a
	    // dynamic RELATIVE relocation for this symbol's GOT entry.
	    if (parameters->options().output_is_position_independent())
	      {
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
		rel_dyn->add_local_relative(
		    object, r_sym, elfcpp::R_ARM_RELATIVE, got,
		    object->local_got_offset(r_sym, GOT_TYPE_STANDARD));
	      }
	  }
      }
      break;

    case elfcpp::R_ARM_TARGET1:
    case elfcpp::R_ARM_TARGET2:
      // This should have been mapped to another type already.
      // Fall through.
    case elfcpp::R_ARM_COPY:
    case elfcpp::R_ARM_GLOB_DAT:
    case elfcpp::R_ARM_JUMP_SLOT:
    case elfcpp::R_ARM_RELATIVE:
      // These are relocations which should only be seen by the
      // dynamic linker, and should never be seen here.
      gold_error(_("%s: unexpected reloc %u in object file"),
		 object->name().c_str(), r_type);
      break;


      // These are initial TLS relocs, which are expected when
      // linking.
    case elfcpp::R_ARM_TLS_GD32:	// Global-dynamic
    case elfcpp::R_ARM_TLS_LDM32:	// Local-dynamic
    case elfcpp::R_ARM_TLS_LDO32:	// Alternate local-dynamic
    case elfcpp::R_ARM_TLS_IE32:	// Initial-exec
    case elfcpp::R_ARM_TLS_LE32:	// Local-exec
      {
	bool output_is_shared = parameters->options().shared();
	const tls::Tls_optimization optimized_type
	    = Target_arm<big_endian>::optimize_tls_reloc(!output_is_shared,
							 r_type);
	switch (r_type)
	  {
	  case elfcpp::R_ARM_TLS_GD32:		// Global-dynamic
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a pair of GOT entries for the module index and
		// dtv-relative offset.
		Arm_output_data_got<big_endian>* got
		    = target->got_section(symtab, layout);
		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
		unsigned int shndx = lsym.get_st_shndx();
		bool is_ordinary;
		shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
		if (!is_ordinary)
		  {
		    object->error(_("local symbol %u has bad shndx %u"),
				  r_sym, shndx);
		    break;
		  }

		if (!parameters->doing_static_link())
		  got->add_local_pair_with_rel(object, r_sym, shndx,
					       GOT_TYPE_TLS_PAIR,
					       target->rel_dyn_section(layout),
					       elfcpp::R_ARM_TLS_DTPMOD32, 0);
		else
		  got->add_tls_gd32_with_static_reloc(GOT_TYPE_TLS_PAIR,
						      object, r_sym);
	      }
	    else
	      // FIXME: TLS optimization not supported yet.
	      gold_unreachable();
	    break;

	  case elfcpp::R_ARM_TLS_LDM32:		// Local-dynamic
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a GOT entry for the module index.
		target->got_mod_index_entry(symtab, layout, object);
	      }
	    else
	      // FIXME: TLS optimization not supported yet.
	      gold_unreachable();
	    break;

	  case elfcpp::R_ARM_TLS_LDO32:		// Alternate local-dynamic
	    break;

	  case elfcpp::R_ARM_TLS_IE32:		// Initial-exec
	    layout->set_has_static_tls();
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a GOT entry for the tp-relative offset.
		Arm_output_data_got<big_endian>* got
		  = target->got_section(symtab, layout);
		unsigned int r_sym =
		   elfcpp::elf_r_sym<32>(reloc.get_r_info());
		if (!parameters->doing_static_link())
		    got->add_local_with_rel(object, r_sym, GOT_TYPE_TLS_OFFSET,
					    target->rel_dyn_section(layout),
					    elfcpp::R_ARM_TLS_TPOFF32);
		else if (!object->local_has_got_offset(r_sym,
						       GOT_TYPE_TLS_OFFSET))
		  {
		    got->add_local(object, r_sym, GOT_TYPE_TLS_OFFSET);
		    unsigned int got_offset =
		      object->local_got_offset(r_sym, GOT_TYPE_TLS_OFFSET);
		    got->add_static_reloc(got_offset,
					  elfcpp::R_ARM_TLS_TPOFF32, object,
					  r_sym);
		  }
	      }
	    else
	      // FIXME: TLS optimization not supported yet.
	      gold_unreachable();
	    break;

	  case elfcpp::R_ARM_TLS_LE32:		// Local-exec
	    layout->set_has_static_tls();
	    if (output_is_shared)
	      {
		// We need to create a dynamic relocation.
		gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION);
		unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info());
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_local(object, r_sym, elfcpp::R_ARM_TLS_TPOFF32,
				   output_section, data_shndx,
				   reloc.get_r_offset());
	      }
	    break;

	  default:
	    gold_unreachable();
	  }
      }
      break;

    case elfcpp::R_ARM_PC24:
    case elfcpp::R_ARM_LDR_SBREL_11_0_NC:
    case elfcpp::R_ARM_ALU_SBREL_19_12_NC:
    case elfcpp::R_ARM_ALU_SBREL_27_20_CK:
    default:
      unsupported_reloc_local(object, r_type);
      break;
    }
}

// Report an unsupported relocation against a global symbol.

template<bool big_endian>
void
Target_arm<big_endian>::Scan::unsupported_reloc_global(
    Sized_relobj_file<32, 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<bool big_endian>
inline bool
Target_arm<big_endian>::Scan::possible_function_pointer_reloc(
    unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_ARM_PC24:
    case elfcpp::R_ARM_THM_CALL:
    case elfcpp::R_ARM_PLT32:
    case elfcpp::R_ARM_CALL:
    case elfcpp::R_ARM_JUMP24:
    case elfcpp::R_ARM_THM_JUMP24:
    case elfcpp::R_ARM_SBREL31:
    case elfcpp::R_ARM_PREL31:
    case elfcpp::R_ARM_THM_JUMP19:
    case elfcpp::R_ARM_THM_JUMP6:
    case elfcpp::R_ARM_THM_JUMP11:
    case elfcpp::R_ARM_THM_JUMP8:
      // All the relocations above are branches except SBREL31 and PREL31.
      return false;

    default:
      // Be conservative and assume this is a function pointer.
      return true;
    }
}

template<bool big_endian>
inline bool
Target_arm<big_endian>::Scan::local_reloc_may_be_function_pointer(
  Symbol_table*,
  Layout*,
  Target_arm<big_endian>* target,
  Sized_relobj_file<32, big_endian>*,
  unsigned int,
  Output_section*,
  const elfcpp::Rel<32, big_endian>&,
  unsigned int r_type,
  const elfcpp::Sym<32, big_endian>&)
{
  r_type = target->get_real_reloc_type(r_type);
  return possible_function_pointer_reloc(r_type);
}

template<bool big_endian>
inline bool
Target_arm<big_endian>::Scan::global_reloc_may_be_function_pointer(
  Symbol_table*,
  Layout*,
  Target_arm<big_endian>* target,
  Sized_relobj_file<32, big_endian>*,
  unsigned int,
  Output_section*,
  const elfcpp::Rel<32, big_endian>&,
  unsigned int r_type,
  Symbol* gsym)
{
  // GOT is not a function.
  if (strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
    return false;

  r_type = target->get_real_reloc_type(r_type);
  return possible_function_pointer_reloc(r_type);
}

// Scan a relocation for a global symbol.

template<bool big_endian>
inline void
Target_arm<big_endian>::Scan::global(Symbol_table* symtab,
				     Layout* layout,
				     Target_arm* target,
				     Sized_relobj_file<32, big_endian>* object,
				     unsigned int data_shndx,
				     Output_section* output_section,
				     const elfcpp::Rel<32, big_endian>& reloc,
				     unsigned int r_type,
				     Symbol* gsym)
{
  // A reference to _GLOBAL_OFFSET_TABLE_ implies that we need a got
  // section.  We check here to avoid creating a dynamic reloc against
  // _GLOBAL_OFFSET_TABLE_.
  if (!target->has_got_section()
      && strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
    target->got_section(symtab, layout);

  r_type = get_real_reloc_type(r_type);
  switch (r_type)
    {
    case elfcpp::R_ARM_NONE:
    case elfcpp::R_ARM_V4BX:
    case elfcpp::R_ARM_GNU_VTENTRY:
    case elfcpp::R_ARM_GNU_VTINHERIT:
      break;

    case elfcpp::R_ARM_ABS32:
    case elfcpp::R_ARM_ABS16:
    case elfcpp::R_ARM_ABS12:
    case elfcpp::R_ARM_THM_ABS5:
    case elfcpp::R_ARM_ABS8:
    case elfcpp::R_ARM_BASE_ABS:
    case elfcpp::R_ARM_MOVW_ABS_NC:
    case elfcpp::R_ARM_MOVT_ABS:
    case elfcpp::R_ARM_THM_MOVW_ABS_NC:
    case elfcpp::R_ARM_THM_MOVT_ABS:
    case elfcpp::R_ARM_ABS32_NOI:
      // Absolute addressing relocations.
      {
	// Make a PLT entry if necessary.
	if (this->symbol_needs_plt_entry(gsym))
	  {
	    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(Scan::get_reference_flags(r_type)))
	  {
	    if (gsym->may_need_copy_reloc())
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, reloc);
	      }
	    else if ((r_type == elfcpp::R_ARM_ABS32
		      || r_type == elfcpp::R_ARM_ABS32_NOI)
		     && gsym->can_use_relative_reloc(false))
	      {
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_global_relative(gsym, elfcpp::R_ARM_RELATIVE,
					     output_section, object,
					     data_shndx, reloc.get_r_offset());
	      }
	    else
	      {
		check_non_pic(object, r_type);
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_global(gsym, r_type, output_section, object,
				    data_shndx, reloc.get_r_offset());
	      }
	  }
      }
      break;

    case elfcpp::R_ARM_GOTOFF32:
    case elfcpp::R_ARM_GOTOFF12:
      // We need a GOT section.
      target->got_section(symtab, layout);
      break;

    case elfcpp::R_ARM_REL32:
    case elfcpp::R_ARM_LDR_PC_G0:
    case elfcpp::R_ARM_SBREL32:
    case elfcpp::R_ARM_THM_PC8:
    case elfcpp::R_ARM_BASE_PREL:
    case elfcpp::R_ARM_MOVW_PREL_NC:
    case elfcpp::R_ARM_MOVT_PREL:
    case elfcpp::R_ARM_THM_MOVW_PREL_NC:
    case elfcpp::R_ARM_THM_MOVT_PREL:
    case elfcpp::R_ARM_THM_ALU_PREL_11_0:
    case elfcpp::R_ARM_THM_PC12:
    case elfcpp::R_ARM_REL32_NOI:
    case elfcpp::R_ARM_ALU_PC_G0_NC:
    case elfcpp::R_ARM_ALU_PC_G0:
    case elfcpp::R_ARM_ALU_PC_G1_NC:
    case elfcpp::R_ARM_ALU_PC_G1:
    case elfcpp::R_ARM_ALU_PC_G2:
    case elfcpp::R_ARM_LDR_PC_G1:
    case elfcpp::R_ARM_LDR_PC_G2:
    case elfcpp::R_ARM_LDRS_PC_G0:
    case elfcpp::R_ARM_LDRS_PC_G1:
    case elfcpp::R_ARM_LDRS_PC_G2:
    case elfcpp::R_ARM_LDC_PC_G0:
    case elfcpp::R_ARM_LDC_PC_G1:
    case elfcpp::R_ARM_LDC_PC_G2:
    case elfcpp::R_ARM_ALU_SB_G0_NC:
    case elfcpp::R_ARM_ALU_SB_G0:
    case elfcpp::R_ARM_ALU_SB_G1_NC:
    case elfcpp::R_ARM_ALU_SB_G1:
    case elfcpp::R_ARM_ALU_SB_G2:
    case elfcpp::R_ARM_LDR_SB_G0:
    case elfcpp::R_ARM_LDR_SB_G1:
    case elfcpp::R_ARM_LDR_SB_G2:
    case elfcpp::R_ARM_LDRS_SB_G0:
    case elfcpp::R_ARM_LDRS_SB_G1:
    case elfcpp::R_ARM_LDRS_SB_G2:
    case elfcpp::R_ARM_LDC_SB_G0:
    case elfcpp::R_ARM_LDC_SB_G1:
    case elfcpp::R_ARM_LDC_SB_G2:
    case elfcpp::R_ARM_MOVW_BREL_NC:
    case elfcpp::R_ARM_MOVT_BREL:
    case elfcpp::R_ARM_MOVW_BREL:
    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
    case elfcpp::R_ARM_THM_MOVT_BREL:
    case elfcpp::R_ARM_THM_MOVW_BREL:
      // Relative addressing relocations.
      {
	// Make a dynamic relocation if necessary.
	if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type)))
	  {
	    if (target->may_need_copy_reloc(gsym))
	      {
		target->copy_reloc(symtab, layout, object,
				   data_shndx, output_section, gsym, reloc);
	      }
	    else
	      {
		check_non_pic(object, r_type);
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_global(gsym, r_type, output_section, object,
				    data_shndx, reloc.get_r_offset());
	      }
	  }
      }
      break;

    case elfcpp::R_ARM_THM_CALL:
    case elfcpp::R_ARM_PLT32:
    case elfcpp::R_ARM_CALL:
    case elfcpp::R_ARM_JUMP24:
    case elfcpp::R_ARM_THM_JUMP24:
    case elfcpp::R_ARM_SBREL31:
    case elfcpp::R_ARM_PREL31:
    case elfcpp::R_ARM_THM_JUMP19:
    case elfcpp::R_ARM_THM_JUMP6:
    case elfcpp::R_ARM_THM_JUMP11:
    case elfcpp::R_ARM_THM_JUMP8:
      // All the relocation above are branches except for the PREL31 ones.
      // A PREL31 relocation can point to a personality function in a shared
      // library.  In that case we want to use a PLT because we want to
      // call the personality routine and the dynamic linkers we care about
      // do not support dynamic PREL31 relocations. An REL31 relocation may
      // point to a function whose unwinding behaviour is being described but
      // we will not mistakenly generate a PLT for that because we should use
      // a local section symbol.

      // If the symbol is fully resolved, this is just a relative
      // local reloc.  Otherwise we need a PLT entry.
      if (gsym->final_value_is_known())
	break;
      // If building a shared library, we can also skip the PLT entry
      // if the symbol is defined in the output file and is protected
      // or hidden.
      if (gsym->is_defined()
	  && !gsym->is_from_dynobj()
	  && !gsym->is_preemptible())
	break;
      target->make_plt_entry(symtab, layout, gsym);
      break;

    case elfcpp::R_ARM_GOT_BREL:
    case elfcpp::R_ARM_GOT_ABS:
    case elfcpp::R_ARM_GOT_PREL:
      {
	// The symbol requires a GOT entry.
	Arm_output_data_got<big_endian>* got =
	  target->got_section(symtab, layout);
	if (gsym->final_value_is_known())
	  got->add_global(gsym, GOT_TYPE_STANDARD);
	else
	  {
	    // If this symbol is not fully resolved, we need to add a
	    // GOT entry with a dynamic relocation.
	    Reloc_section* rel_dyn = target->rel_dyn_section(layout);
	    if (gsym->is_from_dynobj()
		|| gsym->is_undefined()
		|| gsym->is_preemptible()
		|| (gsym->visibility() == elfcpp::STV_PROTECTED
		    && parameters->options().shared()))
	      got->add_global_with_rel(gsym, GOT_TYPE_STANDARD,
				       rel_dyn, elfcpp::R_ARM_GLOB_DAT);
	    else
	      {
		if (got->add_global(gsym, GOT_TYPE_STANDARD))
		  rel_dyn->add_global_relative(
		      gsym, elfcpp::R_ARM_RELATIVE, got,
		      gsym->got_offset(GOT_TYPE_STANDARD));
	      }
	  }
      }
      break;

    case elfcpp::R_ARM_TARGET1:
    case elfcpp::R_ARM_TARGET2:
      // These should have been mapped to other types already.
      // Fall through.
    case elfcpp::R_ARM_COPY:
    case elfcpp::R_ARM_GLOB_DAT:
    case elfcpp::R_ARM_JUMP_SLOT:
    case elfcpp::R_ARM_RELATIVE:
      // These are relocations which should only be seen by the
      // dynamic linker, and should never be seen here.
      gold_error(_("%s: unexpected reloc %u in object file"),
		 object->name().c_str(), r_type);
      break;

      // These are initial tls relocs, which are expected when
      // linking.
    case elfcpp::R_ARM_TLS_GD32:	// Global-dynamic
    case elfcpp::R_ARM_TLS_LDM32:	// Local-dynamic
    case elfcpp::R_ARM_TLS_LDO32:	// Alternate local-dynamic
    case elfcpp::R_ARM_TLS_IE32:	// Initial-exec
    case elfcpp::R_ARM_TLS_LE32:	// Local-exec
      {
	const bool is_final = gsym->final_value_is_known();
	const tls::Tls_optimization optimized_type
	    = Target_arm<big_endian>::optimize_tls_reloc(is_final, r_type);
	switch (r_type)
	  {
	  case elfcpp::R_ARM_TLS_GD32:		// Global-dynamic
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a pair of GOT entries for the module index and
		// dtv-relative offset.
		Arm_output_data_got<big_endian>* got
		    = target->got_section(symtab, layout);
		if (!parameters->doing_static_link())
		  got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR,
						target->rel_dyn_section(layout),
						elfcpp::R_ARM_TLS_DTPMOD32,
						elfcpp::R_ARM_TLS_DTPOFF32);
		else
		  got->add_tls_gd32_with_static_reloc(GOT_TYPE_TLS_PAIR, gsym);
	      }
	    else
	      // FIXME: TLS optimization not supported yet.
	      gold_unreachable();
	    break;

	  case elfcpp::R_ARM_TLS_LDM32:		// Local-dynamic
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a GOT entry for the module index.
		target->got_mod_index_entry(symtab, layout, object);
	      }
	    else
	      // FIXME: TLS optimization not supported yet.
	      gold_unreachable();
	    break;

	  case elfcpp::R_ARM_TLS_LDO32:		// Alternate local-dynamic
	    break;

	  case elfcpp::R_ARM_TLS_IE32:		// Initial-exec
	    layout->set_has_static_tls();
	    if (optimized_type == tls::TLSOPT_NONE)
	      {
		// Create a GOT entry for the tp-relative offset.
		Arm_output_data_got<big_endian>* got
		  = target->got_section(symtab, layout);
		if (!parameters->doing_static_link())
		  got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET,
					   target->rel_dyn_section(layout),
					   elfcpp::R_ARM_TLS_TPOFF32);
		else 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);
		    got->add_static_reloc(got_offset,
					  elfcpp::R_ARM_TLS_TPOFF32, gsym);
		  }
	      }
	    else
	      // FIXME: TLS optimization not supported yet.
	      gold_unreachable();
	    break;

	  case elfcpp::R_ARM_TLS_LE32:	// Local-exec
	    layout->set_has_static_tls();
	    if (parameters->options().shared())
	      {
		// We need to create a dynamic relocation.
		Reloc_section* rel_dyn = target->rel_dyn_section(layout);
		rel_dyn->add_global(gsym, elfcpp::R_ARM_TLS_TPOFF32,
				    output_section, object,
				    data_shndx, reloc.get_r_offset());
	      }
	    break;

	  default:
	    gold_unreachable();
	  }
      }
      break;

    case elfcpp::R_ARM_PC24:
    case elfcpp::R_ARM_LDR_SBREL_11_0_NC:
    case elfcpp::R_ARM_ALU_SBREL_19_12_NC:
    case elfcpp::R_ARM_ALU_SBREL_27_20_CK:
    default:
      unsupported_reloc_global(object, r_type, gsym);
      break;
    }
}

// Process relocations for gc.

template<bool big_endian>
void
Target_arm<big_endian>::gc_process_relocs(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<32, big_endian>* object,
    unsigned int data_shndx,
    unsigned int,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    size_t local_symbol_count,
    const unsigned char* plocal_symbols)
{
  typedef Target_arm<big_endian> Arm;
  typedef typename Target_arm<big_endian>::Scan Scan;

  gold::gc_process_relocs<32, big_endian, Arm, elfcpp::SHT_REL, Scan,
			  typename Target_arm::Relocatable_size_for_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<bool big_endian>
void
Target_arm<big_endian>::scan_relocs(Symbol_table* symtab,
				    Layout* layout,
				    Sized_relobj_file<32, 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 typename Target_arm<big_endian>::Scan Scan;
  if (sh_type == elfcpp::SHT_RELA)
    {
      gold_error(_("%s: unsupported RELA reloc section"),
		 object->name().c_str());
      return;
    }

  gold::scan_relocs<32, big_endian, Target_arm, elfcpp::SHT_REL, Scan>(
    symtab,
    layout,
    this,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols);
}

// Finalize the sections.

template<bool big_endian>
void
Target_arm<big_endian>::do_finalize_sections(
    Layout* layout,
    const Input_objects* input_objects,
    Symbol_table*)
{
  bool merged_any_attributes = false;
  // Merge processor-specific flags.
  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      Arm_relobj<big_endian>* arm_relobj =
	Arm_relobj<big_endian>::as_arm_relobj(*p);
      if (arm_relobj->merge_flags_and_attributes())
	{
	  this->merge_processor_specific_flags(
	      arm_relobj->name(),
	      arm_relobj->processor_specific_flags());
	  this->merge_object_attributes(arm_relobj->name().c_str(),
					arm_relobj->attributes_section_data());
	  merged_any_attributes = true;
	}
    }

  for (Input_objects::Dynobj_iterator p = input_objects->dynobj_begin();
       p != input_objects->dynobj_end();
       ++p)
    {
      Arm_dynobj<big_endian>* arm_dynobj =
	Arm_dynobj<big_endian>::as_arm_dynobj(*p);
      this->merge_processor_specific_flags(
	  arm_dynobj->name(),
	  arm_dynobj->processor_specific_flags());
      this->merge_object_attributes(arm_dynobj->name().c_str(),
				    arm_dynobj->attributes_section_data());
      merged_any_attributes = true;
    }

  // Create an empty uninitialized attribute section if we still don't have it
  // at this moment.  This happens if there is no attributes sections in all
  // inputs.
  if (this->attributes_section_data_ == NULL)
    this->attributes_section_data_ = new Attributes_section_data(NULL, 0);

  const Object_attribute* cpu_arch_attr =
    this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
  // Check if we need to use Cortex-A8 workaround.
  if (parameters->options().user_set_fix_cortex_a8())
    this->fix_cortex_a8_ = parameters->options().fix_cortex_a8();
  else
    {
      // If neither --fix-cortex-a8 nor --no-fix-cortex-a8 is used, turn on
      // Cortex-A8 erratum workaround for ARMv7-A or ARMv7 with unknown
      // profile.
      const Object_attribute* cpu_arch_profile_attr =
	this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch_profile);
      this->fix_cortex_a8_ =
	(cpu_arch_attr->int_value() == elfcpp::TAG_CPU_ARCH_V7
	 && (cpu_arch_profile_attr->int_value() == 'A'
	     || cpu_arch_profile_attr->int_value() == 0));
    }

  // Check if we can use V4BX interworking.
  // The V4BX interworking stub contains BX instruction,
  // which is not specified for some profiles.
  if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING
      && !this->may_use_v4t_interworking())
    gold_error(_("unable to provide V4BX reloc interworking fix up; "
		 "the target profile does not support BX instruction"));

  // Fill in some more dynamic tags.
  const Reloc_section* rel_plt = (this->plt_ == NULL
				  ? NULL
				  : this->plt_->rel_plt());
  layout->add_target_dynamic_tags(true, this->got_plt_, rel_plt,
				  this->rel_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->rel_dyn_section(layout));

  // Handle the .ARM.exidx section.
  Output_section* exidx_section = layout->find_output_section(".ARM.exidx");

  if (!parameters->options().relocatable())
    {
      if (exidx_section != NULL
	  && exidx_section->type() == elfcpp::SHT_ARM_EXIDX)
	{
	  // For the ARM target, we need to add a PT_ARM_EXIDX segment for
	  // the .ARM.exidx section.
	  if (!layout->script_options()->saw_phdrs_clause())
	    {
	      gold_assert(layout->find_output_segment(elfcpp::PT_ARM_EXIDX, 0,
						      0)
			  == NULL);
	      Output_segment*  exidx_segment =
		layout->make_output_segment(elfcpp::PT_ARM_EXIDX, elfcpp::PF_R);
	      exidx_segment->add_output_section_to_nonload(exidx_section,
							   elfcpp::PF_R);
	    }
	}
    }

  // Create an .ARM.attributes section if we have merged any attributes
  // from inputs.
  if (merged_any_attributes)
    {
      Output_attributes_section_data* attributes_section =
      new Output_attributes_section_data(*this->attributes_section_data_);
      layout->add_output_section_data(".ARM.attributes",
				      elfcpp::SHT_ARM_ATTRIBUTES, 0,
				      attributes_section, ORDER_INVALID,
				      false);
    }

  // Fix up links in section EXIDX headers.
  for (Layout::Section_list::const_iterator p = layout->section_list().begin();
       p != layout->section_list().end();
       ++p)
    if ((*p)->type() == elfcpp::SHT_ARM_EXIDX)
      {
	Arm_output_section<big_endian>* os =
	  Arm_output_section<big_endian>::as_arm_output_section(*p);
	os->set_exidx_section_link();
      }
}

// Return whether a direct absolute static relocation needs to be applied.
// In cases where Scan::local() or Scan::global() has created
// a dynamic relocation other than R_ARM_RELATIVE, the addend
// of the relocation is carried in the data, and we must not
// apply the static relocation.

template<bool big_endian>
inline bool
Target_arm<big_endian>::Relocate::should_apply_static_reloc(
    const Sized_symbol<32>* gsym,
    unsigned int r_type,
    bool is_32bit,
    Output_section* output_section)
{
  // If the output section is not allocated, then we didn't call
  // scan_relocs, we didn't create a dynamic reloc, and we must apply
  // the reloc here.
  if ((output_section->flags() & elfcpp::SHF_ALLOC) == 0)
      return true;

  int ref_flags = Scan::get_reference_flags(r_type);

  // For local symbols, we will have created a non-RELATIVE dynamic
  // relocation only if (a) the output is position independent,
  // (b) the relocation is absolute (not pc- or segment-relative), and
  // (c) the relocation is not 32 bits wide.
  if (gsym == NULL)
    return !(parameters->options().output_is_position_independent()
	     && (ref_flags & Symbol::ABSOLUTE_REF)
	     && !is_32bit);

  // For global symbols, we use the same helper routines used in the
  // scan pass.  If we did not create a dynamic relocation, or if we
  // created a RELATIVE dynamic relocation, we should apply the static
  // relocation.
  bool has_dyn = gsym->needs_dynamic_reloc(ref_flags);
  bool is_rel = (ref_flags & Symbol::ABSOLUTE_REF)
		 && gsym->can_use_relative_reloc(ref_flags
						 & Symbol::FUNCTION_CALL);
  return !has_dyn || is_rel;
}

// Perform a relocation.

template<bool big_endian>
inline bool
Target_arm<big_endian>::Relocate::relocate(
    const Relocate_info<32, big_endian>* relinfo,
    Target_arm* target,
    Output_section* output_section,
    size_t relnum,
    const elfcpp::Rel<32, big_endian>& rel,
    unsigned int r_type,
    const Sized_symbol<32>* gsym,
    const Symbol_value<32>* psymval,
    unsigned char* view,
    Arm_address address,
    section_size_type view_size)
{
  typedef Arm_relocate_functions<big_endian> Arm_relocate_functions;

  r_type = get_real_reloc_type(r_type);
  const Arm_reloc_property* reloc_property =
    arm_reloc_property_table->get_implemented_static_reloc_property(r_type);
  if (reloc_property == NULL)
    {
      std::string reloc_name =
	arm_reloc_property_table->reloc_name_in_error_message(r_type);
      gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			     _("cannot relocate %s in object file"),
			     reloc_name.c_str());
      return true;
    }

  const Arm_relobj<big_endian>* object =
    Arm_relobj<big_endian>::as_arm_relobj(relinfo->object);

  // If the final branch target of a relocation is THUMB instruction, this
  // is 1.  Otherwise it is 0.
  Arm_address thumb_bit = 0;
  Symbol_value<32> symval;
  bool is_weakly_undefined_without_plt = false;
  bool have_got_offset = false;
  unsigned int got_offset = 0;

  // If the relocation uses the GOT entry of a symbol instead of the symbol
  // itself, we don't care about whether the symbol is defined or what kind
  // of symbol it is.
  if (reloc_property->uses_got_entry())
    {
      // Get the GOT offset.
      // The GOT pointer points to the end of the GOT section.
      // We need to subtract the size of the GOT section to get
      // the actual offset to use in the relocation.
      // TODO: We should move GOT offset computing code in TLS relocations
      // to here.
      switch (r_type)
	{
	case elfcpp::R_ARM_GOT_BREL:
	case elfcpp::R_ARM_GOT_PREL:
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD));
	      got_offset = (gsym->got_offset(GOT_TYPE_STANDARD)
			    - target->got_size());
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.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)
			    - target->got_size());
	    }
	  have_got_offset = true;
	  break;

	default:
	  break;
	}
    }
  else if (relnum != Target_arm<big_endian>::fake_relnum_for_stubs)
    {
      if (gsym != NULL)
	{
	  // This is a global symbol.  Determine if we use PLT and if the
	  // final target is THUMB.
	  if (gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
	    {
	      // This uses a PLT, change the symbol value.
	      symval.set_output_value(target->plt_section()->address()
				      + gsym->plt_offset());
	      psymval = &symval;
	    }
	  else if (gsym->is_weak_undefined())
	    {
	      // This is a weakly undefined symbol and we do not use PLT
	      // for this relocation.  A branch targeting this symbol will
	      // be converted into an NOP.
	      is_weakly_undefined_without_plt = true;
	    }
	  else if (gsym->is_undefined() && reloc_property->uses_symbol())
	    {
	      // This relocation uses the symbol value but the symbol is
	      // undefined.  Exit early and have the caller reporting an
	      // error.
	      return true;
	    }
	  else
	    {
	      // Set thumb bit if symbol:
	      // -Has type STT_ARM_TFUNC or
	      // -Has type STT_FUNC, is defined and with LSB in value set.
	      thumb_bit =
		(((gsym->type() == elfcpp::STT_ARM_TFUNC)
		 || (gsym->type() == elfcpp::STT_FUNC
		     && !gsym->is_undefined()
		     && ((psymval->value(object, 0) & 1) != 0)))
		? 1
		: 0);
	    }
	}
      else
	{
	  // This is a local symbol.  Determine if the final target is THUMB.
	  // We saved this information when all the local symbols were read.
	  elfcpp::Elf_types<32>::Elf_WXword r_info = rel.get_r_info();
	  unsigned int r_sym = elfcpp::elf_r_sym<32>(r_info);
	  thumb_bit = object->local_symbol_is_thumb_function(r_sym) ? 1 : 0;
	}
    }
  else
    {
      // This is a fake relocation synthesized for a stub.  It does not have
      // a real symbol.  We just look at the LSB of the symbol value to
      // determine if the target is THUMB or not.
      thumb_bit = ((psymval->value(object, 0) & 1) != 0);
    }

  // Strip LSB if this points to a THUMB target.
  if (thumb_bit != 0
      && reloc_property->uses_thumb_bit()
      && ((psymval->value(object, 0) & 1) != 0))
    {
      Arm_address stripped_value =
	psymval->value(object, 0) & ~static_cast<Arm_address>(1);
      symval.set_output_value(stripped_value);
      psymval = &symval;
    }

  // To look up relocation stubs, we need to pass the symbol table index of
  // a local symbol.
  unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());

  // Get the addressing origin of the output segment defining the
  // symbol gsym if needed (AAELF 4.6.1.2 Relocation types).
  Arm_address sym_origin = 0;
  if (reloc_property->uses_symbol_base())
    {
      if (r_type == elfcpp::R_ARM_BASE_ABS && gsym == NULL)
	// R_ARM_BASE_ABS with the NULL symbol will give the
	// absolute address of the GOT origin (GOT_ORG) (see ARM IHI
	// 0044C (AAELF): 4.6.1.8 Proxy generating relocations).
	sym_origin = target->got_plt_section()->address();
      else if (gsym == NULL)
	sym_origin = 0;
      else if (gsym->source() == Symbol::IN_OUTPUT_SEGMENT)
	sym_origin = gsym->output_segment()->vaddr();
      else if (gsym->source() == Symbol::IN_OUTPUT_DATA)
	sym_origin = gsym->output_data()->address();

      // TODO: Assumes the segment base to be zero for the global symbols
      // till the proper support for the segment-base-relative addressing
      // will be implemented.  This is consistent with GNU ld.
    }

  // For relative addressing relocation, find out the relative address base.
  Arm_address relative_address_base = 0;
  switch(reloc_property->relative_address_base())
    {
    case Arm_reloc_property::RAB_NONE:
    // Relocations with relative address bases RAB_TLS and RAB_tp are
    // handled by relocate_tls.  So we do not need to do anything here.
    case Arm_reloc_property::RAB_TLS:
    case Arm_reloc_property::RAB_tp:
      break;
    case Arm_reloc_property::RAB_B_S:
      relative_address_base = sym_origin;
      break;
    case Arm_reloc_property::RAB_GOT_ORG:
      relative_address_base = target->got_plt_section()->address();
      break;
    case Arm_reloc_property::RAB_P:
      relative_address_base = address;
      break;
    case Arm_reloc_property::RAB_Pa:
      relative_address_base = address & 0xfffffffcU;
      break;
    default:
      gold_unreachable();
    }

  typename Arm_relocate_functions::Status reloc_status =
	Arm_relocate_functions::STATUS_OKAY;
  bool check_overflow = reloc_property->checks_overflow();
  switch (r_type)
    {
    case elfcpp::R_ARM_NONE:
      break;

    case elfcpp::R_ARM_ABS8:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::abs8(view, object, psymval);
      break;

    case elfcpp::R_ARM_ABS12:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::abs12(view, object, psymval);
      break;

    case elfcpp::R_ARM_ABS16:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::abs16(view, object, psymval);
      break;

    case elfcpp::R_ARM_ABS32:
      if (should_apply_static_reloc(gsym, r_type, true, output_section))
	reloc_status = Arm_relocate_functions::abs32(view, object, psymval,
						     thumb_bit);
      break;

    case elfcpp::R_ARM_ABS32_NOI:
      if (should_apply_static_reloc(gsym, r_type, true, output_section))
	// No thumb bit for this relocation: (S + A)
	reloc_status = Arm_relocate_functions::abs32(view, object, psymval,
						     0);
      break;

    case elfcpp::R_ARM_MOVW_ABS_NC:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::movw(view, object, psymval,
						    0, thumb_bit,
						    check_overflow);
      break;

    case elfcpp::R_ARM_MOVT_ABS:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::movt(view, object, psymval, 0);
      break;

    case elfcpp::R_ARM_THM_MOVW_ABS_NC:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::thm_movw(view, object, psymval,
							0, thumb_bit, false);
      break;

    case elfcpp::R_ARM_THM_MOVT_ABS:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::thm_movt(view, object,
							psymval, 0);
      break;

    case elfcpp::R_ARM_MOVW_PREL_NC:
    case elfcpp::R_ARM_MOVW_BREL_NC:
    case elfcpp::R_ARM_MOVW_BREL:
      reloc_status =
	Arm_relocate_functions::movw(view, object, psymval,
				     relative_address_base, thumb_bit,
				     check_overflow);
      break;

    case elfcpp::R_ARM_MOVT_PREL:
    case elfcpp::R_ARM_MOVT_BREL:
      reloc_status =
	Arm_relocate_functions::movt(view, object, psymval,
				     relative_address_base);
      break;

    case elfcpp::R_ARM_THM_MOVW_PREL_NC:
    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
    case elfcpp::R_ARM_THM_MOVW_BREL:
      reloc_status =
	Arm_relocate_functions::thm_movw(view, object, psymval,
					 relative_address_base,
					 thumb_bit, check_overflow);
      break;

    case elfcpp::R_ARM_THM_MOVT_PREL:
    case elfcpp::R_ARM_THM_MOVT_BREL:
      reloc_status =
	Arm_relocate_functions::thm_movt(view, object, psymval,
					 relative_address_base);
      break;

    case elfcpp::R_ARM_REL32:
      reloc_status = Arm_relocate_functions::rel32(view, object, psymval,
						   address, thumb_bit);
      break;

    case elfcpp::R_ARM_THM_ABS5:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::thm_abs5(view, object, psymval);
      break;

    // Thumb long branches.
    case elfcpp::R_ARM_THM_CALL:
    case elfcpp::R_ARM_THM_XPC22:
    case elfcpp::R_ARM_THM_JUMP24:
      reloc_status =
	Arm_relocate_functions::thumb_branch_common(
	    r_type, relinfo, view, gsym, object, r_sym, psymval, address,
	    thumb_bit, is_weakly_undefined_without_plt);
      break;

    case elfcpp::R_ARM_GOTOFF32:
      {
	Arm_address got_origin;
	got_origin = target->got_plt_section()->address();
	reloc_status = Arm_relocate_functions::rel32(view, object, psymval,
						     got_origin, thumb_bit);
      }
      break;

    case elfcpp::R_ARM_BASE_PREL:
      gold_assert(gsym != NULL);
      reloc_status =
	  Arm_relocate_functions::base_prel(view, sym_origin, address);
      break;

    case elfcpp::R_ARM_BASE_ABS:
      if (should_apply_static_reloc(gsym, r_type, false, output_section))
	reloc_status = Arm_relocate_functions::base_abs(view, sym_origin);
      break;

    case elfcpp::R_ARM_GOT_BREL:
      gold_assert(have_got_offset);
      reloc_status = Arm_relocate_functions::got_brel(view, got_offset);
      break;

    case elfcpp::R_ARM_GOT_PREL:
      gold_assert(have_got_offset);
      // Get the address origin for GOT PLT, which is allocated right
      // after the GOT section, to calculate an absolute address of
      // the symbol GOT entry (got_origin + got_offset).
      Arm_address got_origin;
      got_origin = target->got_plt_section()->address();
      reloc_status = Arm_relocate_functions::got_prel(view,
						      got_origin + got_offset,
						      address);
      break;

    case elfcpp::R_ARM_PLT32:
    case elfcpp::R_ARM_CALL:
    case elfcpp::R_ARM_JUMP24:
    case elfcpp::R_ARM_XPC25:
      gold_assert(gsym == NULL
		  || gsym->has_plt_offset()
		  || gsym->final_value_is_known()
		  || (gsym->is_defined()
		      && !gsym->is_from_dynobj()
		      && !gsym->is_preemptible()));
      reloc_status =
	Arm_relocate_functions::arm_branch_common(
	    r_type, relinfo, view, gsym, object, r_sym, psymval, address,
	    thumb_bit, is_weakly_undefined_without_plt);
      break;

    case elfcpp::R_ARM_THM_JUMP19:
      reloc_status =
	Arm_relocate_functions::thm_jump19(view, object, psymval, address,
					   thumb_bit);
      break;

    case elfcpp::R_ARM_THM_JUMP6:
      reloc_status =
	Arm_relocate_functions::thm_jump6(view, object, psymval, address);
      break;

    case elfcpp::R_ARM_THM_JUMP8:
      reloc_status =
	Arm_relocate_functions::thm_jump8(view, object, psymval, address);
      break;

    case elfcpp::R_ARM_THM_JUMP11:
      reloc_status =
	Arm_relocate_functions::thm_jump11(view, object, psymval, address);
      break;

    case elfcpp::R_ARM_PREL31:
      reloc_status = Arm_relocate_functions::prel31(view, object, psymval,
						    address, thumb_bit);
      break;

    case elfcpp::R_ARM_V4BX:
      if (target->fix_v4bx() > General_options::FIX_V4BX_NONE)
	{
	  const bool is_v4bx_interworking =
	      (target->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING);
	  reloc_status =
	    Arm_relocate_functions::v4bx(relinfo, view, object, address,
					 is_v4bx_interworking);
	}
      break;

    case elfcpp::R_ARM_THM_PC8:
      reloc_status =
	Arm_relocate_functions::thm_pc8(view, object, psymval, address);
      break;

    case elfcpp::R_ARM_THM_PC12:
      reloc_status =
	Arm_relocate_functions::thm_pc12(view, object, psymval, address);
      break;

    case elfcpp::R_ARM_THM_ALU_PREL_11_0:
      reloc_status =
	Arm_relocate_functions::thm_alu11(view, object, psymval, address,
					  thumb_bit);
      break;

    case elfcpp::R_ARM_ALU_PC_G0_NC:
    case elfcpp::R_ARM_ALU_PC_G0:
    case elfcpp::R_ARM_ALU_PC_G1_NC:
    case elfcpp::R_ARM_ALU_PC_G1:
    case elfcpp::R_ARM_ALU_PC_G2:
    case elfcpp::R_ARM_ALU_SB_G0_NC:
    case elfcpp::R_ARM_ALU_SB_G0:
    case elfcpp::R_ARM_ALU_SB_G1_NC:
    case elfcpp::R_ARM_ALU_SB_G1:
    case elfcpp::R_ARM_ALU_SB_G2:
      reloc_status =
	Arm_relocate_functions::arm_grp_alu(view, object, psymval,
					    reloc_property->group_index(),
					    relative_address_base,
					    thumb_bit, check_overflow);
      break;

    case elfcpp::R_ARM_LDR_PC_G0:
    case elfcpp::R_ARM_LDR_PC_G1:
    case elfcpp::R_ARM_LDR_PC_G2:
    case elfcpp::R_ARM_LDR_SB_G0:
    case elfcpp::R_ARM_LDR_SB_G1:
    case elfcpp::R_ARM_LDR_SB_G2:
      reloc_status =
	  Arm_relocate_functions::arm_grp_ldr(view, object, psymval,
					      reloc_property->group_index(),
					      relative_address_base);
      break;

    case elfcpp::R_ARM_LDRS_PC_G0:
    case elfcpp::R_ARM_LDRS_PC_G1:
    case elfcpp::R_ARM_LDRS_PC_G2:
    case elfcpp::R_ARM_LDRS_SB_G0:
    case elfcpp::R_ARM_LDRS_SB_G1:
    case elfcpp::R_ARM_LDRS_SB_G2:
      reloc_status =
	  Arm_relocate_functions::arm_grp_ldrs(view, object, psymval,
					       reloc_property->group_index(),
					       relative_address_base);
      break;

    case elfcpp::R_ARM_LDC_PC_G0:
    case elfcpp::R_ARM_LDC_PC_G1:
    case elfcpp::R_ARM_LDC_PC_G2:
    case elfcpp::R_ARM_LDC_SB_G0:
    case elfcpp::R_ARM_LDC_SB_G1:
    case elfcpp::R_ARM_LDC_SB_G2:
      reloc_status =
	  Arm_relocate_functions::arm_grp_ldc(view, object, psymval,
					      reloc_property->group_index(),
					      relative_address_base);
      break;

      // These are initial tls relocs, which are expected when
      // linking.
    case elfcpp::R_ARM_TLS_GD32:	// Global-dynamic
    case elfcpp::R_ARM_TLS_LDM32:	// Local-dynamic
    case elfcpp::R_ARM_TLS_LDO32:	// Alternate local-dynamic
    case elfcpp::R_ARM_TLS_IE32:	// Initial-exec
    case elfcpp::R_ARM_TLS_LE32:	// Local-exec
      reloc_status =
	this->relocate_tls(relinfo, target, relnum, rel, r_type, gsym, psymval,
			   view, address, view_size);
      break;

    // The known and unknown unsupported and/or deprecated relocations.
    case elfcpp::R_ARM_PC24:
    case elfcpp::R_ARM_LDR_SBREL_11_0_NC:
    case elfcpp::R_ARM_ALU_SBREL_19_12_NC:
    case elfcpp::R_ARM_ALU_SBREL_27_20_CK:
    default:
      // Just silently leave the method. We should get an appropriate error
      // message in the scan methods.
      break;
    }

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

  return true;
}

// Perform a TLS relocation.

template<bool big_endian>
inline typename Arm_relocate_functions<big_endian>::Status
Target_arm<big_endian>::Relocate::relocate_tls(
    const Relocate_info<32, big_endian>* relinfo,
    Target_arm<big_endian>* target,
    size_t relnum,
    const elfcpp::Rel<32, big_endian>& rel,
    unsigned int r_type,
    const Sized_symbol<32>* gsym,
    const Symbol_value<32>* psymval,
    unsigned char* view,
    elfcpp::Elf_types<32>::Elf_Addr address,
    section_size_type /*view_size*/ )
{
  typedef Arm_relocate_functions<big_endian> ArmRelocFuncs;
  typedef Relocate_functions<32, big_endian> RelocFuncs;
  Output_segment* tls_segment = relinfo->layout->tls_segment();

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

  elfcpp::Elf_types<32>::Elf_Addr value = psymval->value(object, 0);

  const bool is_final = (gsym == NULL
			 ? !parameters->options().shared()
			 : gsym->final_value_is_known());
  const tls::Tls_optimization optimized_type
      = Target_arm<big_endian>::optimize_tls_reloc(is_final, r_type);
  switch (r_type)
    {
    case elfcpp::R_ARM_TLS_GD32:	// Global-dynamic
	{
	  unsigned int got_type = GOT_TYPE_TLS_PAIR;
	  unsigned int got_offset;
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(got_type));
	      got_offset = gsym->got_offset(got_type) - target->got_size();
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
	      gold_assert(object->local_has_got_offset(r_sym, got_type));
	      got_offset = (object->local_got_offset(r_sym, got_type)
			    - target->got_size());
	    }
	  if (optimized_type == tls::TLSOPT_NONE)
	    {
	      Arm_address got_entry =
		target->got_plt_section()->address() + got_offset;

	      // Relocate the field with the PC relative offset of the pair of
	      // GOT entries.
	      RelocFuncs::pcrel32_unaligned(view, got_entry, address);
	      return ArmRelocFuncs::STATUS_OKAY;
	    }
	}
      break;

    case elfcpp::R_ARM_TLS_LDM32:	// Local-dynamic
      if (optimized_type == tls::TLSOPT_NONE)
	{
	  // Relocate the field with the offset of the GOT entry for
	  // the module index.
	  unsigned int got_offset;
	  got_offset = (target->got_mod_index_entry(NULL, NULL, NULL)
			- target->got_size());
	  Arm_address got_entry =
	    target->got_plt_section()->address() + got_offset;

	  // Relocate the field with the PC relative offset of the pair of
	  // GOT entries.
	  RelocFuncs::pcrel32_unaligned(view, got_entry, address);
	  return ArmRelocFuncs::STATUS_OKAY;
	}
      break;

    case elfcpp::R_ARM_TLS_LDO32:	// Alternate local-dynamic
      RelocFuncs::rel32_unaligned(view, value);
      return ArmRelocFuncs::STATUS_OKAY;

    case elfcpp::R_ARM_TLS_IE32:	// Initial-exec
      if (optimized_type == tls::TLSOPT_NONE)
	{
	  // Relocate the field with the offset of the GOT entry for
	  // the tp-relative offset of the symbol.
	  unsigned int got_type = GOT_TYPE_TLS_OFFSET;
	  unsigned int got_offset;
	  if (gsym != NULL)
	    {
	      gold_assert(gsym->has_got_offset(got_type));
	      got_offset = gsym->got_offset(got_type);
	    }
	  else
	    {
	      unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info());
	      gold_assert(object->local_has_got_offset(r_sym, got_type));
	      got_offset = object->local_got_offset(r_sym, got_type);
	    }

	  // All GOT offsets are relative to the end of the GOT.
	  got_offset -= target->got_size();

	  Arm_address got_entry =
	    target->got_plt_section()->address() + got_offset;

	  // Relocate the field with the PC relative offset of the GOT entry.
	  RelocFuncs::pcrel32_unaligned(view, got_entry, address);
	  return ArmRelocFuncs::STATUS_OKAY;
	}
      break;

    case elfcpp::R_ARM_TLS_LE32:	// Local-exec
      // If we're creating a shared library, a dynamic relocation will
      // have been created for this location, so do not apply it now.
      if (!parameters->options().shared())
	{
	  gold_assert(tls_segment != NULL);

	  // $tp points to the TCB, which is followed by the TLS, so we
	  // need to add TCB size to the offset.
	  Arm_address aligned_tcb_size =
	    align_address(ARM_TCB_SIZE, tls_segment->maximum_alignment());
	  RelocFuncs::rel32_unaligned(view, value + aligned_tcb_size);

	}
      return ArmRelocFuncs::STATUS_OKAY;

    default:
      gold_unreachable();
    }

  gold_error_at_location(relinfo, relnum, rel.get_r_offset(),
			 _("unsupported reloc %u"),
			 r_type);
  return ArmRelocFuncs::STATUS_BAD_RELOC;
}

// Relocate section data.

template<bool big_endian>
void
Target_arm<big_endian>::relocate_section(
    const Relocate_info<32, 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,
    Arm_address address,
    section_size_type view_size,
    const Reloc_symbol_changes* reloc_symbol_changes)
{
  typedef typename Target_arm<big_endian>::Relocate Arm_relocate;
  gold_assert(sh_type == elfcpp::SHT_REL);

  // See if we are relocating a relaxed input section.  If so, the view
  // covers the whole output section and we need to adjust accordingly.
  if (needs_special_offset_handling)
    {
      const Output_relaxed_input_section* poris =
	output_section->find_relaxed_input_section(relinfo->object,
						   relinfo->data_shndx);
      if (poris != NULL)
	{
	  Arm_address section_address = poris->address();
	  section_size_type section_size = poris->data_size();

	  gold_assert((section_address >= address)
		      && ((section_address + section_size)
			  <= (address + view_size)));

	  off_t offset = section_address - address;
	  view += offset;
	  address += offset;
	  view_size = section_size;
	}
    }

  gold::relocate_section<32, big_endian, Target_arm, elfcpp::SHT_REL,
			 Arm_relocate>(
    relinfo,
    this,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    view,
    address,
    view_size,
    reloc_symbol_changes);
}

// Return the size of a relocation while scanning during a relocatable
// link.

template<bool big_endian>
unsigned int
Target_arm<big_endian>::Relocatable_size_for_reloc::get_size_for_reloc(
    unsigned int r_type,
    Relobj* object)
{
  r_type = get_real_reloc_type(r_type);
  const Arm_reloc_property* arp =
      arm_reloc_property_table->get_implemented_static_reloc_property(r_type);
  if (arp != NULL)
    return arp->size();
  else
    {
      std::string reloc_name =
	arm_reloc_property_table->reloc_name_in_error_message(r_type);
      gold_error(_("%s: unexpected %s in object file"),
		 object->name().c_str(), reloc_name.c_str());
      return 0;
    }
}

// Scan the relocs during a relocatable link.

template<bool big_endian>
void
Target_arm<big_endian>::scan_relocatable_relocs(
    Symbol_table* symtab,
    Layout* layout,
    Sized_relobj_file<32, 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)
{
  gold_assert(sh_type == elfcpp::SHT_REL);

  typedef Arm_scan_relocatable_relocs<big_endian, elfcpp::SHT_REL,
    Relocatable_size_for_reloc> Scan_relocatable_relocs;

  gold::scan_relocatable_relocs<32, big_endian, elfcpp::SHT_REL,
      Scan_relocatable_relocs>(
    symtab,
    layout,
    object,
    data_shndx,
    prelocs,
    reloc_count,
    output_section,
    needs_special_offset_handling,
    local_symbol_count,
    plocal_symbols,
    rr);
}

// Relocate a section during a relocatable link.

template<bool big_endian>
void
Target_arm<big_endian>::relocate_for_relocatable(
    const Relocate_info<32, big_endian>* relinfo,
    unsigned int sh_type,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    typename elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
    const Relocatable_relocs* rr,
    unsigned char* view,
    Arm_address view_address,
    section_size_type view_size,
    unsigned char* reloc_view,
    section_size_type reloc_view_size)
{
  gold_assert(sh_type == elfcpp::SHT_REL);

  gold::relocate_for_relocatable<32, big_endian, elfcpp::SHT_REL>(
    relinfo,
    prelocs,
    reloc_count,
    output_section,
    offset_in_output_section,
    rr,
    view,
    view_address,
    view_size,
    reloc_view,
    reloc_view_size);
}

// Perform target-specific processing in a relocatable link.  This is
// only used if we use the relocation strategy RELOC_SPECIAL.

template<bool big_endian>
void
Target_arm<big_endian>::relocate_special_relocatable(
    const Relocate_info<32, big_endian>* relinfo,
    unsigned int sh_type,
    const unsigned char* preloc_in,
    size_t relnum,
    Output_section* output_section,
    typename elfcpp::Elf_types<32>::Elf_Off offset_in_output_section,
    unsigned char* view,
    elfcpp::Elf_types<32>::Elf_Addr view_address,
    section_size_type,
    unsigned char* preloc_out)
{
  // We can only handle REL type relocation sections.
  gold_assert(sh_type == elfcpp::SHT_REL);

  typedef typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc Reltype;
  typedef typename Reloc_types<elfcpp::SHT_REL, 32, big_endian>::Reloc_write
    Reltype_write;
  const Arm_address invalid_address = static_cast<Arm_address>(0) - 1;

  const Arm_relobj<big_endian>* object =
    Arm_relobj<big_endian>::as_arm_relobj(relinfo->object);
  const unsigned int local_count = object->local_symbol_count();

  Reltype reloc(preloc_in);
  Reltype_write reloc_write(preloc_out);

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

  const Arm_reloc_property* arp =
    arm_reloc_property_table->get_implemented_static_reloc_property(r_type);
  gold_assert(arp != NULL);

  // Get the new symbol index.
  // We only use RELOC_SPECIAL strategy in local relocations.
  gold_assert(r_sym < local_count);

  // We are adjusting a section symbol.  We need to find
  // the symbol table index of the section symbol for
  // the output section corresponding to input section
  // in which this symbol is defined.
  bool is_ordinary;
  unsigned int shndx = object->local_symbol_input_shndx(r_sym, &is_ordinary);
  gold_assert(is_ordinary);
  Output_section* os = object->output_section(shndx);
  gold_assert(os != NULL);
  gold_assert(os->needs_symtab_index());
  unsigned int new_symndx = os->symtab_index();

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

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

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

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

  // Handle the reloc addend.
  // The relocation uses a section symbol in the input file.
  // We are adjusting it to use a section symbol in the output
  // file.  The input section symbol refers to some address in
  // the input section.  We need the relocation in the output
  // file to refer to that same address.  This adjustment to
  // the addend is the same calculation we use for a simple
  // absolute relocation for the input section symbol.

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

  // Handle THUMB bit.
  Symbol_value<32> symval;
  Arm_address thumb_bit =
     object->local_symbol_is_thumb_function(r_sym) ? 1 : 0;
  if (thumb_bit != 0
      && arp->uses_thumb_bit()
      && ((psymval->value(object, 0) & 1) != 0))
    {
      Arm_address stripped_value =
	psymval->value(object, 0) & ~static_cast<Arm_address>(1);
      symval.set_output_value(stripped_value);
      psymval = &symval;
    }

  unsigned char* paddend = view + offset;
  typename Arm_relocate_functions<big_endian>::Status reloc_status =
	Arm_relocate_functions<big_endian>::STATUS_OKAY;
  switch (r_type)
    {
    case elfcpp::R_ARM_ABS8:
      reloc_status = Arm_relocate_functions<big_endian>::abs8(paddend, object,
							      psymval);
      break;

    case elfcpp::R_ARM_ABS12:
      reloc_status = Arm_relocate_functions<big_endian>::abs12(paddend, object,
							       psymval);
      break;

    case elfcpp::R_ARM_ABS16:
      reloc_status = Arm_relocate_functions<big_endian>::abs16(paddend, object,
							       psymval);
      break;

    case elfcpp::R_ARM_THM_ABS5:
      reloc_status = Arm_relocate_functions<big_endian>::thm_abs5(paddend,
								  object,
								  psymval);
      break;

    case elfcpp::R_ARM_MOVW_ABS_NC:
    case elfcpp::R_ARM_MOVW_PREL_NC:
    case elfcpp::R_ARM_MOVW_BREL_NC:
    case elfcpp::R_ARM_MOVW_BREL:
      reloc_status = Arm_relocate_functions<big_endian>::movw(
	  paddend, object, psymval, 0, thumb_bit, arp->checks_overflow());
      break;

    case elfcpp::R_ARM_THM_MOVW_ABS_NC:
    case elfcpp::R_ARM_THM_MOVW_PREL_NC:
    case elfcpp::R_ARM_THM_MOVW_BREL_NC:
    case elfcpp::R_ARM_THM_MOVW_BREL:
      reloc_status = Arm_relocate_functions<big_endian>::thm_movw(
	  paddend, object, psymval, 0, thumb_bit, arp->checks_overflow());
      break;

    case elfcpp::R_ARM_THM_CALL:
    case elfcpp::R_ARM_THM_XPC22:
    case elfcpp::R_ARM_THM_JUMP24:
      reloc_status =
	Arm_relocate_functions<big_endian>::thumb_branch_common(
	    r_type, relinfo, paddend, NULL, object, 0, psymval, 0, thumb_bit,
	    false);
      break;

    case elfcpp::R_ARM_PLT32:
    case elfcpp::R_ARM_CALL:
    case elfcpp::R_ARM_JUMP24:
    case elfcpp::R_ARM_XPC25:
      reloc_status =
	Arm_relocate_functions<big_endian>::arm_branch_common(
	    r_type, relinfo, paddend, NULL, object, 0, psymval, 0, thumb_bit,
	    false);
      break;

    case elfcpp::R_ARM_THM_JUMP19:
      reloc_status =
	Arm_relocate_functions<big_endian>::thm_jump19(paddend, object,
						       psymval, 0, thumb_bit);
      break;

    case elfcpp::R_ARM_THM_JUMP6:
      reloc_status =
	Arm_relocate_functions<big_endian>::thm_jump6(paddend, object, psymval,
						      0);
      break;

    case elfcpp::R_ARM_THM_JUMP8:
      reloc_status =
	Arm_relocate_functions<big_endian>::thm_jump8(paddend, object, psymval,
						      0);
      break;

    case elfcpp::R_ARM_THM_JUMP11:
      reloc_status =
	Arm_relocate_functions<big_endian>::thm_jump11(paddend, object, psymval,
						       0);
      break;

    case elfcpp::R_ARM_PREL31:
      reloc_status =
	Arm_relocate_functions<big_endian>::prel31(paddend, object, psymval, 0,
						   thumb_bit);
      break;

    case elfcpp::R_ARM_THM_PC8:
      reloc_status =
	Arm_relocate_functions<big_endian>::thm_pc8(paddend, object, psymval,
						    0);
      break;

    case elfcpp::R_ARM_THM_PC12:
      reloc_status =
	Arm_relocate_functions<big_endian>::thm_pc12(paddend, object, psymval,
						     0);
      break;

    case elfcpp::R_ARM_THM_ALU_PREL_11_0:
      reloc_status =
	Arm_relocate_functions<big_endian>::thm_alu11(paddend, object, psymval,
						      0, thumb_bit);
      break;

    // These relocation truncate relocation results so we cannot handle them
    // in a relocatable link.
    case elfcpp::R_ARM_MOVT_ABS:
    case elfcpp::R_ARM_THM_MOVT_ABS:
    case elfcpp::R_ARM_MOVT_PREL:
    case elfcpp::R_ARM_MOVT_BREL:
    case elfcpp::R_ARM_THM_MOVT_PREL:
    case elfcpp::R_ARM_THM_MOVT_BREL:
    case elfcpp::R_ARM_ALU_PC_G0_NC:
    case elfcpp::R_ARM_ALU_PC_G0:
    case elfcpp::R_ARM_ALU_PC_G1_NC:
    case elfcpp::R_ARM_ALU_PC_G1:
    case elfcpp::R_ARM_ALU_PC_G2:
    case elfcpp::R_ARM_ALU_SB_G0_NC:
    case elfcpp::R_ARM_ALU_SB_G0:
    case elfcpp::R_ARM_ALU_SB_G1_NC:
    case elfcpp::R_ARM_ALU_SB_G1:
    case elfcpp::R_ARM_ALU_SB_G2:
    case elfcpp::R_ARM_LDR_PC_G0:
    case elfcpp::R_ARM_LDR_PC_G1:
    case elfcpp::R_ARM_LDR_PC_G2:
    case elfcpp::R_ARM_LDR_SB_G0:
    case elfcpp::R_ARM_LDR_SB_G1:
    case elfcpp::R_ARM_LDR_SB_G2:
    case elfcpp::R_ARM_LDRS_PC_G0:
    case elfcpp::R_ARM_LDRS_PC_G1:
    case elfcpp::R_ARM_LDRS_PC_G2:
    case elfcpp::R_ARM_LDRS_SB_G0:
    case elfcpp::R_ARM_LDRS_SB_G1:
    case elfcpp::R_ARM_LDRS_SB_G2:
    case elfcpp::R_ARM_LDC_PC_G0:
    case elfcpp::R_ARM_LDC_PC_G1:
    case elfcpp::R_ARM_LDC_PC_G2:
    case elfcpp::R_ARM_LDC_SB_G0:
    case elfcpp::R_ARM_LDC_SB_G1:
    case elfcpp::R_ARM_LDC_SB_G2:
      gold_error(_("cannot handle %s in a relocatable link"),
		 arp->name().c_str());
      break;

    default:
      gold_unreachable();
    }

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

// Return the value to use for a dynamic symbol which requires special
// treatment.  This is how we support equality comparisons of function
// pointers across shared library boundaries, as described in the
// processor specific ABI supplement.

template<bool big_endian>
uint64_t
Target_arm<big_endian>::do_dynsym_value(const Symbol* gsym) const
{
  gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset());
  return this->plt_section()->address() + gsym->plt_offset();
}

// Map platform-specific relocs to real relocs
//
template<bool big_endian>
unsigned int
Target_arm<big_endian>::get_real_reloc_type(unsigned int r_type)
{
  switch (r_type)
    {
    case elfcpp::R_ARM_TARGET1:
      // This is either R_ARM_ABS32 or R_ARM_REL32;
      return elfcpp::R_ARM_ABS32;

    case elfcpp::R_ARM_TARGET2:
      // This can be any reloc type but usually is R_ARM_GOT_PREL
      return elfcpp::R_ARM_GOT_PREL;

    default:
      return r_type;
    }
}

// Whether if two EABI versions V1 and V2 are compatible.

template<bool big_endian>
bool
Target_arm<big_endian>::are_eabi_versions_compatible(
    elfcpp::Elf_Word v1,
    elfcpp::Elf_Word v2)
{
  // v4 and v5 are the same spec before and after it was released,
  // so allow mixing them.
  if ((v1 == elfcpp::EF_ARM_EABI_UNKNOWN || v2 == elfcpp::EF_ARM_EABI_UNKNOWN)
      || (v1 == elfcpp::EF_ARM_EABI_VER4 && v2 == elfcpp::EF_ARM_EABI_VER5)
      || (v1 == elfcpp::EF_ARM_EABI_VER5 && v2 == elfcpp::EF_ARM_EABI_VER4))
    return true;

  return v1 == v2;
}

// Combine FLAGS from an input object called NAME and the processor-specific
// flags in the ELF header of the output.  Much of this is adapted from the
// processor-specific flags merging code in elf32_arm_merge_private_bfd_data
// in bfd/elf32-arm.c.

template<bool big_endian>
void
Target_arm<big_endian>::merge_processor_specific_flags(
    const std::string& name,
    elfcpp::Elf_Word flags)
{
  if (this->are_processor_specific_flags_set())
    {
      elfcpp::Elf_Word out_flags = this->processor_specific_flags();

      // Nothing to merge if flags equal to those in output.
      if (flags == out_flags)
	return;

      // Complain about various flag mismatches.
      elfcpp::Elf_Word version1 = elfcpp::arm_eabi_version(flags);
      elfcpp::Elf_Word version2 = elfcpp::arm_eabi_version(out_flags);
      if (!this->are_eabi_versions_compatible(version1, version2)
	  && parameters->options().warn_mismatch())
	gold_error(_("Source object %s has EABI version %d but output has "
		     "EABI version %d."),
		   name.c_str(),
		   (flags & elfcpp::EF_ARM_EABIMASK) >> 24,
		   (out_flags & elfcpp::EF_ARM_EABIMASK) >> 24);
    }
  else
    {
      // If the input is the default architecture and had the default
      // flags then do not bother setting the flags for the output
      // architecture, instead allow future merges to do this.  If no
      // future merges ever set these flags then they will retain their
      // uninitialised values, which surprise surprise, correspond
      // to the default values.
      if (flags == 0)
	return;

      // This is the first time, just copy the flags.
      // We only copy the EABI version for now.
      this->set_processor_specific_flags(flags & elfcpp::EF_ARM_EABIMASK);
    }
}

// Adjust ELF file header.
template<bool big_endian>
void
Target_arm<big_endian>::do_adjust_elf_header(
    unsigned char* view,
    int len) const
{
  gold_assert(len == elfcpp::Elf_sizes<32>::ehdr_size);

  elfcpp::Ehdr<32, big_endian> ehdr(view);
  unsigned char e_ident[elfcpp::EI_NIDENT];
  memcpy(e_ident, ehdr.get_e_ident(), elfcpp::EI_NIDENT);

  if (elfcpp::arm_eabi_version(this->processor_specific_flags())
      == elfcpp::EF_ARM_EABI_UNKNOWN)
    e_ident[elfcpp::EI_OSABI] = elfcpp::ELFOSABI_ARM;
  else
    e_ident[elfcpp::EI_OSABI] = 0;
  e_ident[elfcpp::EI_ABIVERSION] = 0;

  // FIXME: Do EF_ARM_BE8 adjustment.

  elfcpp::Ehdr_write<32, big_endian> oehdr(view);
  oehdr.put_e_ident(e_ident);
}

// 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<32, big_endian> to store ARM specific information.
// Hence we need to have our own ELF object creation.

template<bool big_endian>
Object*
Target_arm<big_endian>::do_make_elf_object(
    const std::string& name,
    Input_file* input_file,
    off_t offset, const elfcpp::Ehdr<32, big_endian>& ehdr)
{
  int et = ehdr.get_e_type();
  // ET_EXEC files are valid input for --just-symbols/-R,
  // and we treat them as relocatable objects.
  if (et == elfcpp::ET_REL
      || (et == elfcpp::ET_EXEC && input_file->just_symbols()))
    {
      Arm_relobj<big_endian>* obj =
	new Arm_relobj<big_endian>(name, input_file, offset, ehdr);
      obj->setup();
      return obj;
    }
  else if (et == elfcpp::ET_DYN)
    {
      Sized_dynobj<32, big_endian>* obj =
	new Arm_dynobj<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;
    }
}

// Read the architecture from the Tag_also_compatible_with attribute, if any.
// Returns -1 if no architecture could be read.
// This is adapted from get_secondary_compatible_arch() in bfd/elf32-arm.c.

template<bool big_endian>
int
Target_arm<big_endian>::get_secondary_compatible_arch(
    const Attributes_section_data* pasd)
{
  const Object_attribute* known_attributes =
    pasd->known_attributes(Object_attribute::OBJ_ATTR_PROC);

  // Note: the tag and its argument below are uleb128 values, though
  // currently-defined values fit in one byte for each.
  const std::string& sv =
    known_attributes[elfcpp::Tag_also_compatible_with].string_value();
  if (sv.size() == 2
      && sv.data()[0] == elfcpp::Tag_CPU_arch
      && (sv.data()[1] & 128) != 128)
   return sv.data()[1];

  // This tag is "safely ignorable", so don't complain if it looks funny.
  return -1;
}

// Set, or unset, the architecture of the Tag_also_compatible_with attribute.
// The tag is removed if ARCH is -1.
// This is adapted from set_secondary_compatible_arch() in bfd/elf32-arm.c.

template<bool big_endian>
void
Target_arm<big_endian>::set_secondary_compatible_arch(
    Attributes_section_data* pasd,
    int arch)
{
  Object_attribute* known_attributes =
    pasd->known_attributes(Object_attribute::OBJ_ATTR_PROC);

  if (arch == -1)
    {
      known_attributes[elfcpp::Tag_also_compatible_with].set_string_value("");
      return;
    }

  // Note: the tag and its argument below are uleb128 values, though
  // currently-defined values fit in one byte for each.
  char sv[3];
  sv[0] = elfcpp::Tag_CPU_arch;
  gold_assert(arch != 0);
  sv[1] = arch;
  sv[2] = '\0';

  known_attributes[elfcpp::Tag_also_compatible_with].set_string_value(sv);
}

// Combine two values for Tag_CPU_arch, taking secondary compatibility tags
// into account.
// This is adapted from tag_cpu_arch_combine() in bfd/elf32-arm.c.

template<bool big_endian>
int
Target_arm<big_endian>::tag_cpu_arch_combine(
    const char* name,
    int oldtag,
    int* secondary_compat_out,
    int newtag,
    int secondary_compat)
{
#define T(X) elfcpp::TAG_CPU_ARCH_##X
  static const int v6t2[] =
    {
      T(V6T2),   // PRE_V4.
      T(V6T2),   // V4.
      T(V6T2),   // V4T.
      T(V6T2),   // V5T.
      T(V6T2),   // V5TE.
      T(V6T2),   // V5TEJ.
      T(V6T2),   // V6.
      T(V7),     // V6KZ.
      T(V6T2)    // V6T2.
    };
  static const int v6k[] =
    {
      T(V6K),    // PRE_V4.
      T(V6K),    // V4.
      T(V6K),    // V4T.
      T(V6K),    // V5T.
      T(V6K),    // V5TE.
      T(V6K),    // V5TEJ.
      T(V6K),    // V6.
      T(V6KZ),   // V6KZ.
      T(V7),     // V6T2.
      T(V6K)     // V6K.
    };
  static const int v7[] =
    {
      T(V7),     // PRE_V4.
      T(V7),     // V4.
      T(V7),     // V4T.
      T(V7),     // V5T.
      T(V7),     // V5TE.
      T(V7),     // V5TEJ.
      T(V7),     // V6.
      T(V7),     // V6KZ.
      T(V7),     // V6T2.
      T(V7),     // V6K.
      T(V7)      // V7.
    };
  static const int v6_m[] =
    {
      -1,        // PRE_V4.
      -1,        // V4.
      T(V6K),    // V4T.
      T(V6K),    // V5T.
      T(V6K),    // V5TE.
      T(V6K),    // V5TEJ.
      T(V6K),    // V6.
      T(V6KZ),   // V6KZ.
      T(V7),     // V6T2.
      T(V6K),    // V6K.
      T(V7),     // V7.
      T(V6_M)    // V6_M.
    };
  static const int v6s_m[] =
    {
      -1,        // PRE_V4.
      -1,        // V4.
      T(V6K),    // V4T.
      T(V6K),    // V5T.
      T(V6K),    // V5TE.
      T(V6K),    // V5TEJ.
      T(V6K),    // V6.
      T(V6KZ),   // V6KZ.
      T(V7),     // V6T2.
      T(V6K),    // V6K.
      T(V7),     // V7.
      T(V6S_M),  // V6_M.
      T(V6S_M)   // V6S_M.
    };
  static const int v7e_m[] =
    {
      -1,	// PRE_V4.
      -1,	// V4.
      T(V7E_M),	// V4T.
      T(V7E_M),	// V5T.
      T(V7E_M),	// V5TE.
      T(V7E_M),	// V5TEJ.
      T(V7E_M),	// V6.
      T(V7E_M),	// V6KZ.
      T(V7E_M),	// V6T2.
      T(V7E_M),	// V6K.
      T(V7E_M),	// V7.
      T(V7E_M),	// V6_M.
      T(V7E_M),	// V6S_M.
      T(V7E_M)	// V7E_M.
    };
  static const int v4t_plus_v6_m[] =
    {
      -1,		// PRE_V4.
      -1,		// V4.
      T(V4T),		// V4T.
      T(V5T),		// V5T.
      T(V5TE),		// V5TE.
      T(V5TEJ),		// V5TEJ.
      T(V6),		// V6.
      T(V6KZ),		// V6KZ.
      T(V6T2),		// V6T2.
      T(V6K),		// V6K.
      T(V7),		// V7.
      T(V6_M),		// V6_M.
      T(V6S_M),		// V6S_M.
      T(V7E_M),		// V7E_M.
      T(V4T_PLUS_V6_M)	// V4T plus V6_M.
    };
  static const int* comb[] =
    {
      v6t2,
      v6k,
      v7,
      v6_m,
      v6s_m,
      v7e_m,
      // Pseudo-architecture.
      v4t_plus_v6_m
    };

  // Check we've not got a higher architecture than we know about.

  if (oldtag > elfcpp::MAX_TAG_CPU_ARCH || newtag > elfcpp::MAX_TAG_CPU_ARCH)
    {
      gold_error(_("%s: unknown CPU architecture"), name);
      return -1;
    }

  // Override old tag if we have a Tag_also_compatible_with on the output.

  if ((oldtag == T(V6_M) && *secondary_compat_out == T(V4T))
      || (oldtag == T(V4T) && *secondary_compat_out == T(V6_M)))
    oldtag = T(V4T_PLUS_V6_M);

  // And override the new tag if we have a Tag_also_compatible_with on the
  // input.

  if ((newtag == T(V6_M) && secondary_compat == T(V4T))
      || (newtag == T(V4T) && secondary_compat == T(V6_M)))
    newtag = T(V4T_PLUS_V6_M);

  // Architectures before V6KZ add features monotonically.
  int tagh = std::max(oldtag, newtag);
  if (tagh <= elfcpp::TAG_CPU_ARCH_V6KZ)
    return tagh;

  int tagl = std::min(oldtag, newtag);
  int result = comb[tagh - T(V6T2)][tagl];

  // Use Tag_CPU_arch == V4T and Tag_also_compatible_with (Tag_CPU_arch V6_M)
  // as the canonical version.
  if (result == T(V4T_PLUS_V6_M))
    {
      result = T(V4T);
      *secondary_compat_out = T(V6_M);
    }
  else
    *secondary_compat_out = -1;

  if (result == -1)
    {
      gold_error(_("%s: conflicting CPU architectures %d/%d"),
		 name, oldtag, newtag);
      return -1;
    }

  return result;
#undef T
}

// Helper to print AEABI enum tag value.

template<bool big_endian>
std::string
Target_arm<big_endian>::aeabi_enum_name(unsigned int value)
{
  static const char* aeabi_enum_names[] =
    { "", "variable-size", "32-bit", "" };
  const size_t aeabi_enum_names_size =
    sizeof(aeabi_enum_names) / sizeof(aeabi_enum_names[0]);

  if (value < aeabi_enum_names_size)
    return std::string(aeabi_enum_names[value]);
  else
    {
      char buffer[100];
      sprintf(buffer, "<unknown value %u>", value);
      return std::string(buffer);
    }
}

// Return the string value to store in TAG_CPU_name.

template<bool big_endian>
std::string
Target_arm<big_endian>::tag_cpu_name_value(unsigned int value)
{
  static const char* name_table[] = {
    // These aren't real CPU names, but we can't guess
    // that from the architecture version alone.
   "Pre v4",
   "ARM v4",
   "ARM v4T",
   "ARM v5T",
   "ARM v5TE",
   "ARM v5TEJ",
   "ARM v6",
   "ARM v6KZ",
   "ARM v6T2",
   "ARM v6K",
   "ARM v7",
   "ARM v6-M",
   "ARM v6S-M",
   "ARM v7E-M"
 };
 const size_t name_table_size = sizeof(name_table) / sizeof(name_table[0]);

  if (value < name_table_size)
    return std::string(name_table[value]);
  else
    {
      char buffer[100];
      sprintf(buffer, "<unknown CPU value %u>", value);
      return std::string(buffer);
    }
}

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

template<bool big_endian>
void
Target_arm<big_endian>::merge_object_attributes(
    const char* name,
    const Attributes_section_data* pasd)
{
  // Return if there is no attributes section data.
  if (pasd == NULL)
    return;

  // If output has no object attributes, just copy.
  const int vendor = Object_attribute::OBJ_ATTR_PROC;
  if (this->attributes_section_data_ == NULL)
    {
      this->attributes_section_data_ = new Attributes_section_data(*pasd);
      Object_attribute* out_attr =
	this->attributes_section_data_->known_attributes(vendor);

      // We do not output objects with Tag_MPextension_use_legacy - we move
      //  the attribute's value to Tag_MPextension_use.  */
      if (out_attr[elfcpp::Tag_MPextension_use_legacy].int_value() != 0)
	{
	  if (out_attr[elfcpp::Tag_MPextension_use].int_value() != 0
	      && out_attr[elfcpp::Tag_MPextension_use_legacy].int_value()
		!= out_attr[elfcpp::Tag_MPextension_use].int_value())
	    {
	      gold_error(_("%s has both the current and legacy "
			   "Tag_MPextension_use attributes"),
			 name);
	    }

	  out_attr[elfcpp::Tag_MPextension_use] =
	    out_attr[elfcpp::Tag_MPextension_use_legacy];
	  out_attr[elfcpp::Tag_MPextension_use_legacy].set_type(0);
	  out_attr[elfcpp::Tag_MPextension_use_legacy].set_int_value(0);
	}

      return;
    }

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

  // This needs to happen before Tag_ABI_FP_number_model is merged.  */
  if (in_attr[elfcpp::Tag_ABI_VFP_args].int_value()
      != out_attr[elfcpp::Tag_ABI_VFP_args].int_value())
    {
      // Ignore mismatches if the object doesn't use floating point.  */
      if (out_attr[elfcpp::Tag_ABI_FP_number_model].int_value() == 0)
	out_attr[elfcpp::Tag_ABI_VFP_args].set_int_value(
	    in_attr[elfcpp::Tag_ABI_VFP_args].int_value());
      else if (in_attr[elfcpp::Tag_ABI_FP_number_model].int_value() != 0
	       && parameters->options().warn_mismatch())
	gold_error(_("%s uses VFP register arguments, output does not"),
		   name);
    }

  for (int i = 4; i < Vendor_object_attributes::NUM_KNOWN_ATTRIBUTES; ++i)
    {
      // Merge this attribute with existing attributes.
      switch (i)
	{
	case elfcpp::Tag_CPU_raw_name:
	case elfcpp::Tag_CPU_name:
	  // These are merged after Tag_CPU_arch.
	  break;

	case elfcpp::Tag_ABI_optimization_goals:
	case elfcpp::Tag_ABI_FP_optimization_goals:
	  // Use the first value seen.
	  break;

	case elfcpp::Tag_CPU_arch:
	  {
	    unsigned int saved_out_attr = out_attr->int_value();
	    // Merge Tag_CPU_arch and Tag_also_compatible_with.
	    int secondary_compat =
	      this->get_secondary_compatible_arch(pasd);
	    int secondary_compat_out =
	      this->get_secondary_compatible_arch(
		  this->attributes_section_data_);
	    out_attr[i].set_int_value(
		tag_cpu_arch_combine(name, out_attr[i].int_value(),
				     &secondary_compat_out,
				     in_attr[i].int_value(),
				     secondary_compat));
	    this->set_secondary_compatible_arch(this->attributes_section_data_,
						secondary_compat_out);

	    // Merge Tag_CPU_name and Tag_CPU_raw_name.
	    if (out_attr[i].int_value() == saved_out_attr)
	      ; // Leave the names alone.
	    else if (out_attr[i].int_value() == in_attr[i].int_value())
	      {
		// The output architecture has been changed to match the
		// input architecture.  Use the input names.
		out_attr[elfcpp::Tag_CPU_name].set_string_value(
		    in_attr[elfcpp::Tag_CPU_name].string_value());
		out_attr[elfcpp::Tag_CPU_raw_name].set_string_value(
		    in_attr[elfcpp::Tag_CPU_raw_name].string_value());
	      }
	    else
	      {
		out_attr[elfcpp::Tag_CPU_name].set_string_value("");
		out_attr[elfcpp::Tag_CPU_raw_name].set_string_value("");
	      }

	    // If we still don't have a value for Tag_CPU_name,
	    // make one up now.  Tag_CPU_raw_name remains blank.
	    if (out_attr[elfcpp::Tag_CPU_name].string_value() == "")
	      {
		const std::string cpu_name =
		  this->tag_cpu_name_value(out_attr[i].int_value());
		// FIXME:  If we see an unknown CPU, this will be set
		// to "<unknown CPU n>", where n is the attribute value.
		// This is different from BFD, which leaves the name alone.
		out_attr[elfcpp::Tag_CPU_name].set_string_value(cpu_name);
	      }
	  }
	  break;

	case elfcpp::Tag_ARM_ISA_use:
	case elfcpp::Tag_THUMB_ISA_use:
	case elfcpp::Tag_WMMX_arch:
	case elfcpp::Tag_Advanced_SIMD_arch:
	  // ??? Do Advanced_SIMD (NEON) and WMMX conflict?
	case elfcpp::Tag_ABI_FP_rounding:
	case elfcpp::Tag_ABI_FP_exceptions:
	case elfcpp::Tag_ABI_FP_user_exceptions:
	case elfcpp::Tag_ABI_FP_number_model:
	case elfcpp::Tag_VFP_HP_extension:
	case elfcpp::Tag_CPU_unaligned_access:
	case elfcpp::Tag_T2EE_use:
	case elfcpp::Tag_Virtualization_use:
	case elfcpp::Tag_MPextension_use:
	  // Use the largest value specified.
	  if (in_attr[i].int_value() > out_attr[i].int_value())
	    out_attr[i].set_int_value(in_attr[i].int_value());
	  break;

	case elfcpp::Tag_ABI_align8_preserved:
	case elfcpp::Tag_ABI_PCS_RO_data:
	  // Use the smallest value specified.
	  if (in_attr[i].int_value() < out_attr[i].int_value())
	    out_attr[i].set_int_value(in_attr[i].int_value());
	  break;

	case elfcpp::Tag_ABI_align8_needed:
	  if ((in_attr[i].int_value() > 0 || out_attr[i].int_value() > 0)
	      && (in_attr[elfcpp::Tag_ABI_align8_preserved].int_value() == 0
		  || (out_attr[elfcpp::Tag_ABI_align8_preserved].int_value()
		      == 0)))
	    {
	      // This error message should be enabled once all non-conforming
	      // binaries in the toolchain have had the attributes set
	      // properly.
	      // gold_error(_("output 8-byte data alignment conflicts with %s"),
	      // 	    name);
	    }
	  // Fall through.
	case elfcpp::Tag_ABI_FP_denormal:
	case elfcpp::Tag_ABI_PCS_GOT_use:
	  {
	    // These tags have 0 = don't care, 1 = strong requirement,
	    // 2 = weak requirement.
	    static const int order_021[3] = {0, 2, 1};

	    // Use the "greatest" from the sequence 0, 2, 1, or the largest
	    // value if greater than 2 (for future-proofing).
	    if ((in_attr[i].int_value() > 2
		 && in_attr[i].int_value() > out_attr[i].int_value())
		|| (in_attr[i].int_value() <= 2
		    && out_attr[i].int_value() <= 2
		    && (order_021[in_attr[i].int_value()]
			> order_021[out_attr[i].int_value()])))
	      out_attr[i].set_int_value(in_attr[i].int_value());
	  }
	  break;

	case elfcpp::Tag_CPU_arch_profile:
	  if (out_attr[i].int_value() != in_attr[i].int_value())
	    {
	      // 0 will merge with anything.
	      // 'A' and 'S' merge to 'A'.
	      // 'R' and 'S' merge to 'R'.
	      // 'M' and 'A|R|S' is an error.
	      if (out_attr[i].int_value() == 0
		  || (out_attr[i].int_value() == 'S'
		      && (in_attr[i].int_value() == 'A'
			  || in_attr[i].int_value() == 'R')))
		out_attr[i].set_int_value(in_attr[i].int_value());
	      else if (in_attr[i].int_value() == 0
		       || (in_attr[i].int_value() == 'S'
			   && (out_attr[i].int_value() == 'A'
			       || out_attr[i].int_value() == 'R')))
		; // Do nothing.
	      else if (parameters->options().warn_mismatch())
		{
		  gold_error
		    (_("conflicting architecture profiles %c/%c"),
		     in_attr[i].int_value() ? in_attr[i].int_value() : '0',
		     out_attr[i].int_value() ? out_attr[i].int_value() : '0');
		}
	    }
	  break;
	case elfcpp::Tag_VFP_arch:
	    {
	      static const struct
	      {
		  int ver;
		  int regs;
	      } vfp_versions[7] =
		{
		  {0, 0},
		  {1, 16},
		  {2, 16},
		  {3, 32},
		  {3, 16},
		  {4, 32},
		  {4, 16}
		};

	      // Values greater than 6 aren't defined, so just pick the
	      // biggest.
	      if (in_attr[i].int_value() > 6
		  && in_attr[i].int_value() > out_attr[i].int_value())
		{
		  *out_attr = *in_attr;
		  break;
		}
	      // The output uses the superset of input features
	      // (ISA version) and registers.
	      int ver = std::max(vfp_versions[in_attr[i].int_value()].ver,
				 vfp_versions[out_attr[i].int_value()].ver);
	      int regs = std::max(vfp_versions[in_attr[i].int_value()].regs,
				  vfp_versions[out_attr[i].int_value()].regs);
	      // This assumes all possible supersets are also a valid
	      // options.
	      int newval;
	      for (newval = 6; newval > 0; newval--)
		{
		  if (regs == vfp_versions[newval].regs
		      && ver == vfp_versions[newval].ver)
		    break;
		}
	      out_attr[i].set_int_value(newval);
	    }
	  break;
	case elfcpp::Tag_PCS_config:
	  if (out_attr[i].int_value() == 0)
	    out_attr[i].set_int_value(in_attr[i].int_value());
	  else if (in_attr[i].int_value() != 0
		   && out_attr[i].int_value() != 0
		   && parameters->options().warn_mismatch())
	    {
	      // It's sometimes ok to mix different configs, so this is only
	      // a warning.
	      gold_warning(_("%s: conflicting platform configuration"), name);
	    }
	  break;
	case elfcpp::Tag_ABI_PCS_R9_use:
	  if (in_attr[i].int_value() != out_attr[i].int_value()
	      && out_attr[i].int_value() != elfcpp::AEABI_R9_unused
	      && in_attr[i].int_value() != elfcpp::AEABI_R9_unused
	      && parameters->options().warn_mismatch())
	    {
	      gold_error(_("%s: conflicting use of R9"), name);
	    }
	  if (out_attr[i].int_value() == elfcpp::AEABI_R9_unused)
	    out_attr[i].set_int_value(in_attr[i].int_value());
	  break;
	case elfcpp::Tag_ABI_PCS_RW_data:
	  if (in_attr[i].int_value() == elfcpp::AEABI_PCS_RW_data_SBrel
	      && (in_attr[elfcpp::Tag_ABI_PCS_R9_use].int_value()
		  != elfcpp::AEABI_R9_SB)
	      && (out_attr[elfcpp::Tag_ABI_PCS_R9_use].int_value()
		  != elfcpp::AEABI_R9_unused)
	      && parameters->options().warn_mismatch())
	    {
	      gold_error(_("%s: SB relative addressing conflicts with use "
			   "of R9"),
			   name);
	    }
	  // Use the smallest value specified.
	  if (in_attr[i].int_value() < out_attr[i].int_value())
	    out_attr[i].set_int_value(in_attr[i].int_value());
	  break;
	case elfcpp::Tag_ABI_PCS_wchar_t:
	  if (out_attr[i].int_value()
	      && in_attr[i].int_value()
	      && out_attr[i].int_value() != in_attr[i].int_value()
	      && parameters->options().warn_mismatch()
	      && parameters->options().wchar_size_warning())
	    {
	      gold_warning(_("%s uses %u-byte wchar_t yet the output is to "
			     "use %u-byte wchar_t; use of wchar_t values "
			     "across objects may fail"),
			   name, in_attr[i].int_value(),
			   out_attr[i].int_value());
	    }
	  else if (in_attr[i].int_value() && !out_attr[i].int_value())
	    out_attr[i].set_int_value(in_attr[i].int_value());
	  break;
	case elfcpp::Tag_ABI_enum_size:
	  if (in_attr[i].int_value() != elfcpp::AEABI_enum_unused)
	    {
	      if (out_attr[i].int_value() == elfcpp::AEABI_enum_unused
		  || out_attr[i].int_value() == elfcpp::AEABI_enum_forced_wide)
		{
		  // The existing object is compatible with anything.
		  // Use whatever requirements the new object has.
		  out_attr[i].set_int_value(in_attr[i].int_value());
		}
	      else if (in_attr[i].int_value() != elfcpp::AEABI_enum_forced_wide
		       && out_attr[i].int_value() != in_attr[i].int_value()
		       && parameters->options().warn_mismatch()
		       && parameters->options().enum_size_warning())
		{
		  unsigned int in_value = in_attr[i].int_value();
		  unsigned int out_value = out_attr[i].int_value();
		  gold_warning(_("%s uses %s enums yet the output is to use "
				 "%s enums; use of enum values across objects "
				 "may fail"),
			       name,
			       this->aeabi_enum_name(in_value).c_str(),
			       this->aeabi_enum_name(out_value).c_str());
		}
	    }
	  break;
	case elfcpp::Tag_ABI_VFP_args:
	  // Already done.
	  break;
	case elfcpp::Tag_ABI_WMMX_args:
	  if (in_attr[i].int_value() != out_attr[i].int_value()
	      && parameters->options().warn_mismatch())
	    {
	      gold_error(_("%s uses iWMMXt register arguments, output does "
			   "not"),
			 name);
	    }
	  break;
	case Object_attribute::Tag_compatibility:
	  // Merged in target-independent code.
	  break;
	case elfcpp::Tag_ABI_HardFP_use:
	  // 1 (SP) and 2 (DP) conflict, so combine to 3 (SP & DP).
	  if ((in_attr[i].int_value() == 1 && out_attr[i].int_value() == 2)
	      || (in_attr[i].int_value() == 2 && out_attr[i].int_value() == 1))
	    out_attr[i].set_int_value(3);
	  else if (in_attr[i].int_value() > out_attr[i].int_value())
	    out_attr[i].set_int_value(in_attr[i].int_value());
	  break;
	case elfcpp::Tag_ABI_FP_16bit_format:
	  if (in_attr[i].int_value() != 0 && out_attr[i].int_value() != 0)
	    {
	      if (in_attr[i].int_value() != out_attr[i].int_value()
		  && parameters->options().warn_mismatch())
		gold_error(_("fp16 format mismatch between %s and output"),
			   name);
	    }
	  if (in_attr[i].int_value() != 0)
	    out_attr[i].set_int_value(in_attr[i].int_value());
	  break;

	case elfcpp::Tag_DIV_use:
	  // This tag is set to zero if we can use UDIV and SDIV in Thumb
	  // mode on a v7-M or v7-R CPU; to one if we can not use UDIV or
	  // SDIV at all; and to two if we can use UDIV or SDIV on a v7-A
	  // CPU.  We will merge as follows: If the input attribute's value
	  // is one then the output attribute's value remains unchanged.  If
	  // the input attribute's value is zero or two then if the output
	  // attribute's value is one the output value is set to the input
	  // value, otherwise the output value must be the same as the
	  // inputs.  */
	  if (in_attr[i].int_value() != 1 && out_attr[i].int_value() != 1)
	    {
	      if (in_attr[i].int_value() != out_attr[i].int_value())
		{
		  gold_error(_("DIV usage mismatch between %s and output"),
			     name);
		}
	    }

	  if (in_attr[i].int_value() != 1)
	    out_attr[i].set_int_value(in_attr[i].int_value());

	  break;

	case elfcpp::Tag_MPextension_use_legacy:
	  // We don't output objects with Tag_MPextension_use_legacy - we
	  // move the value to Tag_MPextension_use.
	  if (in_attr[i].int_value() != 0
	      && in_attr[elfcpp::Tag_MPextension_use].int_value() != 0)
	    {
	      if (in_attr[elfcpp::Tag_MPextension_use].int_value()
		  != in_attr[i].int_value())
		{
		  gold_error(_("%s has has both the current and legacy "
			       "Tag_MPextension_use attributes"),
			     name);
		}
	    }

	  if (in_attr[i].int_value()
	      > out_attr[elfcpp::Tag_MPextension_use].int_value())
	    out_attr[elfcpp::Tag_MPextension_use] = in_attr[i];

	  break;

	case elfcpp::Tag_nodefaults:
	  // This tag is set if it exists, but the value is unused (and is
	  // typically zero).  We don't actually need to do anything here -
	  // the merge happens automatically when the type flags are merged
	  // below.
	  break;
	case elfcpp::Tag_also_compatible_with:
	  // Already done in Tag_CPU_arch.
	  break;
	case elfcpp::Tag_conformance:
	  // Keep the attribute if it matches.  Throw it away otherwise.
	  // No attribute means no claim to conform.
	  if (in_attr[i].string_value() != out_attr[i].string_value())
	    out_attr[i].set_string_value("");
	  break;

	default:
	  {
	    const char* err_object = NULL;

	    // The "known_obj_attributes" table does contain some undefined
	    // attributes.  Ensure that there are unused.
	    if (out_attr[i].int_value() != 0
		|| out_attr[i].string_value() != "")
	      err_object = "output";
	    else if (in_attr[i].int_value() != 0
		     || in_attr[i].string_value() != "")
	      err_object = name;

	    if (err_object != NULL
		&& parameters->options().warn_mismatch())
	      {
		// Attribute numbers >=64 (mod 128) can be safely ignored.
		if ((i & 127) < 64)
		  gold_error(_("%s: unknown mandatory EABI object attribute "
			       "%d"),
			     err_object, i);
		else
		  gold_warning(_("%s: unknown EABI object attribute %d"),
			       err_object, i);
	      }

	    // Only pass on attributes that match in both inputs.
	    if (!in_attr[i].matches(out_attr[i]))
	      {
		out_attr[i].set_int_value(0);
		out_attr[i].set_string_value("");
	      }
	  }
	}

      // If out_attr was copied from in_attr then it won't have a type yet.
      if (in_attr[i].type() && !out_attr[i].type())
	out_attr[i].set_type(in_attr[i].type());
    }

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

  // Check for any attributes not known on ARM.
  typedef Vendor_object_attributes::Other_attributes Other_attributes;
  const Other_attributes* in_other_attributes = pasd->other_attributes(vendor);
  Other_attributes::const_iterator in_iter = in_other_attributes->begin();
  Other_attributes* out_other_attributes =
    this->attributes_section_data_->other_attributes(vendor);
  Other_attributes::iterator out_iter = out_other_attributes->begin();

  while (in_iter != in_other_attributes->end()
	 || out_iter != out_other_attributes->end())
    {
      const char* err_object = NULL;
      int err_tag = 0;

      // The tags for each list are in numerical order.
      // If the tags are equal, then merge.
      if (out_iter != out_other_attributes->end()
	  && (in_iter == in_other_attributes->end()
	      || in_iter->first > out_iter->first))
	{
	  // This attribute only exists in output.  We can't merge, and we
	  // don't know what the tag means, so delete it.
	  err_object = "output";
	  err_tag = out_iter->first;
	  int saved_tag = out_iter->first;
	  delete out_iter->second;
	  out_other_attributes->erase(out_iter);
	  out_iter = out_other_attributes->upper_bound(saved_tag);
	}
      else if (in_iter != in_other_attributes->end()
	       && (out_iter != out_other_attributes->end()
		   || in_iter->first < out_iter->first))
	{
	  // This attribute only exists in input. We can't merge, and we
	  // don't know what the tag means, so ignore it.
	  err_object = name;
	  err_tag = in_iter->first;
	  ++in_iter;
	}
      else // The tags are equal.
	{
	  // As present, all attributes in the list are unknown, and
	  // therefore can't be merged meaningfully.
	  err_object = "output";
	  err_tag = out_iter->first;

	  //  Only pass on attributes that match in both inputs.
	  if (!in_iter->second->matches(*(out_iter->second)))
	    {
	      // No match.  Delete the attribute.
	      int saved_tag = out_iter->first;
	      delete out_iter->second;
	      out_other_attributes->erase(out_iter);
	      out_iter = out_other_attributes->upper_bound(saved_tag);
	    }
	  else
	    {
	      // Matched.  Keep the attribute and move to the next.
	      ++out_iter;
	      ++in_iter;
	    }
	}

      if (err_object && parameters->options().warn_mismatch())
	{
	  // Attribute numbers >=64 (mod 128) can be safely ignored.  */
	  if ((err_tag & 127) < 64)
	    {
	      gold_error(_("%s: unknown mandatory EABI object attribute %d"),
			 err_object, err_tag);
	    }
	  else
	    {
	      gold_warning(_("%s: unknown EABI object attribute %d"),
			   err_object, err_tag);
	    }
	}
    }
}

// Stub-generation methods for Target_arm.

// Make a new Arm_input_section object.

template<bool big_endian>
Arm_input_section<big_endian>*
Target_arm<big_endian>::new_arm_input_section(
    Relobj* relobj,
    unsigned int shndx)
{
  Section_id sid(relobj, shndx);

  Arm_input_section<big_endian>* arm_input_section =
    new Arm_input_section<big_endian>(relobj, shndx);
  arm_input_section->init();

  // Register new Arm_input_section in map for look-up.
  std::pair<typename Arm_input_section_map::iterator, bool> ins =
    this->arm_input_section_map_.insert(std::make_pair(sid, arm_input_section));

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

  return arm_input_section;
}

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

template<bool big_endian>
Arm_input_section<big_endian>*
Target_arm<big_endian>::find_arm_input_section(
    Relobj* relobj,
    unsigned int shndx) const
{
  Section_id sid(relobj, shndx);
  typename Arm_input_section_map::const_iterator p =
    this->arm_input_section_map_.find(sid);
  return (p != this->arm_input_section_map_.end()) ? p->second : NULL;
}

// Make a new stub table.

template<bool big_endian>
Stub_table<big_endian>*
Target_arm<big_endian>::new_stub_table(Arm_input_section<big_endian>* owner)
{
  Stub_table<big_endian>* stub_table =
    new Stub_table<big_endian>(owner);
  this->stub_tables_.push_back(stub_table);

  stub_table->set_address(owner->address() + owner->data_size());
  stub_table->set_file_offset(owner->offset() + owner->data_size());
  stub_table->finalize_data_size();

  return stub_table;
}

// Scan a relocation for stub generation.

template<bool big_endian>
void
Target_arm<big_endian>::scan_reloc_for_stub(
    const Relocate_info<32, big_endian>* relinfo,
    unsigned int r_type,
    const Sized_symbol<32>* gsym,
    unsigned int r_sym,
    const Symbol_value<32>* psymval,
    elfcpp::Elf_types<32>::Elf_Swxword addend,
    Arm_address address)
{
  const Arm_relobj<big_endian>* arm_relobj =
    Arm_relobj<big_endian>::as_arm_relobj(relinfo->object);

  bool target_is_thumb;
  Symbol_value<32> symval;
  if (gsym != NULL)
    {
      // This is a global symbol.  Determine if we use PLT and if the
      // final target is THUMB.
      if (gsym->use_plt_offset(Scan::get_reference_flags(r_type)))
	{
	  // This uses a PLT, change the symbol value.
	  symval.set_output_value(this->plt_section()->address()
				  + gsym->plt_offset());
	  psymval = &symval;
	  target_is_thumb = false;
	}
      else if (gsym->is_undefined())
	// There is no need to generate a stub symbol is undefined.
	return;
      else
	{
	  target_is_thumb =
	    ((gsym->type() == elfcpp::STT_ARM_TFUNC)
	     || (gsym->type() == elfcpp::STT_FUNC
		 && !gsym->is_undefined()
		 && ((psymval->value(arm_relobj, 0) & 1) != 0)));
	}
    }
  else
    {
      // This is a local symbol.  Determine if the final target is THUMB.
      target_is_thumb = arm_relobj->local_symbol_is_thumb_function(r_sym);
    }

  // Strip LSB if this points to a THUMB target.
  const Arm_reloc_property* reloc_property =
    arm_reloc_property_table->get_implemented_static_reloc_property(r_type);
  gold_assert(reloc_property != NULL);
  if (target_is_thumb
      && reloc_property->uses_thumb_bit()
      && ((psymval->value(arm_relobj, 0) & 1) != 0))
    {
      Arm_address stripped_value =
	psymval->value(arm_relobj, 0) & ~static_cast<Arm_address>(1);
      symval.set_output_value(stripped_value);
      psymval = &symval;
    }

  // Get the symbol value.
  Symbol_value<32>::Value value = psymval->value(arm_relobj, 0);

  // Owing to pipelining, the PC relative branches below actually skip
  // two instructions when the branch offset is 0.
  Arm_address destination;
  switch (r_type)
    {
    case elfcpp::R_ARM_CALL:
    case elfcpp::R_ARM_JUMP24:
    case elfcpp::R_ARM_PLT32:
      // ARM branches.
      destination = value + addend + 8;
      break;
    case elfcpp::R_ARM_THM_CALL:
    case elfcpp::R_ARM_THM_XPC22:
    case elfcpp::R_ARM_THM_JUMP24:
    case elfcpp::R_ARM_THM_JUMP19:
      // THUMB branches.
      destination = value + addend + 4;
      break;
    default:
      gold_unreachable();
    }

  Reloc_stub* stub = NULL;
  Stub_type stub_type =
    Reloc_stub::stub_type_for_reloc(r_type, address, destination,
				    target_is_thumb);
  if (stub_type != arm_stub_none)
    {
      // Try looking up an existing stub from a stub table.
      Stub_table<big_endian>* stub_table =
	arm_relobj->stub_table(relinfo->data_shndx);
      gold_assert(stub_table != NULL);

      // Locate stub by destination.
      Reloc_stub::Key stub_key(stub_type, gsym, arm_relobj, r_sym, addend);

      // Create a stub if there is not one already
      stub = stub_table->find_reloc_stub(stub_key);
      if (stub == NULL)
	{
	  // create a new stub and add it to stub table.
	  stub = this->stub_factory().make_reloc_stub(stub_type);
	  stub_table->add_reloc_stub(stub, stub_key);
	}

      // Record the destination address.
      stub->set_destination_address(destination
				    | (target_is_thumb ? 1 : 0));
    }

  // For Cortex-A8, we need to record a relocation at 4K page boundary.
  if (this->fix_cortex_a8_
      && (r_type == elfcpp::R_ARM_THM_JUMP24
	  || r_type == elfcpp::R_ARM_THM_JUMP19
	  || r_type == elfcpp::R_ARM_THM_CALL
	  || r_type == elfcpp::R_ARM_THM_XPC22)
      && (address & 0xfffU) == 0xffeU)
    {
      // Found a candidate.  Note we haven't checked the destination is
      // within 4K here: if we do so (and don't create a record) we can't
      // tell that a branch should have been relocated when scanning later.
      this->cortex_a8_relocs_info_[address] =
	new Cortex_a8_reloc(stub, r_type,
			    destination | (target_is_thumb ? 1 : 0));
    }
}

// This function scans a relocation sections 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<bool big_endian>
template<int sh_type>
void inline
Target_arm<big_endian>::scan_reloc_section_for_stubs(
    const Relocate_info<32, big_endian>* relinfo,
    const unsigned char* prelocs,
    size_t reloc_count,
    Output_section* output_section,
    bool needs_special_offset_handling,
    const unsigned char* view,
    elfcpp::Elf_types<32>::Elf_Addr view_address,
    section_size_type)
{
  typedef typename Reloc_types<sh_type, 32, big_endian>::Reloc Reltype;
  const int reloc_size =
    Reloc_types<sh_type, 32, big_endian>::reloc_size;

  Arm_relobj<big_endian>* arm_object =
    Arm_relobj<big_endian>::as_arm_relobj(relinfo->object);
  unsigned int local_count = arm_object->local_symbol_count();

  Comdat_behavior comdat_behavior = CB_UNDETERMINED;

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

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

      r_type = this->get_real_reloc_type(r_type);

      // Only a few relocation types need stubs.
      if ((r_type != elfcpp::R_ARM_CALL)
	 && (r_type != elfcpp::R_ARM_JUMP24)
	 && (r_type != elfcpp::R_ARM_PLT32)
	 && (r_type != elfcpp::R_ARM_THM_CALL)
	 && (r_type != elfcpp::R_ARM_THM_XPC22)
	 && (r_type != elfcpp::R_ARM_THM_JUMP24)
	 && (r_type != elfcpp::R_ARM_THM_JUMP19)
	 && (r_type != elfcpp::R_ARM_V4BX))
	continue;

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

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

      // Create a v4bx stub if --fix-v4bx-interworking is used.
      if (r_type == elfcpp::R_ARM_V4BX)
	{
	  if (this->fix_v4bx() == General_options::FIX_V4BX_INTERWORKING)
	    {
	      // Get the BX instruction.
	      typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
	      const Valtype* wv =
		reinterpret_cast<const Valtype*>(view + offset);
	      elfcpp::Elf_types<32>::Elf_Swxword insn =
		elfcpp::Swap<32, big_endian>::readval(wv);
	      const uint32_t reg = (insn & 0xf);

	      if (reg < 0xf)
		{
		  // Try looking up an existing stub from a stub table.
		  Stub_table<big_endian>* stub_table =
		    arm_object->stub_table(relinfo->data_shndx);
		  gold_assert(stub_table != NULL);

		  if (stub_table->find_arm_v4bx_stub(reg) == NULL)
		    {
		      // create a new stub and add it to stub table.
		      Arm_v4bx_stub* stub =
			this->stub_factory().make_arm_v4bx_stub(reg);
		      gold_assert(stub != NULL);
		      stub_table->add_arm_v4bx_stub(stub);
		    }
		}
	    }
	  continue;
	}

      // Get the addend.
      Stub_addend_reader<sh_type, big_endian> stub_addend_reader;
      elfcpp::Elf_types<32>::Elf_Swxword addend =
	stub_addend_reader(r_type, view + offset, reloc);

      const Sized_symbol<32>* sym;

      Symbol_value<32> symval;
      const Symbol_value<32> *psymval;
      bool is_defined_in_discarded_section;
      unsigned int shndx;
      if (r_sym < local_count)
	{
	  sym = NULL;
	  psymval = arm_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
	     && !arm_object->is_section_included(shndx)
	     && !relinfo->symtab->is_section_folded(arm_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<32, big_endian> ObjType;
	      typename ObjType::Compute_final_local_value_status status =
		arm_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 =
			arm_object->section_name(shndx);
		      arm_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 = arm_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<32>*>(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<32>* sized_symbol =
	    symtab->get_sized_symbol<32>(gsym);
	  Symbol_table::Compute_final_value_status status;
	  Arm_address value =
	    symtab->compute_final_value<32>(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<32> symval2;
      if (is_defined_in_discarded_section)
	{
	  if (comdat_behavior == CB_UNDETERMINED)
	    {
	      std::string name = arm_object->section_name(relinfo->data_shndx);
	      comdat_behavior = get_comdat_behavior(name.c_str());
	    }
	  if (comdat_behavior == CB_PRETEND)
	    {
	      // FIXME: This case does not work for global symbols.
	      // We have no place to store the original section index.
	      // Fortunately this does not matter for comdat sections,
	      // only for sections explicitly discarded by a linker
	      // script.
	      bool found;
	      typename elfcpp::Elf_types<32>::Elf_Addr value =
		arm_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);
    }
}

// Scan an input section for stub generation.

template<bool big_endian>
void
Target_arm<big_endian>::scan_section_for_stubs(
    const Relocate_info<32, 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,
    Arm_address view_address,
    section_size_type view_size)
{
  if (sh_type == elfcpp::SHT_REL)
    this->scan_reloc_section_for_stubs<elfcpp::SHT_REL>(
	relinfo,
	prelocs,
	reloc_count,
	output_section,
	needs_special_offset_handling,
	view,
	view_address,
	view_size);
  else if (sh_type == elfcpp::SHT_RELA)
    // We do not support RELA type relocations yet.  This is provided for
    // completeness.
    this->scan_reloc_section_for_stubs<elfcpp::SHT_RELA>(
	relinfo,
	prelocs,
	reloc_count,
	output_section,
	needs_special_offset_handling,
	view,
	view_address,
	view_size);
  else
    gold_unreachable();
}

// 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<bool big_endian>
void
Target_arm<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_allocated_sections(&section_list);
  for (Layout::Section_list::const_iterator p = section_list.begin();
       p != section_list.end();
       ++p)
    {
      Arm_output_section<big_endian>* output_section =
	Arm_output_section<big_endian>::as_arm_output_section(*p);
      output_section->group_sections(group_size, stubs_always_after_branch,
				     this, task);
    }
}

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

template<bool big_endian>
bool
Target_arm<big_endian>::do_relax(
    int pass,
    const Input_objects* input_objects,
    Symbol_table* symtab,
    Layout* layout,
    const Task* task)
{
  // No need to generate stubs if this is a relocatable link.
  gold_assert(!parameters->options().relocatable());

  // If this is the first pass, we need to group input sections into
  // stub groups.
  bool done_exidx_fixup = false;
  typedef typename Stub_table_list::iterator Stub_table_iterator;
  if (pass == 1)
    {
      // Determine the stub group size.  The group size is the absolute
      // value of the parameter --stub-group-size.  If --stub-group-size
      // is passed a negative value, we restrict stubs to be always after
      // the stubbed branches.
      int32_t stub_group_size_param =
	parameters->options().stub_group_size();
      bool stubs_always_after_branch = stub_group_size_param < 0;
      section_size_type stub_group_size = abs(stub_group_size_param);

      if (stub_group_size == 1)
	{
	  // Default value.
	  // Thumb branch range is +-4MB has to be used as the default
	  // maximum size (a given section can contain both ARM and Thumb
	  // code, so the worst case has to be taken into account).  If we are
	  // fixing cortex-a8 errata, the branch range has to be even smaller,
	  // since wide conditional branch has a range of +-1MB only.
	  //
	  // This value is 48K less than that, which allows for 4096
	  // 12-byte stubs.  If we exceed that, then we will fail to link.
	  // The user will have to relink with an explicit group size
	  // option.
	    stub_group_size = 4145152;
	}

      // The Cortex-A8 erratum fix depends on stubs not being in the same 4K
      // page as the first half of a 32-bit branch straddling two 4K pages.
      // This is a crude way of enforcing that.  In addition, long conditional
      // branches of THUMB-2 have a range of +-1M.  If we are fixing cortex-A8
      // erratum, limit the group size to  (1M - 12k) to avoid unreachable
      // cortex-A8 stubs from long conditional branches.
      if (this->fix_cortex_a8_)
	{
	  stubs_always_after_branch = true;
	  const section_size_type cortex_a8_group_size = 1024 * (1024 - 12);
	  stub_group_size = std::max(stub_group_size, cortex_a8_group_size);
	}

      group_sections(layout, stub_group_size, stubs_always_after_branch, task);

      // Also fix .ARM.exidx section coverage.
      Arm_output_section<big_endian>* exidx_output_section = NULL;
      for (Layout::Section_list::const_iterator p =
	     layout->section_list().begin();
	   p != layout->section_list().end();
	   ++p)
	if ((*p)->type() == elfcpp::SHT_ARM_EXIDX)
	  {
	    if (exidx_output_section == NULL)
	      exidx_output_section =
		Arm_output_section<big_endian>::as_arm_output_section(*p);
	    else
	      // We cannot handle this now.
	      gold_error(_("multiple SHT_ARM_EXIDX sections %s and %s in a "
			   "non-relocatable link"),
			  exidx_output_section->name(),
			  (*p)->name());
	  }

      if (exidx_output_section != NULL)
	{
	  this->fix_exidx_coverage(layout, input_objects, exidx_output_section,
				   symtab, task);
	  done_exidx_fixup = true;
	}
    }
  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)
	{
	  Arm_input_section<big_endian>* owner = (*sp)->owner();
	  off_t off = align_address(owner->original_size(),
				    (*sp)->addralign());
	  (*sp)->set_address_and_file_offset(owner->address() + off,
					     owner->offset() + off);
	}
    }

  // The Cortex-A8 stubs are sensitive to layout of code sections.  At the
  // beginning of each relaxation pass, just blow away all the stubs.
  // Alternatively, we could selectively remove only the stubs and reloc
  // information for code sections that have moved since the last pass.
  // That would require more book-keeping.
  if (this->fix_cortex_a8_)
    {
      // Clear all Cortex-A8 reloc information.
      for (typename Cortex_a8_relocs_info::const_iterator p =
	     this->cortex_a8_relocs_info_.begin();
	   p != this->cortex_a8_relocs_info_.end();
	   ++p)
	delete p->second;
      this->cortex_a8_relocs_info_.clear();

      // Remove all Cortex-A8 stubs.
      for (Stub_table_iterator sp = this->stub_tables_.begin();
	   sp != this->stub_tables_.end();
	   ++sp)
	(*sp)->remove_all_cortex_a8_stubs();
    }

  // Scan relocs for relocation stubs
  for (Input_objects::Relobj_iterator op = input_objects->relobj_begin();
       op != input_objects->relobj_end();
       ++op)
    {
      Arm_relobj<big_endian>* arm_relobj =
	Arm_relobj<big_endian>::as_arm_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, arm_relobj);
      arm_relobj->scan_sections_for_stubs(this, symtab, layout);
    }

  // Check all stub tables to see if any of them have their data sizes
  // or addresses alignments changed.  These are the only things that
  // matter.
  bool any_stub_table_changed = false;
  Unordered_set<const Output_section*> sections_needing_adjustment;
  for (Stub_table_iterator sp = this->stub_tables_.begin();
       (sp != this->stub_tables_.end()) && !any_stub_table_changed;
       ++sp)
    {
      if ((*sp)->update_data_size_and_addralign())
	{
	  // Update data size of stub table owner.
	  Arm_input_section<big_endian>* owner = (*sp)->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);

	  sections_needing_adjustment.insert(owner->output_section());
	  any_stub_table_changed = true;
	}
    }

  // Output_section_data::output_section() returns a const pointer but we
  // need to update output sections, so we record all output sections needing
  // update above and scan the sections here to find out what sections need
  // to be updated.
  for (Layout::Section_list::const_iterator p = layout->section_list().begin();
      p != layout->section_list().end();
      ++p)
    {
      if (sections_needing_adjustment.find(*p)
	  != sections_needing_adjustment.end())
	(*p)->set_section_offsets_need_adjustment();
    }

  // Stop relaxation if no EXIDX fix-up and no stub table change.
  bool continue_relaxation = done_exidx_fixup || any_stub_table_changed;

  // Finalize the stubs in the last relaxation pass.
  if (!continue_relaxation)
    {
      for (Stub_table_iterator sp = this->stub_tables_.begin();
	   (sp != this->stub_tables_.end()) && !any_stub_table_changed;
	    ++sp)
	(*sp)->finalize_stubs();

      // Update output local symbol counts of objects if necessary.
      for (Input_objects::Relobj_iterator op = input_objects->relobj_begin();
	   op != input_objects->relobj_end();
	   ++op)
	{
	  Arm_relobj<big_endian>* arm_relobj =
	    Arm_relobj<big_endian>::as_arm_relobj(*op);

	  // Update output local symbol counts.  We need to discard local
	  // symbols defined in parts of input sections that are discarded by
	  // relaxation.
	  if (arm_relobj->output_local_symbol_count_needs_update())
	    {
	      // We need to lock the object's file to update it.
	      Task_lock_obj<Object> tl(task, arm_relobj);
	      arm_relobj->update_output_local_symbol_count();
	    }
	}
    }

  return continue_relaxation;
}

// Relocate a stub.

template<bool big_endian>
void
Target_arm<big_endian>::relocate_stub(
    Stub* stub,
    const Relocate_info<32, big_endian>* relinfo,
    Output_section* output_section,
    unsigned char* view,
    Arm_address address,
    section_size_type view_size)
{
  Relocate relocate;
  const Stub_template* stub_template = stub->stub_template();
  for (size_t i = 0; i < stub_template->reloc_count(); i++)
    {
      size_t reloc_insn_index = stub_template->reloc_insn_index(i);
      const Insn_template* insn = &stub_template->insns()[reloc_insn_index];

      unsigned int r_type = insn->r_type();
      section_size_type reloc_offset = stub_template->reloc_offset(i);
      section_size_type reloc_size = insn->size();
      gold_assert(reloc_offset + reloc_size <= view_size);

      // This is the address of the stub destination.
      Arm_address target = stub->reloc_target(i) + insn->reloc_addend();
      Symbol_value<32> symval;
      symval.set_output_value(target);

      // Synthesize a fake reloc just in case.  We don't have a symbol so
      // we use 0.
      unsigned char reloc_buffer[elfcpp::Elf_sizes<32>::rel_size];
      memset(reloc_buffer, 0, sizeof(reloc_buffer));
      elfcpp::Rel_write<32, big_endian> reloc_write(reloc_buffer);
      reloc_write.put_r_offset(reloc_offset);
      reloc_write.put_r_info(elfcpp::elf_r_info<32>(0, r_type));
      elfcpp::Rel<32, big_endian> rel(reloc_buffer);

      relocate.relocate(relinfo, this, output_section,
			this->fake_relnum_for_stubs, rel, r_type,
			NULL, &symval, view + reloc_offset,
			address + reloc_offset, reloc_size);
    }
}

// Determine whether an object attribute tag takes an integer, a
// string or both.

template<bool big_endian>
int
Target_arm<big_endian>::do_attribute_arg_type(int tag) const
{
  if (tag == Object_attribute::Tag_compatibility)
    return (Object_attribute::ATTR_TYPE_FLAG_INT_VAL
	    | Object_attribute::ATTR_TYPE_FLAG_STR_VAL);
  else if (tag == elfcpp::Tag_nodefaults)
    return (Object_attribute::ATTR_TYPE_FLAG_INT_VAL
	    | Object_attribute::ATTR_TYPE_FLAG_NO_DEFAULT);
  else if (tag == elfcpp::Tag_CPU_raw_name || tag == elfcpp::Tag_CPU_name)
    return Object_attribute::ATTR_TYPE_FLAG_STR_VAL;
  else if (tag < 32)
    return Object_attribute::ATTR_TYPE_FLAG_INT_VAL;
  else
    return ((tag & 1) != 0
	    ? Object_attribute::ATTR_TYPE_FLAG_STR_VAL
	    : Object_attribute::ATTR_TYPE_FLAG_INT_VAL);
}

// Reorder attributes.
//
// The ABI defines that Tag_conformance should be emitted first, and that
// Tag_nodefaults should be second (if either is defined).  This sets those
// two positions, and bumps up the position of all the remaining tags to
// compensate.

template<bool big_endian>
int
Target_arm<big_endian>::do_attributes_order(int num) const
{
  // Reorder the known object attributes in output.  We want to move
  // Tag_conformance to position 4 and Tag_conformance to position 5
  // and shift everything between 4 .. Tag_conformance - 1 to make room.
  if (num == 4)
    return elfcpp::Tag_conformance;
  if (num == 5)
    return elfcpp::Tag_nodefaults;
  if ((num - 2) < elfcpp::Tag_nodefaults)
    return num - 2;
  if ((num - 1) < elfcpp::Tag_conformance)
    return num - 1;
  return num;
}

// Scan a span of THUMB code for Cortex-A8 erratum.

template<bool big_endian>
void
Target_arm<big_endian>::scan_span_for_cortex_a8_erratum(
    Arm_relobj<big_endian>* arm_relobj,
    unsigned int shndx,
    section_size_type span_start,
    section_size_type span_end,
    const unsigned char* view,
    Arm_address address)
{
  // Scan for 32-bit Thumb-2 branches which span two 4K regions, where:
  //
  // The opcode is BLX.W, BL.W, B.W, Bcc.W
  // The branch target is in the same 4KB region as the
  // first half of the branch.
  // The instruction before the branch is a 32-bit
  // length non-branch instruction.
  section_size_type i = span_start;
  bool last_was_32bit = false;
  bool last_was_branch = false;
  while (i < span_end)
    {
      typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
      const Valtype* wv = reinterpret_cast<const Valtype*>(view + i);
      uint32_t insn = elfcpp::Swap<16, big_endian>::readval(wv);
      bool is_blx = false, is_b = false;
      bool is_bl = false, is_bcc = false;

      bool insn_32bit = (insn & 0xe000) == 0xe000 && (insn & 0x1800) != 0x0000;
      if (insn_32bit)
	{
	  // Load the rest of the insn (in manual-friendly order).
	  insn = (insn << 16) | elfcpp::Swap<16, big_endian>::readval(wv + 1);

	  // Encoding T4: B<c>.W.
	  is_b = (insn & 0xf800d000U) == 0xf0009000U;
	  // Encoding T1: BL<c>.W.
	  is_bl = (insn & 0xf800d000U) == 0xf000d000U;
	  // Encoding T2: BLX<c>.W.
	  is_blx = (insn & 0xf800d000U) == 0xf000c000U;
	  // Encoding T3: B<c>.W (not permitted in IT block).
	  is_bcc = ((insn & 0xf800d000U) == 0xf0008000U
		    && (insn & 0x07f00000U) != 0x03800000U);
	}

      bool is_32bit_branch = is_b || is_bl || is_blx || is_bcc;

      // If this instruction is a 32-bit THUMB branch that crosses a 4K
      // page boundary and it follows 32-bit non-branch instruction,
      // we need to work around.
      if (is_32bit_branch
	  && ((address + i) & 0xfffU) == 0xffeU
	  && last_was_32bit
	  && !last_was_branch)
	{
	  // Check to see if there is a relocation stub for this branch.
	  bool force_target_arm = false;
	  bool force_target_thumb = false;
	  const Cortex_a8_reloc* cortex_a8_reloc = NULL;
	  Cortex_a8_relocs_info::const_iterator p =
	    this->cortex_a8_relocs_info_.find(address + i);

	  if (p != this->cortex_a8_relocs_info_.end())
	    {
	      cortex_a8_reloc = p->second;
	      bool target_is_thumb = (cortex_a8_reloc->destination() & 1) != 0;

	      if (cortex_a8_reloc->r_type() == elfcpp::R_ARM_THM_CALL
		  && !target_is_thumb)
		force_target_arm = true;
	      else if (cortex_a8_reloc->r_type() == elfcpp::R_ARM_THM_CALL
		       && target_is_thumb)
		force_target_thumb = true;
	    }

	  off_t offset;
	  Stub_type stub_type = arm_stub_none;

	  // Check if we have an offending branch instruction.
	  uint16_t upper_insn = (insn >> 16) & 0xffffU;
	  uint16_t lower_insn = insn & 0xffffU;
	  typedef class Arm_relocate_functions<big_endian> RelocFuncs;

	  if (cortex_a8_reloc != NULL
	      && cortex_a8_reloc->reloc_stub() != NULL)
	    // We've already made a stub for this instruction, e.g.
	    // it's a long branch or a Thumb->ARM stub.  Assume that
	    // stub will suffice to work around the A8 erratum (see
	    // setting of always_after_branch above).
	    ;
	  else if (is_bcc)
	    {
	      offset = RelocFuncs::thumb32_cond_branch_offset(upper_insn,
							      lower_insn);
	      stub_type = arm_stub_a8_veneer_b_cond;
	    }
	  else if (is_b || is_bl || is_blx)
	    {
	      offset = RelocFuncs::thumb32_branch_offset(upper_insn,
							 lower_insn);
	      if (is_blx)
		offset &= ~3;

	      stub_type = (is_blx
			   ? arm_stub_a8_veneer_blx
			   : (is_bl
			      ? arm_stub_a8_veneer_bl
			      : arm_stub_a8_veneer_b));
	    }

	  if (stub_type != arm_stub_none)
	    {
	      Arm_address pc_for_insn = address + i + 4;

	      // The original instruction is a BL, but the target is
	      // an ARM instruction.  If we were not making a stub,
	      // the BL would have been converted to a BLX.  Use the
	      // BLX stub instead in that case.
	      if (this->may_use_v5t_interworking() && force_target_arm
		  && stub_type == arm_stub_a8_veneer_bl)
		{
		  stub_type = arm_stub_a8_veneer_blx;
		  is_blx = true;
		  is_bl = false;
		}
	      // Conversely, if the original instruction was
	      // BLX but the target is Thumb mode, use the BL stub.
	      else if (force_target_thumb
		       && stub_type == arm_stub_a8_veneer_blx)
		{
		  stub_type = arm_stub_a8_veneer_bl;
		  is_blx = false;
		  is_bl = true;
		}

	      if (is_blx)
		pc_for_insn &= ~3;

	      // If we found a relocation, use the proper destination,
	      // not the offset in the (unrelocated) instruction.
	      // Note this is always done if we switched the stub type above.
	      if (cortex_a8_reloc != NULL)
		offset = (off_t) (cortex_a8_reloc->destination() - pc_for_insn);

	      Arm_address target = (pc_for_insn + offset) | (is_blx ? 0 : 1);

	      // Add a new stub if destination address in in the same page.
	      if (((address + i) & ~0xfffU) == (target & ~0xfffU))
		{
		  Cortex_a8_stub* stub =
		    this->stub_factory_.make_cortex_a8_stub(stub_type,
							    arm_relobj, shndx,
							    address + i,
							    target, insn);
		  Stub_table<big_endian>* stub_table =
		    arm_relobj->stub_table(shndx);
		  gold_assert(stub_table != NULL);
		  stub_table->add_cortex_a8_stub(address + i, stub);
		}
	    }
	}

      i += insn_32bit ? 4 : 2;
      last_was_32bit = insn_32bit;
      last_was_branch = is_32bit_branch;
    }
}

// Apply the Cortex-A8 workaround.

template<bool big_endian>
void
Target_arm<big_endian>::apply_cortex_a8_workaround(
    const Cortex_a8_stub* stub,
    Arm_address stub_address,
    unsigned char* insn_view,
    Arm_address insn_address)
{
  typedef typename elfcpp::Swap<16, big_endian>::Valtype Valtype;
  Valtype* wv = reinterpret_cast<Valtype*>(insn_view);
  Valtype upper_insn = elfcpp::Swap<16, big_endian>::readval(wv);
  Valtype lower_insn = elfcpp::Swap<16, big_endian>::readval(wv + 1);
  off_t branch_offset = stub_address - (insn_address + 4);

  typedef class Arm_relocate_functions<big_endian> RelocFuncs;
  switch (stub->stub_template()->type())
    {
    case arm_stub_a8_veneer_b_cond:
      // For a conditional branch, we re-write it to be an unconditional
      // branch to the stub.  We use the THUMB-2 encoding here.
      upper_insn = 0xf000U;
      lower_insn = 0xb800U;
      // Fall through
    case arm_stub_a8_veneer_b:
    case arm_stub_a8_veneer_bl:
    case arm_stub_a8_veneer_blx:
      if ((lower_insn & 0x5000U) == 0x4000U)
	// For a BLX instruction, make sure that the relocation is
	// rounded up to a word boundary.  This follows the semantics of
	// the instruction which specifies that bit 1 of the target
	// address will come from bit 1 of the base address.
	branch_offset = (branch_offset + 2) & ~3;

      // Put BRANCH_OFFSET back into the insn.
      gold_assert(!Bits<25>::has_overflow32(branch_offset));
      upper_insn = RelocFuncs::thumb32_branch_upper(upper_insn, branch_offset);
      lower_insn = RelocFuncs::thumb32_branch_lower(lower_insn, branch_offset);
      break;

    default:
      gold_unreachable();
    }

  // Put the relocated value back in the object file:
  elfcpp::Swap<16, big_endian>::writeval(wv, upper_insn);
  elfcpp::Swap<16, big_endian>::writeval(wv + 1, lower_insn);
}

// Target selector for ARM.  Note this is never instantiated directly.
// It's only used in Target_selector_arm_nacl, below.

template<bool big_endian>
class Target_selector_arm : public Target_selector
{
 public:
  Target_selector_arm()
    : Target_selector(elfcpp::EM_ARM, 32, big_endian,
		      (big_endian ? "elf32-bigarm" : "elf32-littlearm"),
		      (big_endian ? "armelfb" : "armelf"))
  { }

  Target*
  do_instantiate_target()
  { return new Target_arm<big_endian>(); }
};

// Fix .ARM.exidx section coverage.

template<bool big_endian>
void
Target_arm<big_endian>::fix_exidx_coverage(
    Layout* layout,
    const Input_objects* input_objects,
    Arm_output_section<big_endian>* exidx_section,
    Symbol_table* symtab,
    const Task* task)
{
  // We need to look at all the input sections in output in ascending
  // order of of output address.  We do that by building a sorted list
  // of output sections by addresses.  Then we looks at the output sections
  // in order.  The input sections in an output section are already sorted
  // by addresses within the output section.

  typedef std::set<Output_section*, output_section_address_less_than>
      Sorted_output_section_list;
  Sorted_output_section_list sorted_output_sections;

  // Find out all the output sections of input sections pointed by
  // EXIDX input sections.
  for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
       p != input_objects->relobj_end();
       ++p)
    {
      Arm_relobj<big_endian>* arm_relobj =
	Arm_relobj<big_endian>::as_arm_relobj(*p);
      std::vector<unsigned int> shndx_list;
      arm_relobj->get_exidx_shndx_list(&shndx_list);
      for (size_t i = 0; i < shndx_list.size(); ++i)
	{
	  const Arm_exidx_input_section* exidx_input_section =
	    arm_relobj->exidx_input_section_by_shndx(shndx_list[i]);
	  gold_assert(exidx_input_section != NULL);
	  if (!exidx_input_section->has_errors())
	    {
	      unsigned int text_shndx = exidx_input_section->link();
	      Output_section* os = arm_relobj->output_section(text_shndx);
	      if (os != NULL && (os->flags() & elfcpp::SHF_ALLOC) != 0)
		sorted_output_sections.insert(os);
	    }
	}
    }

  // Go over the output sections in ascending order of output addresses.
  typedef typename Arm_output_section<big_endian>::Text_section_list
      Text_section_list;
  Text_section_list sorted_text_sections;
  for (typename Sorted_output_section_list::iterator p =
	sorted_output_sections.begin();
      p != sorted_output_sections.end();
      ++p)
    {
      Arm_output_section<big_endian>* arm_output_section =
	Arm_output_section<big_endian>::as_arm_output_section(*p);
      arm_output_section->append_text_sections_to_list(&sorted_text_sections);
    }

  exidx_section->fix_exidx_coverage(layout, sorted_text_sections, symtab,
				    merge_exidx_entries(), task);
}

template<bool big_endian>
void
Target_arm<big_endian>::do_define_standard_symbols(
    Symbol_table* symtab,
    Layout* layout)
{
  // Handle the .ARM.exidx section.
  Output_section* exidx_section = layout->find_output_section(".ARM.exidx");

  if (exidx_section != NULL)
    {
      // Create __exidx_start and __exidx_end symbols.
      symtab->define_in_output_data("__exidx_start",
				    NULL, // version
				    Symbol_table::PREDEFINED,
				    exidx_section,
				    0, // value
				    0, // symsize
				    elfcpp::STT_NOTYPE,
				    elfcpp::STB_GLOBAL,
				    elfcpp::STV_HIDDEN,
				    0, // nonvis
				    false, // offset_is_from_end
				    true); // only_if_ref

      symtab->define_in_output_data("__exidx_end",
				    NULL, // version
				    Symbol_table::PREDEFINED,
				    exidx_section,
				    0, // value
				    0, // symsize
				    elfcpp::STT_NOTYPE,
				    elfcpp::STB_GLOBAL,
				    elfcpp::STV_HIDDEN,
				    0, // nonvis
				    true, // offset_is_from_end
				    true); // only_if_ref
    }
  else
    {
      // Define __exidx_start and __exidx_end even when .ARM.exidx
      // section is missing to match ld's behaviour.
      symtab->define_as_constant("__exidx_start", NULL,
				 Symbol_table::PREDEFINED,
				 0, 0, elfcpp::STT_OBJECT,
				 elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
				 true, false);
      symtab->define_as_constant("__exidx_end", NULL,
				 Symbol_table::PREDEFINED,
				 0, 0, elfcpp::STT_OBJECT,
				 elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
				 true, false);
    }
}

// NaCl variant.  It uses different PLT contents.

template<bool big_endian>
class Output_data_plt_arm_nacl;

template<bool big_endian>
class Target_arm_nacl : public Target_arm<big_endian>
{
 public:
  Target_arm_nacl()
    : Target_arm<big_endian>(&arm_nacl_info)
  { }

 protected:
  virtual Output_data_plt_arm<big_endian>*
  do_make_data_plt(Layout* layout, Output_data_space* got_plt)
  { return new Output_data_plt_arm_nacl<big_endian>(layout, got_plt); }

 private:
  static const Target::Target_info arm_nacl_info;
};

template<bool big_endian>
const Target::Target_info Target_arm_nacl<big_endian>::arm_nacl_info =
{
  32,			// size
  big_endian,		// is_big_endian
  elfcpp::EM_ARM,	// 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-nacl-arm.so.1", // dynamic_linker
  0x20000,		// default_text_segment_address
  0x10000,		// abi_pagesize (overridable by -z max-page-size)
  0x10000,		// common_pagesize (overridable by -z common-page-size)
  true,                 // isolate_execinstr
  0x10000000,           // rosegment_gap
  elfcpp::SHN_UNDEF,	// small_common_shndx
  elfcpp::SHN_UNDEF,	// large_common_shndx
  0,			// small_common_section_flags
  0,			// large_common_section_flags
  ".ARM.attributes",	// attributes_section
  "aeabi"		// attributes_vendor
};

template<bool big_endian>
class Output_data_plt_arm_nacl : public Output_data_plt_arm<big_endian>
{
 public:
  Output_data_plt_arm_nacl(Layout* layout, Output_data_space* got_plt)
    : Output_data_plt_arm<big_endian>(layout, 16, got_plt)
  { }

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

  // Return the size of a PLT entry.
  virtual unsigned int
  do_get_plt_entry_size() const
  { return sizeof(plt_entry); }

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

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

 private:
  inline uint32_t arm_movw_immediate(uint32_t value)
  {
    return (value & 0x00000fff) | ((value & 0x0000f000) << 4);
  }

  inline uint32_t arm_movt_immediate(uint32_t value)
  {
    return ((value & 0x0fff0000) >> 16) | ((value & 0xf0000000) >> 12);
  }

  // Template for the first PLT entry.
  static const uint32_t first_plt_entry[16];

  // Template for subsequent PLT entries.
  static const uint32_t plt_entry[4];
};

// The first entry in the PLT.
template<bool big_endian>
const uint32_t Output_data_plt_arm_nacl<big_endian>::first_plt_entry[16] =
{
  // First bundle:
  0xe300c000,                           // movw	ip, #:lower16:&GOT[2]-.+8
  0xe340c000,                           // movt	ip, #:upper16:&GOT[2]-.+8
  0xe08cc00f,                           // add	ip, ip, pc
  0xe52dc008,                           // str	ip, [sp, #-8]!
  // Second bundle:
  0xe7dfcf1f,                           // bfc	ip, #30, #2
  0xe59cc000,                           // ldr	ip, [ip]
  0xe3ccc13f,                           // bic	ip, ip, #0xc000000f
  0xe12fff1c,                           // bx	ip
  // Third bundle:
  0xe320f000,                           // nop
  0xe320f000,                           // nop
  0xe320f000,                           // nop
  // .Lplt_tail:
  0xe50dc004,                           // str	ip, [sp, #-4]
  // Fourth bundle:
  0xe7dfcf1f,                           // bfc	ip, #30, #2
  0xe59cc000,                           // ldr	ip, [ip]
  0xe3ccc13f,                           // bic	ip, ip, #0xc000000f
  0xe12fff1c,                           // bx	ip
};

template<bool big_endian>
void
Output_data_plt_arm_nacl<big_endian>::do_fill_first_plt_entry(
    unsigned char* pov,
    Arm_address got_address,
    Arm_address plt_address)
{
  // Write first PLT entry.  All but first two words are constants.
  const size_t num_first_plt_words = (sizeof(first_plt_entry)
				      / sizeof(first_plt_entry[0]));

  int32_t got_displacement = got_address + 8 - (plt_address + 16);

  elfcpp::Swap<32, big_endian>::writeval
    (pov + 0, first_plt_entry[0] | arm_movw_immediate (got_displacement));
  elfcpp::Swap<32, big_endian>::writeval
    (pov + 4, first_plt_entry[1] | arm_movt_immediate (got_displacement));

  for (size_t i = 2; i < num_first_plt_words; ++i)
    elfcpp::Swap<32, big_endian>::writeval(pov + i * 4, first_plt_entry[i]);
}

// Subsequent entries in the PLT.

template<bool big_endian>
const uint32_t Output_data_plt_arm_nacl<big_endian>::plt_entry[4] =
{
  0xe300c000,                           // movw	ip, #:lower16:&GOT[n]-.+8
  0xe340c000,                           // movt	ip, #:upper16:&GOT[n]-.+8
  0xe08cc00f,                           // add	ip, ip, pc
  0xea000000,                           // b	.Lplt_tail
};

template<bool big_endian>
void
Output_data_plt_arm_nacl<big_endian>::do_fill_plt_entry(
    unsigned char* pov,
    Arm_address got_address,
    Arm_address plt_address,
    unsigned int got_offset,
    unsigned int plt_offset)
{
  // Calculate the displacement between the PLT slot and the
  // common tail that's part of the special initial PLT slot.
  int32_t tail_displacement = (plt_address + (11 * sizeof(uint32_t))
			       - (plt_address + plt_offset
				  + sizeof(plt_entry) + sizeof(uint32_t)));
  gold_assert((tail_displacement & 3) == 0);
  tail_displacement >>= 2;

  gold_assert ((tail_displacement & 0xff000000) == 0
	       || (-tail_displacement & 0xff000000) == 0);

  // Calculate the displacement between the PLT slot and the entry
  // in the GOT.  The offset accounts for the value produced by
  // adding to pc in the penultimate instruction of the PLT stub.
  const int32_t got_displacement = (got_address + got_offset
				    - (plt_address + sizeof(plt_entry)));

  elfcpp::Swap<32, big_endian>::writeval
    (pov + 0, plt_entry[0] | arm_movw_immediate (got_displacement));
  elfcpp::Swap<32, big_endian>::writeval
    (pov + 4, plt_entry[1] | arm_movt_immediate (got_displacement));
  elfcpp::Swap<32, big_endian>::writeval
    (pov + 8, plt_entry[2]);
  elfcpp::Swap<32, big_endian>::writeval
    (pov + 12, plt_entry[3] | (tail_displacement & 0x00ffffff));
}

// Target selectors.

template<bool big_endian>
class Target_selector_arm_nacl
  : public Target_selector_nacl<Target_selector_arm<big_endian>,
				Target_arm_nacl<big_endian> >
{
 public:
  Target_selector_arm_nacl()
    : Target_selector_nacl<Target_selector_arm<big_endian>,
			   Target_arm_nacl<big_endian> >(
	  "arm",
	  big_endian ? "elf32-bigarm-nacl" : "elf32-littlearm-nacl",
	  big_endian ? "armelfb_nacl" : "armelf_nacl")
  { }
};

Target_selector_arm_nacl<false> target_selector_arm;
Target_selector_arm_nacl<true> target_selector_armbe;

} // End anonymous namespace.
