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

// Copyright 2009, 2010 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"

namespace
{

using namespace gold;

template<bool big_endian>
class Output_data_plt_arm;

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 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 invalid index.  This points to a global symbol.
    // Otherwise, this points a relobj.  We used the unsized and target
    // independent Symbol and Relobj classes instead of Sized_symbol<32> and  
    // Arm_relobj.  This is done 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 with using KEY.  Caller is reponsible for avoid adding
  // if already a STUB with the same key has 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.
  // Caller is reponsible for avoid adding if already a STUB with the same
  // address has 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
  // reponsible 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;

  Arm_output_section(const char* name, elfcpp::Elf_Word type,
		     elfcpp::Elf_Xword flags)
    : Output_section(name, type, 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<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<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<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<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 reloction 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<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<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<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<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<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 incontigious
// 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.
	  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;
	  default:
	    // For all other static relocations, return RELOC_SPECIAL.
	    return Relocatable_relocs::RELOC_SPECIAL;
	  }
      }
  }
};

// Utilities for manipulating integers of up to 32-bits

namespace utils
{
  // Sign extend an n-bit unsigned integer stored in an uint32_t into
  // an int32_t.  NO_BITS must be between 1 to 32.
  template<int no_bits>
  static inline int32_t
  sign_extend(uint32_t bits)
  {
    gold_assert(no_bits >= 0 && no_bits <= 32);
    if (no_bits == 32)
      return static_cast<int32_t>(bits);
    uint32_t mask = (~((uint32_t) 0)) >> (32 - no_bits);
    bits &= mask;
    uint32_t top_bit = 1U << (no_bits - 1);
    int32_t as_signed = static_cast<int32_t>(bits);
    return (bits & top_bit) ? as_signed + (-top_bit * 2) : as_signed;
  }

  // Detects overflow of an NO_BITS integer stored in a uint32_t.
  template<int no_bits>
  static inline bool
  has_overflow(uint32_t bits)
  {
    gold_assert(no_bits >= 0 && no_bits <= 32);
    if (no_bits == 32)
      return false;
    int32_t max = (1 << (no_bits - 1)) - 1;
    int32_t min = -(1 << (no_bits - 1));
    int32_t as_signed = static_cast<int32_t>(bits);
    return as_signed > max || as_signed < min;
  }

  // Detects overflow of an NO_BITS integer stored in a uint32_t when it
  // fits in the given number of bits as either a signed or unsigned value.
  // For example, has_signed_unsigned_overflow<8> would check
  // -128 <= bits <= 255
  template<int no_bits>
  static inline bool
  has_signed_unsigned_overflow(uint32_t bits)
  {
    gold_assert(no_bits >= 2 && no_bits <= 32);
    if (no_bits == 32)
      return false;
    int32_t max = static_cast<int32_t>((1U << no_bits) - 1);
    int32_t min = -(1 << (no_bits - 1));
    int32_t as_signed = static_cast<int32_t>(bits);
    return as_signed > max || as_signed < min;
  }

  // Select bits from A and B using bits in MASK.  For each n in [0..31],
  // the n-th bit in the result is chosen from the n-th bits of A and B.
  // A zero selects A and a one selects B.
  static inline uint32_t
  bit_select(uint32_t a, uint32_t b, uint32_t mask)
  { return (a & ~mask) | (b & mask); }
};

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()
    : Sized_target<32, big_endian>(&arm_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()),
      may_use_blx_(false), should_force_pic_veneer_(false),
      arm_input_section_map_(), attributes_section_data_(NULL),
      fix_cortex_a8_(false), cortex_a8_relocs_info_()
  { }

  // 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
  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
  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::section_may_have_icf_unsafe_pointers(section_name));
  }
  
  // Whether we can use BLX.
  bool
  may_use_blx() const
  { return this->may_use_blx_; }

  // Set use-BLX flag.
  void
  set_may_use_blx(bool value)
  { this->may_use_blx_ = value; }
  
  // 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);
  }
  
  // Process the relocations to determine unreferenced sections for 
  // garbage collection.
  void
  gc_process_relocs(Symbol_table* symtab,
		    Layout* layout,
		    Sized_relobj<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<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<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,
			   off_t 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,
			       off_t 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(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 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();
  }

 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<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<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<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<32, big_endian>* ,
	           			 unsigned int ,
	           			 Output_section* ,
	           			 const elfcpp::Rel<32, big_endian>& ,
					 unsigned int , Symbol*);

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

    static void
    unsupported_reloc_global(Sized_relobj<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<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<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 can use BLX.
  bool may_use_blx_;
  // 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
  '\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)
  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 oveflow.
    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 utils::sign_extend<16>(((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 utils::sign_extend<16>(((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 utils::sign_extend<25>((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 utils::sign_extend<21>((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.
  // Caller is reponsible 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<32, big_endian>* object,
       const Symbol_value<32>* psymval)
  {
    typedef typename elfcpp::Swap<8, big_endian>::Valtype Valtype;
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Reltype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype val = elfcpp::Swap<8, big_endian>::readval(wv);
    Reltype addend = utils::sign_extend<8>(val);
    Reltype x = psymval->value(object, addend);
    val = utils::bit_select(val, x, 0xffU);
    elfcpp::Swap<8, big_endian>::writeval(wv, val);

    // R_ARM_ABS8 permits signed or unsigned results.
    int signed_x = static_cast<int32_t>(x);
    return ((signed_x < -128 || signed_x > 255)
	    ? 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<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 = utils::bit_select(val, x << 6, 0x7e0U);
    elfcpp::Swap<16, big_endian>::writeval(wv, val);

    // R_ARM_ABS16 permits signed or unsigned results.
    int signed_x = static_cast<int32_t>(x);
    return ((signed_x < -32768 || signed_x > 65535)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_ABS12: S + A
  static inline typename This::Status
  abs12(unsigned char* view,
	const Sized_relobj<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 = utils::bit_select(val, x, 0x0fffU);
    elfcpp::Swap<32, big_endian>::writeval(wv, val);
    return (utils::has_overflow<12>(x)
	    ? This::STATUS_OVERFLOW
	    : This::STATUS_OKAY);
  }

  // R_ARM_ABS16: S + A
  static inline typename This::Status
  abs16(unsigned char* view,
	const Sized_relobj<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 = utils::sign_extend<16>(val);
    Reltype x = psymval->value(object, addend);
    val = utils::bit_select(val, x, 0xffffU);
    elfcpp::Swap<16, big_endian>::writeval(wv, val);
    return (utils::has_signed_unsigned_overflow<16>(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<32, big_endian>* object,
	const Symbol_value<32>* psymval,
	Arm_address thumb_bit)
  {
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype addend = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype x = psymval->value(object, addend) | thumb_bit;
    elfcpp::Swap<32, big_endian>::writeval(wv, x);
    return This::STATUS_OKAY;
  }

  // R_ARM_REL32: (S + A) | T - P
  static inline typename This::Status
  rel32(unsigned char* view,
	const Sized_relobj<32, big_endian>* object,
	const Symbol_value<32>* psymval,
	Arm_address address,
	Arm_address thumb_bit)
  {
    typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
    Valtype* wv = reinterpret_cast<Valtype*>(view);
    Valtype addend = elfcpp::Swap<32, big_endian>::readval(wv);
    Valtype x = (psymval->value(object, addend) | thumb_bit) - address;
    elfcpp::Swap<32, big_endian>::writeval(wv, 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<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<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);
    Reltype addend = utils::sign_extend<8>((val & 0x00ff) << 1);
    Reltype x = (psymval->value(object, addend) - address);
    elfcpp::Swap<16, big_endian>::writeval(wv, (val & 0xff00) | ((x & 0x01fe) >> 1));
    return (utils::has_overflow<8>(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<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);
    Reltype addend = utils::sign_extend<11>((val & 0x07ff) << 1);
    Reltype x = (psymval->value(object, addend) - address);
    elfcpp::Swap<16, big_endian>::writeval(wv, (val & 0xf800) | ((x & 0x0ffe) >> 1));
    return (utils::has_overflow<11>(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<32, big_endian>* object,
	 const Symbol_value<32>* psymval,
	 Arm_address address,
	 Arm_address thumb_bit)
  {
    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 = utils::sign_extend<31>(val);
    Valtype x = (psymval->value(object, addend) | thumb_bit) - address;
    val = utils::bit_select(val, x, 0x7fffffffU);
    elfcpp::Swap<32, big_endian>::writeval(wv, val);
    return (utils::has_overflow<31>(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<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 && utils::has_overflow<16>(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<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<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 && utils::has_overflow<16>(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<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<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<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<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<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<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<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<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 = utils::sign_extend<26>(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_blx();
  Reloc_stub* stub = NULL;

  if (!parameters->options().relocatable()
      && (utils::has_overflow<26>(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(!utils::has_overflow<26>(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 = utils::bit_select(val, (branch_offset >> 2), 0xffffffUL);
  elfcpp::Swap<32, big_endian>::writeval(wv, val);
  return (utils::has_overflow<26>(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_blx();
  if (thumb_bit == 0 && may_use_blx)
    branch_target = utils::bit_select(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 && utils::has_overflow<23>(branch_offset))
	  || (thumb2 && utils::has_overflow<25>(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 = utils::bit_select(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(!utils::has_overflow<25>(branch_offset));

  return ((thumb2
	   ? utils::has_overflow<25>(branch_offset)
	   : utils::has_overflow<23>(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 (utils::has_overflow<21>(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);

      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_, ORDER_DATA, false);

      // 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_, ORDER_DATA, false);

      // 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 liitle 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_blx();
      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_blx();
      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;
  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 = utils::bit_select(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 = (parameters->options().shared()
			       || 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 = (parameters->options().shared()
			       || 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 = (parameters->options().shared()
			   || 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 = (parameters->options().shared()
			   || 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 = (parameters->options().shared()
			   || 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.

// Removel 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);
  
  typedef typename elfcpp::Swap<32, big_endian>::Valtype Valtype;
  Valtype* wv = reinterpret_cast<Valtype*>(oview);

  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 (utils::has_overflow<31>(offset))
    gold_error(_("PREL31 overflow in EXIDX_CANTUNWIND entry"));
  elfcpp::Swap<32, big_endian>::writeval(wv, prel31_offset & 0x7fffffffU);
  elfcpp::Swap<32, big_endian>::writeval(wv + 1, 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.  Othewise, 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 seens 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())
	  && p->data_size() != 0)
	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 targer hook inside
// Sized_relobj<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<32, big_endian>::do_count_local_symbols(pool, dynpool);
  const unsigned int loccount = this->local_symbol_count();
  if (loccount == 0)
    return;

  // Intialize 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<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<32, big_endian>::Views* pviews)
{
  // Call parent to relocate sections.
  Sized_relobj<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 the the first
// relocation.  4.4.1 of the EHABI specifications says that an EXIDX section
// must be linked to 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 currenlty 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<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 implict
// 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<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<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 struct 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 utils::sign_extend<26>(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<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<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.

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*, 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.
  static unsigned int
  first_plt_entry_offset()
  { return sizeof(first_plt_entry); }

  // Return the size of a PLT entry.
  static unsigned int
  get_plt_entry_size()
  { return sizeof(plt_entry); }

 protected:
  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:
  // 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];

  // Set the final size.
  void
  set_final_data_size()
  {
    this->set_data_size(sizeof(first_plt_entry)
			+ this->count_ * sizeof(plt_entry));
  }

  // 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,
						     Output_data_space* got_plt)
  : Output_section_data(4), 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_) * sizeof(plt_entry)
		       + sizeof(first_plt_entry));

  ++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.
}

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

// Subsequent entries in the PLT.

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

// 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.  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));
  pov += sizeof(first_plt_entry);

  unsigned char* got_pov = got_view;

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

  const int rel_size = elfcpp::Elf_sizes<32>::rel_size;
  unsigned int plt_offset = sizeof(first_plt_entry);
  unsigned int plt_rel_offset = 0;
  unsigned int got_offset = 12;
  const unsigned int count = this->count_;
  for (unsigned int i = 0;
       i < count;
       ++i,
	 pov += sizeof(plt_entry),
	 got_pov += 4,
	 plt_offset += sizeof(plt_entry),
	 plt_rel_offset += rel_size,
	 got_offset += 4)
    {
      // Set and adjust the PLT entry itself.
      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);

      // 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_ = new Output_data_plt_arm<big_endian>(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 Output_data_plt_arm<big_endian>::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 Output_data_plt_arm<big_endian>::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<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_PREL31:
    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:
      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<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<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<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<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<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<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 dyanmic 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())
	      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<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<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* symtab)
{
  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);

  // Check BLX use.
  const Object_attribute* cpu_arch_attr =
    this->get_aeabi_object_attribute(elfcpp::Tag_CPU_arch);
  if (cpu_arch_attr->int_value() > elfcpp::TAG_CPU_ARCH_V4)
    this->set_may_use_blx(true);
 
  // 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_blx())
    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)
        {
          // Create __exidx_start and __exdix_end symbols.
          symtab->define_in_output_data("__exidx_start", NULL,
                                        Symbol_table::PREDEFINED,
                                        exidx_section, 0, 0, elfcpp::STT_OBJECT,
                                        elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN,
                                        0, false, true);
          symtab->define_in_output_data("__exidx_end", NULL,
                                        Symbol_table::PREDEFINED,
                                        exidx_section, 0, 0, elfcpp::STT_OBJECT,
                                        elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN,
                                        0, true, true);

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

  // 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<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(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(view, got_entry, address);
	  return ArmRelocFuncs::STATUS_OKAY;
        }
      break;

    case elfcpp::R_ARM_TLS_LDO32:	// Alternate local-dynamic
      RelocFuncs::rel32(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(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(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<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,
    off_t 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,
    off_t 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 ususally 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<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();
  if (et == elfcpp::ET_REL)
    {
      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-conformant
	      // 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:
	  // Aready 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)
{
  typedef typename Target_arm<big_endian>::Relocate Relocate;

  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<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 goup input sections in an output sections 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_ALWATS_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 restict 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 eveything 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 struct 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_blx() && 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 struct 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 a uncondition
      // 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(!utils::has_overflow<25>(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);
}

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"))
  { }

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

Target_selector_arm<false> target_selector_arm;
Target_selector_arm<true> target_selector_armbe;

} // End anonymous namespace.
